Optimize glyph quantity; Fix glyph visual for COMBINING DOUBLE CIRCUMFLEX ABOVE (U+1DCD
). (#2252)
This commit is contained in:
parent
96456df68a
commit
63ec70d905
6 changed files with 59 additions and 65 deletions
|
@ -8,3 +8,4 @@
|
|||
* Fix width of PUNCTUATION SPACE (`U+2008`) under Quasi-Proportional.
|
||||
* Fix `percent`=`dots` glyphs for PER {MILLE|TEN THOUSAND} SIGN (`U+2030`..`U+2031`) under Quasi-Proportional when `NWID` is enabled.
|
||||
* Remove untagged variant selector for Cyrillic Capital Ef (`Ф`).
|
||||
* Fix glyph visual for COMBINING DOUBLE CIRCUMFLEX ABOVE (`U+1DCD`).
|
||||
|
|
|
@ -12,16 +12,24 @@ glyph-block Letter-Shared : begin
|
|||
glyph-block-import Common-Derivatives
|
||||
glyph-block-import Mark-Adjustment : TurnMarks LeaningAnchorMap
|
||||
|
||||
glyph-block-export CreateMultiAccentedComposition
|
||||
define [CreateMultiAccentedComposition dst u gnSrc gnAccents]
|
||||
derive-multi-part-glyphs dst u { gnSrc :: gnAccents } : function [gns gr] : glyph-proc
|
||||
local { gnBase :: gnAccents } gns
|
||||
|
||||
include [refer-glyph gnBase] AS_BASE ALSO_METRICS
|
||||
foreach gnAccent [items-of gnAccents] : begin
|
||||
local gAccent : query-glyph gnAccent
|
||||
currentGlyph.includeMarkWithLeaningSupport gAccent LeaningAnchorMap
|
||||
|
||||
if (!gr) : begin
|
||||
if (gnAccents.length === 1 && gnAccents.0 === 'dotAbove')
|
||||
: then : Dotless.set currentGlyph gnBase
|
||||
: else : CvDecompose.set currentGlyph { gnSrc :: gnAccents }
|
||||
|
||||
glyph-block-export CreateAccentedComposition
|
||||
define [CreateAccentedComposition dst u srcGid accentGid]
|
||||
derive-multi-part-glyphs dst u { srcGid accentGid } : function [gns gr] : glyph-proc
|
||||
local { base mark } gns
|
||||
local gMark : query-glyph mark
|
||||
|
||||
include [refer-glyph base] AS_BASE ALSO_METRICS
|
||||
currentGlyph.includeMarkWithLeaningSupport gMark LeaningAnchorMap
|
||||
|
||||
if (!gr && accentGid === 'dotAbove') : Dotless.set currentGlyph base
|
||||
CreateMultiAccentedComposition dst u srcGid { accentGid }
|
||||
|
||||
glyph-block-export CreateOgonekComposition
|
||||
define [CreateOgonekComposition dst u srcGid]
|
||||
|
@ -44,13 +52,6 @@ glyph-block Letter-Shared : begin
|
|||
include : ApparentTranslate commaOffset 0
|
||||
include [refer-glyph base] AS_BASE ALSO_METRICS
|
||||
|
||||
glyph-block-export CreateMultiAccentedComposition
|
||||
define [CreateMultiAccentedComposition dstGid unicode srcGid accentGids fDontDecompose]
|
||||
derive-glyphs dstGid unicode srcGid : lambda [src gr] : glyph-proc
|
||||
include [refer-glyph src] AS_BASE ALSO_METRICS
|
||||
foreach accentGid [items-of accentGids] : include [refer-glyph accentGid]
|
||||
if (!fDontDecompose && !gr) : CvDecompose.set currentGlyph { src :: accentGids }
|
||||
|
||||
glyph-block-export CreateDependentComposite
|
||||
define [CreateDependentComposite gidDst unicode gidPart1 gidPart2Map] : begin
|
||||
local sourceGidList { gidPart1 }
|
||||
|
|
|
@ -135,10 +135,21 @@ glyph-block Mark-Tie : begin
|
|||
set-base-anchor 'aboveBraceR' (0 + 0.5 * markExtend) aboveTieMid
|
||||
|
||||
TieGlyph.set currentGlyph
|
||||
include : CaretShape
|
||||
xMiddle -- 0
|
||||
width -- CaretCaronWidth
|
||||
top -- aboveTieTop + markFine * 0.7
|
||||
bottom -- aboveTieBottom + markStress - markFine
|
||||
swEnd -- CaretCaronTerminalSw
|
||||
swMid -- CaretCaronMidSw
|
||||
|
||||
local leftHalf : include : dispiro
|
||||
flat tieLeft aboveTieBottom [widths.center CaretCaronTerminalSw]
|
||||
curl 0 aboveTieTop [widths.center CaretCaronMidSw]
|
||||
local rightHalf : include : dispiro
|
||||
flat tieRight aboveTieBottom [widths.center CaretCaronTerminalSw]
|
||||
curl 0 aboveTieTop [widths.center CaretCaronMidSw]
|
||||
|
||||
local a leftHalf.lhsKnots.1
|
||||
local b rightHalf.rhsKnots.1
|
||||
local c leftHalf.rhsKnots.1
|
||||
local d rightHalf.lhsKnots.1
|
||||
|
||||
include : spiro-outline
|
||||
corner a.x a.y
|
||||
corner b.x b.y
|
||||
corner [Math.max c.x d.x] d.y
|
||||
corner [Math.min c.x d.x] c.y
|
||||
|
|
|
@ -359,9 +359,14 @@ function rectifyGlyphAndMarkComponents(glyphStore, aliasMap, markedGlyphs, memo,
|
|||
if (memo.has(g)) return;
|
||||
memo.add(g);
|
||||
|
||||
analyzeRefs: {
|
||||
let refs = g.geometry.toReferences();
|
||||
if (refs) {
|
||||
let parts = [];
|
||||
if (!refs) break analyzeRefs;
|
||||
|
||||
let partGns = []; // The names of the referenced glyphs
|
||||
let parts = []; // The parts of the new geometry
|
||||
let hasMarked = false; // Whether any of the referenced glyphs is marked
|
||||
|
||||
for (let sr of refs) {
|
||||
// Resolve alias
|
||||
const alias = aliasMap.get(sr.glyph);
|
||||
|
@ -371,14 +376,14 @@ function rectifyGlyphAndMarkComponents(glyphStore, aliasMap, markedGlyphs, memo,
|
|||
sr.y += alias.y;
|
||||
}
|
||||
|
||||
// Resolve reference
|
||||
const gn = glyphStore.queryNameOf(sr.glyph);
|
||||
if (!gn) {
|
||||
// Reference is invalid. The root glyph will be radicalized.
|
||||
g.geometry = new Geometry.RadicalGeometry(g.geometry.unlinkReferences());
|
||||
return;
|
||||
break analyzeRefs;
|
||||
} else {
|
||||
// Reference is valid. Process the referenced glyph.
|
||||
if (!markedGlyphs.has(gn)) markedGlyphs.set(gn, d + 0x10000);
|
||||
if (markedGlyphs.has(gn)) hasMarked = true;
|
||||
rectifyGlyphAndMarkComponents(
|
||||
glyphStore,
|
||||
aliasMap,
|
||||
|
@ -388,10 +393,18 @@ function rectifyGlyphAndMarkComponents(glyphStore, aliasMap, markedGlyphs, memo,
|
|||
d + 0x10000,
|
||||
);
|
||||
parts.push(new Geometry.ReferenceGeometry(sr.glyph, sr.x, sr.y));
|
||||
partGns.push(gn);
|
||||
}
|
||||
}
|
||||
|
||||
// If any of the referenced glyphs is marked, mark all the remaining references.
|
||||
if (hasMarked) {
|
||||
for (const gn of partGns) if (!markedGlyphs.has(gn)) markedGlyphs.set(gn, d + 0x10000);
|
||||
g.geometry = new Geometry.CombineGeometry(parts);
|
||||
} else {
|
||||
g.geometry = new Geometry.RadicalGeometry(g.geometry.unlinkReferences());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the glyph radical if it has no marked references.
|
||||
g.geometry = g.geometry.unlinkReferences();
|
||||
}
|
||||
|
|
|
@ -12,44 +12,12 @@ export function finalizeGlyphs(cache, para, glyphStore) {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function regulateGlyphStore(cache, skew, glyphStore) {
|
||||
const compositeMemo = new Map();
|
||||
for (const g of glyphStore.glyphs()) {
|
||||
if (!(g.geometry.measureComplexity() & Geom.CPLX_NON_EMPTY)) continue;
|
||||
if (!regulateCompositeGlyph(glyphStore, compositeMemo, g)) {
|
||||
g.geometry = g.geometry.unlinkReferences();
|
||||
}
|
||||
}
|
||||
for (const g of glyphStore.glyphs()) {
|
||||
if (!compositeMemo.get(g)) flattenSimpleGlyph(cache, skew, g);
|
||||
if (!g.geometry.toReferences()) flattenSimpleGlyph(cache, skew, g);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function regulateCompositeGlyph(glyphStore, memo, g) {
|
||||
if (memo.has(g)) return memo.get(g);
|
||||
|
||||
let refs = g.geometry.toReferences();
|
||||
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);
|
||||
}
|
||||
|
||||
let refGeometries = [];
|
||||
for (const sr of refs) refGeometries.push(new Geom.ReferenceGeometry(sr.glyph, sr.x, sr.y));
|
||||
g.geometry = new Geom.CombineGeometry(refGeometries);
|
||||
return memoSet(memo, g, true);
|
||||
}
|
||||
|
||||
function memoSet(memo, g, v) {
|
||||
memo.set(g, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function flattenSimpleGlyph(cache, skew, g) {
|
||||
const ck = Geom.hashGeometry(g.geometry);
|
||||
const cached = cache.getGF(ck);
|
||||
|
|
|
@ -145,7 +145,7 @@ class MappedGlyphStore {
|
|||
const gl = new Ot.Glyph.GeometryList();
|
||||
for (const ref of rs) {
|
||||
const target = this.queryBySourceGlyph(ref.glyph);
|
||||
if (!target) throw new Error("Unreachable");
|
||||
if (!target) throw new Error("Unreachable: glyph not found");
|
||||
const tfm = Ot.Glyph.Transform2X3.Translate(ref.x, ref.y);
|
||||
gl.items.push(new Ot.Glyph.TtReference(target, tfm));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue