516 lines
23 KiB
Text
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
|