Iosevka/packages/font-glyphs/src/meta/aesthetics.ptl

516 lines
23 KiB
Text

import [Point] from "@iosevka/geometry/point"
import [Transform] from "@iosevka/geometry/transform"
import [Anchor] from "@iosevka/geometry/anchor"
import [mix linreg clamp fallback] from "@iosevka/util"
# Parameter generation
export : define [calculateMetrics para] : begin
define UPM 1000
define HalfUPM : UPM / 2
# Key metrics
define Width : Math.round para.width
define SB : Math.round para.sb
define CAP : Math.round para.cap
define XH : Math.round para.xHeight
define Ascender : Math.round para.ascender
define Descender : Math.round : fallback para.descender (XH - Ascender)
# Key metrics for symbols
define SymbolMid : Math.round para.symbolMid
define halfParenSize : Math.ceil (para.parenSize / 2)
define ParenTop : SymbolMid + halfParenSize
define ParenBot : SymbolMid - halfParenSize
define OperTop : SymbolMid + para.operSize * (Width - SB * 2)
define OperBot : SymbolMid - para.operSize * (Width - SB * 2)
define TackTop : SymbolMid + para.tackSize * (Width - SB * 2)
define TackBot : SymbolMid - para.tackSize * (Width - SB * 2)
define PlusTop : SymbolMid + para.plusSize * (Width - SB * 2)
define PlusBot : SymbolMid - para.plusSize * (Width - SB * 2)
define PictTop : SymbolMid + para.pictSize * (Width - SB * 2)
define PictBot : SymbolMid - para.pictSize * (Width - SB * 2)
define BgOpTop : SymbolMid + para.bgopSize * (Width - SB * 2)
define BgOpBot : SymbolMid - para.bgopSize * (Width - SB * 2)
define BgTkTop : SymbolMid + para.bgtkSize * (Width - SB * 2)
define BgTkBot : SymbolMid - para.bgtkSize * (Width - SB * 2)
define Contrast : fallback para.contrast 1
# Transform constructors
define [Italify angle shift] : begin
local slope : Math.tan : [fallback angle para.slopeAngle] / 180 * Math.PI
return : new Transform 1 slope 0 1 [fallback shift : (-slope) * SymbolMid] 0
define [Upright angle shift] [Italify angle shift :.inverse]
define [Scale sx sy] : new Transform sx 0 0 [fallback sy sx] 0 0
define [Translate x y] : new Transform 1 0 0 1 x y
define [ApparentTranslate x y] : Translate (x + TanSlope * y) y
define [Rotate angle] : new Transform [Math.cos angle] [Math.sin (-angle)] [Math.sin angle] [Math.cos angle] 0 0
define GlobalTransform : Italify para.slopeAngle
define TanSlope GlobalTransform.xy
define SinSlope : Math.sin : para.slopeAngle / 180 * Math.PI
define CosSlope : Math.cos : para.slopeAngle / 180 * Math.PI
define HVContrast : Contrast * CosSlope + SinSlope * TanSlope
define [HSwToV sw] : sw * HVContrast
define [VSwToH sw] : sw / HVContrast
# Orient parameters
define Upward : new Point Point.Type.Corner (-HVContrast) 0
define Downward : new Point Point.Type.Corner (+HVContrast) 0
define Rightward : new Point Point.Type.Corner 0 (+1)
define Leftward : new Point Point.Type.Corner 0 (-1)
# Style parameters
define O para.overshoot
define OX para.overshootx
define OXHook para.oxhook
define Hook para.hook
define AHook para.ahook
define SHook para.shook
define RHook para.rhook
define JHook para.jhook
define HookX para.hookx
define TailX para.tailX
define TailY para.tailY
define ArchDepth para.archDepth
define SmallArchDepth para.smallArchDepth
# Weight Control
define BaseFillRate : Math.min 0.95 : [HSwToV : 2 * para.stroke] / (Width - SB * 2)
define WeightControlFactor : [Math.atanh BaseFillRate] / BaseFillRate
define [StrokeWeightControlSigmoid x] : Math.tanh : WeightControlFactor * x
define [AdviceStrokeInSpace availSpace contrast crowdedness mul] : begin
local nonAdjustedFillRate : crowdedness * contrast * para.stroke / availSpace
local adjustedFillRate : StrokeWeightControlSigmoid nonAdjustedFillRate
local strokeWidthScalar : Math.min 1 : mul * adjustedFillRate / nonAdjustedFillRate
return : para.stroke * strokeWidthScalar
define [AdviceStroke crowdedness adws mul] : begin
local spaceH : Width * [fallback adws 1] - SB * 2
return : AdviceStrokeInSpace spaceH HVContrast crowdedness [fallback mul 1]
define [AdviceStroke2 crwX crwY refH adws] : begin
local spaceH : Width * [fallback adws 1] - SB * 2
local spaceV refH
return : Math.min
AdviceStrokeInSpace spaceH HVContrast crwX 1
AdviceStrokeInSpace spaceV 1 crwY 1
define Stroke : AdviceStroke 2
define HalfStroke : Stroke / 2
define QuarterStroke : Stroke / 4
define DotSize : fallback para.dotSize Stroke
define PeriodSize : fallback para.periodSize DotSize
define HBarPos : DesignParameters.hBarPos - 0.09 * Stroke / CAP
define OverlayPos DesignParameters.overlayPos
define Jut para.jut
define LongJut para.longjut
define VJut para.vjut
define LongVJut : fallback para.longvjut LongJut
define MidJutSide : Math.max Jut : mix [HSwToV HalfStroke] LongJut 0.5
define MidJutCenter : Math.max Jut : mix [HSwToV HalfStroke] LongJut 0.6
define AccentStackOffset para.accentStackOffset
define AccentWidth para.accentWidth
define AccentClearance para.accentClearance
define AccentHeight para.accentHeight
define CThin : fallback para.cthin 0.75
define CThinB : fallback para.cthinb 0.50
define SLAB para.slab
define [IBalance df] : df.adws * df.adws * [fallback para.ibalance (LongJut * 0.04)] # Serifed
define [IBalance2 df] : df.adws * [fallback para.ibalance2 (LongJut * 0.14)] # Hooky, Tailed
define JBalance : fallback para.jbalance 0
define JBalance2 : fallback para.jbalance2 (LongJut * 0.04 + QuarterStroke)
define TBalance : fallback para.tbalance JBalance
define TBalance2 : fallback para.tbalance2 TBalance
define RBalance : fallback para.rbalance (JBalance * 0.3)
define RBalance2 : fallback para.rbalance2 0
define FBalance : fallback para.fbalance 0
define OneBalance : fallback para.onebalance 0
# derived metrics
define WideWidth0 : if para.isQuasiProportional UPM (Width * 2)
define WideWidth1 : if (para.spacing >= 1) WideWidth0 Width
define WideWidth2 : if (para.spacing >= 2) WideWidth0 Width
define WideWidth3 : if (para.spacing >= 3) WideWidth0 Width
define WideWidth4 : if (para.spacing >= 4) WideWidth0 Width
define [NarrowUnicodeT wd] : function [u] : if (wd === Width) u null
define [WideUnicodeT wd] : function [u] : if (wd !== Width) u null
define EssUpper : Stroke * [fallback para.essRatioUpper para.essRatio Contrast]
define EssLower : Stroke * [fallback para.essRatioLower para.essRatio Contrast]
define EssQuestion : Stroke * [fallback para.essRatioQuestion para.essRatio Contrast]
define RightSB : Width - SB
define Middle : Width / 2
define DotRadius : DotSize / 2
define PeriodRadius : PeriodSize / 2
define SideJut : Jut - [HSwToV HalfStroke]
define VJutStroke : AdviceStroke 3.5
define DToothlessRise : Hook * 0.25 + Stroke / 16
define DMBlend 0.80
define [StrokeWidthBlend min max sw] : linreg para.canonicalStrokeWidthMin min para.canonicalStrokeWidthMax max [fallback sw Stroke]
define SmoothAdjust : StrokeWidthBlend 80 144
define [ArchDepthAOf archDepth width] : archDepth - TanSlope * SmoothAdjust / Width * width
define [ArchDepthBOf archDepth width] : archDepth + TanSlope * SmoothAdjust / Width * width
define [YSmoothMidR top bot _ada _adb] : begin
local ada : fallback _ada ArchDepthA
local adb : fallback _adb ArchDepthB
local delta : (adb - ada) / 2
local smOfSma : ada + delta
local smOfSmb : adb - delta
local yNotAdjusted : mix top bot : smOfSmb / (smOfSma + smOfSmb)
return : yNotAdjusted - delta * [Math.min 1 : (top - bot) / (ada + adb)]
set YSmoothMidR.cr : function [c r _ada _adb] : YSmoothMidR (c + r) (c - r) _ada _adb
define [YSmoothMidL top bot _ada _adb] : begin
local ada : fallback _ada ArchDepthA
local adb : fallback _adb ArchDepthB
local delta : (adb - ada) / 2
local smOfSma : ada + delta
local smOfSmb : adb - delta
local yNotAdjusted : mix top bot : smOfSma / (smOfSma + smOfSmb)
return : yNotAdjusted + delta * [Math.min 1 : (top - bot) / (ada + adb)]
set YSmoothMidL.cr : function [c r _ada _adb] : YSmoothMidL (c + r) (c - r) _ada _adb
define ArchDepthA : ArchDepth - TanSlope * SmoothAdjust
define ArchDepthB : ArchDepth + TanSlope * SmoothAdjust
define SmallArchDepthA : SmallArchDepth - TanSlope * SmoothAdjust
define SmallArchDepthB : SmallArchDepth + TanSlope * SmoothAdjust
define CorrectionOMidX : TanSlope * 0.9 * [StrokeWidthBlend 1.3 0.9]
define CorrectionOMidS : Stroke * CorrectionOMidX
define OverlayStroke : AdviceStroke 3.75
define OperatorStroke : AdviceStroke 2.75
define GeometryStroke : AdviceStroke 4
define ShoulderFine : Math.min (Stroke * para.shoulderFineMin) : AdviceStroke 24
define [UnicodeWeightGrade n _scl _swRef] : begin
define scl : fallback _scl 1
define kw : 10 - scl - n / 200
define [mulPow s] : (0.25 + s / 8) * [StrokeWidthBlend 2 1]
define kMul : [Math.pow (n / 100) : mulPow scl] / [Math.pow 4 : mulPow 2]
define kAdj : [fallback _swRef Stroke] / [AdviceStroke 6]
return : kMul * kAdj * [AdviceStroke kw]
define [AdviceGlottalStopArchDepth y sign] : begin
return : ((y - Stroke) * 0.24 + Stroke * 0.625) + sign * TanSlope * SmoothAdjust
define VERY-FAR : UPM * 16
define TINY : 1 / 128
return [object
DesignParameters UPM HalfUPM Width SB CAP XH Ascender Descender Contrast SymbolMid ParenTop
ParenBot OperTop OperBot TackTop TackBot PlusTop PlusBot PictTop PictBot BgOpTop BgOpBot
BgTkTop BgTkBot Italify Upright Scale Translate ApparentTranslate Rotate GlobalTransform
TanSlope HVContrast Upward Downward Rightward Leftward O OX OXHook Hook AHook SHook RHook
JHook HookX TailX TailY ArchDepth SmallArchDepth Stroke HalfStroke QuarterStroke DotSize
PeriodSize HBarPos OverlayPos Jut VJut LongJut LongVJut VJutStroke AccentStackOffset
AccentWidth AccentClearance AccentHeight CThin CThinB SLAB IBalance IBalance2 JBalance
JBalance2 TBalance TBalance2 RBalance RBalance2 FBalance OneBalance WideWidth0 WideWidth1
WideWidth2 WideWidth3 WideWidth4 EssUpper EssLower EssQuestion RightSB Middle DotRadius
PeriodRadius ArchDepthA ArchDepthB SmallArchDepthA SmallArchDepthB CorrectionOMidX
CorrectionOMidS compositeBaseAnchors AdviceStroke AdviceStroke2 AdviceStrokeInSpace
OverlayStroke OperatorStroke GeometryStroke ShoulderFine UnicodeWeightGrade
AdviceGlottalStopArchDepth StrokeWidthBlend ArchDepthAOf ArchDepthBOf SmoothAdjust SideJut
MidJutSide MidJutCenter YSmoothMidR YSmoothMidL DToothlessRise DMBlend HSwToV VSwToH
NarrowUnicodeT WideUnicodeT VERY-FAR TINY]
export : define [setFontMetrics para metrics fm] : begin
define [object CAP Descender XH Width SymbolMid] metrics
define leading : Math.round para.leading
define asc : Math.round : SymbolMid + leading / 2
define desc : Math.round : SymbolMid - leading / 2
define descenderPad : Math.round : fallback para.descenderPad 0
define winMetricAscenderPad : Math.round : fallback para.winMetricAscenderPad 0
define winMetricDescenderPad : Math.round : fallback para.winMetricDescenderPad 0
set fm.os2.xAvgCharWidth Width
set fm.head.unitsPerEm 1000
set fm.hhea.ascender asc
set fm.os2.usWinAscent (asc + winMetricAscenderPad)
set fm.os2.sTypoAscender asc
set fm.hhea.descender (Descender - descenderPad)
set fm.os2.usWinDescent ([Math.abs desc] + descenderPad + winMetricDescenderPad)
set fm.os2.sTypoDescender (desc - descenderPad)
set fm.hhea.lineGap (leading - asc + Descender)
set fm.os2.sTypoLineGap (leading - asc + desc)
set fm.os2.sxHeight XH
set fm.os2.sCapHeight CAP
local slope : Math.tan para.slopeAngle
set fm.post.italicAngle : Math.round (0 - para.slopeAngle)
set fm.hhea.caretSlopeRise : if para.slopeAngle (1000) 1
set fm.hhea.caretSlopeRun : if para.slopeAngle ((-slope) * 1000) 0
set fm.hhea.caretOffset : if para.slopeAngle ((-slope) * para.symbolMid) 0
# Fixed metrics
set fm.os2.yStrikeoutPosition para."os2.yStrikeoutPosition"
set fm.os2.yStrikeoutSize para."os2.yStrikeoutSize"
set fm.os2.ySubscriptXOffset para."os2.ySubscriptXOffset"
set fm.os2.ySubscriptXSize para."os2.ySubscriptXSize"
set fm.os2.ySubscriptYOffset para."os2.ySubscriptYOffset"
set fm.os2.ySubscriptYSize para."os2.ySubscriptYSize"
set fm.os2.ySuperscriptXOffset para."os2.ySuperscriptXOffset"
set fm.os2.ySuperscriptXSize para."os2.ySuperscriptXSize"
set fm.os2.ySuperscriptYOffset para."os2.ySuperscriptYOffset"
set fm.os2.ySuperscriptYSize para."os2.ySuperscriptYSize"
set fm.post.underlinePosition para."post.underlinePosition"
set fm.post.underlineThickness para."post.underlineThickness"
export : define [copyFontMetrics fm1 fm2] : begin
set fm2.os2.xAvgCharWidth fm1.os2.xAvgCharWidth
set fm2.head.unitsPerEm fm1.head.unitsPerEm
set fm2.hhea.ascender fm1.hhea.ascender
set fm2.os2.usWinAscent fm1.os2.usWinAscent
set fm2.os2.sTypoAscender fm1.os2.sTypoAscender
set fm2.hhea.descender fm1.hhea.descender
set fm2.os2.usWinDescent fm1.os2.usWinDescent
set fm2.os2.sTypoDescender fm1.os2.sTypoDescender
set fm2.hhea.lineGap fm1.hhea.lineGap
set fm2.os2.sTypoLineGap fm1.os2.sTypoLineGap
set fm2.os2.sxHeight fm1.os2.sxHeight
set fm2.os2.sCapHeight fm1.os2.sCapHeight
set fm2.post.italicAngle fm1.post.italicAngle
set fm2.hhea.caretSlopeRise fm1.hhea.caretSlopeRise
set fm2.hhea.caretSlopeRun fm1.hhea.caretSlopeRun
set fm2.hhea.caretOffset fm1.hhea.caretOffset
set fm2.os2.yStrikeoutPosition fm1.os2.yStrikeoutPosition
set fm2.os2.yStrikeoutSize fm1.os2.yStrikeoutSize
set fm2.os2.ySubscriptXOffset fm1.os2.ySubscriptXOffset
set fm2.os2.ySubscriptXSize fm1.os2.ySubscriptXSize
set fm2.os2.ySubscriptYOffset fm1.os2.ySubscriptYOffset
set fm2.os2.ySubscriptYSize fm1.os2.ySubscriptYSize
set fm2.os2.ySuperscriptXOffset fm1.os2.ySuperscriptXOffset
set fm2.os2.ySuperscriptXSize fm1.os2.ySuperscriptXSize
set fm2.os2.ySuperscriptYOffset fm1.os2.ySuperscriptYOffset
set fm2.os2.ySuperscriptYSize fm1.os2.ySuperscriptYSize
set fm2.post.underlinePosition fm1.post.underlinePosition
set fm2.post.underlineThickness fm1.post.underlineThickness
class CMarkSet
public [new markAnchors baseAnchors] : begin
set this.markAnchors markAnchors
set this.baseAnchors baseAnchors
public [applyToGlyph g] : begin
g.clearAnchors
g.copyAnchors this
export : define [compositeBaseAnchors] : begin
local baseAnchorSink {.}
foreach a [items-of arguments] : foreach k [items-of [Object.keys a.baseAnchors]] : begin
set baseAnchorSink.(k) : new Anchor a.baseAnchors.(k).x a.baseAnchors.(k).y a.baseAnchors.(k).type a.baseAnchors.(k).mbx a.baseAnchors.(k).mby
return : new CMarkSet null baseAnchorSink
define [MarksetDiv p sbMul me] : begin
define width : p * me.Width
define middle : p * me.Middle
define leftSB me.SB
define rightSB : me.Width * p - me.SB
define [ta anchor] : return : new Anchor
me.GlobalTransform.applyX anchor.x anchor.y
me.GlobalTransform.applyY anchor.x anchor.y
define [MarkAbove zone] {.baseAnchors {.above [ta : new Anchor middle zone.top]}}
define [MarkBelow zone] {.baseAnchors {.below [ta : new Anchor middle zone.bot]}}
define [MarkTopLeft zone] {.baseAnchors {.topLeft [ta : new Anchor leftSB zone.top]}}
define [MarkTopRight zone] {.baseAnchors {.topRight [ta : new Anchor rightSB zone.top]}}
define [MarkBottomLeft zone] {.baseAnchors {.bottomLeft [ta : new Anchor leftSB zone.bot]}}
define [MarkBottomRight zone] {.baseAnchors {.bottomRight [ta : new Anchor rightSB zone.bot]}}
define markTieAbove {.baseAnchors {.tieAbove [ta : new Anchor width (me.XH + me.AccentStackOffset * 1.38)]}}
define markTieBelow {.baseAnchors {.tieBelow [ta : new Anchor width me.Descender ]}}
define [buildStandardMarkSet zone] : lambda [] : begin
if (this && this.baseAnchors) : begin
throw : new Error "A mark set is now a function. Please call it before inclusion"
local a : compositeBaseAnchors
MarkAbove zone
MarkBelow zone
MarkTopLeft zone
MarkTopRight zone
MarkBottomLeft zone
MarkBottomRight zone
begin markTieAbove
begin markTieBelow
# Overlay on stems
set a.baseAnchors.overlay : new Anchor
* [mix a.baseAnchors.below.x a.baseAnchors.above.x me.OverlayPos]
* [mix a.baseAnchors.below.y a.baseAnchors.above.y me.OverlayPos]
# Slash over entire letter
set a.baseAnchors.slash : new Anchor
* [mix a.baseAnchors.below.x a.baseAnchors.above.x 0.5]
* [mix a.baseAnchors.below.y a.baseAnchors.above.y 0.5]
# Horizontal or near-horizontal strike on letter counter or bowl
set a.baseAnchors.strike : new Anchor
* [mix a.baseAnchors.below.x a.baseAnchors.above.x 0.5]
* [mix a.baseAnchors.below.y a.baseAnchors.above.y 0.5]
return a
return : object
OfZone buildStandardMarkSet
capital : buildStandardMarkSet {.top me.CAP .bot 0}
b : buildStandardMarkSet {.top me.Ascender .bot 0}
e : buildStandardMarkSet {.top me.XH .bot 0}
p : buildStandardMarkSet {.top me.XH .bot me.Descender}
oper : buildStandardMarkSet {.top me.OperTop .bot me.OperBot}
tack : buildStandardMarkSet {.top me.TackTop .bot me.TackBot}
plus : buildStandardMarkSet {.top me.PlusTop .bot me.PlusBot}
bp : buildStandardMarkSet {.top me.Ascender .bot me.Descender}
capDesc : buildStandardMarkSet {.top me.CAP .bot me.Descender}
export : define DesignParameters : object
# V shape
straightVShapeSbShrink 0.8
straightSmallYShapeSbShrink 0.8
#
equal_wideness 0.075
logic_narrow_shrink 0.75
GeometricLargeX : lambda [mw uw] : (mw + uw / 2) / mw
geometric_tiny_x (1 / 7)
geometric_very_small_x (2.5 / 7)
geometric_slightly_small_x (3.25 / 7)
geometric_small_x (4 / 7)
geometric_medium_small_x (4.75 / 7)
geometric_medium_x (5.5 / 7)
arrow_size 0.45
# ()
parenOutside 0.2
parenOutsideSwAdj 0.2
parenInside 0.9
parenInsideSwAdj 0.35
parenCurliness 0.7
parenOvershoot 0.0375
# []
bracketOutside 0.2
bracketOutsideSwAdj 0.2
bracketInside 0.9
# {}
braceOutside 0.05
braceInside 0.9
braceCurlyM1 0.6
braceCurlyM2 0.45
braceOvershoot 0.02
# Bar position
hBarPos 0.525
eBarPos 0.5
fiveBarPos 0.64
overlayPos 0.52
fBarPosToXH 0.875
gBarPos 0.42
upperEBarPos 0.52
# Fine adjustments
fbarStrokeAdj 0.25
superness 2.275
tightHookSuperness 2.30
# Serif creation
serifShiftX 0.60
# Square dot
squareDotScalar 0.95
export : define [GenDivFrame metrics] : begin
# Implementation class of a division frame, used to model a letter's core X-direction structure
class CDivFrame
# _adws: scale factor of advance width
# _hPack: number of horizontal divisions
# _sbMul: scale factor of sidebearings
# _mvs: desired stroke width
# _ox: overshoot correction
public [new _adws _hPack _sbMul _mvs _ox] : begin
local ox : fallback _ox 0
local adws : fallback _adws 1
local hPack : Math.max 1 [fallback _hPack 0]
local mvs : fallback _mvs
if _hPack [metrics.AdviceStroke _hPack adws] metrics.Stroke
local sbMul : fallback _sbMul
Math.min 1 : (metrics.Width * adws - hPack * mvs) / (2 * hPack * metrics.SB)
set this.params : object adws hPack sbMul mvs ox
set this.adws adws
set this.hPack hPack
set this.width : metrics.Width * adws
set this.middle : metrics.Middle * adws
set this.sb : metrics.SB * sbMul
set this.leftSB : metrics.SB * sbMul
set this.rightSB : metrics.Width * adws - metrics.SB * sbMul
set this.mvs mvs
set this.shoulderFine : metrics.ShoulderFine * (mvs / metrics.Stroke)
set this.markSet : MarksetDiv adws sbMul metrics
# No-overshoot metrics -- used for arch depth calculation
set this.ox ox
set this.widthNoOvershoot : this.width - ox
set this.divNoOvershoot : this.widthNoOvershoot / metrics.Width
set this.archDepth : this.archDepthOf metrics.ArchDepth mvs
set this.archDepthA : this.archDepthAOf metrics.ArchDepth mvs
set this.archDepthB : this.archDepthBOf metrics.ArchDepth mvs
set this.smallArchDepth : this.archDepthOf metrics.SmallArchDepth mvs
set this.smallArchDepthA : this.archDepthAOf metrics.SmallArchDepth mvs
set this.smallArchDepthB : this.archDepthBOf metrics.SmallArchDepth mvs
public [archDepthOf d _stroke] : begin
return : Math.max (d * this.divNoOvershoot) (1.125 * [fallback _stroke this.mvs])
public [archDepthAOf d _stroke] : begin
return : metrics.ArchDepthAOf [this.archDepthOf d _stroke] this.widthNoOvershoot
public [archDepthBOf d _stroke] : begin
return : metrics.ArchDepthBOf [this.archDepthOf d _stroke] this.widthNoOvershoot
public [slice _divisions _keeps _o] : begin
local o : fallback _o 0
local divisions : fallback _divisions this.hPack
local keeps : fallback _keeps 2
return : this.sliceFine divisions keeps ((keeps - 1) / (divisions - 1)) 0 o
public [sliceFine strokes keeps pGap _extraGap _o] : begin
local o : fallback _o 0
local extraGap : fallback _extraGap 0
local oneStroke : metrics.HVContrast * this.mvs
local totalGap : this.rightSB - this.leftSB - strokes * oneStroke - 2 * o
local subDfWidth : 2 * this.leftSB + 2 * o + totalGap * pGap + extraGap + oneStroke * keeps
local subDfDiv : subDfWidth / metrics.Width
return : new CDivFrame subDfDiv keeps (this.leftSB / metrics.SB) this.mvs o
public [rest sub _hPack] : begin
return : new CDivFrame ((this.width - sub.width) / metrics.Width) [fallback _hPack (this.hPack - sub.hPack + 1)] (this.leftSB / metrics.SB) this.mvs this.ox
public [restCompact kKern sub _hPack] : begin
local kern : kKern * ((this.width - this.rightSB) + sub.leftSB)
return : new CDivFrame ((this.width - sub.width + kern) / metrics.Width) [fallback _hPack (this.hPack - sub.hPack + 1)] (this.leftSB / metrics.SB) this.mvs this.ox
public [applyToGlyph g] : begin
g.setWidth this.width
set g.divFrameParams this.params
return this
public [adviceStroke c] : metrics.AdviceStroke c this.adws
public [adviceStroke2 c d h] : metrics.AdviceStroke2 c d h this.adws
# Factory function for CDivFrame
define [F _adws _hPack _sbMul _mvs _ox] : begin
return : new CDivFrame _adws _hPack _sbMul _mvs _ox
set F.fromParams : lambda [params] : begin
return : new CDivFrame params.adws params.hPack params.sbMul params.mvs params.ox
return F