Fix overshoot of oval-shaped 0
, and open 6
/9
(#1455).
This commit is contained in:
parent
9764a3b199
commit
e7d2d8c6cb
6 changed files with 42 additions and 23 deletions
|
@ -1 +1,2 @@
|
||||||
* Fix metrics of ASCII single quotes under Aile (#1454).
|
* Fix metrics of ASCII single quotes under Aile (#1454).
|
||||||
|
* Fix overshoot of oval-shaped `0`, and open `6`/`9` (#1455).
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Point } from "../../support/geometry/point.mjs";
|
||||||
import { Transform } from "../../support/geometry/transform.mjs";
|
import { Transform } from "../../support/geometry/transform.mjs";
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function regulateGlyphStore(cache, skew, glyphStore) {
|
function regulateGlyphStore(cache, skew, glyphStore) {
|
||||||
const compositeMemo = new Map();
|
const compositeMemo = new Map();
|
||||||
for (const g of glyphStore.glyphs()) {
|
for (const g of glyphStore.glyphs()) {
|
||||||
|
@ -18,19 +19,20 @@ function regulateGlyphStore(cache, skew, glyphStore) {
|
||||||
if (!compositeMemo.get(g)) flattenSimpleGlyph(cache, skew, g);
|
if (!compositeMemo.get(g)) flattenSimpleGlyph(cache, skew, g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
function memoSet(memo, g, v) {
|
|
||||||
memo.set(g, v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
function regulateCompositeGlyph(glyphStore, memo, g) {
|
function regulateCompositeGlyph(glyphStore, memo, g) {
|
||||||
if (memo.has(g)) return memo.get(g);
|
if (memo.has(g)) return memo.get(g);
|
||||||
|
|
||||||
let refs = g.geometry.asReferences();
|
let refs = g.geometry.asReferences();
|
||||||
if (!refs) return memoSet(memo, g, false);
|
if (!refs) return memoSet(memo, g, false);
|
||||||
|
|
||||||
for (const sr of refs) {
|
for (const sr of refs) {
|
||||||
const gn = glyphStore.queryNameOf(sr.glyph);
|
const gn = glyphStore.queryNameOf(sr.glyph);
|
||||||
if (!gn) return memoSet(memo, g, false);
|
if (!gn) return memoSet(memo, g, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-doppelganger
|
// De-doppelganger
|
||||||
while (refs.length === 1 && regulateCompositeGlyph(glyphStore, memo, refs[0].glyph)) {
|
while (refs.length === 1 && regulateCompositeGlyph(glyphStore, memo, refs[0].glyph)) {
|
||||||
const sr = refs[0];
|
const sr = refs[0];
|
||||||
|
@ -41,8 +43,10 @@ function regulateCompositeGlyph(glyphStore, memo, g) {
|
||||||
}
|
}
|
||||||
refs = g.geometry.asReferences();
|
refs = g.geometry.asReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
return memoSet(memo, g, true);
|
return memoSet(memo, g, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function flattenSimpleGlyph(cache, skew, g) {
|
function flattenSimpleGlyph(cache, skew, g) {
|
||||||
const ck = Geom.hashGeometry(g.geometry);
|
const ck = Geom.hashGeometry(g.geometry);
|
||||||
const cached = cache.getGF(ck);
|
const cached = cache.getGF(ck);
|
||||||
|
@ -51,19 +55,32 @@ function flattenSimpleGlyph(cache, skew, g) {
|
||||||
g.includeContours(CurveUtil.repToShape(cached), 0, 0);
|
g.includeContours(CurveUtil.repToShape(cached), 0, 0);
|
||||||
cache.refreshGF(ck);
|
cache.refreshGF(ck);
|
||||||
} else {
|
} else {
|
||||||
const tfBack = g.gizmo ? g.gizmo.inverse() : new Transform(1, -skew, 0, 1, 0, 0);
|
let gSimplified;
|
||||||
const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0);
|
if (skew) {
|
||||||
const g1 = new Geom.TransformedGeometry(
|
const tfBack = g.gizmo ? g.gizmo.inverse() : new Transform(1, -skew, 0, 1, 0, 0);
|
||||||
new SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)),
|
const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0);
|
||||||
tfForward
|
gSimplified = new Geom.TransformedGeometry(
|
||||||
);
|
new SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)),
|
||||||
const cs = g1.asContours();
|
tfForward
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
gSimplified = new SimplifyGeometry(g.geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cs = gSimplified.asContours();
|
||||||
g.clearGeometry();
|
g.clearGeometry();
|
||||||
g.includeContours(cs, 0, 0);
|
g.includeContours(cs, 0, 0);
|
||||||
if (ck) cache.saveGF(ck, CurveUtil.shapeToRep(cs));
|
if (ck) cache.saveGF(ck, CurveUtil.shapeToRep(cs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function memoSet(memo, g, v) {
|
||||||
|
memo.set(g, v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class SimplifyGeometry extends Geom.GeometryBase {
|
class SimplifyGeometry extends Geom.GeometryBase {
|
||||||
constructor(g) {
|
constructor(g) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -151,14 +151,14 @@ glyph-block CommonShapes : begin
|
||||||
define [RoundStrokeTerminalAt x y r] : CircleRing (y + r) (y - r) (x - HVContrast * r) (x + HVContrast * r) true
|
define [RoundStrokeTerminalAt x y r] : CircleRing (y + r) (y - r) (x - HVContrast * r) (x + HVContrast * r) true
|
||||||
|
|
||||||
glyph-block-export OShapeT
|
glyph-block-export OShapeT
|
||||||
define [OShapeT sink u d l r _width _ada _adb] : glyph-proc
|
define [OShapeT sink u d l r _width _ada _adb] : begin
|
||||||
local middle : (l + r) / 2
|
local middle : (l + r) / 2
|
||||||
local width : fallback _width Stroke
|
local width : fallback _width Stroke
|
||||||
local ada : fallback _ada SmallArchDepthA
|
local ada : fallback _ada SmallArchDepthA
|
||||||
local adb : fallback _adb SmallArchDepthB
|
local adb : fallback _adb SmallArchDepthB
|
||||||
local mc : CorrectionOMidX * width
|
local mc : CorrectionOMidX * width
|
||||||
if (u - d > ada + adb) : then : begin
|
if (u - d > ada + adb) : then : begin
|
||||||
include : sink
|
return : sink
|
||||||
widths width 0
|
widths width 0
|
||||||
g4 (middle - mc) (u - O)
|
g4 (middle - mc) (u - O)
|
||||||
archv
|
archv
|
||||||
|
@ -174,7 +174,7 @@ glyph-block CommonShapes : begin
|
||||||
: else : begin
|
: else : begin
|
||||||
local ymiddlea : mix d u (adb / (ada + adb))
|
local ymiddlea : mix d u (adb / (ada + adb))
|
||||||
local ymiddleb : mix d u (ada / (ada + adb))
|
local ymiddleb : mix d u (ada / (ada + adb))
|
||||||
include : sink
|
return : sink
|
||||||
widths width 0
|
widths width 0
|
||||||
g4 (middle - mc) (u - O)
|
g4 (middle - mc) (u - O)
|
||||||
archv
|
archv
|
||||||
|
|
|
@ -12,11 +12,11 @@ glyph-block Digits-Zero : begin
|
||||||
|
|
||||||
define [OvalShapeT sink t b l r] : let [m : mix l r 0.5] : sink
|
define [OvalShapeT sink t b l r] : let [m : mix l r 0.5] : sink
|
||||||
widths.rhs
|
widths.rhs
|
||||||
g4 (m - CorrectionOMidS) t
|
g4 (m - CorrectionOMidS) (t - O)
|
||||||
archv
|
archv
|
||||||
g4 r [YSmoothMidR t b SmallArchDepthA SmallArchDepthB]
|
g4 r [YSmoothMidR t b SmallArchDepthA SmallArchDepthB]
|
||||||
arcvh
|
arcvh
|
||||||
g4 (m + CorrectionOMidS) b
|
g4 (m + CorrectionOMidS) (b + O)
|
||||||
archv
|
archv
|
||||||
g4 l [YSmoothMidL t b SmallArchDepthA SmallArchDepthB]
|
g4 l [YSmoothMidL t b SmallArchDepthA SmallArchDepthB]
|
||||||
arcvh
|
arcvh
|
||||||
|
|
|
@ -31,7 +31,7 @@ glyph-block Digits-Six : begin
|
||||||
archv
|
archv
|
||||||
g4.up.mid (SB + OX) (ymiddlea + Stroke * 0.3) [widths.rhs coFine]
|
g4.up.mid (SB + OX) (ymiddlea + Stroke * 0.3) [widths.rhs coFine]
|
||||||
quadControls 0 0.85
|
quadControls 0 0.85
|
||||||
g4 ([mix SB RightSB 0.85] - 0.25 * Stroke * HVContrast) (charTop - O) [widths.rhs]
|
g4 ([mix SB RightSB 0.85] - 0.25 * Stroke * HVContrast) (charTop - 0.75 * O) [widths.rhs]
|
||||||
|
|
||||||
glyph-block-export ClosedContourNineShape
|
glyph-block-export ClosedContourNineShape
|
||||||
define [ClosedContourNineShape top] : glyph-proc
|
define [ClosedContourNineShape top] : glyph-proc
|
||||||
|
|
|
@ -125,19 +125,20 @@ export class DiSpiroGeometry extends GeometryBase {
|
||||||
asContours() {
|
asContours() {
|
||||||
if (this.m_cachedContours) return this.m_cachedContours;
|
if (this.m_cachedContours) return this.m_cachedContours;
|
||||||
const expandResult = this.expand();
|
const expandResult = this.expand();
|
||||||
const lhs = [...expandResult.lhs];
|
const lhs = [...expandResult.lhsUntransformed];
|
||||||
const rhs = [...expandResult.rhs];
|
const rhs = [...expandResult.rhsUntransformed];
|
||||||
|
|
||||||
let rawGeometry;
|
let rawGeometry;
|
||||||
if (this.m_closed) {
|
if (this.m_closed) {
|
||||||
rawGeometry = new CombineGeometry([
|
rawGeometry = new CombineGeometry([
|
||||||
new SpiroGeometry(Transform.Id(), true, lhs.slice(0, -1)),
|
new SpiroGeometry(this.m_gizmo, true, lhs),
|
||||||
new SpiroGeometry(Transform.Id(), true, rhs.reverse().slice(0, -1))
|
new SpiroGeometry(this.m_gizmo, true, rhs.reverse())
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
lhs[0].type = lhs[lhs.length - 1].type = "corner";
|
lhs[0].type = lhs[lhs.length - 1].type = "corner";
|
||||||
rhs[0].type = rhs[rhs.length - 1].type = "corner";
|
rhs[0].type = rhs[rhs.length - 1].type = "corner";
|
||||||
const allKnots = lhs.concat(rhs.reverse());
|
const allKnots = lhs.concat(rhs.reverse());
|
||||||
rawGeometry = new SpiroGeometry(Transform.Id(), true, allKnots);
|
rawGeometry = new SpiroGeometry(this.m_gizmo, true, allKnots);
|
||||||
}
|
}
|
||||||
this.m_cachedContours = rawGeometry.asContours();
|
this.m_cachedContours = rawGeometry.asContours();
|
||||||
return this.m_cachedContours;
|
return this.m_cachedContours;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue