966 lines
40 KiB
Text
966 lines
40 KiB
Text
###### Automatic builds
|
|
$$include '../meta/macros.ptl'
|
|
|
|
import [mix linreg clamp fallback] from '../support/utils'
|
|
import [getGrMesh AnyDerivingCv CvDecompose] from "../support/gr"
|
|
|
|
glyph-module
|
|
|
|
define DECOMPOSABLE true
|
|
define NON-DECOMPOSABLE false
|
|
|
|
glyph-block Autobuild-Enclosure-Shared : begin
|
|
glyph-block-import CommonShapes
|
|
|
|
glyph-block-export CircNameNoCheck
|
|
define [CircNameNoCheck unicode prefix parts suffix] : begin
|
|
local baseName : prefix + '{' + unicode + '}{' + [parts.join '}{'] + '}'
|
|
return : if suffix (baseName + "." + suffix) baseName
|
|
|
|
glyph-block-export CircName
|
|
define [CircName unicode prefix parts suffix] : begin
|
|
local name : CircNameNoCheck unicode prefix parts suffix
|
|
if [query-glyph name] : begin
|
|
throw : new Error "Glyph exists : \(name)"
|
|
return name
|
|
|
|
glyph-block-export EnsureComponentGlyphT
|
|
define [EnsureComponentGlyphT gidPart fnBuildup] : begin
|
|
local gniPart : fnBuildup gidPart
|
|
local grs : AnyDerivingCv.query [query-glyph gidPart]
|
|
if grs : foreach gr [items-of grs] : begin
|
|
local relatedGidPart : gr.get [query-glyph gidPart]
|
|
local gniRelated : fnBuildup relatedGidPart
|
|
if [query-glyph gniPart] : gr.set [query-glyph gniPart] gniRelated
|
|
return gniPart
|
|
|
|
glyph-block-export CollectJobs
|
|
define [CollectJobs globallyDecomposable prefix suffix demands] : begin
|
|
local nonDecomposable { }
|
|
local decomposableJobs { }
|
|
local decomposableRelJobs { }
|
|
local relApplications { }
|
|
foreach demand [items-of demands] : do
|
|
local unicode demand.0
|
|
local parts demand.1
|
|
local restInfo : demand.slice 2
|
|
local origJobGlyphGn : CircName unicode prefix parts suffix
|
|
|
|
local demandDecomposable globallyDecomposable
|
|
foreach part [items-of parts] : if [query-glyph part] : begin
|
|
local g : query-glyph part
|
|
local relatedGlyphs : AnyDerivingCv.query g
|
|
foreach gr [items-of relatedGlyphs] : if [query-glyph : gr.get g] : begin
|
|
if ([query-glyph : gr.get g].advanceWidth != g.advanceWidth)
|
|
set demandDecomposable false
|
|
|
|
local jobsOrig : if demandDecomposable decomposableJobs nonDecomposable
|
|
local jobsRel : if demandDecomposable decomposableRelJobs nonDecomposable
|
|
|
|
jobsOrig.push { origJobGlyphGn unicode parts :: restInfo }
|
|
local mesh : getGrMesh parts AnyDerivingCv query-glyph
|
|
foreach {gr fromParts toParts} [items-of mesh] : do
|
|
local fromGn : CircNameNoCheck unicode prefix fromParts suffix
|
|
local toGn : CircName unicode prefix toParts suffix
|
|
jobsRel.push { toGn null toParts :: restInfo }
|
|
if [not demandDecomposable] : relApplications.push : list gr fromGn toGn
|
|
return : object nonDecomposable decomposableJobs decomposableRelJobs relApplications
|
|
|
|
glyph-block-export CreateDerivedFontFromJobs
|
|
define [CreateDerivedFontFromJobs aj restGids fn] : begin
|
|
define [object nonDecomposable decomposableJobs decomposableRelJobs] aj
|
|
local dfJobs : nonDecomposable.concat decomposableJobs decomposableRelJobs
|
|
local pendingGlyphs : restGids.slice 0
|
|
foreach {gnf unicode parts} [items-of dfJobs] : foreach gn [items-of parts]
|
|
pendingGlyphs.push gn
|
|
return : fn pendingGlyphs
|
|
|
|
glyph-block-export applyRelations
|
|
define [applyRelations relApplications] : begin
|
|
foreach {gr f t} [items-of relApplications] : begin
|
|
if [query-glyph f] : gr.set [query-glyph f] t
|
|
|
|
glyph-block AutoBuild-Enclosure : begin
|
|
glyph-block-import CommonShapes
|
|
glyph-block-import Autobuild-Enclosure-Shared : CircNameNoCheck CircName CollectJobs EnsureComponentGlyphT CreateDerivedFontFromJobs applyRelations
|
|
|
|
define circleWidthClasses {{'NWID' Width 0.12} {'WWID' WideWidth0 0.08}}
|
|
define [AdjustDigitCount digits width] : Math.max 1 (digits * Width / width)
|
|
define [EnclosureStrokeScale dscale digits width] : dscale / [Math.pow [AdjustDigitCount digits width] 0.66]
|
|
|
|
define [EnsureInnerSubGlyphImpl miniatureFont prefix finalPlacement dscale xCompress shift] : lambda [gidPart] : begin
|
|
define gniPart : '.ci.' + gidPart + '@' + [{ prefix finalPlacement dscale xCompress shift }.join '/']
|
|
if [not : query-glyph gniPart] : create-glyph gniPart : glyph-construction
|
|
set-width 0
|
|
include miniatureFont.(gidPart)
|
|
apply-transform : Upright
|
|
apply-transform : Scale (dscale * xCompress) dscale
|
|
apply-transform : Translate 0 (dscale * (-CAP / 2 + shift))
|
|
apply-transform : Translate 0 (CAP / 2 * dscale)
|
|
apply-transform : Translate 0 (symbolMid - CAP * dscale / 2)
|
|
apply-transform : Italify
|
|
apply-transform : Translate finalPlacement 0
|
|
return gniPart
|
|
|
|
define [EnsureInnerSubGlyphSeq miniatureFont prefix job dimens] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define [object width mockInnerWidth dscale] dimens
|
|
|
|
local totalWidth 0
|
|
local firstDerivedGyph null
|
|
local shift 0
|
|
foreach [gidPart : items-of parts] : do
|
|
local derivedGlyph miniatureFont.(gidPart)
|
|
if [not firstDerivedGyph] : set firstDerivedGyph derivedGlyph
|
|
set totalWidth : totalWidth + derivedGlyph.advanceWidth
|
|
local xCompress [Math.min 1 (mockInnerWidth / totalWidth)]
|
|
set totalWidth : Math.min mockInnerWidth totalWidth
|
|
if (firstDerivedGyph && firstDerivedGyph.baseAnchors.above && firstDerivedGyph.baseAnchors.below) : begin
|
|
if bal : set shift : CAP / 2 - [mix baly [mix firstDerivedGyph.baseAnchors.above.y firstDerivedGyph.baseAnchors.below.y 0.5] bal]
|
|
: else : set shift : CAP / 2 - [mix firstDerivedGyph.baseAnchors.above.y firstDerivedGyph.baseAnchors.below.y 0.5]
|
|
|
|
local finalParts {}
|
|
local accumulatedAdvanceSoFar 0
|
|
foreach partIndex [range 0 parts.length] : do
|
|
define gidPart parts.(partIndex)
|
|
define finalPlacement : accumulatedAdvanceSoFar - width / 2 - totalWidth * dscale / 2
|
|
finalParts.push : EnsureComponentGlyphT gidPart : EnsureInnerSubGlyphImpl miniatureFont prefix finalPlacement dscale xCompress shift
|
|
set accumulatedAdvanceSoFar : accumulatedAdvanceSoFar + miniatureFont.(gidPart).advanceWidth * dscale * xCompress
|
|
|
|
return finalParts
|
|
|
|
define [EnclosureInner gnEnclosure miniatureFont prefix job dimens] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define [object width mockInnerWidth dscale] dimens
|
|
local finalParts : EnsureInnerSubGlyphSeq miniatureFont prefix job dimens
|
|
local inner : create-glyph : glyph-construction
|
|
foreach [gidPart : items-of finalParts] : include [refer-glyph gidPart]
|
|
apply-transform : Translate width 0
|
|
return : glyph-construction
|
|
include inner
|
|
if (gnEnclosure) : CvDecompose.set currentGlyph [{gnEnclosure}.concat finalParts]
|
|
|
|
define [CircCrowd digits width] : 2 + 2 * [Math.pow [AdjustDigitCount digits width] 0.5] * [Math.max 1 (HalfUPM / Width)]
|
|
define [CircScale digits width] : 0.65 / [Math.pow [AdjustDigitCount digits width] 0.5]
|
|
|
|
define [circleDimens digits w m] : begin
|
|
define width : fallback w Width
|
|
define dscale : linreg HalfUPM 0.55 UPM 0.6 width
|
|
define spatt : [linreg HalfUPM 0.22 UPM 0.27 width] * (Width / HalfUPM)
|
|
define sw0 : [EnclosureStrokeScale dscale digits width] * [adviceBlackness [CircCrowd digits width]] / [CircScale digits width]
|
|
define sw : Math.max sw0 [fallback m 0]
|
|
define top : symbolMid + CAP * dscale / 2 + (CAP * spatt)
|
|
define bot : symbolMid - CAP * dscale / 2 - (CAP * spatt)
|
|
define mosaicLeft 0
|
|
define mosaicRight width
|
|
define mosaicBot fontMetrics.OS_2.sTypoDescender
|
|
define mosaicTop fontMetrics.OS_2.sTypoAscender
|
|
define left : Math.max
|
|
SB + O * 3
|
|
Math.min
|
|
width / 2 - (top - bot) / 2
|
|
width / 2 - CAP / 2 * dscale - sw * 2.5
|
|
define right : Math.min
|
|
width - SB - O * 3
|
|
Math.max
|
|
width / 2 + (top - bot) / 2
|
|
width / 2 + CAP / 2 * dscale + sw * 2.5
|
|
define mockInnerWidth : width + 2 * (Stroke - sw) * dscale
|
|
define smoothA : SmoothAOf (SmallSmooth * (right - left) / (RightSB - SB)) width
|
|
define smoothB : SmoothBOf (SmallSmooth * (right - left) / (RightSB - SB)) width
|
|
return : object width mockInnerWidth dscale sw0 sw top bot left right mosaicTop mosaicBot mosaicLeft mosaicRight smoothA smoothB
|
|
|
|
define [CircledMiniatureFont digits width] : lambda [gs] : Miniature
|
|
glyphs -- gs
|
|
crowd -- [CircCrowd digits width]
|
|
scale -- [CircScale digits width]
|
|
sbscale -- 1
|
|
|
|
define [EnclosureT prefix globallyDecomposable digits demands fnEnclosure fn] : begin
|
|
foreach {suffix ww gap} [items-of circleWidthClasses] : do
|
|
define jobs : CollectJobs globallyDecomposable (prefix + digits) suffix demands
|
|
define miniatureFont : CreateDerivedFontFromJobs jobs {} : CircledMiniatureFont digits ww
|
|
define gnEnclosure : CircName null (prefix + digits + '.enclosure') {} suffix
|
|
if [not : query-glyph gnEnclosure] : create-glyph gnEnclosure : fnEnclosure ww gap
|
|
foreach job [items-of jobs.decomposableJobs] : fn (prefix + digits) ww gap job miniatureFont gnEnclosure true
|
|
foreach job [items-of jobs.nonDecomposable] : fn (prefix + digits) ww gap job miniatureFont gnEnclosure false
|
|
applyRelations jobs.relApplications
|
|
|
|
define [createCircledGlyphs digits demands] : EnclosureT 'circle' DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width sw top bot left right smoothA smoothB] : circleDimens digits ww
|
|
set-width width
|
|
include : OShape top bot left right sw smoothA smoothB
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
include : refer-glyph gnEnclosure
|
|
|
|
define [createBoxedGlyphs digits demands] : EnclosureT 'boxed' DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width mockInnerWidth sw top bot left right] : circleDimens digits ww
|
|
set-width width
|
|
include : union
|
|
HBarTop left right top sw
|
|
HBarBottom left right bot sw
|
|
VBarLeft left bot top sw
|
|
VBarRight right bot top sw
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
include : refer-glyph gnEnclosure
|
|
|
|
define [createInsetCircledGlyphs digits demands] : EnclosureT 'inset-circle' NON-DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width sw top bot left right smoothA smoothB] : circleDimens digits ww
|
|
set-width width
|
|
include : OShapeOutline top bot left right sw smoothA smoothB
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : difference
|
|
refer-glyph gnEnclosure
|
|
EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
|
|
define [createInsetBoxedGlyphs digits demands] : EnclosureT 'inset-boxed' NON-DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width top bot left right] : circleDimens digits ww
|
|
set-width width
|
|
include : spiro-outline
|
|
corner left top
|
|
corner left bot
|
|
corner right bot
|
|
corner right top
|
|
close
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : difference
|
|
refer-glyph gnEnclosure
|
|
EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
|
|
define [createInsetMosaicGlyphs digits demands] : EnclosureT 'inset-mosaic' NON-DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width mockInnerWidth mosaicTop mosaicBot mosaicLeft mosaicRight] : circleDimens digits ww
|
|
set-width width
|
|
include : ForceUpright
|
|
include : spiro-outline
|
|
corner mosaicLeft mosaicTop
|
|
corner mosaicLeft mosaicBot
|
|
corner mosaicRight mosaicBot
|
|
corner mosaicRight mosaicTop
|
|
close
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : difference
|
|
refer-glyph gnEnclosure
|
|
EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
|
|
define [createDoubleCircledGlyphs digits demands] : EnclosureT 'double-circle' DECOMPOSABLE digits demands
|
|
lambda [ww gap] : glyph-construction
|
|
define [object width mockInnerWidth sw0 sw top bot left right smoothA smoothB] : circleDimens digits ww (ww * gap)
|
|
set-width width
|
|
define sw1 : Math.min sw0 (sw / 3)
|
|
include : OShape top bot left right sw1 smoothA smoothB
|
|
include : OShape
|
|
top - sw + sw1
|
|
bot + sw - sw1
|
|
left + sw * HVContrast - sw1 * HVContrast
|
|
right - sw * HVContrast + sw1 * HVContrast
|
|
begin sw1
|
|
smoothA - sw + sw1
|
|
smoothB - sw + sw1
|
|
lambda [prefix ww gap job miniatureFont gnEnclosure decomposable] : begin
|
|
define { gn unicode parts w bal baly } job
|
|
define dimens : circleDimens digits ww (ww * gap)
|
|
define [object width mockInnerWidth dscale] dimens
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww && unicode) : assign-unicode unicode
|
|
include : EnclosureInner [if decomposable gnEnclosure null] miniatureFont prefix job dimens
|
|
include : refer-glyph gnEnclosure
|
|
|
|
define [BraceCrowd digits width] : 2.75 + [AdjustDigitCount digits width]
|
|
define [BraceScale digits width] : 0.65 / [Math.pow [AdjustDigitCount digits width] 0.5]
|
|
define [bracedDottdeDimens digits width] : begin
|
|
define dscale : linreg Width 0.55 UPM 0.65 width
|
|
define pscale : linreg Width 0.6 UPM 0.75 width
|
|
define sw0 : [EnclosureStrokeScale dscale digits width] * [adviceBlackness [BraceCrowd digits width]] / [BraceScale digits width]
|
|
define sw : Math.min Stroke sw0
|
|
define l : Math.max (SB + O * 3) (width / 2 - [Math.max (Width * digits) CAP] / 2)
|
|
define r : width - l
|
|
define mockInnerWidth : width + 2 * (Stroke - sw) * dscale
|
|
return : object width sw dscale pscale l r mockInnerWidth
|
|
|
|
define [createBracedGlyphs digits demands] : begin
|
|
foreach {suffix ww} [items-of circleWidthClasses] : do
|
|
define prefix ('braced' + digits)
|
|
define jobs : CollectJobs DECOMPOSABLE prefix suffix demands
|
|
define miniatureFont : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Miniature
|
|
glyphs -- gs
|
|
crowd -- [BraceCrowd digits ww]
|
|
scale -- [BraceScale digits ww]
|
|
sbscale -- 1
|
|
|
|
define gnb : CircName null ('.braced-brace' + digits) {} suffix
|
|
if [not : query-glyph gnb] : create-glyph gnb : glyph-construction
|
|
define [object width dscale pscale sw l r] : bracedDottdeDimens digits ww
|
|
local s : TanSlope * symbolMid / 2
|
|
local p : 0.1 * [Math.sqrt : Math.min 1 (width / (digits * Width))]
|
|
set-width width
|
|
include : dispiro
|
|
widths.lhs sw
|
|
g4 ([mix l r p] - s) (parenTop * pscale)
|
|
g4.down.mid (l - s + O) (symbolMid * pscale)
|
|
g4 ([mix l r p] - s) (parenBot * pscale)
|
|
|
|
include : dispiro
|
|
widths.rhs sw
|
|
g4 ([mix r l p] + s) (parenTop * pscale)
|
|
g4.down.mid (r + s - O) (symbolMid * pscale)
|
|
g4 ([mix r l p] + s) (parenBot * pscale)
|
|
|
|
include : Upright
|
|
include : Translate 0 (symbolMid - symbolMid * pscale)
|
|
include : Italify
|
|
|
|
define [CreateGlyphImpl jobDecomposable job] : begin
|
|
local {gn unicode parts w bal baly} job
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
define dimens : bracedDottdeDimens digits ww
|
|
define [object width mockInnerWidth dscale] dimens
|
|
set-width width
|
|
if (w == ww) : assign-unicode unicode
|
|
include : refer-glyph gnb
|
|
include : EnclosureInner [if jobDecomposable gnb null] miniatureFont prefix job dimens
|
|
|
|
foreach job [items-of jobs.decomposableJobs] : CreateGlyphImpl true job
|
|
foreach job [items-of jobs.nonDecomposable] : CreateGlyphImpl false job
|
|
|
|
applyRelations jobs.relApplications
|
|
|
|
define [DottedCrowd digits width] : 2 + [AdjustDigitCount digits width]
|
|
define [DottedScale digits width] : 1 / [Math.pow [AdjustDigitCount digits width] 0.5]
|
|
define [createDottedGlyphs digits gidDot demands] : begin
|
|
foreach {suffix ww} [items-of circleWidthClasses] : do
|
|
define jobs : CollectJobs DECOMPOSABLE ('dotted' + digits) suffix demands
|
|
|
|
local miniatureFont : CreateDerivedFontFromJobs jobs {gidDot} : lambda [gs]: Miniature
|
|
glyphs -- gs
|
|
crowd -- [DottedCrowd digits ww]
|
|
scale -- [DottedScale digits ww]
|
|
sbscale -- 1
|
|
|
|
define [ensureDottedPartImpl item offset xCompress xTranslate] : lambda [gidPart] : begin
|
|
define gniPart : '.dotted-inner.' + gidPart + '@' + [{ item digits offset xCompress xTranslate }.join '/']
|
|
if [query-glyph gniPart] : return gniPart
|
|
create-glyph gniPart : glyph-construction
|
|
set-width 0
|
|
include miniatureFont.(gidPart)
|
|
include : Upright
|
|
include : Translate offset 0
|
|
include : Scale xCompress 1
|
|
include : Translate xTranslate 0
|
|
include : Italify
|
|
return gniPart
|
|
|
|
define [createDottedGlyphImpl job jobDecomposable] : begin
|
|
local {gn unicode parts w} job
|
|
define [object width dscale pscale sw l r] : bracedDottdeDimens 1 ww
|
|
|
|
local totalWidth 0
|
|
local offsets { }
|
|
local partsWithDot : parts.concat { gidDot }
|
|
foreach [j : range 0 partsWithDot.length] : begin
|
|
local gidPart partsWithDot.(j)
|
|
if j : set totalWidth : totalWidth - SB
|
|
set offsets.(j) totalWidth
|
|
set totalWidth : totalWidth + miniatureFont.(gidPart).advanceWidth
|
|
set totalWidth : totalWidth - SB
|
|
local xCompress : if (totalWidth > width) (width / totalWidth) 1
|
|
local xTranslate : [if (totalWidth > width) 0 (width / 2 - totalWidth / 2)] - width
|
|
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
set-width width
|
|
if (w == ww) : assign-unicode unicode
|
|
local ps {gnSpace}
|
|
foreach [j : range 0 partsWithDot.length] : begin
|
|
local gidPart partsWithDot.(j)
|
|
local p : EnsureComponentGlyphT gidPart : ensureDottedPartImpl j offsets.(j) xCompress xTranslate
|
|
include : refer-glyph p
|
|
ps.push p
|
|
apply-transform : Translate width 0
|
|
if jobDecomposable : CvDecompose.set currentGlyph ps
|
|
set currentGlyph.autoRefPriority 11
|
|
|
|
|
|
define gnSpace : '.dotted-space.' + [{ digits suffix }.join '/']
|
|
if [not : query-glyph gnSpace] : create-glyph gnSpace : glyph-construction
|
|
set-width ww
|
|
|
|
foreach job [items-of jobs.nonDecomposable] : createDottedGlyphImpl job false
|
|
foreach job [items-of jobs.decomposableJobs] : createDottedGlyphImpl job true
|
|
|
|
applyRelations jobs.relApplications
|
|
|
|
# Circled & Braced
|
|
define [digitGlyphNames j] : begin
|
|
return : [(j+'').split ''].map: c => unicodeGlyphs.(['0'.charCodeAt 0] + (c - 0)).name
|
|
|
|
if [not recursive] : do "Single-digit circled"
|
|
local compositions : list
|
|
list 0xA9 {'C'} WideWidth2
|
|
list 0x1F12F {'turnC'} WideWidth2
|
|
list 0xAE {'R'} WideWidth2
|
|
list 0x2117 {'P'} WideWidth2
|
|
list 0x24EA {'zero.lnum'} WideWidth1
|
|
foreach [j : range 1 till 9] : compositions.push : list
|
|
0x2460 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 0 26] : compositions.push {(0x24B6 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WideWidth1}
|
|
foreach [j : range 0 26] : compositions.push {(0x24D0 + j) {unicodeGlyphs.(['a'.charCodeAt 0] + j).name} WideWidth1 0.5 (XH/2)}
|
|
createCircledGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "Double-digit circled"
|
|
local compositions : list
|
|
list null {'markBaseSpace'} WideWidth1
|
|
list 0x1F16D {'C' 'C'} WideWidth1
|
|
list 0x1F12D {'C' 'D'} WideWidth1
|
|
list 0x1F12E {'W' 'z'} WideWidth1
|
|
foreach [j : range 10 till 20] : compositions.push : list
|
|
0x2460 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 21 till 35] : compositions.push : list
|
|
0x3251 + j - 21
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 36 till 50] : compositions.push : list
|
|
0x32B1 + j - 36
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createCircledGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "Single-digit inset circled"
|
|
local compositions : list
|
|
list 0x24FF {'zero.lnum'} WideWidth1
|
|
foreach [j : range 1 till 9] : compositions.push : list
|
|
0x2776 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 0 26] : compositions.push {(0x1F150 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WideWidth1}
|
|
createInsetCircledGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "Double-digit inset circled"
|
|
local compositions : list
|
|
foreach [j : range 10 till 10] : compositions.push : list
|
|
0x2776 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 11 till 20] : compositions.push : list
|
|
0x24EB + j - 11
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createInsetCircledGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "boxed"
|
|
local compositions {}
|
|
compositions.push { null {'markBaseSpace'} WideWidth1 }
|
|
foreach [j : range 0 26] : compositions.push {(0x1F130 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WideWidth1}
|
|
createBoxedGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "double-digit boxed"
|
|
local compositions : list
|
|
list null {'markBaseSpace'} WideWidth1
|
|
list 0x1F14A {'H' 'V'} WideWidth1
|
|
list 0x1F14B {'M' 'V'} WideWidth1
|
|
list 0x1F14C {'S' 'D'} WideWidth1
|
|
list 0x1F14D {'S' 'S'} WideWidth1
|
|
list 0x1F14F {'W' 'C'} WideWidth1
|
|
list 0x1F191 {'C' 'L'} WideWidth1
|
|
list 0x1F194 {'I' 'D'} WideWidth1
|
|
list 0x1F196 {'N' 'G'} WideWidth1
|
|
list 0x1F197 {'O' 'K'} WideWidth1
|
|
list 0x1F19A {'V' 'S'} WideWidth1
|
|
createBoxedGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "triple-digit boxed"
|
|
local compositions : list
|
|
list null {'markBaseSpace'} WideWidth1
|
|
list 0x1F14E {'P' 'P' 'V'} WideWidth1
|
|
list 0x1F195 {'N' 'E' 'W'} WideWidth1
|
|
list 0x1F198 {'S' 'O' 'S'} WideWidth1
|
|
list 0x1F199 {'U' 'P' 'exclam'} WideWidth1
|
|
createBoxedGlyphs 3 compositions
|
|
|
|
if [not recursive] : do "quad-digit boxed"
|
|
local compositions : list
|
|
list null {'markBaseSpace'} WideWidth1
|
|
list 0x1F192 {'C' 'O' 'O' 'L'} WideWidth1
|
|
list 0x1F193 {'F' 'R' 'E' 'E'} WideWidth1
|
|
createBoxedGlyphs 4 compositions
|
|
|
|
if [not recursive] : do "inset boxed"
|
|
local compositions {}
|
|
foreach [j : range 0 26] : compositions.push {(0x1F170 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WideWidth1}
|
|
createInsetBoxedGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "double-digit inset boxed"
|
|
local compositions : list
|
|
list 0x1F18B {'I' 'C'} WideWidth1
|
|
list 0x1F18C {'P' 'A'} WideWidth1
|
|
list 0x1F18D {'S' 'A'} WideWidth1
|
|
list 0x1F18E {'A' 'B'} WideWidth1
|
|
list 0x1F18F {'W' 'C'} WideWidth1
|
|
createInsetBoxedGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "inset mosaic"
|
|
local compositions {}
|
|
compositions.push { 0x1FBB1 { [unicodeGlyphs.(0x2714).name.replace [regex '.WWID$'] ".NWID"] } WideWidth2 }
|
|
compositions.push { 0x1FBB4 { [unicodeGlyphs.(0x21B2).name.replace [regex '.WWID$'] ".NWID"] } WideWidth2 }
|
|
compositions.push { 0x1FBC4 { [unicodeGlyphs.(0x003F).name.replace [regex '.WWID$'] ".NWID"] } WideWidth2 }
|
|
createInsetMosaicGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "Single-digit double circled"
|
|
local compositions {}
|
|
compositions.push { null {'markBaseSpace'} WideWidth1 }
|
|
foreach [j : range 1 till 9] : compositions.push : list
|
|
0x24F5 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createDoubleCircledGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "Double-digit double circled"
|
|
local compositions {}
|
|
compositions.push { null {'markBaseSpace'} WideWidth1 }
|
|
foreach [j : range 10 till 10] : compositions.push : list
|
|
0x24F5 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createDoubleCircledGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "Single-digit braced"
|
|
local compositions {}
|
|
foreach [j : range 1 till 9] : compositions.push : list
|
|
0x2474 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
foreach [j : range 0 26] : compositions.push {(0x249C + j) {unicodeGlyphs.(['a'.charCodeAt 0] + j).name} WideWidth1 0.5 (XH/2)}
|
|
foreach [j : range 0 26] : compositions.push {(0x1F110 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WideWidth1}
|
|
createBracedGlyphs 1 compositions
|
|
|
|
if [not recursive] : do "Double-digit braced"
|
|
local compositions {}
|
|
foreach [j : range 10 till 20] : compositions.push : list
|
|
0x2474 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createBracedGlyphs 2 compositions
|
|
|
|
if [not recursive] : do "Single-digit dotted"
|
|
local compositions : list
|
|
list 0x1F100 {'zero.lnum'} WideWidth1
|
|
foreach [j : range 1 till 9] : compositions.push : list
|
|
0x2488 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createDottedGlyphs 1 'period' compositions
|
|
|
|
if [not recursive] : do "Single-digit comma"
|
|
local compositions {}
|
|
foreach [j : range 0 till 9] : compositions.push : list
|
|
0x1F101 + j
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createDottedGlyphs 1 'comma' compositions
|
|
|
|
if [not recursive] : do "Double-digit dotted"
|
|
local compositions : list
|
|
foreach [j : range 10 till 20] : compositions.push : list
|
|
0x2488 + j - 1
|
|
digitGlyphNames j
|
|
begin WideWidth1
|
|
createDottedGlyphs 2 'period' compositions
|
|
|
|
glyph-block Autobuild-Fractions : begin
|
|
glyph-block-import CommonShapes
|
|
glyph-block-import Overmarks
|
|
glyph-block-import Autobuild-Enclosure-Shared : CollectJobs EnsureComponentGlyphT CreateDerivedFontFromJobs applyRelations
|
|
|
|
define [createFracImpl prefix demands fine scaleFactor closing] : begin
|
|
local jobs : CollectJobs DECOMPOSABLE prefix '' demands
|
|
define miniatureFont : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Miniature
|
|
glyphs -- gs
|
|
crowd -- 4
|
|
scale -- (scaleFactor + 0.05)
|
|
|
|
local dist : XH * (1 - scaleFactor - closing)
|
|
local gnFractionBar ".frac-bar-\(prefix)"
|
|
|
|
define [numeratorImpl numid] : begin
|
|
local gnn ".frac-num-\(prefix){\(numid)}"
|
|
if [not : query-glyph gnn] : create-glyph gnn : glyph-construction
|
|
set-width 0
|
|
if [not miniatureFont.(numid)] : console.log numid
|
|
include miniatureFont.(numid)
|
|
apply-transform : Upright
|
|
apply-transform : Translate (- miniatureFont.(numid).advanceWidth / 2) 0
|
|
apply-transform : Scale scaleFactor
|
|
apply-transform : Translate Middle (symbolMid + dist / 2)
|
|
apply-transform : Italify
|
|
apply-transform : Translate (-Width) 0
|
|
return gnn
|
|
|
|
define [denumeratorImpl denid] : begin
|
|
local gnd ".frac-den-\(prefix){\(denid)}"
|
|
if [not : query-glyph gnd] : create-glyph gnd : glyph-construction
|
|
set-width 0
|
|
include miniatureFont.(denid)
|
|
apply-transform : Upright
|
|
apply-transform : Translate (- miniatureFont.(denid).advanceWidth / 2) 0
|
|
apply-transform : Scale scaleFactor
|
|
apply-transform : Translate Middle (symbolMid - CAP * scaleFactor - dist / 2)
|
|
apply-transform : Italify
|
|
apply-transform : Translate (-Width) 0
|
|
return gnd
|
|
|
|
define [createFractionImpl job jobDecomposable] : begin
|
|
local {gnf unicode {numid denid}} job
|
|
local gnn : EnsureComponentGlyphT numid numeratorImpl
|
|
local gnd : EnsureComponentGlyphT denid denumeratorImpl
|
|
if [not : query-glyph gnf] : create-glyph gnf : glyph-construction
|
|
assign-unicode unicode
|
|
include : refer-glyph gnn
|
|
include : refer-glyph gnd
|
|
apply-transform : Translate (Width) 0
|
|
include : refer-glyph gnFractionBar
|
|
if jobDecomposable : CvDecompose.set currentGlyph { gnFractionBar gnn gnd }
|
|
|
|
create-glyph gnFractionBar : glyph-construction
|
|
set-width Width
|
|
if fine : include : HBar SB RightSB symbolMid (fine * 0.75)
|
|
|
|
foreach job [items-of jobs.nonDecomposable] : createFractionImpl job false
|
|
foreach job [items-of jobs.decomposableJobs] : createFractionImpl job true
|
|
|
|
applyRelations jobs.relApplications
|
|
|
|
define [createFractions records] : createFracImpl 'frac' records [adviceBlackness 3] 0.55 0.05
|
|
define [createPowerlineStacks records] : createFracImpl 'pwlStack' records 0 0.6 0.15
|
|
|
|
if [not recursive] : createFractions : list
|
|
list 0x00BC { 'one.lnum' 'four.lnum' }
|
|
list 0x00BD { 'one.lnum' 'two.lnum' }
|
|
list 0x00BE { 'three.lnum' 'four.lnum' }
|
|
list 0x2150 { 'one.lnum' 'seven.lnum' }
|
|
list 0x2151 { 'one.lnum' 'nine.lnum' }
|
|
list 0x2152 { 'one.lnum' 'numbers/ten{one.lnum}{zero.lnum}' }
|
|
list 0x2153 { 'one.lnum' 'three.lnum' }
|
|
list 0x2154 { 'two.lnum' 'three.lnum' }
|
|
list 0x2155 { 'one.lnum' 'five.lnum' }
|
|
list 0x2156 { 'two.lnum' 'five.lnum' }
|
|
list 0x2157 { 'three.lnum' 'five.lnum' }
|
|
list 0x2158 { 'four.lnum' 'five.lnum' }
|
|
list 0x2159 { 'one.lnum' 'six.lnum' }
|
|
list 0x215A { 'five.lnum' 'six.lnum' }
|
|
list 0x215B { 'one.lnum' 'eight.lnum' }
|
|
list 0x215C { 'three.lnum' 'eight.lnum' }
|
|
list 0x215D { 'five.lnum' 'eight.lnum' }
|
|
list 0x215E { 'seven.lnum' 'eight.lnum' }
|
|
list 0x2189 { 'zero.lnum' 'three.lnum' }
|
|
# care-of
|
|
list 0x2100 { 'largescripta' 'C' }
|
|
list 0x2101 { 'largescripta' 'S' }
|
|
list 0x214D { 'A' 'S' }
|
|
list 0x2105 { 'C' 'O' }
|
|
list 0x2106 { 'C' 'U' }
|
|
|
|
if [not recursive] : createPowerlineStacks : list
|
|
# Powerline LN symbol
|
|
list 0xE0A1 { 'L' 'N' }
|
|
list 0xE0A3 { 'C' 'N' }
|
|
|
|
glyph-block AutoBuild-Accented-Equal : begin
|
|
glyph-block-import CommonShapes
|
|
glyph-block-import Overmarks
|
|
glyph-block-import Autobuild-Enclosure-Shared : CollectJobs CreateDerivedFontFromJobs EnsureComponentGlyphT applyRelations
|
|
|
|
define [createAccentedOp gnBase crowd scale shiftX shiftY demands] : begin
|
|
define prefix : 'accent-op{' + gnBase + '}{' + [{crowd scale shiftX shiftY}.join '-'] + '}'
|
|
local jobs : CollectJobs DECOMPOSABLE prefix '' demands
|
|
local dFont : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Miniature
|
|
glyphs -- gs
|
|
crowd -- crowd
|
|
scale -- scale
|
|
mono -- true
|
|
|
|
define [ComponentImpl offset totalWidth] : lambda [gidPart] : begin
|
|
define gni : '.accented-op-part.' + gidPart + '@' + [{ prefix offset totalWidth }.join '/']
|
|
if [query-glyph gni] : return gni
|
|
create-glyph gni : glyph-construction
|
|
set-width 0
|
|
include dFont.(gidPart)
|
|
apply-transform : Upright
|
|
apply-transform : Translate (-totalWidth / 2 + offset) 0
|
|
apply-transform : Scale scale
|
|
apply-transform : Translate (Middle + shiftX - Width) shiftY
|
|
apply-transform : Italify
|
|
return gni
|
|
|
|
define [createAccentedOpImpl job decomposable] : begin
|
|
local { gn unicode parts } job
|
|
local totalWidth 0
|
|
local offsets { }
|
|
foreach [j : range 0 parts.length] : begin
|
|
local gidPart parts.(j)
|
|
set offsets.(j) totalWidth
|
|
set totalWidth : totalWidth + dFont.(gidPart).advanceWidth
|
|
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
assign-unicode unicode
|
|
set-width Width
|
|
local ps { gnBase }
|
|
foreach [j : range 0 parts.length] : begin
|
|
local gidPart parts.(j)
|
|
local p : EnsureComponentGlyphT gidPart : ComponentImpl offsets.(j) totalWidth
|
|
include : refer-glyph p
|
|
ps.push p
|
|
apply-transform : Translate Width 0
|
|
include : refer-glyph gnBase
|
|
if decomposable : CvDecompose.set currentGlyph ps
|
|
|
|
foreach job [items-of jobs.nonDecomposable] : createAccentedOpImpl job false
|
|
foreach job [items-of jobs.decomposableJobs] : createAccentedOpImpl job true
|
|
|
|
applyRelations jobs.relApplications
|
|
|
|
if [not recursive] : createAccentedOp 'equal' 7 0.4 0 aboveMarkBot : list
|
|
list 0x2257 {"o"}
|
|
list 0x225e {"m"}
|
|
list 0x225F {"question"}
|
|
if [not recursive] : createAccentedOp 'sqrt' 5 0.5 (-Width / 4) [mix operBot operTop 0.6] : list
|
|
list 0x221b {"three.lnum"}
|
|
list 0x221c {"four.lnum"}
|
|
if [not recursive] : createAccentedOp 'equal' 8 0.3 0 aboveMarkBot : list
|
|
list 0x225d {"d" "e" "f"}
|
|
|
|
glyph-block Autobuild-Ligatures : begin
|
|
glyph-block-import CommonShapes
|
|
glyph-block-import Overmarks
|
|
glyph-block-import Autobuild-Enclosure-Shared : CollectJobs CreateDerivedFontFromJobs EnsureComponentGlyphT applyRelations
|
|
|
|
define [createLigatures prefix _shrink1 _shrink2 wadj1 wadj2 demands] : for-width-kinds WideWidth2
|
|
local ww : if FMosaicWide (MosaicWidth * para.diversityM) MosaicWidth
|
|
local jobs : CollectJobs DECOMPOSABLE prefix MosaicNameSuffix demands
|
|
local shrink1 : if FMosaicWide 1 [clamp 0 1 (_shrink1 * ww / Width)]
|
|
local shrink2 : if FMosaicWide 1 [clamp 0 1 (_shrink2 * ww / Width)]
|
|
local df1 : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Thinner gs shrink1
|
|
local df2 : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Thinner gs shrink2
|
|
|
|
define [LigaturePartImpl df offset1 compress offset2 aw] : lambda [gidPart] : begin
|
|
define gni : '.ligature-part-1.' + gidPart + '@' + [{prefix compress offset1 offset2 aw}.join '/']
|
|
if [query-glyph gni] : return gni
|
|
create-glyph gni : glyph-construction
|
|
set-width aw
|
|
include df.(gidPart)
|
|
apply-transform : Upright
|
|
apply-transform : Translate offset1 0
|
|
apply-transform : Scale compress 1
|
|
apply-transform : Translate offset2 0
|
|
apply-transform : Italify
|
|
return gni
|
|
|
|
define [LigatureImpl job decomposable] : begin
|
|
local { gn unicode { c1 c2 } desiredWidth } job
|
|
local ps {}
|
|
|
|
local dfg1 df1.(c1)
|
|
local dfg2 df2.(c2)
|
|
|
|
if FMosaicWide : begin
|
|
local aw : dfg1.advanceWidth + dfg2.advanceWidth
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
if ( unicode && [MangleUnicode unicode desiredWidth] )
|
|
assign-unicode [MangleUnicode unicode desiredWidth]
|
|
set-width aw
|
|
local part1 : EnsureComponentGlyphT c1
|
|
LigaturePartImpl df1 0 1 0 aw
|
|
local part2 : EnsureComponentGlyphT c2
|
|
LigaturePartImpl df2 dfg1.advanceWidth 1 (-aw) 0
|
|
include : refer-glyph part1
|
|
include : WithTransform [Translate aw 0] : refer-glyph part2
|
|
if decomposable : CvDecompose.set currentGlyph { part1 part2 }
|
|
: else : begin
|
|
local sumChildrenWidth : dfg1.advanceWidth * wadj1 + dfg2.advanceWidth * wadj2
|
|
local kern : Math.max 0 (SB * 7/8 * (shrink1 + shrink2) - [Math.max 0 (ww - sumChildrenWidth)])
|
|
local refW : sumChildrenWidth - kern
|
|
|
|
local offset1Part1 : - refW / 2
|
|
local offset1Part2 : dfg1.advanceWidth * wadj1 - kern - refW / 2
|
|
local compress : clamp 0 1 ((ww - SB * 1.25) / (ww - SB * 2) * ww / refW)
|
|
local offset2 : ww / 2
|
|
|
|
if [not : query-glyph gn] : create-glyph gn : glyph-construction
|
|
if ( unicode && [MangleUnicode unicode desiredWidth] )
|
|
assign-unicode [MangleUnicode unicode desiredWidth]
|
|
set-width ww
|
|
local part1 : EnsureComponentGlyphT c1
|
|
LigaturePartImpl df1 offset1Part1 compress offset2 ww
|
|
local part2 : EnsureComponentGlyphT c2
|
|
LigaturePartImpl df2 offset1Part2 compress (offset2 - ww) 0
|
|
include : refer-glyph part1
|
|
include : WithTransform [Translate ww 0] : refer-glyph part2
|
|
if decomposable : CvDecompose.set currentGlyph { part1 part2 }
|
|
|
|
|
|
foreach job [items-of jobs.nonDecomposable] : LigatureImpl job false
|
|
foreach job [items-of jobs.decomposableJobs] : LigatureImpl job true
|
|
|
|
applyRelations jobs.relApplications
|
|
|
|
define stdShrink : clamp 0.75 0.9 : linreg 72 0.75 108 0.9 Stroke
|
|
if [not recursive] : createLigatures 'compatLigature1' stdShrink stdShrink 1 1 : list
|
|
list 0x1C4 { 'D' 'Zcaron' }
|
|
list 0x1C5 { 'D' 'zcaron' }
|
|
list 0x1C6 { 'd' 'zcaron' }
|
|
list 0x1C7 { 'L' 'J' }
|
|
list 0x1C8 { 'L' 'j' }
|
|
list 0x1C9 { 'l' 'j' }
|
|
list 0x1CA { 'N' 'J' }
|
|
list 0x1CB { 'N' 'j' }
|
|
list 0x1CC { 'n' 'j' }
|
|
list 0x1F1 { 'D' 'Z' }
|
|
list 0x1F2 { 'D' 'z' }
|
|
list 0x1F3 { 'd' 'z' }
|
|
list 0x478 { 'O' 'y' }
|
|
list 0x479 { 'o' 'y' }
|
|
list 0x20A8 { 'R' 's' }
|
|
list 0x20AF { 'D' 'rho' }
|
|
list 0x203c { 'exclam' 'exclam' }
|
|
list 0x2047 { 'question' 'question' }
|
|
list 0x2048 { 'question' 'exclam' }
|
|
list 0x2049 { 'exclam' 'question' }
|
|
list 0x1F190 { 'D' 'J' } WideWidth1
|
|
if [not recursive] : createLigatures 'temperature' 0.7 0.8 0.75 0.9 : list
|
|
list 0x2103 { 'degree' 'C' }
|
|
list 0x2109 { 'degree' 'F' }
|
|
|
|
glyph-block Autobuild-Pnonetic-Ligatures : begin
|
|
glyph-block-import CommonShapes
|
|
glyph-block-import Overmarks
|
|
|
|
define [glyphNameIsNotUsed name] : begin
|
|
if [query-glyph name] : throw : new Error "Glyph \(name) already exists!"
|
|
return name
|
|
define [PhoneticLigatureGlyphName a b] : glyphNameIsNotUsed "phonetic{\(a)}{\(b)}"
|
|
|
|
define [createPhoneticLigatures _shrink1 _shrink2 wadj1 wadj2 records] : begin
|
|
local pendingGlyphs1 : records.map : [record] => record.1
|
|
local pendingGlyphs2 : records.map : [record] => record.2
|
|
local shrink1 : clamp 0 1 _shrink1
|
|
local shrink2 : clamp 0 1 _shrink2
|
|
local kern : SB * shrink1 + SB * shrink2 + 0.5 * Stroke * [mix shrink1 shrink2 0.5] - OX * 2
|
|
local antiScale : (Width * shrink1 + Width * shrink2 - kern) / Width
|
|
foreach [cycle : range 0 4] : begin
|
|
set kern : SB * shrink1 + SB * shrink2 + 0.5 * Stroke * [mix shrink1 shrink2 0.5] - OX * 2
|
|
local tmp-shrink1 : (shrink1 * Width + kern * shrink1 / (shrink1 + shrink2)) / (Width * shrink1 + Width * shrink2 - kern) * antiScale
|
|
local tmp-shrink2 : (shrink2 * Width + kern * shrink2 / (shrink1 + shrink2)) / (Width * shrink1 + Width * shrink2 - kern) * antiScale
|
|
set shrink1 : clamp 0 1 tmp-shrink1
|
|
set shrink2 : clamp 0 1 tmp-shrink2
|
|
|
|
local df1 : Thinner pendingGlyphs1 shrink1
|
|
local df2 : Thinner pendingGlyphs2 shrink2
|
|
|
|
foreach [{unicode c1 c2} : items-of records] : begin
|
|
local glyphName : PhoneticLigatureGlyphName c1 c2
|
|
|
|
define [maskOut] : create-glyph : glyph-construction
|
|
local s 0
|
|
local step (-OX)
|
|
local dist (Stroke * 2)
|
|
while (s < dist) : begin
|
|
include df2.(c2)
|
|
apply-transform : Translate step 0
|
|
set s : s + step
|
|
apply-transform : Translate (df1.(c1).advanceWidth * wadj1 - kern) 0
|
|
|
|
create-glyph glyphName unicode : glyph-construction
|
|
local sumChildrenWidth : df1.(c1).advanceWidth * wadj1 + df2.(c2).advanceWidth * wadj2
|
|
local refW : sumChildrenWidth - kern
|
|
include df2.(c2)
|
|
include : Translate (df1.(c1).advanceWidth * wadj1 - kern) 0
|
|
include : difference
|
|
intersection
|
|
Rect (CAP * 2) (Descender * 2) (-Width) (df1.(c1).advanceWidth * wadj1 - kern + df2.(c2).advanceWidth * wadj2 / 2)
|
|
glyph-construction : include df1.(c1)
|
|
maskOut
|
|
include : Upright
|
|
include : Translate (-refW / 2) 0
|
|
include : Scale [clamp 0 1 ((Width - SB * 1.25) / (Width - SB * 2) * Width / refW)] 1
|
|
include : Translate (Width / 2) 0
|
|
include : Italify
|
|
|
|
define stdShrink : clamp 0.75 0.9 : linreg 72 0.75 108 0.9 Stroke
|
|
if [not recursive] : createPhoneticLigatures stdShrink stdShrink 1 1 : list
|
|
list 0x02A3 'd' 'z'
|
|
list 0x02A4 'd' 'ezh'
|
|
list 0x02A5 'd' 'zcurlytail'
|
|
list 0x02A6 't.phoneticLeft' 's.phoneticRight'
|
|
list 0x02A7 't.phoneticLeft.extended' 'esh'
|
|
list 0x02A8 't.phoneticLeft' 'ccurlytail'
|
|
list 0x02A9 'f.phoneticLeft' 'eng'
|
|
list 0x02AA 'l.phoneticLeft' 's.phoneticRight'
|
|
list 0x02AB 'l.phoneticLeft' 'z'
|
|
list 0xAB66 'd' 'zrtailBR'
|
|
list 0xAB67 't.phoneticLeft' 'srtail'
|
|
|
|
glyph-block Autobuild-Grouped-Digits : begin
|
|
glyph-block-import CommonShapes
|
|
|
|
define [createGroupedDigits shrink crowd numberGlyphIDs] : begin
|
|
create-glyph '.nd-shade' : glyph-construction
|
|
include : intersection
|
|
HBarBottom 0 Width (Descender * 0.75) [adviceBlackness 4]
|
|
glyph-construction
|
|
include : refer-glyph "denseShade.WWID"
|
|
apply-transform : Translate (-Width / 2) 0
|
|
apply-transform : Translate (-Width) 0
|
|
set-width 0
|
|
|
|
foreach [gid : items-of numberGlyphIDs] : foreach [nd : items-of {0 1 2 3 4 5 6}]
|
|
create-glyph (gid + ".nd" + nd) : glyph-construction
|
|
include : refer-glyph gid
|
|
if (nd >= 3 && nd <= 5) : begin
|
|
include : WithTransform [Translate Width 0] : refer-glyph '.nd-shade'
|
|
CvDecompose.set currentGlyph { gid '.nd-shade' }
|
|
: else : begin
|
|
CvDecompose.set currentGlyph { gid }
|
|
|
|
if [not recursive] : createGroupedDigits 0.9 3.0 {
|
|
'zero.lnum' 'one.lnum' 'two.lnum' 'three.lnum' 'four.lnum'
|
|
'five.lnum' 'six.lnum' 'seven.lnum' 'eight.lnum' 'nine.lnum'
|
|
}
|