Add apparent translate mechanism to improve component sharing

This commit is contained in:
be5invis 2021-02-02 01:56:43 -08:00
parent 3fd1ebfec3
commit fdff7dbb60
18 changed files with 154 additions and 225 deletions

View file

@ -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;
}
}