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 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";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function regulateGlyphStore(cache, skew, glyphStore) {
|
||||
const compositeMemo = new Map();
|
||||
for (const g of glyphStore.glyphs()) {
|
||||
|
@ -18,19 +19,20 @@ function regulateGlyphStore(cache, skew, glyphStore) {
|
|||
if (!compositeMemo.get(g)) flattenSimpleGlyph(cache, skew, g);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
function memoSet(memo, g, v) {
|
||||
memo.set(g, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
function regulateCompositeGlyph(glyphStore, memo, g) {
|
||||
if (memo.has(g)) return memo.get(g);
|
||||
|
||||
let refs = g.geometry.asReferences();
|
||||
if (!refs) return memoSet(memo, g, false);
|
||||
|
||||
for (const sr of refs) {
|
||||
const gn = glyphStore.queryNameOf(sr.glyph);
|
||||
if (!gn) return memoSet(memo, g, false);
|
||||
}
|
||||
|
||||
// De-doppelganger
|
||||
while (refs.length === 1 && regulateCompositeGlyph(glyphStore, memo, refs[0].glyph)) {
|
||||
const sr = refs[0];
|
||||
|
@ -41,8 +43,10 @@ function regulateCompositeGlyph(glyphStore, memo, g) {
|
|||
}
|
||||
refs = g.geometry.asReferences();
|
||||
}
|
||||
|
||||
return memoSet(memo, g, true);
|
||||
}
|
||||
|
||||
function flattenSimpleGlyph(cache, skew, g) {
|
||||
const ck = Geom.hashGeometry(g.geometry);
|
||||
const cached = cache.getGF(ck);
|
||||
|
@ -51,19 +55,32 @@ function flattenSimpleGlyph(cache, skew, g) {
|
|||
g.includeContours(CurveUtil.repToShape(cached), 0, 0);
|
||||
cache.refreshGF(ck);
|
||||
} else {
|
||||
const tfBack = g.gizmo ? g.gizmo.inverse() : new Transform(1, -skew, 0, 1, 0, 0);
|
||||
const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0);
|
||||
const g1 = new Geom.TransformedGeometry(
|
||||
new SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)),
|
||||
tfForward
|
||||
);
|
||||
const cs = g1.asContours();
|
||||
let gSimplified;
|
||||
if (skew) {
|
||||
const tfBack = g.gizmo ? g.gizmo.inverse() : new Transform(1, -skew, 0, 1, 0, 0);
|
||||
const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0);
|
||||
gSimplified = new Geom.TransformedGeometry(
|
||||
new SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)),
|
||||
tfForward
|
||||
);
|
||||
} else {
|
||||
gSimplified = new SimplifyGeometry(g.geometry);
|
||||
}
|
||||
|
||||
const cs = gSimplified.asContours();
|
||||
g.clearGeometry();
|
||||
g.includeContours(cs, 0, 0);
|
||||
if (ck) cache.saveGF(ck, CurveUtil.shapeToRep(cs));
|
||||
}
|
||||
}
|
||||
|
||||
function memoSet(memo, g, v) {
|
||||
memo.set(g, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SimplifyGeometry extends Geom.GeometryBase {
|
||||
constructor(g) {
|
||||
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
|
||||
|
||||
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 width : fallback _width Stroke
|
||||
local ada : fallback _ada SmallArchDepthA
|
||||
local adb : fallback _adb SmallArchDepthB
|
||||
local mc : CorrectionOMidX * width
|
||||
if (u - d > ada + adb) : then : begin
|
||||
include : sink
|
||||
return : sink
|
||||
widths width 0
|
||||
g4 (middle - mc) (u - O)
|
||||
archv
|
||||
|
@ -174,7 +174,7 @@ glyph-block CommonShapes : begin
|
|||
: else : begin
|
||||
local ymiddlea : mix d u (adb / (ada + adb))
|
||||
local ymiddleb : mix d u (ada / (ada + adb))
|
||||
include : sink
|
||||
return : sink
|
||||
widths width 0
|
||||
g4 (middle - mc) (u - O)
|
||||
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
|
||||
widths.rhs
|
||||
g4 (m - CorrectionOMidS) t
|
||||
g4 (m - CorrectionOMidS) (t - O)
|
||||
archv
|
||||
g4 r [YSmoothMidR t b SmallArchDepthA SmallArchDepthB]
|
||||
arcvh
|
||||
g4 (m + CorrectionOMidS) b
|
||||
g4 (m + CorrectionOMidS) (b + O)
|
||||
archv
|
||||
g4 l [YSmoothMidL t b SmallArchDepthA SmallArchDepthB]
|
||||
arcvh
|
||||
|
|
|
@ -31,7 +31,7 @@ glyph-block Digits-Six : begin
|
|||
archv
|
||||
g4.up.mid (SB + OX) (ymiddlea + Stroke * 0.3) [widths.rhs coFine]
|
||||
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
|
||||
define [ClosedContourNineShape top] : glyph-proc
|
||||
|
|
|
@ -125,19 +125,20 @@ export class DiSpiroGeometry extends GeometryBase {
|
|||
asContours() {
|
||||
if (this.m_cachedContours) return this.m_cachedContours;
|
||||
const expandResult = this.expand();
|
||||
const lhs = [...expandResult.lhs];
|
||||
const rhs = [...expandResult.rhs];
|
||||
const lhs = [...expandResult.lhsUntransformed];
|
||||
const rhs = [...expandResult.rhsUntransformed];
|
||||
|
||||
let rawGeometry;
|
||||
if (this.m_closed) {
|
||||
rawGeometry = new CombineGeometry([
|
||||
new SpiroGeometry(Transform.Id(), true, lhs.slice(0, -1)),
|
||||
new SpiroGeometry(Transform.Id(), true, rhs.reverse().slice(0, -1))
|
||||
new SpiroGeometry(this.m_gizmo, true, lhs),
|
||||
new SpiroGeometry(this.m_gizmo, true, rhs.reverse())
|
||||
]);
|
||||
} else {
|
||||
lhs[0].type = lhs[lhs.length - 1].type = "corner";
|
||||
rhs[0].type = rhs[rhs.length - 1].type = "corner";
|
||||
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();
|
||||
return this.m_cachedContours;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue