Fix rounding errors found in certain Extended glyphs (#1100).
This commit is contained in:
parent
a16554a244
commit
b7e7752109
3 changed files with 23 additions and 5 deletions
|
@ -1,2 +1,3 @@
|
||||||
* Fix Aile's long-S at Italic (#1098).
|
* Fix Aile's long-S at Italic (#1098).
|
||||||
* Fix assignment of capital Gamma in `ss14` (#1099).
|
* Fix assignment of capital Gamma in `ss14` (#1099).
|
||||||
|
* Fix rounding errors found in certain Extended glyphs (#1100).
|
|
@ -4,7 +4,7 @@ const fs = require("fs-extra");
|
||||||
const zlib = require("zlib");
|
const zlib = require("zlib");
|
||||||
const { encode, decode } = require("@msgpack/msgpack");
|
const { encode, decode } = require("@msgpack/msgpack");
|
||||||
|
|
||||||
const Edition = 4;
|
const Edition = 5;
|
||||||
const MAX_AGE = 5;
|
const MAX_AGE = 5;
|
||||||
|
|
||||||
class GfEntry {
|
class GfEntry {
|
||||||
|
|
|
@ -121,11 +121,13 @@ class SimplifyGeometry extends Geom.GeometryBase {
|
||||||
|
|
||||||
class FairizedShapeSink {
|
class FairizedShapeSink {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.lastReferenceZ = null;
|
||||||
this.contours = [];
|
this.contours = [];
|
||||||
this.lastContour = [];
|
this.lastContour = [];
|
||||||
}
|
}
|
||||||
beginShape() {}
|
beginShape() {}
|
||||||
endShape() {
|
endShape() {
|
||||||
|
this.lastReferenceZ = null;
|
||||||
if (this.lastContour.length > 2) {
|
if (this.lastContour.length > 2) {
|
||||||
// TT use CW for outline, being different from Clipper
|
// TT use CW for outline, being different from Clipper
|
||||||
const c = this.lastContour.reverse();
|
const c = this.lastContour.reverse();
|
||||||
|
@ -136,20 +138,32 @@ class FairizedShapeSink {
|
||||||
}
|
}
|
||||||
this.lastContour = [];
|
this.lastContour = [];
|
||||||
}
|
}
|
||||||
|
tryAlignWithPreviousKnot(z) {
|
||||||
|
if (!this.lastReferenceZ) return z;
|
||||||
|
let x1 = z.x,
|
||||||
|
y1 = z.y;
|
||||||
|
if (geometryPrecisionEqual(x1, this.lastReferenceZ.x)) x1 = this.lastReferenceZ.x;
|
||||||
|
if (geometryPrecisionEqual(y1, this.lastReferenceZ.y)) y1 = this.lastReferenceZ.y;
|
||||||
|
return Point.fromXY(z.type, x1, y1).round(CurveUtil.GEOMETRY_PRECISION);
|
||||||
|
}
|
||||||
moveTo(x, y) {
|
moveTo(x, y) {
|
||||||
this.endShape();
|
this.endShape();
|
||||||
this.lineTo(x, y);
|
this.lineTo(x, y);
|
||||||
}
|
}
|
||||||
lineTo(x, y) {
|
lineTo(x, y) {
|
||||||
const z = Point.fromXY(Point.Type.Corner, x, y).round(1);
|
const z0 = Point.fromXY(Point.Type.Corner, x, y);
|
||||||
|
const z = this.tryAlignWithPreviousKnot(z0);
|
||||||
this.popOccurrentKnots(z);
|
this.popOccurrentKnots(z);
|
||||||
this.popColinearKnots(z);
|
this.popColinearKnots(z);
|
||||||
this.lastContour.push(z);
|
this.lastContour.push(z);
|
||||||
|
this.lastReferenceZ = z0;
|
||||||
}
|
}
|
||||||
arcTo(arc, x, y) {
|
arcTo(arc, x, y) {
|
||||||
const offPoints = TypoGeom.Quadify.auto(arc, 1, 8);
|
const offPoints = TypoGeom.Quadify.auto(arc, 1, 8);
|
||||||
for (const z of offPoints) {
|
for (const z of offPoints) {
|
||||||
this.lastContour.push(Point.from(Point.Type.Quadratic, z).round(1));
|
this.lastContour.push(
|
||||||
|
this.tryAlignWithPreviousKnot(Point.from(Point.Type.Quadratic, z))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.lineTo(x, y);
|
this.lineTo(x, y);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +209,10 @@ function isOccurrent(zFirst, zLast) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
function geometryPrecisionEqual(a, b) {
|
function geometryPrecisionEqual(a, b) {
|
||||||
return Math.round(a) === Math.round(b);
|
return (
|
||||||
|
Math.round(a * CurveUtil.RECIP_GEOMETRY_PRECISION) ===
|
||||||
|
Math.round(b * CurveUtil.RECIP_GEOMETRY_PRECISION)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function aligned(a, b, c) {
|
function aligned(a, b, c) {
|
||||||
return geometryPrecisionEqual(a, b) && geometryPrecisionEqual(b, c);
|
return geometryPrecisionEqual(a, b) && geometryPrecisionEqual(b, c);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue