Add frakturs in the Letterlike Symbols (#2438)
* * Add characters: - BLACK-LETTER CAPITAL I (`U+2111`). - BLACK-LETTER CAPITAL R (`U+211C`). * Complete frakturs in Letterlike Symbols block * Update geom cache version
This commit is contained in:
parent
61ad3c365c
commit
bff9e0b1c5
11 changed files with 496 additions and 8 deletions
|
@ -5,6 +5,7 @@ import * as CurveUtil from "./curve-util.mjs";
|
|||
import { Point } from "./point.mjs";
|
||||
import { QuadifySink } from "./quadify.mjs";
|
||||
import { SpiroExpander } from "./spiro-expand.mjs";
|
||||
import { createSpiroPenGeometry } from "./spiro-pen-expander.mjs";
|
||||
import { spiroToOutlineWithSimplification } from "./spiro-to-outline.mjs";
|
||||
import { strokeArcs } from "./stroke.mjs";
|
||||
import { Transform } from "./transform.mjs";
|
||||
|
@ -139,6 +140,83 @@ export class SpiroGeometry extends CachedGeometry {
|
|||
}
|
||||
}
|
||||
|
||||
export class SpiroPenGeometry extends CachedGeometry {
|
||||
constructor(gizmo, closed, pen, knots) {
|
||||
super();
|
||||
this.m_gizmo = gizmo;
|
||||
this.m_closed = closed;
|
||||
this.m_knots = knots;
|
||||
this.m_pen = pen;
|
||||
}
|
||||
|
||||
toContoursImpl() {
|
||||
let contours = createSpiroPenGeometry(
|
||||
this.m_gizmo,
|
||||
this.m_closed,
|
||||
this.m_knots,
|
||||
this.m_pen,
|
||||
);
|
||||
|
||||
if (!contours.length) return [];
|
||||
|
||||
let stack = [];
|
||||
for (const [i, c] of contours.entries()) {
|
||||
stack.push({
|
||||
type: "operand",
|
||||
fillType: TypoGeom.Boolean.PolyFillType.pftNonZero,
|
||||
shape: CurveUtil.convertShapeToArcs([c]),
|
||||
});
|
||||
if (i > 0) {
|
||||
stack.push({ type: "operator", operator: TypoGeom.Boolean.ClipType.ctUnion });
|
||||
}
|
||||
}
|
||||
|
||||
const arcs = TypoGeom.Boolean.combineStack(stack, CurveUtil.BOOLE_RESOLUTION);
|
||||
const ctx = new CurveUtil.BezToContoursSink();
|
||||
TypoGeom.ShapeConv.transferBezArcShape(arcs, ctx);
|
||||
return ctx.contours;
|
||||
}
|
||||
|
||||
toReferences() {
|
||||
return null;
|
||||
}
|
||||
getDependencies() {
|
||||
return null;
|
||||
}
|
||||
filterTag(fn) {
|
||||
return this;
|
||||
}
|
||||
|
||||
measureComplexity() {
|
||||
let cplx = CPLX_NON_EMPTY | CPLX_NON_SIMPLE;
|
||||
for (const z of this.m_pen) {
|
||||
if (!isFinite(z.x) || !isFinite(z.y)) cplx |= CPLX_BROKEN;
|
||||
}
|
||||
for (const z of this.m_knots) {
|
||||
if (!isFinite(z.x) || !isFinite(z.y)) cplx |= CPLX_BROKEN;
|
||||
}
|
||||
return cplx;
|
||||
}
|
||||
|
||||
hash(h) {
|
||||
h.beginStruct("SpiroPenGeometry");
|
||||
h.gizmo(this.m_gizmo);
|
||||
h.bool(this.m_closed);
|
||||
|
||||
// Serialize the pen
|
||||
h.beginArray(this.m_pen.length);
|
||||
for (const z of this.m_pen) h.point(z);
|
||||
h.endArray();
|
||||
|
||||
// Serialize the knots
|
||||
h.beginArray(this.m_knots.length);
|
||||
for (const knot of this.m_knots) h.embed(knot);
|
||||
h.endArray();
|
||||
|
||||
h.endStruct();
|
||||
}
|
||||
}
|
||||
|
||||
export class DiSpiroGeometry extends CachedGeometry {
|
||||
constructor(gizmo, contrast, closed, biKnots) {
|
||||
super();
|
||||
|
|
81
packages/geometry/src/spiro-pen-expander.mjs
Normal file
81
packages/geometry/src/spiro-pen-expander.mjs
Normal file
|
@ -0,0 +1,81 @@
|
|||
import * as SpiroJs from "spiro";
|
||||
import * as CurveUtil from "./curve-util.mjs";
|
||||
|
||||
import { Point } from "./point.mjs";
|
||||
|
||||
export function createSpiroPenGeometry(gizmo, closed, knots, pen) {
|
||||
const collector = new ArcCollector(gizmo, pen);
|
||||
SpiroJs.spiroToBezierOnContext(knots, closed, collector, CurveUtil.GEOMETRY_PRECISION);
|
||||
return collector.contoursCollected;
|
||||
}
|
||||
|
||||
class ArcCollector {
|
||||
constructor(gizmo, pen) {
|
||||
this.gizmo = gizmo;
|
||||
this.lastX = 0;
|
||||
this.lastY = 0;
|
||||
this.m_pen = pen;
|
||||
this.contoursCollected = [];
|
||||
}
|
||||
|
||||
beginShape() {}
|
||||
endShape() {}
|
||||
|
||||
moveTo(x, y) {
|
||||
const lastTf = this.gizmo.applyXY(x, y);
|
||||
this.lastX = lastTf.x;
|
||||
this.lastY = lastTf.y;
|
||||
this.addPenProfileAt(this.lastX, this.lastY);
|
||||
}
|
||||
|
||||
lineTo(x1, y1) {
|
||||
const z1 = this.gizmo.applyXY(x1, y1);
|
||||
for (let i = 0; i < this.m_pen.length; i++) {
|
||||
let penPrev = this.m_pen[i];
|
||||
let penNext = this.m_pen[(i + 1) % this.m_pen.length];
|
||||
|
||||
const l1 = new Point(Point.Type.Corner, this.lastX + penPrev.x, this.lastY + penPrev.y);
|
||||
const l2 = new Point(Point.Type.Corner, z1.x + penPrev.x, z1.y + penPrev.y);
|
||||
const r2 = new Point(Point.Type.Corner, z1.x + penNext.x, z1.y + penNext.y);
|
||||
const r1 = new Point(Point.Type.Corner, this.lastX + penNext.x, this.lastY + penNext.y);
|
||||
|
||||
this.contoursCollected.push([l1, l2, r2, r1]);
|
||||
}
|
||||
this.lastX = z1.x;
|
||||
this.lastY = z1.y;
|
||||
this.addPenProfileAt(this.lastX, this.lastY);
|
||||
}
|
||||
|
||||
cubicTo(x2, y2, x3, y3, x4, y4) {
|
||||
const z2 = this.gizmo.applyXY(x2, y2);
|
||||
const z3 = this.gizmo.applyXY(x3, y3);
|
||||
const z4 = this.gizmo.applyXY(x4, y4);
|
||||
for (let i = 0; i < this.m_pen.length; i++) {
|
||||
let penPrev = this.m_pen[i];
|
||||
let penNext = this.m_pen[(i + 1) % this.m_pen.length];
|
||||
|
||||
const l1 = new Point(Point.Type.Corner, this.lastX + penPrev.x, this.lastY + penPrev.y);
|
||||
const l2 = new Point(Point.Type.CubicStart, z2.x + penPrev.x, z2.y + penPrev.y);
|
||||
const l3 = new Point(Point.Type.CubicEnd, z3.x + penPrev.x, z3.y + penPrev.y);
|
||||
const l4 = new Point(Point.Type.Corner, z4.x + penPrev.x, z4.y + penPrev.y);
|
||||
const r4 = new Point(Point.Type.Corner, z4.x + penNext.x, z4.y + penNext.y);
|
||||
const r3 = new Point(Point.Type.CubicStart, z3.x + penNext.x, z3.y + penNext.y);
|
||||
const r2 = new Point(Point.Type.CubicEnd, z2.x + penNext.x, z2.y + penNext.y);
|
||||
const r1 = new Point(Point.Type.Corner, this.lastX + penNext.x, this.lastY + penNext.y);
|
||||
|
||||
this.contoursCollected.push([l1, l2, l3, l4, r4, r3, r2, r1]);
|
||||
}
|
||||
this.lastX = z4.x;
|
||||
this.lastY = z4.y;
|
||||
this.addPenProfileAt(this.lastX, this.lastY);
|
||||
}
|
||||
|
||||
addPenProfileAt(x, y) {
|
||||
let c = [];
|
||||
for (let i = 0; i < this.m_pen.length; i++) {
|
||||
let pen = this.m_pen[i];
|
||||
c.push(new Point(Point.Type.Corner, x + pen.x, y + pen.y));
|
||||
}
|
||||
this.contoursCollected.push(c);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ import * as SpiroJs from "spiro";
|
|||
import * as TypoGeom from "typo-geom";
|
||||
|
||||
import * as CurveUtil from "./curve-util.mjs";
|
||||
import { Vec2 } from "./point.mjs";
|
||||
|
||||
export function spiroToOutline(knots, fClosed, gizmo) {
|
||||
const s = new CurveUtil.BezToContoursSink(gizmo);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue