Add apparent translate mechanism to improve component sharing
This commit is contained in:
parent
3fd1ebfec3
commit
fdff7dbb60
18 changed files with 154 additions and 225 deletions
|
@ -4,102 +4,6 @@ const Transform = require("./transform");
|
|||
const Point = require("./point");
|
||||
const Anchor = require("./anchor");
|
||||
|
||||
class GeometryStore {
|
||||
constructor() {
|
||||
this.m_contours = [];
|
||||
this.m_references = [];
|
||||
}
|
||||
|
||||
addContour(c) {
|
||||
this.m_contours.push(c);
|
||||
}
|
||||
addReference(glyph, x, y) {
|
||||
this.m_references.push({ glyph, x, y });
|
||||
}
|
||||
asContours() {
|
||||
let result = [];
|
||||
for (const c of this.m_contours) {
|
||||
const c1 = [...c];
|
||||
if (c.tag) c1.tag = c.tag;
|
||||
result.push(c1);
|
||||
}
|
||||
for (const r of this.m_references) {
|
||||
for (const c of r.glyph.geometry.asContours()) {
|
||||
let c1 = [];
|
||||
for (const z of c) c1.push(Point.fromXY(z.type, z.x + r.x, z.y + r.y));
|
||||
if (c.tag) c1.tag = c.tag;
|
||||
result.push(c1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
asReferences() {
|
||||
if (this.m_contours && this.m_contours.length) return null;
|
||||
if (!this.m_references.length) return null;
|
||||
return this.m_references;
|
||||
}
|
||||
|
||||
applyTranslate(shiftX, shiftY) {
|
||||
for (const c of this.m_contours) {
|
||||
for (let k = 0; k < c.length; k++) {
|
||||
c[k] = Point.translated(c[k], shiftX, shiftY);
|
||||
}
|
||||
}
|
||||
for (const r of this.m_references) {
|
||||
r.x += shiftX;
|
||||
r.y += shiftY;
|
||||
}
|
||||
}
|
||||
applyTransform(tfm) {
|
||||
const cs = this.asContours();
|
||||
for (const c of cs) {
|
||||
for (let k = 0; k < c.length; k++) {
|
||||
c[k] = Point.transformed(tfm, c[k]);
|
||||
}
|
||||
}
|
||||
this.m_contours = cs;
|
||||
this.m_references.length = 0;
|
||||
}
|
||||
|
||||
reTagContour(oldTag, newTag) {
|
||||
for (const c of this.m_contours) {
|
||||
if (c.tag === oldTag) c.tag = newTag;
|
||||
}
|
||||
}
|
||||
ejectContour(tag) {
|
||||
const cs = this.asContours();
|
||||
let i = 0,
|
||||
j = 0;
|
||||
for (; i < cs.length; i++) if (!cs[i].tag || cs[i].tag !== tag) cs[j++] = cs[i];
|
||||
cs.length = j;
|
||||
this.m_contours = cs;
|
||||
this.m_references = [];
|
||||
}
|
||||
|
||||
suppressNaN() {
|
||||
let broken = false,
|
||||
complexity = 0;
|
||||
for (const c of this.m_contours) {
|
||||
for (const z of c) {
|
||||
complexity++;
|
||||
if (!isFinite(z.x)) {
|
||||
broken = true;
|
||||
z.x = 0;
|
||||
}
|
||||
if (!isFinite(z.y)) {
|
||||
broken = true;
|
||||
z.y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return broken ? 0xffff : complexity;
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return !this.m_contours.length && !this.m_references.length;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = class Glyph {
|
||||
constructor(_identifier) {
|
||||
this._m_identifier = _identifier;
|
||||
|
@ -216,23 +120,6 @@ module.exports = class Glyph {
|
|||
}
|
||||
}
|
||||
|
||||
combineAnchor(shift, baseThis, markThat, basesThat) {
|
||||
if (!baseThis || !markThat) return;
|
||||
shift.x = baseThis.x - markThat.x;
|
||||
shift.y = baseThis.y - markThat.y;
|
||||
if (basesThat) {
|
||||
for (const bk in basesThat) {
|
||||
this.baseAnchors[bk] = new Anchor(
|
||||
shift.x + basesThat[bk].x,
|
||||
shift.y + basesThat[bk].y
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
copyAnchors(g) {
|
||||
if (g.markAnchors) for (const k in g.markAnchors) this.markAnchors[k] = g.markAnchors[k];
|
||||
if (g.baseAnchors) for (const k in g.baseAnchors) this.baseAnchors[k] = g.baseAnchors[k];
|
||||
}
|
||||
applyTransform(tfm, alsoAnchors) {
|
||||
if (Transform.isTranslate(tfm)) {
|
||||
this.geometry.applyTranslate(tfm.x, tfm.y);
|
||||
|
@ -275,6 +162,23 @@ module.exports = class Glyph {
|
|||
}
|
||||
|
||||
// Anchors
|
||||
combineAnchor(shift, baseThis, markThat, basesThat) {
|
||||
if (!baseThis || !markThat) return;
|
||||
shift.x = baseThis.x - markThat.x;
|
||||
shift.y = baseThis.y - markThat.y;
|
||||
if (basesThat) {
|
||||
for (const bk in basesThat) {
|
||||
this.baseAnchors[bk] = new Anchor(
|
||||
shift.x + basesThat[bk].x,
|
||||
shift.y + basesThat[bk].y
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
copyAnchors(g) {
|
||||
if (g.markAnchors) for (const k in g.markAnchors) this.markAnchors[k] = g.markAnchors[k];
|
||||
if (g.baseAnchors) for (const k in g.baseAnchors) this.baseAnchors[k] = g.baseAnchors[k];
|
||||
}
|
||||
setBaseAnchor(id, x, y) {
|
||||
this.baseAnchors[id] = new Anchor(x, y).transform(this.gizmo);
|
||||
}
|
||||
|
@ -291,3 +195,99 @@ module.exports = class Glyph {
|
|||
delete this.markAnchors[id];
|
||||
}
|
||||
};
|
||||
|
||||
class GeometryStore {
|
||||
constructor() {
|
||||
this.m_contours = [];
|
||||
this.m_references = [];
|
||||
}
|
||||
|
||||
addContour(c) {
|
||||
this.m_contours.push(c);
|
||||
}
|
||||
addReference(glyph, x, y) {
|
||||
this.m_references.push({ glyph, x, y });
|
||||
}
|
||||
asContours() {
|
||||
let result = [];
|
||||
for (const c of this.m_contours) {
|
||||
const c1 = [...c];
|
||||
if (c.tag) c1.tag = c.tag;
|
||||
result.push(c1);
|
||||
}
|
||||
for (const r of this.m_references) {
|
||||
for (const c of r.glyph.geometry.asContours()) {
|
||||
let c1 = [];
|
||||
for (const z of c) c1.push(Point.fromXY(z.type, z.x + r.x, z.y + r.y));
|
||||
if (c.tag) c1.tag = c.tag;
|
||||
result.push(c1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
asReferences() {
|
||||
if (this.m_contours && this.m_contours.length) return null;
|
||||
if (!this.m_references.length) return null;
|
||||
return this.m_references;
|
||||
}
|
||||
|
||||
applyTranslate(shiftX, shiftY) {
|
||||
for (const c of this.m_contours) {
|
||||
for (let k = 0; k < c.length; k++) {
|
||||
c[k] = Point.translated(c[k], shiftX, shiftY);
|
||||
}
|
||||
}
|
||||
for (const r of this.m_references) {
|
||||
r.x += shiftX;
|
||||
r.y += shiftY;
|
||||
}
|
||||
}
|
||||
applyTransform(tfm) {
|
||||
const cs = this.asContours();
|
||||
for (const c of cs) {
|
||||
for (let k = 0; k < c.length; k++) {
|
||||
c[k] = Point.transformed(tfm, c[k]);
|
||||
}
|
||||
}
|
||||
this.m_contours = cs;
|
||||
this.m_references.length = 0;
|
||||
}
|
||||
|
||||
reTagContour(oldTag, newTag) {
|
||||
for (const c of this.m_contours) {
|
||||
if (c.tag === oldTag) c.tag = newTag;
|
||||
}
|
||||
}
|
||||
ejectContour(tag) {
|
||||
const cs = this.asContours();
|
||||
let i = 0,
|
||||
j = 0;
|
||||
for (; i < cs.length; i++) if (!cs[i].tag || cs[i].tag !== tag) cs[j++] = cs[i];
|
||||
cs.length = j;
|
||||
this.m_contours = cs;
|
||||
this.m_references = [];
|
||||
}
|
||||
|
||||
suppressNaN() {
|
||||
let broken = false,
|
||||
complexity = 0;
|
||||
for (const c of this.m_contours) {
|
||||
for (const z of c) {
|
||||
complexity++;
|
||||
if (!isFinite(z.x)) {
|
||||
broken = true;
|
||||
z.x = 0;
|
||||
}
|
||||
if (!isFinite(z.y)) {
|
||||
broken = true;
|
||||
z.y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return broken ? 0xffff : complexity;
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return !this.m_contours.length && !this.m_references.length;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue