Further cleanup of point types

This commit is contained in:
be5invis 2020-12-05 19:01:16 -08:00
parent 82cea0e06d
commit e58a6965db
14 changed files with 231 additions and 252 deletions

View file

@ -34,47 +34,6 @@ exports.OffsetCurve = class OffsetCurve {
}
};
exports.convertContourToCubic = function convertContourToCubic(contour) {
if (!contour || !contour.length) return [];
const newContour = [];
let z0 = contour[0];
newContour.push(Point.cornerFrom(z0));
for (let j = 1; j < contour.length; j++) {
const z = contour[j];
if (z.on) {
newContour.push(Point.cornerFrom(z));
z0 = z;
} else if (z.cubic) {
const z1 = z;
const z2 = contour[j + 1];
const z3 = contour[j + 2];
newContour.push(Point.cubicOffFrom(z1));
newContour.push(Point.cubicOffFrom(z2));
newContour.push(Point.cornerFrom(z3));
z0 = z3;
j += 2;
} else {
const zc = z;
let zf = contour[j + 1] || contour[0];
const zfIsCorner = zf.on;
if (!zfIsCorner) zf = Point.cornerFrom(zc).mix(0.5, zf);
newContour.push(Point.cubicOffFrom(z0).mix(2 / 3, zc));
newContour.push(Point.cubicOffFrom(zf).mix(2 / 3, zc));
newContour.push(Point.cornerFrom(zf));
z0 = zf;
if (zfIsCorner) j++;
}
}
return newContour;
};
exports.convertShapeToArcs = function convertShapeToArcs(shape) {
return shape.map(convertContourToArcs);
};
@ -83,48 +42,55 @@ function convertContourToArcs(contour) {
if (!contour || !contour.length) return [];
const newContour = [];
let z0 = Point.cornerFrom(contour[0]);
let z0 = Point.from(Point.Type.Corner, contour[0]);
for (let j = 1; j < contour.length; j++) {
const z = contour[j];
if (z.on) {
newContour.push(
TypoGeom.Arcs.Bez3.fromStraightSegment(
new TypoGeom.Arcs.StraightSegment(z0, Point.cornerFrom(z))
)
);
z0 = z;
} else if (z.cubic) {
const z1 = z;
const z2 = contour[j + 1];
const z3 = contour[j + 2];
newContour.push(
new TypoGeom.Arcs.Bez3(
z0,
Point.cubicOffFrom(z1),
Point.cubicOffFrom(z2),
Point.cornerFrom(z3)
)
);
z0 = z3;
j += 2;
} else {
const zc = z;
let zf = contour[j + 1] || contour[0];
const zfIsCorner = zf.on;
if (!zfIsCorner) zf = Point.cornerFrom(zc).mix(0.5, zf);
switch (z.type) {
case Point.Type.CubicStart: {
const z1 = z;
const z2 = contour[j + 1];
const z3 = contour[j + 2];
newContour.push(
new TypoGeom.Arcs.Bez3(
z0,
Point.from(Point.Type.CubicStart, z1),
Point.from(Point.Type.CubicEnd, z2),
Point.from(Point.Type.Corner, z3)
)
);
z0 = z3;
j += 2;
break;
}
case Point.Type.Quadratic: {
const zc = z;
let zf = contour[j + 1] || contour[0];
const zfIsCorner = zf.type === Point.Type.contour;
if (!zfIsCorner) zf = Point.from(Point.Type.Corner, zc).mix(0.5, zf);
newContour.push(
new TypoGeom.Arcs.Bez3(
z0,
Point.cubicOffFrom(z0).mix(2 / 3, zc),
Point.cubicOffFrom(zf).mix(2 / 3, zc),
Point.cornerFrom(zf)
)
);
newContour.push(
new TypoGeom.Arcs.Bez3(
z0,
Point.from(Point.Type.CubicStart, z0).mix(2 / 3, zc),
Point.from(Point.Type.CubicEnd, zf).mix(2 / 3, zc),
Point.from(Point.Type.Corner, zf)
)
);
z0 = zf;
if (zfIsCorner) j++;
z0 = zf;
if (zfIsCorner) j++;
break;
}
default: {
newContour.push(
TypoGeom.Arcs.Bez3.fromStraightSegment(
new TypoGeom.Arcs.StraightSegment(z0, Point.from(Point.Type.Corner, z))
)
);
z0 = z;
break;
}
}
}
@ -146,18 +112,18 @@ exports.BezToContoursSink = class BezToContoursSink {
}
moveTo(x, y) {
this.endShape();
this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y));
}
lineTo(x, y) {
this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y));
}
curveTo(xc, yc, x, y) {
this.lastContour.push(Point.transformedXY(this.gizmo, xc, yc, false, false));
this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Quadratic, xc, yc));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y));
}
cubicTo(x1, y1, x2, y2, x, y) {
this.lastContour.push(Point.transformedXY(this.gizmo, x1, y1, false, true));
this.lastContour.push(Point.transformedXY(this.gizmo, x2, y2, false, true));
this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.CubicStart, x1, y1));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.CubicEnd, x2, y2));
this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y));
}
};

View file

@ -216,7 +216,7 @@ module.exports = class Glyph {
for (let k = 0; k < c1.length; k++) {
const z1 = c1[k],
z2 = c2[k];
if (z1.x !== z2.x || z1.y !== z2.y || z1.on !== z2.on) return;
if (z1.x !== z2.x || z1.y !== z2.y || z1.type !== z2.type) return;
}
}
this.semanticInclusions = [

View file

@ -1,71 +1,63 @@
"use strict";
module.exports = class Point {
constructor(x, y, on, cubic) {
class Point {
constructor(type, x, y) {
this.type = type;
this.x = x;
this.y = y;
this.on = on;
this.cubic = cubic;
}
get on() {
throw new Error("Unreachable");
}
get cubic() {
throw new Error("Unreachable");
}
add(z2) {
return this.addScale(1, z2);
}
addScale(scale, z2) {
return new Point(this.x + scale * z2.x, this.y + scale * z2.y, this.on, this.cubic);
return new Point(this.type, this.x + scale * z2.x, this.y + scale * z2.y);
}
mix(scale, z2) {
return new Point(
this.type,
this.x + scale * (z2.x - this.x),
this.y + scale * (z2.y - this.y),
this.on,
this.cubic
this.y + scale * (z2.y - this.y)
);
}
scale(t) {
return new Point(t * this.x, t * this.y, this.on, this.cubic);
return new Point(this.type, t * this.x, t * this.y);
}
round(d) {
return new Point(
Math.round(d * this.x) / d,
Math.round(d * this.y) / d,
this.on,
this.cubic
);
return new Point(this.type, Math.round(d * this.x) / d, Math.round(d * this.y) / d);
}
static from(z, on, cubic) {
return new Point(z.x || 0, z.y || 0, on, cubic);
static from(type, z) {
return new Point(type, z.x || 0, z.y || 0);
}
static cornerFrom(z) {
return new Point(z.x || 0, z.y || 0, true, false);
}
static offFrom(z) {
return new Point(z.x || 0, z.y || 0, false, false);
}
static cubicOffFrom(z) {
return new Point(z.x || 0, z.y || 0, false, true);
}
static cornerFromXY(x, y) {
return new Point(x || 0, y || 0, true, false);
}
static offFromXY(x, y) {
return new Point(x || 0, y || 0, false, false);
}
static cubicOffFromXY(x, y) {
return new Point(x || 0, y || 0, false, true);
static fromXY(type, x, y) {
return new Point(type, x || 0, y || 0);
}
static transformed(tfm, z) {
return Point.transformedXY(tfm, z.x, z.y, z.on, z.cubic);
return Point.transformedXY(tfm, z.type, z.x, z.y);
}
static transformedXY(tfm, x, y, on, cubic) {
static transformedXY(tfm, type, x, y) {
return new Point(
type,
x * tfm.xx + y * tfm.yx + tfm.x || 0,
x * tfm.xy + y * tfm.yy + tfm.y || 0,
on,
cubic
x * tfm.xy + y * tfm.yy + tfm.y || 0
);
}
static translated(z, dx, dy) {
return new Point(z.x + dx || 0, z.y + dy || 0, z.on, z.cubic);
return new Point(z.type, z.x + dx || 0, z.y + dy || 0);
}
}
Point.Type = {
Corner: 0,
CubicStart: 1,
CubicEnd: 2,
Quadratic: 3
};
module.exports = Point;