From 95b0ceee171da92717fbecba71ff8c0fd3fb392a Mon Sep 17 00:00:00 2001 From: be5invis Date: Tue, 14 Jun 2016 10:06:57 +0800 Subject: [PATCH] A massive refactor --- .gitignore | 1 + buildglyphs.ptl | 204 +--- glyphs/autobuilds.ptl | 1436 ++++++++++++++------------- glyphs/common-shapes.ptl | 1178 +++++++++++----------- glyphs/letters-unified-basic.ptl | 152 ++- glyphs/letters-unified-extended.ptl | 240 ++--- glyphs/numbers.ptl | 19 +- glyphs/overmarks.ptl | 72 +- glyphs/symbol-braille.ptl | 20 +- glyphs/symbol-geometric.ptl | 37 +- glyphs/symbol-letter.ptl | 23 +- glyphs/symbol-math.ptl | 30 +- glyphs/symbol-other.ptl | 39 +- glyphs/symbol-punctuation.ptl | 68 +- makesupport.mk | 22 +- meta/macros.ptl | 169 ++++ 16 files changed, 1920 insertions(+), 1790 deletions(-) create mode 100644 meta/macros.ptl diff --git a/.gitignore b/.gitignore index 7f3376a7d..593ecd4e1 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,5 @@ support/spiroexpand.js support/spirokit.js support/utils.js meta/*.js +glyphs/*.js testdrive/assets \ No newline at end of file diff --git a/buildglyphs.ptl b/buildglyphs.ptl index a59a90027..edbd05288 100644 --- a/buildglyphs.ptl +++ b/buildglyphs.ptl @@ -13,143 +13,14 @@ import [calculateMetrics setFontMetrics] from './meta/aesthetics' import [nameFont] from './meta/naming' import './meta/features' as Features -### Autoarg macro +$$include 'meta/macros.ptl' + define [$NamedParameterPair$ l r] : begin set this.left l set this.right r return this -define-operator "--" 890 'right' : syntax-rules - `(@l -- @r) [atom l] `[new $NamedParameterPair$ @{".quote" [formOf l]} @r] - -define-macro params : syntax-rules - `[params @_pairs @body] : begin - local ta : env.newt - local tb : env.newt - local t : env.newt - local ps `[begin - [local @ta : {}.slice.call arguments 0] - [local @tb {}] - [for [local @t 0] (@t < @ta.length) [inc @t] : if [not : @ta.(@t) <@ $NamedParameterPair$] : @tb.push @ta.(@t)] - ] - local aps `[begin] - local dps `[begin] - local j 0 - foreach [pf : items-of : formOf _pairs] : begin - local name - if [atom pf] : then - ps.push `[local @pf : fallback @pf (@tb).(@{".quote" j})] - set name pf - : else - ps.push `[local @(pf.0) : fallback @(pf.0) (@tb).(@{".quote" j}) @(pf.1)] - set name pf.0 - aps.push `[if (@t && @t <@ $NamedParameterPair$ && @t.left == @{".quote" name}) [set @name @t.right]] - if pf.2 : dps.push `[local @(pf.2) @name] - inc j - ps.push `[foreach [@t : items-of @ta] @aps] - ps.push dps - ps.push : formOf body - return : dirty ps - -### Point macro -define-operator "<>" 800 "never" : begin - local tClass [definingEnv.newt 'class'] - local m : syntax-rules - `(@x <> @y) `[new @tClass @x @y] - - set coinit.initFn : lambda [m] : begin - set m.toPattern : lambda [form env wrapper] : match form - `(@x <> @y) : begin - local p1 [toPattern x env wrapper] - local p2 [toPattern y env wrapper] - object - whether : lambda [t] `(@t && @[p1.whether `(@t.x)] && @[p2.whether `(@t.y)]) - assign : lambda [t locallyQ] : ex `[begin - @{".preserve" [p1.assign `(@t.x) locallyQ]} - @{".preserve" [p2.assign `(@t.y) locallyQ]} - ] env - - set coinit.injectForm `[define [@tClass x y] : begin \\ - set this.x x - set this.y y - return nothing - ] - return m - -# A symbol block defines a group of similar glyphs. They may expose some functions used in glyphs in other blocks. -define-macro symbol-block : syntax-rules - `[symbol-block @name @::steps] : let [t : env.newt] : dirty `[begin [let : set @t : begin @::[steps.map formOf]] [progress @name] @t] - -### Necessary macros -# A glyph construction is a function which "modifies" a glyph. -define-macro glyph-construction : syntax-rules - `[glyph-construction @::steps] {'.syntactic-closure' `[lambda [] [begin \\ - local currentGlyph this - begin @::[steps.map formOf] - return nothing - ]] env} -# Remap Glyph's methods to macros in order to simplify writing -define-macro set-width : syntax-rules - `[set-width @::args] {'.syntactic-closure' `[currentGlyph.set-width @::args] env} -define-macro start-from : syntax-rules - `[start-from @::args] {'.syntactic-closure' `[currentGlyph.start-from @::args] env} -define-macro line-to : syntax-rules - `[line-to @::args] {'.syntactic-closure' `[currentGlyph.line-to @::args] env} -define-macro curve-to : syntax-rules - `[curve-to @::args] {'.syntactic-closure' `[currentGlyph.curve-to @::args] env} -define-macro cubic-to : syntax-rules - `[cubic-to @::args] {'.syntactic-closure' `[currentGlyph.cubic-to @::args] env} -define-macro include : syntax-rules - `[include glyphs.(@name) @::args] : dirty `[includeGlyphPart currentGlyph glyphs @name @::args] - `[include @::args] {'.syntactic-closure' `[currentGlyph.include @::args] env} -define-macro set-anchor : syntax-rules - `[set-anchor @::args] {'.syntactic-closure' `[currentGlyph.set-anchor @::args] env} -define-macro apply-transform : syntax-rules - `[apply-transform @::args] {'.syntactic-closure' `[currentGlyph.apply-transform @::args] env} -define-macro reverse-last : syntax-rules - `[reverse-last @::args] {'.syntactic-closure' `[currentGlyph.reverse-last @::args] env} -define-macro depends-on : syntax-rules - `[depends-on @::args] {'.syntactic-closure' `[currentGlyph.depends-on @::args] env} -define-macro eject-contour : syntax-rules - `[eject-contour @::args] {'.syntactic-closure' `[currentGlyph.eject-contour @::args] env} -define-macro tag-contour : syntax-rules - `[tag-contour @::args] {'.syntactic-closure' `[currentGlyph.tag-contour @::args] env} -define-macro retag-contour : syntax-rules - `[retag-contour @::args] {'.syntactic-closure' `[currentGlyph.retag-contour @::args] env} -define-macro assign-unicode : syntax-rules - `[assign-unicode @code] {".syntactic-closure" `[begin \\ - currentGlyph.assign-unicode @code - set unicodeGlyphs.(currentGlyph.unicode.((currentGlyph.unicode.length - 1))) currentGlyph - ] env} - -###### Canvas-based mechanism define [$donothing$] nothing -define-macro sketch : syntax-rules - `[sketch @::steps] : begin - if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 - inc externEnv.$nWFGlyphs$ - dirty `[[lambda [currentGlyph] [begin \\ - if [not currentGlyph] : return nothing - if [glyphList.(glyphList.length - 1).name === @{".quote" (".WF" + externEnv.$nWFGlyphs$)}] : glyphList.pop - begin @::[steps.map formOf] - set dependencyProfile.(currentGlyph.name) : getDependencyProfile currentGlyph - return currentGlyph - ]] [create-glyph @{".quote" (".WF" + externEnv.$nWFGlyphs$)} $donothing$]] - -define-macro branch : syntax-rules - `[branch @::steps] : begin - if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 - inc externEnv.$nWFGlyphs$ - dirty `[[lambda [currentGlyph] [begin \\ - if [not currentGlyph] : return nothing - if [glyphList.(glyphList.length - 1).name === @{".quote" (".WF" + externEnv.$nWFGlyphs$)}] : glyphList.pop - begin @::[steps.map formOf] - set dependencyProfile.(currentGlyph.name) : getDependencyProfile currentGlyph - return currentGlyph - ]] [create-glyph @{".quote" (".WF" + externEnv.$nWFGlyphs$)} [lambda : begin [this.include currentGlyph true] [set this.advanceWidth currentGlyph.advanceWidth]]]] - -define-macro save : syntax-rules - `[save @::args] : dirty `[$save$.call currentGlyph @::args] # contour tagging define [tagged tag component] : begin @@ -172,17 +43,7 @@ export as build : define [buildFont para recursive recursiveCodes] : begin return nothing define metrics : calculateMetrics para - define [object - UPM WIDTH SB CAP XH DESCENDER CONTRAST - parenMid parenTop parenBot operTop operBot operMid Italify Upright Scale Translate Rotate globalTransform - TANSLANT SINSLANT COSSLANT HVCONTRAST UPWARD DOWNWARD RIGHTWARD LEFTWARD - O OX OXHOOK HOOK AHOOK SHOOK RHOOK JHOOK FHOOK HOOKX SMOOTH SMALLSMOOTH STROKE DOTSIZE PERIODSIZE - BARPOS GBARPOS PBARPOS EBARPOS OVERLAYPOS FIVEBARPOS LONGJUT JUT VJUT ACCENT ACCENTX CTHIN CTHINB SLAB - TAILADJX TAILADJY LBALANCE IBALANCE JBALANCE JBALANCE2 TBALANCE TBALANCE2 RBALANCE RBALANCE2 - FBALANCE ONEBALANCE FULLWIDTH FULLWIDTH1 FULLWIDTH2 FULLWIDTH3 OXE ESS ESSQUESTION XO CAPO HALFSTROKE RIGHTSB FWRSB - MIDDLE FWMIDDLE CAPMIDDLE CAP_SMOOTH DOTRADIUS PERIODRADIUS SIDEJUT SMOOTHA SMOOTHB SMALLSMOOTHA SMALLSMOOTHB CORRECTION_OMIDX CORRECTION_OMIDS - WHITENESS adviceBlackness MVERTSTROKE OVERLAYSTROKE OPERATORSTROKE SHOULDERFINE SUPERNESS superxy - adviceSSmooth adviceGlottalStopSmooth shoulderMidSlope] metrics + define [object globalTransform MIDDLE CAP XH SB RIGHTSB CONTRAST STROKE SUPERNESS WIDTH TANSLANT OVERLAYPOS DESCENDER] metrics # Anchor parameters define [object MARK BASE] Anchor @@ -226,6 +87,7 @@ export as build : define [buildFont para recursive recursiveCodes] : begin ### Glyph slots and dependency profile generation (used for recursive subfonts) local dependencyProfile {.} local nTemp 0 + define [newtemp] : set nTemp (nTemp + 1) local nPending 0 local pickHash : if recursive then : let [h {.}] : begin @@ -260,7 +122,7 @@ export as build : define [buildFont para recursive recursiveCodes] : begin return glyphObject `[@actions] : begin - local glyphName ('.temp-' + [set nTemp (nTemp + 1)]) + local glyphName ('.temp-' + [newtemp]) if para.verbose : console.log glyphName local glyphObject [new Glyph glyphName] glyphObject.set-width WIDTH @@ -284,39 +146,13 @@ export as build : define [buildFont para recursive recursiveCodes] : begin ### Spiro constructions # Basic knots - local [object - g4 g2 corner flat curl close end straight - widths heading unimportant important - alsothru alsothruthem bezcontrols quadcontrols archv arcvh complexThru - dispiro spiro-outline] : spirokit.SetupBuilders : object globalTransform CONTRAST STROKE Glyph para SUPERNESS + define spirofns : spirokit.SetupBuilders : object globalTransform CONTRAST STROKE Glyph para SUPERNESS ###### HERE WE GO! - ### Metadata nameFont para metrics font setFontMetrics para metrics font - # Metric metadata - # Note: we use 1000upm in design, and (1000 * upmsacle)upm in production, to avoid rounding error. - - let [asc : para.leading * CAP / (CAP - DESCENDER)] [desc : para.leading * DESCENDER / (CAP - DESCENDER)] : begin - local descenderPad : fallback para.descenderPad 0 - set font.head.unitsPerEm 1000 - set font.hhea.ascender asc - set font.OS_2.usWinAscent asc - set font.OS_2.sTypoAscender asc - - set font.hhea.descender (DESCENDER - descenderPad) - set font.OS_2.usWinDescent ([Math.abs desc] + descenderPad) - set font.OS_2.sTypoDescender (desc - descenderPad) - - set font.hhea.lineGap (para.leading - asc + DESCENDER) - set font.OS_2.sTypoLineGap (para.leading - asc + desc) - - set font.OS_2.sxHeight XH - set font.OS_2.sCapHeight CAP - set font.post.italicAngle (0 - para.slantAngle) - # Necessary notdef, .null and nonmarkingreturn glyph sketch # .notdef start-from SB 0 @@ -344,28 +180,30 @@ export as build : define [buildFont para recursive recursiveCodes] : begin set-width WIDTH include markset.e save 'space' ' ' + + define capture : object metrics $NamedParameterPair$ $donothing$ para recursive recursiveCodes variantSelector font glyphs glyphList unicodeGlyphs create-glyph $save$ spirofns markset MARK BASE AS_BASE ALSO_METRICS pickHash dependencyProfile getDependencyProfile buildFont newtemp tagged ### HERE WE GO - $$include 'glyphs/common-shapes.ptl' - $$include 'glyphs/overmarks.ptl' + set capture.commonShapes : [import './glyphs/common-shapes.js'].apply.call capture + set capture.overmarks : [import './glyphs/overmarks.js'].apply.call capture # Unified letters - $$include 'glyphs/letters-unified-basic.ptl' - $$include 'glyphs/letters-unified-extended.ptl' + set capture.letterBasic : [import './glyphs/letters-unified-basic.js'].apply.call capture + set capture.letterExt : [import './glyphs/letters-unified-extended.js'].apply.call capture # Numbers - $$include 'glyphs/numbers.ptl' + [import './glyphs/numbers.js'].apply.call capture # Symbols - $$include 'glyphs/symbol-punctuation.ptl' - $$include 'glyphs/symbol-math.ptl' - $$include 'glyphs/symbol-letter.ptl' - $$include 'glyphs/symbol-geometric.ptl' - $$include 'glyphs/symbol-braille.ptl' - $$include 'glyphs/symbol-other.ptl' - + [import './glyphs/symbol-punctuation.js'].apply.call capture + [import './glyphs/symbol-math.js'].apply.call capture + [import './glyphs/symbol-letter.js'].apply.call capture + set capture.geometricSymbols : [import './glyphs/symbol-geometric.js'].apply.call capture + [import './glyphs/symbol-braille.js'].apply.call capture + [import './glyphs/symbol-other.js'].apply.call capture + # Autobuilds - $$include 'glyphs/autobuilds.ptl' + [import './glyphs/autobuilds.js'].apply.call capture if [not recursive] : begin set {.GSUB font.GSUB .GPOS font.GPOS .GDEF font.GDEF} : Features.apply para glyphList diff --git a/glyphs/autobuilds.ptl b/glyphs/autobuilds.ptl index f76df231f..9b0574962 100644 --- a/glyphs/autobuilds.ptl +++ b/glyphs/autobuilds.ptl @@ -1,6 +1,17 @@ ###### Automatic builds +$$include '../meta/macros.ptl' -# Build accented glyphs +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' define customDecompositions : object # Latvians use comma instead of cedillas in several letters. @@ -72,20 +83,15 @@ define customDecompositions : object ."\u04AB" "\u0441\u0327" # Spacing modifers -# ."`" " \u0300" ."\u02CB" " \u0300" -# ."\u00B4" " \u0301" ."\u02CA" " \u0301" -# ."^" " \u0302" ."\u02C6" " \u0302" -# ."~" " \u0303" ."\u02DC" " \u0303" ."\u00AF" " \u0304" ."\u02C9" " \u0304" ."\u02D8" " \u0306" ."\u02D9" " \u0307" ."\u00A8" " \u0308" -# ."\u00B0" " \u030A" ."\u02DA" " \u030A" ."\u02C7" " \u030C" ."\u00B8" " \u0327" @@ -125,729 +131,727 @@ define customDecompositions : object ."\u219B" "" ."\u21AE" "" -let : begin - if [not recursive] : suggestGC - define [isAboveMark mark] : mark && mark.anchors && mark.anchors.above && mark.anchors.above.type === MARK - define [iotaBelowToLF p j parts] : if (p === glyphs.iotaBelow) : set parts.(j) glyphs.iotaLF - define [ogonekBelowToTR p j parts] : if (p === glyphs.ogonekBelow) : set parts.(j) glyphs.ogonekTR - define [subParts parts] : begin - local hasMarkAbove false - foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true - - # replace dotted-i and dotted-j with dotless equalivents - if ((parts.0 === glyphs.i || parts.0 === glyphs.cyrUkrainiani) && hasMarkAbove) : parts.0 = glyphs.dotlessi - if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj - - # replace below marks with trailing marks - if parts.0.anchors.lf : parts.forEach iotaBelowToLF - if parts.0.anchors.trailing : parts.forEach ogonekBelowToTR - - # composite greek overmarks - for [local j 0] (j < parts.length) [inc j] : piecewise - (parts.(j) === glyphs.commaAbove) : begin - piecewise - (parts.(j + 1) === glyphs.graveAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.psilivaria - (parts.(j + 1) === glyphs.acuteAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.psilioxia - (parts.(j + 1) === glyphs.perispomeniAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.psiliperispomeni - (parts.(j) === glyphs.revCommaAbove) : begin - piecewise - (parts.(j + 1) === glyphs.graveAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.dasiavaria - (parts.(j + 1) === glyphs.acuteAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.dasiaoxia - (parts.(j + 1) === glyphs.perispomeniAbove) : begin - set parts.(j) null; set parts.(j + 1) glyphs.dasiaperispomeni - return parts - define [pad _s n] : begin - local s _s - while (s.length < n) : s = '0' + s - return s - local nComposed 0 - local foundDecompositions {.} - define [decideName namingParts parts code] : begin - local baseName namingParts.0.name - local glyphName baseName - foreach [part : namingParts.slice 1] : if part : glyphName = glyphName + [fallback part.shortName part.name] - if foundDecompositions.(glyphName) : begin + + + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks + # Build accented glyphs + let : begin + if [not recursive] : suggestGC + define [isAboveMark mark] : mark && mark.anchors && mark.anchors.above && mark.anchors.above.type === MARK + define [iotaBelowToLF p j parts] : if (p === glyphs.iotaBelow) : set parts.(j) glyphs.iotaLF + define [ogonekBelowToTR p j parts] : if (p === glyphs.ogonekBelow) : set parts.(j) glyphs.ogonekTR + define [subParts parts] : begin + local hasMarkAbove false + foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true + + # replace dotted-i and dotted-j with dotless equalivents + if ((parts.0 === glyphs.i || parts.0 === glyphs.cyrUkrainiani) && hasMarkAbove) : parts.0 = glyphs.dotlessi + if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj + + # replace below marks with trailing marks + if parts.0.anchors.lf : parts.forEach iotaBelowToLF + if parts.0.anchors.trailing : parts.forEach ogonekBelowToTR + + # composite greek overmarks + for [local j 0] (j < parts.length) [inc j] : piecewise + (parts.(j) === glyphs.commaAbove) : begin + piecewise + (parts.(j + 1) === glyphs.graveAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.psilivaria + (parts.(j + 1) === glyphs.acuteAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.psilioxia + (parts.(j + 1) === glyphs.perispomeniAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.psiliperispomeni + (parts.(j) === glyphs.revCommaAbove) : begin + piecewise + (parts.(j + 1) === glyphs.graveAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.dasiavaria + (parts.(j + 1) === glyphs.acuteAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.dasiaoxia + (parts.(j + 1) === glyphs.perispomeniAbove) : begin + set parts.(j) null; set parts.(j + 1) glyphs.dasiaperispomeni + return parts + + define [pad _s n] : begin + local s _s + while (s.length < n) : s = '0' + s + return s + local nComposed 0 + local foundDecompositions {.} + define [decideName namingParts parts code] : begin + local baseName namingParts.0.name + local glyphName baseName + foreach [part : namingParts.slice 1] : if part : glyphName = glyphName + [fallback part.shortName part.name] + if foundDecompositions.(glyphName) : begin + local j 2 + while foundDecompositions.(glyphName + j) [inc j] + set glyphName (glyphName + j) + if (glyphName.length > 27) : set glyphName ('uni' + [pad [[code.toString 16].toUpperCase] 4]) + return glyphName + local [buildForCode code] : if [not unicodeGlyphs.(code)] : begin + local str : String.fromCharCode code + local nfd : fallback customDecompositions.(str) : unorm.nfd str + if (nfd.length > 1) : begin + local parts {} + local allFound true + foreach j [range 0 nfd.length] : begin + local part unicodeGlyphs.([nfd.charCodeAt j]) + if [not part] : then : set allFound false + : else : set parts.(j) unicodeGlyphs.([nfd.charCodeAt j]) + if allFound : begin + local namingParts : parts.slice 0 + set parts : subParts parts + local glyphName : decideName namingParts parts code + set foundDecompositions.(glyphName) {glyphName code parts} + + if recursiveCodes : recursiveCodes.forEach buildForCode + : else : foreach code [range 0x0000 0xFFFF] : buildForCode code + suggestGC + + local {glyphName code parts} {} + define construction : glyph-construction + if code : assign-unicode code + include parts.0 AS_BASE + set-width parts.0.advanceWidth + + local names {parts.0.name} + foreach part [items-of : parts.slice 1] : if part : begin + include part + names.push part.name + if (part.name === 'rtailBR') : eject-contour 'serifRB' + inc nComposed + + define [cfv glyphName _pa] : if (!recursive && _pa.0.featureSelector) : begin + local h {.} + foreach [feature : items-of : Object.keys _pa.0.featureSelector] : begin + local variant _pa.0.featureSelector.(feature) + local variantRoot glyphs.(variant) + if variantRoot : begin + set parts {variantRoot :: [_pa.slice 1]} + set code null + create-glyph (glyphName + '.' + feature) construction + + set h.(feature) (glyphName + '.' + feature) + if glyphs.(glyphName) : set glyphs.(glyphName).featureSelector h + + foreach [_id : items-of : Object.keys foundDecompositions] : begin + set {glyphName code parts} foundDecompositions.(_id) + create-glyph glyphName construction + cfv glyphName parts + + suggestGC + + + define [suggestName _name] : begin + local name _name + if glyphs.(name) : begin local j 2 - while foundDecompositions.(glyphName + j) [inc j] - set glyphName (glyphName + j) - if (glyphName.length > 27) : set glyphName ('uni' + [pad [[code.toString 16].toUpperCase] 4]) - return glyphName - local [buildForCode code] : if [not unicodeGlyphs.(code)] : begin - local str : String.fromCharCode code - local nfd : fallback customDecompositions.(str) : unorm.nfd str - if (nfd.length > 1) : begin - local parts {} - local allFound true - foreach j [range 0 nfd.length] : begin - local part unicodeGlyphs.([nfd.charCodeAt j]) - if [not part] : then : set allFound false - : else : set parts.(j) unicodeGlyphs.([nfd.charCodeAt j]) - if allFound : begin - local namingParts : parts.slice 0 - set parts : subParts parts - local glyphName : decideName namingParts parts code - set foundDecompositions.(glyphName) {glyphName code parts} - - if recursiveCodes : recursiveCodes.forEach buildForCode - : else : foreach code [range 0x0000 0xFFFF] : buildForCode code - progress "Composition Decision" - suggestGC - - local {glyphName code parts} {} - define construction : glyph-construction - if code : assign-unicode code - include parts.0 AS_BASE - set-width parts.0.advanceWidth + while glyphs.(name + j) : inc j + set name (name + j) + return name + # Build miniature clyphs : circled, superscripts, subscripts... + define [createCircledGlyphs records] : if [not recursive] : begin + local dscale 0.55 + local pendingGlyphs : records.map : [record] => record.1 + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- [fallback para.smallCrowd 3.75] + scale -- 0.65 + unfair -- true - local names {parts.0.name} - foreach part [items-of : parts.slice 1] : if part : begin - include part - names.push part.name - if (part.name === 'rtailBR') : eject-contour 'serifRB' - inc nComposed - - define [cfv glyphName _pa] : if (!recursive && _pa.0.featureSelector) : begin - local h {.} - foreach [feature : items-of : Object.keys _pa.0.featureSelector] : begin - local variant _pa.0.featureSelector.(feature) - local variantRoot glyphs.(variant) - if variantRoot : begin - set parts {variantRoot :: [_pa.slice 1]} - set code null - create-glyph (glyphName + '.' + feature) construction - - set h.(feature) (glyphName + '.' + feature) - if glyphs.(glyphName) : set glyphs.(glyphName).featureSelector h - - foreach [_id : items-of : Object.keys foundDecompositions] : begin - set {glyphName code parts} foundDecompositions.(_id) - create-glyph glyphName construction - cfv glyphName parts - - progress "Unicode Precomposites (\(nComposed) glyphs)" - suggestGC - - -define [suggestName _name] : begin - local name _name - if glyphs.(name) : begin - local j 2 - while glyphs.(name + j) : inc j - set name (name + j) - return name -# Build miniature clyphs : circled, superscripts, subscripts... -define [createCircledGlyphs records] : if [not recursive] : begin - local dscale 0.55 - local pendingGlyphs : records.map : [record] => record.1 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- [fallback para.smallCrowd 3.75] - scale -- 0.65 - unfair -- true - - foreach {unicode glyphid w} [items-of records] : create-glyph [suggestName : 'circle' + glyphid] : glyph-construction - local width : fallback w WIDTH - set-width width - local sw [adviceBlackness 5] - if unicode : assign-unicode unicode - include : create-glyph [suggestName : 'circleinner' + glyphid] : glyph-construction - local g miniatureFont.(glyphid) - include g - local shift 0 - if (g.anchors.above && g.anchors.below) : set shift : CAP / 2 - [mix g.anchors.above.y g.anchors.below.y 0.5] + foreach {unicode glyphid w} [items-of records] : create-glyph [suggestName : 'circle' + glyphid] : glyph-construction + local width : fallback w WIDTH + set-width width + local sw [adviceBlackness 5] + if unicode : assign-unicode unicode + include : create-glyph [suggestName : 'circleinner' + glyphid] : glyph-construction + local g miniatureFont.(glyphid) + include g + local shift 0 + if (g.anchors.above && g.anchors.below) : set shift : CAP / 2 - [mix g.anchors.above.y g.anchors.below.y 0.5] + apply-transform : Upright + apply-transform : Translate (-WIDTH / 2) (-CAP / 2 + shift) + apply-transform : Scale dscale + apply-transform : Translate (width / 2) (CAP / 2 * dscale) + apply-transform : Italify + set currentGlyph.cmpPriority 12 + refair this + + include : OShape + * (CAP * dscale + [Math.max (CAP * 0.175) (sw * 3)]) + * (-[Math.max (CAP * 0.175) (sw * 3)]) + * [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)] + * [Math.min (width - SB - O * 3) (width / 2 + CAP / 2 * dscale + sw * 2.5)] + * sw + * (SMALLSMOOTHA * width / WIDTH) + * (SMALLSMOOTHB * width / WIDTH) apply-transform : Upright - apply-transform : Translate (-WIDTH / 2) (-CAP / 2 + shift) - apply-transform : Scale dscale - apply-transform : Translate (width / 2) (CAP / 2 * dscale) + apply-transform : Translate 0 (parenMid - CAP * dscale / 2) apply-transform : Italify - set currentGlyph.cmpPriority 12 - refair this - - include : OShape - * (CAP * dscale + [Math.max (CAP * 0.175) (sw * 3)]) - * (-[Math.max (CAP * 0.175) (sw * 3)]) - * [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)] - * [Math.min (width - SB - O * 3) (width / 2 + CAP / 2 * dscale + sw * 2.5)] - * sw - * (SMALLSMOOTHA * width / WIDTH) - * (SMALLSMOOTHB * width / WIDTH) - apply-transform : Upright - apply-transform : Translate 0 (parenMid - CAP * dscale / 2) - apply-transform : Italify -define [createBracedGlyphs records] : if [not recursive] : begin - local dscale 0.55 - local pscale 0.6 - local pendingGlyphs : records.map : [record] => record.1 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- [fallback para.smallCrowd 3.75] - scale -- 0.65 - sbscale -- 1 - unfair -- true - - foreach {unicode glyphid w} [items-of records] : sketch - local width : fallback w WIDTH - set-width width - local sw [adviceBlackness 5] - local l : [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)] + OX - local r : width - l + define [createBracedGlyphs records] : if [not recursive] : begin + local dscale 0.55 + local pscale 0.6 + local pendingGlyphs : records.map : [record] => record.1 + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- [fallback para.smallCrowd 3.75] + scale -- 0.65 + sbscale -- 1 + unfair -- true - include : create-glyph [suggestName : 'braceinner' + glyphid] : glyph-construction + foreach {unicode glyphid w} [items-of records] : sketch + local width : fallback w WIDTH + set-width width + local sw [adviceBlackness 5] + local l : [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)] + OX + local r : width - l + + include : create-glyph [suggestName : 'braceinner' + glyphid] : glyph-construction + include miniatureFont.(glyphid) + apply-transform : Upright + apply-transform : Translate (-WIDTH / 2) 0 + apply-transform : Scale dscale + apply-transform : Translate (width / 2) 0 + apply-transform : Italify + set currentGlyph.cmpPriority 11 + refair this + + include : dispiro + widths.lhs sw + g4 [mix l r 0.15] (parenTop * pscale) + g4.down.mid l (parenMid * pscale) + g4 [mix l r 0.15] (parenBot * pscale) + + include : dispiro + widths.rhs sw + g4 [mix r l 0.15] (parenTop * pscale) + g4.down.mid r (parenMid * pscale) + g4 [mix r l 0.15] (parenBot * pscale) + + include : Upright + include : Translate 0 (parenMid - parenMid * pscale) + include : Italify + + save [suggestName : 'braced' + glyphid] unicode + + define [createSuperscripts records] : if [not recursive] : begin + local pendingGlyphs : records.map : [record] => record.1 + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- [fallback para.smallCrowd 3.5] + scale -- 0.7 + unfair -- true + foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sup' + glyphid] : glyph-construction + if unicode : assign-unicode unicode + include miniatureFont.(glyphid) AS_BASE + apply-transform [Upright] true + apply-transform [Translate (-MIDDLE) (-CAP)] true + apply-transform [Scale 0.7] true + apply-transform [Translate MIDDLE (CAP + ACCENT / 2)] true + apply-transform [Italify] true + if pri : set currentGlyph.cmpPriority pri + refair this + + define [createSubscripts records] : if [not recursive] : begin + local pendingGlyphs : records.map : [record] => record.1 + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- [fallback para.smallCrowd 3.5] + scale -- 0.7 + unfair -- true + foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sub' + glyphid] : glyph-construction + if unicode : assign-unicode unicode + include miniatureFont.(glyphid) AS_BASE + apply-transform [Upright] true + apply-transform [Translate (-MIDDLE) 0] true + apply-transform [Scale 0.7] true + apply-transform [Translate MIDDLE (DESCENDER / 2)] true + apply-transform [Italify] true + if pri : set currentGlyph.cmpPriority pri + refair this + + define [createSMCPs records] : if [not recursive] : begin + local pendingGlyphs : records.map : [record] => record.1 + local forkedParams : Object.create para + set forkedParams.cap0 para.cap + set forkedParams.cap XH + set forkedParams.xheight (XH * XH / CAP) + local sf : Fork pendingGlyphs forkedParams + foreach {unicode glyphid tfm} [items-of records] : create-glyph [suggestName : 'smcp' + glyphid] : glyph-construction + if unicode : assign-unicode unicode + include sf.(glyphid) AS_BASE + if tfm : include tfm + + define [createMedievalCombs records] : if [not recursive] : begin + local pendingGlyphs : records.map : [record] => record.1 + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- [fallback para.smallCrowd2 3.5] + scale -- 0.7 + unfair -- true + foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'comb' + glyphid] : glyph-construction + set-width 0 + if unicode : assign-unicode unicode include miniatureFont.(glyphid) apply-transform : Upright - apply-transform : Translate (-WIDTH / 2) 0 - apply-transform : Scale dscale - apply-transform : Translate (width / 2) 0 - apply-transform : Italify - set currentGlyph.cmpPriority 11 + apply-transform : Translate (-MIDDLE) 0 + apply-transform : Scale 0.4 + apply-transform : Translate markMiddle aboveMarkBot + apply-transform : Italify refair this - - include : dispiro - widths.lhs sw - g4 [mix l r 0.15] (parenTop * pscale) - g4.down.mid l (parenMid * pscale) - g4 [mix l r 0.15] (parenBot * pscale) - - include : dispiro - widths.rhs sw - g4 [mix r l 0.15] (parenTop * pscale) - g4.down.mid r (parenMid * pscale) - g4 [mix r l 0.15] (parenBot * pscale) - - include : Upright - include : Translate 0 (parenMid - parenMid * pscale) - include : Italify - - save [suggestName : 'braced' + glyphid] unicode + set-anchor 'above' MARK markMiddle XH markMiddle aboveMarkTop -define [createSuperscripts records] : if [not recursive] : begin - local pendingGlyphs : records.map : [record] => record.1 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- [fallback para.smallCrowd 3.5] - scale -- 0.7 - unfair -- true - foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sup' + glyphid] : glyph-construction - if unicode : assign-unicode unicode - include miniatureFont.(glyphid) AS_BASE - apply-transform [Upright] true - apply-transform [Translate (-MIDDLE) (-CAP)] true - apply-transform [Scale 0.7] true - apply-transform [Translate MIDDLE (CAP + ACCENT / 2)] true - apply-transform [Italify] true - if pri : set currentGlyph.cmpPriority pri - refair this - -define [createSubscripts records] : if [not recursive] : begin - local pendingGlyphs : records.map : [record] => record.1 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- [fallback para.smallCrowd 3.5] - scale -- 0.7 - unfair -- true - foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sub' + glyphid] : glyph-construction - if unicode : assign-unicode unicode - include miniatureFont.(glyphid) AS_BASE - apply-transform [Upright] true - apply-transform [Translate (-MIDDLE) 0] true - apply-transform [Scale 0.7] true - apply-transform [Translate MIDDLE (DESCENDER / 2)] true - apply-transform [Italify] true - if pri : set currentGlyph.cmpPriority pri - refair this - -define [createSMCPs records] : if [not recursive] : begin - local pendingGlyphs : records.map : [record] => record.1 - local forkedParams : Object.create para - set forkedParams.cap0 para.cap - set forkedParams.cap XH - set forkedParams.xheight (XH * XH / CAP) - local sf : Fork pendingGlyphs forkedParams - foreach {unicode glyphid tfm} [items-of records] : create-glyph [suggestName : 'smcp' + glyphid] : glyph-construction - if unicode : assign-unicode unicode - include sf.(glyphid) AS_BASE - if tfm : include tfm - -define [createMedievalCombs records] : if [not recursive] : begin - local pendingGlyphs : records.map : [record] => record.1 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- [fallback para.smallCrowd2 3.5] - scale -- 0.7 - unfair -- true - foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'comb' + glyphid] : glyph-construction - set-width 0 - if unicode : assign-unicode unicode - include miniatureFont.(glyphid) - apply-transform : Upright - apply-transform : Translate (-MIDDLE) 0 - apply-transform : Scale 0.4 - apply-transform : Translate markMiddle aboveMarkBot - apply-transform : Italify - refair this - set-anchor 'above' MARK markMiddle XH markMiddle aboveMarkTop - -define [createFractions records] : if [not recursive] : begin - local pendingGlyphs : [records.map : [record] => record.1].concat : records.map : [record] => record.2 - local miniatureFont : Miniature - glyphs -- pendingGlyphs - crowd -- 4 - scale -- 0.6 - unfair -- true - foreach {unicode numid denid height} [items-of records] : create-glyph [suggestName : numid + 'over' + denid] : glyph-construction - if unicode : assign-unicode unicode - local fine : adviceBlackness 3 - local dist : XH * 0.4 - include : create-glyph : glyph-construction - include : create-glyph [suggestName : 'num' + numid] : glyph-construction - include miniatureFont.(numid) - apply-transform : Upright - apply-transform : Translate (- miniatureFont.(numid).advanceWidth / 2) 0 - apply-transform : Scale (CAP / [fallback height CAP] * 0.55) - apply-transform : Translate MIDDLE 0 - apply-transform : Italify - refair this - apply-transform : Upright - apply-transform : Translate 0 (CAP * 0.55 + dist) - apply-transform : Italify - include : create-glyph [suggestName : 'den' + denid] : glyph-construction - include miniatureFont.(denid) - apply-transform : Upright - apply-transform : Translate (- miniatureFont.(denid).advanceWidth / 2) 0 - apply-transform : Scale (CAP / [fallback height CAP] * 0.55) - apply-transform : Translate MIDDLE 0 - apply-transform : Italify - refair this - apply-transform : Upright - apply-transform : Translate (-MIDDLE) (-CAP * 0.55 - dist / 2) - apply-transform : Translate MIDDLE parenMid - apply-transform : Italify - include : HBar SB RIGHTSB parenMid (fine * 0.75) - - -symbol-block 'Circled and Braced' : if [not recursive] : begin - local compositions : list - list 0xA9 'C' - list 0xAE 'R' - list 0x2117 'P' - list 0x24EA 'zero' FULLWIDTH1 - list null 'space' FULLWIDTH1 - foreach [j : range 1 till 9] : compositions.push {(0x2460 + j - 1) unicodeGlyphs.(['0'.charCodeAt 0] + j).name FULLWIDTH1} - foreach [j : range 0 26] : compositions.push {(0x24B6 + j) unicodeGlyphs.(['A'.charCodeAt 0] + j).name FULLWIDTH1} - foreach [j : range 0 26] : compositions.push {(0x24D0 + j) unicodeGlyphs.(['a'.charCodeAt 0] + j).name FULLWIDTH1} - createCircledGlyphs compositions - - local compositions : list - list null 'space' FULLWIDTH1 - foreach [j : range 1 till 9] : compositions.push {(0x2474 + j - 1) unicodeGlyphs.(['0'.charCodeAt 0] + j).name FULLWIDTH1} - foreach [j : range 0 26] : compositions.push {(0x249C + j) unicodeGlyphs.(['a'.charCodeAt 0] + j).name FULLWIDTH1} - createBracedGlyphs compositions - -createSMCPs : list - list 0x1D00 'A' - list 0x1D01 'AE' - list 0x1D03 'Bbar' - list 0x1D04 'C' - list 0x1D05 'D' - list 0x1D06 'Dcroat' - list 0x1D07 'E' - list 0x1D08 'cyrZe' - list 0x1D0A 'J' - list 0x1D0B 'K' - list 0x1D0C 'Lslash' - list 0x1D0D 'M' - list 0x1D0E 'cyrI' - list 0x1D0F 'O' - list 0x1D10 'turnC' - list 0x1D15 'OU' - list 0x1D18 'P' - list 0x1D19 'cyrYa' - list 0x1D1A 'R' [FlipAround MIDDLE (XH / 2)] - list 0x1D1B 'T' - list 0x1D20 'V' - list 0x1D21 'W' - list 0x1D22 'Z' - list 0x1D23 'Ezh' - list 0x1D26 'Gamma' - list 0x1D27 'Lambda' - list 0x1D28 'Pi' - list 0x1D29 'Rho' - list 0x1D2B 'cyrEl' -progress 'Small Caps' - -createSuperscripts : list - list 0x2070 'zero' - list 0x00B9 'one' - list 0x00B2 'two' - list 0x00B3 'three' - list 0x2074 'four' - list 0x2075 'five' - list 0x2076 'six' - list 0x2077 'seven' - list 0x2078 'eight' - list 0x2079 'nine' - list 0x02B0 'h' - list 0x02B1 'hhooktop' - list 0x02B2 'j' - list 0x02B3 'r' - list 0x02B4 'turnr' - list 0x02B5 'turnrrtail' - list 0x02B6 'invsmcpR' - list 0x02B7 'w' - list 0x02B8 'y' - list 0x02C0 'fineglottalstop' - list 0x02C1 'finerevglottalstop' - list 0x02E0 'latingamma' - list 0x02E1 'l' - list 0x02E2 's' - list 0x02E3 'x' - list 0x02E4 'revglottalstop' - list 0x2071 'i' - list 0x207F 'n' - list 0x1D43 'a' - list 0x1D44 'turna' - list 0x1D45 'scripta' - list 0x1D46 'turnae' - list 0x1D47 'b' - list 0x1D48 'd' - list 0x1D49 'e' - list 0x1D4A 'turne' - list 0x1D4B 'epsilon' - list 0x1D4C 'cyrze' - list 0x1D4D 'g' - list 0x1D4E 'turni' - list 0x1D4F 'k' - list 0x1D50 'm' - list 0x1D51 'eng' - list 0x1D52 'o' - list 0x1D53 'turnc' - list 0x1D54 'oupperhalf' - list 0x1D55 'olowerhalf' - list 0x1D56 'p' - list 0x1D57 't' - list 0x1D58 'u' - list 0x1D5A 'turnm' - list 0x1D5B 'v' - list 0x1D5D 'beta' - list 0x1D5E 'gamma' - list 0x1D5F 'delta' - list 0x1D60 'phi' - list 0x1D61 'chi' - list 0x1D78 'smcpH' - list 0x1D9B 'turnscripta' - list 0x1D9C 'c' - list 0x1D9D 'ccurlytail' - list 0x1D9E 'eth' - list 0x1D9F 'revlatinepsilon' - list 0x1DA0 'f' - list 0x1DA1 'turnf' - list 0x1DA2 'scriptg' - list 0x1DA3 'turnh' - list 0x1DA4 'ibarOver' - list 0x1DA5 'latiniota' - list 0x1DA6 'smcpI' - list 0x1DA7 'smcpIbarOver' - list 0x1DA8 'jcurlytail' - list 0x1DAB 'smcpL' - list 0x1DA9 'lrtail' - list 0x1DAC 'mltail' - list 0x1DAD 'turnmleg' - list 0x1DAE 'nltail' - list 0x1DAF 'nrtailBR' - list 0x1DB0 'smcpN' - list 0x1DB1 'obar' - list 0x1DB2 'varphi' - list 0x1DB3 'srtail' - list 0x1DB4 'esh' - list 0x1DB5 'tltail' - list 0x1DB6 'ulongBarOver' - list 0x1DB7 'latinupsilon1' - list 0x1DB8 'smcpU' - list 0x1DB9 'latinupsilon2' - list 0x1DBA 'turnv' - list 0x1DBC 'zrtailBR' - list 0x1DBD 'zcurlytail' - list 0x1DBE 'ezh' - list 0x1DBF 'theta' - list 0x1DBB 'z' - list 0x1D2C 'A' - list 0x1D2D 'AE' - list 0x1D2E 'B' - list 0x1D2F 'Bbar' - list 0x1D30 'D' - list 0x1D31 'E' - list 0x1D32 'turnE' - list 0x1D33 'G' - list 0x1D34 'H' - list 0x1D35 'I' - list 0x1D36 'J' - list 0x1D37 'K' - list 0x1D38 'L' - list 0x1D39 'M' - list 0x1D3A 'N' - list 0x1D3B 'cyrI' - list 0x1D3C 'O' - list 0x1D3D 'OU' - list 0x1D3E 'P' - list 0x1D3F 'R' - list null 'S' # there is no superscript S in unicode, but is is used for the SM symbol - list 0x1D40 'T' - list 0x1D41 'U' - list 0x1D42 'W' - list 0x2C7D 'V' - list 0x207A 'plus' (-11) - list 0x207B 'minus' (-11) - list 0x207C 'equal' (-11) - list 0x207D 'parenLeft' (-11) - list 0x207E 'parenRight' (-11) -if [not recursive] : let [df : Miniature {'a' 'o'} 3.5 0.7] : begin - sketch # ordfeminine - include df.a - include : HBarBottom SB RIGHTSB DESCENDER - apply-transform : Upright - apply-transform : Translate (-MIDDLE) (-XH) - apply-transform : Scale 0.7 - apply-transform : Translate MIDDLE CAP - apply-transform : Italify - save 'ordfeminine' 0xAA - - sketch # ordmasculine - include df.o - include : HBarBottom SB RIGHTSB DESCENDER - apply-transform : Upright - apply-transform : Translate (-MIDDLE) (-XH) - apply-transform : Scale 0.7 - apply-transform : Translate MIDDLE CAP - apply-transform : Italify - save 'ordmasculine' 0xBA -progress 'Superscripts' - -createSubscripts : list - list 0x2080 'zero' - list 0x2081 'one' - list 0x2082 'two' - list 0x2083 'three' - list 0x2084 'four' - list 0x2085 'five' - list 0x2086 'six' - list 0x2087 'seven' - list 0x2088 'eight' - list 0x2089 'nine' - list 0x2090 'a' - list 0x2091 'e' - list 0x2092 'o' - list 0x2093 'x' - list 0x2094 'turne' - list 0x2095 'h' - list 0x2096 'k' - list 0x2097 'l' - list 0x2098 'm' - list 0x2099 'n' - list 0x209A 'p' - list 0x209B 's' - list 0x209C 't' - list 0x1D62 'i' - list 0x1D63 'r' - list 0x1D64 'u' - list 0x1D65 'v' - list 0x1D66 'beta' - list 0x1D67 'gamma' - list 0x1D68 'rho' - list 0x1D69 'phi' - list 0x1D6A 'chi' - list 0x2C7C 'j' - list 0x208A 'plus' (-11) - list 0x208B 'minus' (-11) - list 0x208C 'equal' (-11) - list 0x208D 'parenLeft' (-11) - list 0x208E 'parenRight' (-11) -progress 'Subscripts' - -createFractions : list - list 0x00BC 'one' 'four' - list 0x00BD 'one' 'two' - list 0x00BE 'three' 'four' - list 0x2150 'one' 'seven' - list 0x2151 'one' 'nine' - list 0x2152 'one' 'ten' - list 0x2153 'one' 'three' - list 0x2154 'two' 'three' - list 0x2155 'one' 'five' - list 0x2156 'two' 'five' - list 0x2157 'three' 'five' - list 0x2158 'four' 'five' - list 0x2159 'one' 'six' - list 0x215A 'five' 'six' - list 0x215B 'one' 'eight' - list 0x215C 'three' 'eight' - list 0x215D 'five' 'eight' - list 0x215E 'seven' 'eight' - list 0x2189 'zero' 'three' - # care-of - list 0x2105 'C' 'O' - list 0x2106 'C' 'U' - # Powerline LN symbol - list 0xE0A1 'L' 'N' - list 0xE0A3 'C' 'N' - # fraction bar - list null 'space' 'space' -progress 'Fractions' - -createMedievalCombs : list - list 0x363 'a' - list 0x364 'e' - list 0x365 'i' - list 0x366 'o' - list 0x367 'u' - list 0x368 'c' - list 0x369 'd' - list 0x36A 'h' - list 0x36B 'm' - list 0x36C 'r' - list 0x36D 't' - list 0x36E 'v' - list 0x36F 'x' - list 0x1DD4 'ae' - list 0x1DD7 'ccedillaBelow' - list 0x1DD8 'cyrde.italic' - list 0x1DD9 'eth' - list 0x1DDA 'g' - list 0x1DDB 'G' - list 0x1DDC 'k' - list 0x1DDD 'l' - list 0x1DDE 'L' - list 0x1DDF 'M' - list 0x1DE0 'n' - list 0x1DE1 'N' - list 0x1DE2 'R' - list 0x1DE3 'rrotunda' - list 0x1DE4 's' - list 0x1DE5 'longs' - list 0x1DE6 'z' - list 0x1DE7 'alpha' - list 0x1DE8 'b' - list 0x1DE9 'beta' - list 0x1DEA 'turne' - list 0x1DEB 'f' - list 0x1DEE 'p' - list 0x1DEF 'esh' - list 0x1DF0 'mu' - list 0x1DF1 'w' - list 0x1DF2 'adieresis' - list 0x1DF3 'odieresis' - list 0x1DF4 'udieresis' -progress 'Medival Combining Characters' - -# Ligatures -symbol-block 'Unicode Ligatures' - define shrink : clamp 0.75 0.9 : linreg 72 0.75 108 0.9 STROKE - define [createLigatures records] : if [not recursive] : begin + define [createFractions records] : if [not recursive] : begin local pendingGlyphs : [records.map : [record] => record.1].concat : records.map : [record] => record.2 - local df : Thinner pendingGlyphs shrink 1 - foreach [{unicode c1 c2 mark} : items-of records] : begin - local glyphName "\(c1)_\(c2)" - if glyphs.(glyphName) : begin - local j 2 - while glyphs.(glyphName + j) : inc j - set glyphName (glyphName + j) - - sketch - include df.(c2) - include : Translate (WIDTH * shrink - SB * shrink * 1.75) 0 - include df.(c1) - include : Upright - include : Translate (-WIDTH * shrink + (SB * shrink * 7/8)) 0 - include : Scale ((WIDTH - SB * 1.25) / (WIDTH - SB * 2) * WIDTH / (WIDTH * shrink * 2 - SB * shrink * 1.75)) 1 - include : Translate (WIDTH / 2) 0 - include : Italify + local miniatureFont : Miniature + glyphs -- pendingGlyphs + crowd -- 4 + scale -- 0.6 + unfair -- true + foreach {unicode numid denid height} [items-of records] : create-glyph [suggestName : numid + 'over' + denid] : glyph-construction + if unicode : assign-unicode unicode + local fine : adviceBlackness 3 + local dist : XH * 0.4 + include : create-glyph : glyph-construction + include : create-glyph [suggestName : 'num' + numid] : glyph-construction + include miniatureFont.(numid) + apply-transform : Upright + apply-transform : Translate (- miniatureFont.(numid).advanceWidth / 2) 0 + apply-transform : Scale (CAP / [fallback height CAP] * 0.55) + apply-transform : Translate MIDDLE 0 + apply-transform : Italify + refair this + apply-transform : Upright + apply-transform : Translate 0 (CAP * 0.55 + dist) + apply-transform : Italify + include : create-glyph [suggestName : 'den' + denid] : glyph-construction + include miniatureFont.(denid) + apply-transform : Upright + apply-transform : Translate (- miniatureFont.(denid).advanceWidth / 2) 0 + apply-transform : Scale (CAP / [fallback height CAP] * 0.55) + apply-transform : Translate MIDDLE 0 + apply-transform : Italify + refair this + apply-transform : Upright + apply-transform : Translate (-MIDDLE) (-CAP * 0.55 - dist / 2) + apply-transform : Translate MIDDLE parenMid + apply-transform : Italify + include : HBar SB RIGHTSB parenMid (fine * 0.75) + + + if [not recursive] : let : begin + local compositions : list + list 0xA9 'C' + list 0xAE 'R' + list 0x2117 'P' + list 0x24EA 'zero' FULLWIDTH1 + list null 'space' FULLWIDTH1 + foreach [j : range 1 till 9] : compositions.push {(0x2460 + j - 1) unicodeGlyphs.(['0'.charCodeAt 0] + j).name FULLWIDTH1} + foreach [j : range 0 26] : compositions.push {(0x24B6 + j) unicodeGlyphs.(['A'.charCodeAt 0] + j).name FULLWIDTH1} + foreach [j : range 0 26] : compositions.push {(0x24D0 + j) unicodeGlyphs.(['a'.charCodeAt 0] + j).name FULLWIDTH1} + createCircledGlyphs compositions + + local compositions : list + list null 'space' FULLWIDTH1 + foreach [j : range 1 till 9] : compositions.push {(0x2474 + j - 1) unicodeGlyphs.(['0'.charCodeAt 0] + j).name FULLWIDTH1} + foreach [j : range 0 26] : compositions.push {(0x249C + j) unicodeGlyphs.(['a'.charCodeAt 0] + j).name FULLWIDTH1} + createBracedGlyphs compositions + + createSMCPs : list + list 0x1D00 'A' + list 0x1D01 'AE' + list 0x1D03 'Bbar' + list 0x1D04 'C' + list 0x1D05 'D' + list 0x1D06 'Dcroat' + list 0x1D07 'E' + list 0x1D08 'cyrZe' + list 0x1D0A 'J' + list 0x1D0B 'K' + list 0x1D0C 'Lslash' + list 0x1D0D 'M' + list 0x1D0E 'cyrI' + list 0x1D0F 'O' + list 0x1D10 'turnC' + list 0x1D15 'OU' + list 0x1D18 'P' + list 0x1D19 'cyrYa' + list 0x1D1A 'R' [FlipAround MIDDLE (XH / 2)] + list 0x1D1B 'T' + list 0x1D20 'V' + list 0x1D21 'W' + list 0x1D22 'Z' + list 0x1D23 'Ezh' + list 0x1D26 'Gamma' + list 0x1D27 'Lambda' + list 0x1D28 'Pi' + list 0x1D29 'Rho' + list 0x1D2B 'cyrEl' + + createSuperscripts : list + list 0x2070 'zero' + list 0x00B9 'one' + list 0x00B2 'two' + list 0x00B3 'three' + list 0x2074 'four' + list 0x2075 'five' + list 0x2076 'six' + list 0x2077 'seven' + list 0x2078 'eight' + list 0x2079 'nine' + list 0x02B0 'h' + list 0x02B1 'hhooktop' + list 0x02B2 'j' + list 0x02B3 'r' + list 0x02B4 'turnr' + list 0x02B5 'turnrrtail' + list 0x02B6 'invsmcpR' + list 0x02B7 'w' + list 0x02B8 'y' + list 0x02C0 'fineglottalstop' + list 0x02C1 'finerevglottalstop' + list 0x02E0 'latingamma' + list 0x02E1 'l' + list 0x02E2 's' + list 0x02E3 'x' + list 0x02E4 'revglottalstop' + list 0x2071 'i' + list 0x207F 'n' + list 0x1D43 'a' + list 0x1D44 'turna' + list 0x1D45 'scripta' + list 0x1D46 'turnae' + list 0x1D47 'b' + list 0x1D48 'd' + list 0x1D49 'e' + list 0x1D4A 'turne' + list 0x1D4B 'epsilon' + list 0x1D4C 'cyrze' + list 0x1D4D 'g' + list 0x1D4E 'turni' + list 0x1D4F 'k' + list 0x1D50 'm' + list 0x1D51 'eng' + list 0x1D52 'o' + list 0x1D53 'turnc' + list 0x1D54 'oupperhalf' + list 0x1D55 'olowerhalf' + list 0x1D56 'p' + list 0x1D57 't' + list 0x1D58 'u' + list 0x1D5A 'turnm' + list 0x1D5B 'v' + list 0x1D5D 'beta' + list 0x1D5E 'gamma' + list 0x1D5F 'delta' + list 0x1D60 'phi' + list 0x1D61 'chi' + list 0x1D78 'smcpH' + list 0x1D9B 'turnscripta' + list 0x1D9C 'c' + list 0x1D9D 'ccurlytail' + list 0x1D9E 'eth' + list 0x1D9F 'revlatinepsilon' + list 0x1DA0 'f' + list 0x1DA1 'turnf' + list 0x1DA2 'scriptg' + list 0x1DA3 'turnh' + list 0x1DA4 'ibarOver' + list 0x1DA5 'latiniota' + list 0x1DA6 'smcpI' + list 0x1DA7 'smcpIbarOver' + list 0x1DA8 'jcurlytail' + list 0x1DAB 'smcpL' + list 0x1DA9 'lrtail' + list 0x1DAC 'mltail' + list 0x1DAD 'turnmleg' + list 0x1DAE 'nltail' + list 0x1DAF 'nrtailBR' + list 0x1DB0 'smcpN' + list 0x1DB1 'obar' + list 0x1DB2 'varphi' + list 0x1DB3 'srtail' + list 0x1DB4 'esh' + list 0x1DB5 'tltail' + list 0x1DB6 'ulongBarOver' + list 0x1DB7 'latinupsilon1' + list 0x1DB8 'smcpU' + list 0x1DB9 'latinupsilon2' + list 0x1DBA 'turnv' + list 0x1DBC 'zrtailBR' + list 0x1DBD 'zcurlytail' + list 0x1DBE 'ezh' + list 0x1DBF 'theta' + list 0x1DBB 'z' + list 0x1D2C 'A' + list 0x1D2D 'AE' + list 0x1D2E 'B' + list 0x1D2F 'Bbar' + list 0x1D30 'D' + list 0x1D31 'E' + list 0x1D32 'turnE' + list 0x1D33 'G' + list 0x1D34 'H' + list 0x1D35 'I' + list 0x1D36 'J' + list 0x1D37 'K' + list 0x1D38 'L' + list 0x1D39 'M' + list 0x1D3A 'N' + list 0x1D3B 'cyrI' + list 0x1D3C 'O' + list 0x1D3D 'OU' + list 0x1D3E 'P' + list 0x1D3F 'R' + list null 'S' # there is no superscript S in unicode, but is is used for the SM symbol + list 0x1D40 'T' + list 0x1D41 'U' + list 0x1D42 'W' + list 0x2C7D 'V' + list 0x207A 'plus' (-11) + list 0x207B 'minus' (-11) + list 0x207C 'equal' (-11) + list 0x207D 'parenLeft' (-11) + list 0x207E 'parenRight' (-11) + if [not recursive] : let [df : Miniature {'a' 'o'} 3.5 0.7] : begin + sketch # ordfeminine + include df.a + include : HBarBottom SB RIGHTSB DESCENDER + apply-transform : Upright + apply-transform : Translate (-MIDDLE) (-XH) + apply-transform : Scale 0.7 + apply-transform : Translate MIDDLE CAP + apply-transform : Italify + save 'ordfeminine' 0xAA + + sketch # ordmasculine + include df.o + include : HBarBottom SB RIGHTSB DESCENDER + apply-transform : Upright + apply-transform : Translate (-MIDDLE) (-XH) + apply-transform : Scale 0.7 + apply-transform : Translate MIDDLE CAP + apply-transform : Italify + save 'ordmasculine' 0xBA + + createSubscripts : list + list 0x2080 'zero' + list 0x2081 'one' + list 0x2082 'two' + list 0x2083 'three' + list 0x2084 'four' + list 0x2085 'five' + list 0x2086 'six' + list 0x2087 'seven' + list 0x2088 'eight' + list 0x2089 'nine' + list 0x2090 'a' + list 0x2091 'e' + list 0x2092 'o' + list 0x2093 'x' + list 0x2094 'turne' + list 0x2095 'h' + list 0x2096 'k' + list 0x2097 'l' + list 0x2098 'm' + list 0x2099 'n' + list 0x209A 'p' + list 0x209B 's' + list 0x209C 't' + list 0x1D62 'i' + list 0x1D63 'r' + list 0x1D64 'u' + list 0x1D65 'v' + list 0x1D66 'beta' + list 0x1D67 'gamma' + list 0x1D68 'rho' + list 0x1D69 'phi' + list 0x1D6A 'chi' + list 0x2C7C 'j' + list 0x208A 'plus' (-11) + list 0x208B 'minus' (-11) + list 0x208C 'equal' (-11) + list 0x208D 'parenLeft' (-11) + list 0x208E 'parenRight' (-11) + + createFractions : list + list 0x00BC 'one' 'four' + list 0x00BD 'one' 'two' + list 0x00BE 'three' 'four' + list 0x2150 'one' 'seven' + list 0x2151 'one' 'nine' + list 0x2152 'one' 'ten' + list 0x2153 'one' 'three' + list 0x2154 'two' 'three' + list 0x2155 'one' 'five' + list 0x2156 'two' 'five' + list 0x2157 'three' 'five' + list 0x2158 'four' 'five' + list 0x2159 'one' 'six' + list 0x215A 'five' 'six' + list 0x215B 'one' 'eight' + list 0x215C 'three' 'eight' + list 0x215D 'five' 'eight' + list 0x215E 'seven' 'eight' + list 0x2189 'zero' 'three' + # care-of + list 0x2105 'C' 'O' + list 0x2106 'C' 'U' + # Powerline LN symbol + list 0xE0A1 'L' 'N' + list 0xE0A3 'C' 'N' + # fraction bar + list null 'space' 'space' + + createMedievalCombs : list + list 0x363 'a' + list 0x364 'e' + list 0x365 'i' + list 0x366 'o' + list 0x367 'u' + list 0x368 'c' + list 0x369 'd' + list 0x36A 'h' + list 0x36B 'm' + list 0x36C 'r' + list 0x36D 't' + list 0x36E 'v' + list 0x36F 'x' + list 0x1DD4 'ae' + list 0x1DD7 'ccedillaBelow' + list 0x1DD8 'cyrde.italic' + list 0x1DD9 'eth' + list 0x1DDA 'g' + list 0x1DDB 'G' + list 0x1DDC 'k' + list 0x1DDD 'l' + list 0x1DDE 'L' + list 0x1DDF 'M' + list 0x1DE0 'n' + list 0x1DE1 'N' + list 0x1DE2 'R' + list 0x1DE3 'rrotunda' + list 0x1DE4 's' + list 0x1DE5 'longs' + list 0x1DE6 'z' + list 0x1DE7 'alpha' + list 0x1DE8 'b' + list 0x1DE9 'beta' + list 0x1DEA 'turne' + list 0x1DEB 'f' + list 0x1DEE 'p' + list 0x1DEF 'esh' + list 0x1DF0 'mu' + list 0x1DF1 'w' + list 0x1DF2 'adieresis' + list 0x1DF3 'odieresis' + list 0x1DF4 'udieresis' + + # Unicode Ligatures + let : begin + define shrink : clamp 0.75 0.9 : linreg 72 0.75 108 0.9 STROKE + define [createLigatures records] : if [not recursive] : begin + local pendingGlyphs : [records.map : [record] => record.1].concat : records.map : [record] => record.2 + local df : Thinner pendingGlyphs shrink 1 + foreach [{unicode c1 c2 mark} : items-of records] : begin + local glyphName "\(c1)_\(c2)" + if glyphs.(glyphName) : begin + local j 2 + while glyphs.(glyphName + j) : inc j + set glyphName (glyphName + j) - if mark : include mark - save glyphName unicode + sketch + include df.(c2) + include : Translate (WIDTH * shrink - SB * shrink * 1.75) 0 + include df.(c1) + include : Upright + include : Translate (-WIDTH * shrink + (SB * shrink * 7/8)) 0 + include : Scale ((WIDTH - SB * 1.25) / (WIDTH - SB * 2) * WIDTH / (WIDTH * shrink * 2 - SB * shrink * 1.75)) 1 + include : Translate (WIDTH / 2) 0 + include : Italify + + if mark : include mark + save glyphName unicode - createLigatures : 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 0x2A3 'd' 'z' - list 0x1F1 'D' 'Z' - list 0x1F2 'D' 'z' - list 0x1F3 'd' 'z' - list 0x2A4 'd' 'ezh' - list 0x2A5 'd' 'zcurlytail' - list 0x2A6 't' 's' - list 0x2A7 't' 'esh' - list 0x2A8 't' 'ccurlytail' - list 0x2A9 'f' 'eng' - list 0x2AA 'l' 's' - list 0x2AB 'l' 'z' - list 0x478 'O' 'y' markset.if - list 0x479 'o' 'y' markset.p - list 0x20A7 'P' 's' - list 0x20A8 'R' 's' + createLigatures : 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 0x2A3 'd' 'z' + list 0x1F1 'D' 'Z' + list 0x1F2 'D' 'z' + list 0x1F3 'd' 'z' + list 0x2A4 'd' 'ezh' + list 0x2A5 'd' 'zcurlytail' + list 0x2A6 't' 's' + list 0x2A7 't' 'esh' + list 0x2A8 't' 'ccurlytail' + list 0x2A9 'f' 'eng' + list 0x2AA 'l' 's' + list 0x2AB 'l' 'z' + list 0x478 'O' 'y' markset.if + list 0x479 'o' 'y' markset.p + list 0x20A7 'P' 's' + list 0x20A8 'R' 's' -# Composite superscripts and subscripts -let : begin - define [doubleSuperscript a b] : glyph-construction - include a - apply-transform : Translate (-WIDTH * 0.6) 0 - include b - apply-transform : Upright - apply-transform : Translate (-WIDTH * 0.2) (-CAP) - apply-transform : Scale 0.8 - apply-transform : Translate MIDDLE CAP - apply-transform : Italify - - sketch # trademark - include : doubleSuperscript glyphs.supT glyphs.supM - save 'trademark' 0x2122 - - sketch # servicemark - include : doubleSuperscript glyphs.supS glyphs.supM - save 'servicemark' 0x2120 -progress 'Double Superscripts' + # Composite superscripts and subscripts + let : begin + define [doubleSuperscript a b] : glyph-construction + include a + apply-transform : Translate (-WIDTH * 0.6) 0 + include b + apply-transform : Upright + apply-transform : Translate (-WIDTH * 0.2) (-CAP) + apply-transform : Scale 0.8 + apply-transform : Translate MIDDLE CAP + apply-transform : Italify + + sketch # trademark + include : doubleSuperscript glyphs.supT glyphs.supM + save 'trademark' 0x2122 + + sketch # servicemark + include : doubleSuperscript glyphs.supS glyphs.supM + save 'servicemark' 0x2120 - -# CJK double width letters -symbol-block 'CJK Double Width Characters' : if [not recursive] : begin - define [createDoubleWidth records] : begin - local scale 1.25 - local pendingGlyphs : records.map : [record] => record.1 - local widenFont : Widen pendingGlyphs scale (scale * 1.1) - foreach {unicode glyphid} [items-of records] : begin - if [not unicodeGlyphs.(unicode)] : then : create-glyph [suggestName : 'dw' + glyphid] : glyph-construction - set-width UPM - if unicode : assign-unicode unicode - include widenFont.(glyphid) AS_BASE - apply-transform [Translate (UPM / 2 - (WIDTH * scale) / 2) 0] true - : else : let [this-glyph widenFont.(glyphid)] [that-glyph unicodeGlyphs.(unicode)] : if (this-glyph && that-glyph) : begin - set that-glyph.advanceWidth FULLWIDTH - set that-glyph.anchors this-glyph.anchors - set that-glyph.contours this-glyph.contours - that-glyph.include : Translate (FULLWIDTH / 2 - this-glyph.advanceWidth / 2) 0 - - createDoubleWidth : let [a {}] : begin - foreach [j : range 1 0x5f] : if [not unicodeGlyphs.(0xff00 + j)] : a.push {(0xff00 + j) unicodeGlyphs.(0x20 + j).name} - if para.fullwidth_codes : foreach [j : items-of para.fullwidth_codes] : if (unicodeGlyphs.(j) && unicodeGlyphs.(j).advanceWidth < 1000) : begin - a.push {j unicodeGlyphs.(j).name} - a.push {0xFFE0 'cent'} - a.push {0xFFE1 'sterling'} - a.push {0xFFE5 'yen'} - * a - - if (para.spacing == 0) : begin - set font.glyf : font.glyf.filter [lambda [g] : g.advanceWidth <= WIDTH] - set glyphList.length font.glyf.length - for [local j 0] (j < font.glyf.length) [inc j] : set glyphList.(j) font.glyf.(j) \ No newline at end of file + # CJK double width letters + if [not recursive] : let : begin + define [createDoubleWidth records] : begin + local scale 1.25 + local pendingGlyphs : records.map : [record] => record.1 + local widenFont : Widen pendingGlyphs scale (scale * 1.1) + foreach {unicode glyphid} [items-of records] : begin + if [not unicodeGlyphs.(unicode)] : then : create-glyph [suggestName : 'dw' + glyphid] : glyph-construction + set-width UPM + if unicode : assign-unicode unicode + include widenFont.(glyphid) AS_BASE + apply-transform [Translate (UPM / 2 - (WIDTH * scale) / 2) 0] true + : else : let [this-glyph widenFont.(glyphid)] [that-glyph unicodeGlyphs.(unicode)] : if (this-glyph && that-glyph) : begin + set that-glyph.advanceWidth FULLWIDTH + set that-glyph.anchors this-glyph.anchors + set that-glyph.contours this-glyph.contours + that-glyph.include : Translate (FULLWIDTH / 2 - this-glyph.advanceWidth / 2) 0 + + createDoubleWidth : let [a {}] : begin + foreach [j : range 1 0x5f] : if [not unicodeGlyphs.(0xff00 + j)] : a.push {(0xff00 + j) unicodeGlyphs.(0x20 + j).name} + if para.fullwidth_codes : foreach [j : items-of para.fullwidth_codes] : if (unicodeGlyphs.(j) && unicodeGlyphs.(j).advanceWidth < 1000) : begin + a.push {j unicodeGlyphs.(j).name} + a.push {0xFFE0 'cent'} + a.push {0xFFE1 'sterling'} + a.push {0xFFE5 'yen'} + * a + + if (para.spacing == 0) : begin + set font.glyf : font.glyf.filter [lambda [g] : g.advanceWidth <= WIDTH] + set glyphList.length font.glyf.length + for [local j 0] (j < font.glyf.length) [inc j] : set glyphList.(j) font.glyf.(j) \ No newline at end of file diff --git a/glyphs/common-shapes.ptl b/glyphs/common-shapes.ptl index ea0b12a9a..129c59d67 100644 --- a/glyphs/common-shapes.ptl +++ b/glyphs/common-shapes.ptl @@ -1,614 +1,632 @@ -###### COMMON GLYPH CONSTRUCTIONS -define [select-variant name unicode default featureSelector] : begin - if (pickHash && [not pickHash.(name)]) : return nothing - local variant : variantSelector.(name) || default - local chosenGlyph glyphs.((name + '.' + variant)) - create-glyph name : glyph-construction - include chosenGlyph AS_BASE ALSO_METRICS +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry + ###### COMMON GLYPH CONSTRUCTIONS + define [select-variant name unicode default featureSelector] : begin + if (pickHash && [not pickHash.(name)]) : return nothing + local variant : variantSelector.(name) || default + local chosenGlyph glyphs.((name + '.' + variant)) + create-glyph name : glyph-construction + include chosenGlyph AS_BASE ALSO_METRICS + if unicode : assign-unicode unicode + if featureSelector : set currentGlyph.featureSelector featureSelector + + define [italic-variant name unicode] : create-glyph name : glyph-construction + if para.isItalic + then : include glyphs.(name + '.italic') AS_BASE + else : include glyphs.(name + '.upright') AS_BASE if unicode : assign-unicode unicode - if featureSelector : set currentGlyph.featureSelector featureSelector -define [italic-variant name unicode] : create-glyph name : glyph-construction - if para.isItalic - then : include glyphs.(name + '.italic') AS_BASE - else : include glyphs.(name + '.upright') AS_BASE - if unicode : assign-unicode unicode + define [alias newid unicode oldid] : begin + create-glyph newid : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(oldid) AS_BASE + set-width glyphs.(oldid).advanceWidth + set this.featureSelector glyphs.(oldid).featureSelector -define [alias newid unicode oldid] : begin - create-glyph newid : glyph-construction + define [composite newid] : let [parts : {}.slice.call arguments 1] : begin + create-glyph [fallback newid ('glyph' + [newtemp])] : glyph-construction + local first true + foreach [part : items-of parts] : begin + include part first + if first : set-width part.advanceWidth + set first false + + define [into-unicode code] : glyph-construction + if code : assign-unicode code + + # Transformation variants + define [turned newid unicode id x y mark] : create-glyph [fallback newid : 'turn' + id] : glyph-construction if unicode : assign-unicode unicode - include glyphs.(oldid) AS_BASE - set-width glyphs.(oldid).advanceWidth - set this.featureSelector glyphs.(oldid).featureSelector - -define [composite newid] : let [parts : {}.slice.call arguments 1] : begin - create-glyph [fallback newid ('glyph' + [set nTemp (nTemp + 1)])] : glyph-construction - local first true - foreach [part : items-of parts] : begin - include part first - if first : set-width part.advanceWidth - set first false - -define [into-unicode code] : glyph-construction - if code : assign-unicode code - -# Transformation variants -define [turned newid unicode id x y mark] : create-glyph [fallback newid : 'turn' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) [if mark false AS_BASE] - set-width glyphs.(id).advanceWidth - if mark : include mark - include : FlipAround x y -# Dual derivatives -define [dual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) AS_BASE - apply-transform : Translate (-spacing) 0 - include glyphs.(id) - apply-transform : Translate (spacing / 2) 0 - -define [vdual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction - if unicode : assign-unicode unicode - depends-on glyphs.(id) - include : create-glyph : glyph-construction + include glyphs.(id) [if mark false AS_BASE] + set-width glyphs.(id).advanceWidth + if mark : include mark + include : FlipAround x y + # Dual derivatives + define [dual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(id) AS_BASE + apply-transform : Translate (-spacing) 0 include glyphs.(id) - apply-transform : Upright - apply-transform : Translate 0 (-spacing) - include : create-glyph : glyph-construction + apply-transform : Translate (spacing / 2) 0 + + define [vdual newid unicode id spacing] : create-glyph [fallback newid : 'double' + id] : glyph-construction + if unicode : assign-unicode unicode + depends-on glyphs.(id) + include : create-glyph : glyph-construction + include glyphs.(id) + apply-transform : Upright + apply-transform : Translate 0 (-spacing) + include : create-glyph : glyph-construction + include glyphs.(id) + apply-transform : Upright + apply-transform : Translate 0 (spacing / 2) + apply-transform : Italify + # Full-width derivatives + define [fwl newid unicode id] : create-glyph [fallback newid : 'fwl' + id] : glyph-construction + if unicode : assign-unicode unicode include glyphs.(id) - apply-transform : Upright - apply-transform : Translate 0 (spacing / 2) - apply-transform : Italify -# Full-width derivatives -define [fwl newid unicode id] : create-glyph [fallback newid : 'fwl' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) - set-width FULLWIDTH + set-width FULLWIDTH -define [fwr newid unicode id] : create-glyph [fallback newid : 'fwr' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) - set-width FULLWIDTH - apply-transform : Translate (FULLWIDTH - WIDTH) 0 + define [fwr newid unicode id] : create-glyph [fallback newid : 'fwr' + id] : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(id) + set-width FULLWIDTH + apply-transform : Translate (FULLWIDTH - WIDTH) 0 -define [dwl newid unicode id] : create-glyph [fallback newid : 'dwl' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) - set-width UPM + define [dwl newid unicode id] : create-glyph [fallback newid : 'dwl' + id] : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(id) + set-width UPM -define [dwr newid unicode id] : create-glyph [fallback newid : 'dwr' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) - set-width UPM - apply-transform : Translate (UPM - WIDTH) 0 + define [dwr newid unicode id] : create-glyph [fallback newid : 'dwr' + id] : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(id) + set-width UPM + apply-transform : Translate (UPM - WIDTH) 0 -define [dwc newid unicode id] : create-glyph [fallback newid : 'dwc' + id] : glyph-construction - if unicode : assign-unicode unicode - include glyphs.(id) - set-width UPM - apply-transform : Translate ((UPM - WIDTH) / 2) 0 + define [dwc newid unicode id] : create-glyph [fallback newid : 'dwc' + id] : glyph-construction + if unicode : assign-unicode unicode + include glyphs.(id) + set-width UPM + apply-transform : Translate ((UPM - WIDTH) / 2) 0 -###### COMMON SHAPES -define [Ring u d l r transformShiftOnly] : create-glyph : glyph-construction - local my ((u + d) / 2) - local mx ((l + r) / 2) - currentGlyph.gizmo = [if transformShiftOnly [Translate 0 0] globalTransform] - include : spiro-outline - begin [lambda : set this.gizmo currentGlyph.gizmo] - g4 mx d - archv - g4 l my - arcvh - g4 mx u - archv - g4 r my - arcvh - close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]] - if transformShiftOnly : begin - local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}] - apply-transform : Translate (mx1 - mx) (my1 - my) -define [RingAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) -define [DotAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) true - -define [CircleRing u d l r transformShiftOnly] : create-glyph : glyph-construction - local my ((u + d) / 2) - local mx ((l + r) / 2) - currentGlyph.gizmo = [if transformShiftOnly [Translate 0 0] globalTransform] - include : spiro-outline - begin [lambda : set this.gizmo currentGlyph.gizmo] - g4 mx d - g4 l my - g4 mx u - g4 r my - close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]] - if transformShiftOnly : begin - local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}] - apply-transform : Translate (mx1 - mx) (my1 - my) -define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) -define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true - -define [OShape u d l r _width _sma _smb ai] : glyph-construction - local middle : (l + r) / 2 - local width : fallback _width STROKE - local sma : fallback _sma SMALLSMOOTHA - local smb : fallback _smb SMALLSMOOTHB - local mc : CORRECTION_OMIDX * width - if (u - d > sma + smb) : then : begin - include : dispiro - widths width 0 - g4 (middle - mc) (u - O) + ###### COMMON SHAPES + define [Ring u d l r transformShiftOnly] : create-glyph : glyph-construction + local my ((u + d) / 2) + local mx ((l + r) / 2) + currentGlyph.gizmo = [if transformShiftOnly [Translate 0 0] globalTransform] + include : spiro-outline + begin [lambda : set this.gizmo currentGlyph.gizmo] + g4 mx d archv - [if ai flat.ai flat] (l + OX) (u - sma) - [if ai curl.ai curl] (l + OX) (d + smb) + g4 l my arcvh - g4 (middle + mc) (d + O) + g4 mx u archv - [if ai flat.ai flat] (r - OX) (d + sma) - [if ai curl.ai curl] (r - OX) (u - smb) + g4 r my + arcvh + close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]] + if transformShiftOnly : begin + local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}] + apply-transform : Translate (mx1 - mx) (my1 - my) + define [RingAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) + define [DotAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) true + + define [CircleRing u d l r transformShiftOnly] : create-glyph : glyph-construction + local my ((u + d) / 2) + local mx ((l + r) / 2) + currentGlyph.gizmo = [if transformShiftOnly [Translate 0 0] globalTransform] + include : spiro-outline + begin [lambda : set this.gizmo currentGlyph.gizmo] + g4 mx d + g4 l my + g4 mx u + g4 r my + close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]] + if transformShiftOnly : begin + local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}] + apply-transform : Translate (mx1 - mx) (my1 - my) + define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) + define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true + + define [OShape u d l r _width _sma _smb ai] : glyph-construction + local middle : (l + r) / 2 + local width : fallback _width STROKE + local sma : fallback _sma SMALLSMOOTHA + local smb : fallback _smb SMALLSMOOTHB + local mc : CORRECTION_OMIDX * width + if (u - d > sma + smb) : then : begin + include : dispiro + widths width 0 + g4 (middle - mc) (u - O) + archv + [if ai flat.ai flat] (l + OX) (u - sma) + [if ai curl.ai curl] (l + OX) (d + smb) + arcvh + g4 (middle + mc) (d + O) + archv + [if ai flat.ai flat] (r - OX) (d + sma) + [if ai curl.ai curl] (r - OX) (u - smb) + arcvh + close + : else : begin + local ymiddlea : mix d u (smb / (sma + smb)) + local ymiddleb : mix d u (sma / (sma + smb)) + include : dispiro + widths width 0 + g4 (middle - mc) (u - O) + archv + g4 (l + OX) ymiddlea + arcvh + g4 (middle + mc) (d + O) + archv + g4 (r - OX) ymiddleb + arcvh + close + define [OBarLeftShape _top _left] : glyph-construction + local top : fallback _top XH + local left : fallback _left SB + local fine SHOULDERFINE + local st : shoulderMidSlope fine nothing 1 + local sb : shoulderMidSlope fine nothing (-1) + local mt : [mix left RIGHTSB 0.5] + (st - CORRECTION_OMIDX) * STROKE + local mb : [mix left RIGHTSB 0.5] + (sb + CORRECTION_OMIDX) * STROKE + include : dispiro + widths.lhs + g4 (mt) (top - O) [heading {.y (-1) .x (-st)}] + archv + flat (left + (STROKE - fine) * HVCONTRAST) (top - SMALLSMOOTHA) [widths fine 0] + curl (left + (STROKE - fine) * HVCONTRAST) (0 + SMALLSMOOTHB) [widths fine 0] + arcvh + g4 (mb) O [widths.heading STROKE 0 {.y (1) .x (-sb)}] + archv + [if ((SMALLSMOOTHA + SMALLSMOOTHB) / top > 0.75) flat.ai flat] (RIGHTSB - OX) (0 + SMALLSMOOTHA) + [if ((SMALLSMOOTHA + SMALLSMOOTHB) / top > 0.75) curl.ai curl] (RIGHTSB - OX) (top - SMALLSMOOTHB) arcvh close - : else : begin - local ymiddlea : mix d u (smb / (sma + smb)) - local ymiddleb : mix d u (sma / (sma + smb)) + + define [OBarRightShape top right] : glyph-construction + include : create-glyph [OBarLeftShape top (WIDTH - [fallback right RIGHTSB])] + include : FlipAround MIDDLE ([fallback top XH] / 2) + + define SERIF_SHIFT_X 0.6 + define [LeftwardTopSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE include : dispiro - widths width 0 - g4 (middle - mc) (u - O) - archv - g4 (l + OX) ymiddlea + flat (x + HALFSTROKE * HVCONTRAST) y [widths.heading sw 0 LEFTWARD] + curl (x - length - TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [LeftwardBottomSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE + include : dispiro + flat (x + HALFSTROKE * HVCONTRAST) y [widths.heading 0 sw LEFTWARD] + curl (x - length + TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [RightwardTopSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE + include : dispiro + flat (x - HALFSTROKE * HVCONTRAST) y [widths.heading 0 sw RIGHTWARD] + curl (x + length - TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [RightwardBottomSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE + include : dispiro + flat (x - HALFSTROKE * HVCONTRAST) y [widths.heading sw 0 RIGHTWARD] + curl (x + length + TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [CenterTopSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE + include : dispiro + flat (x + length - TANSLANT * (sw * SERIF_SHIFT_X)) y [widths sw 0] + curl (x - length - TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [CenterBottomSerif x y length _sw] : glyph-construction + local sw : fallback _sw STROKE + include : dispiro + flat (x + length + TANSLANT * (sw * SERIF_SHIFT_X)) y [widths 0 sw] + curl (x - length + TANSLANT * (sw * SERIF_SHIFT_X)) y + + define [DownwardRightSerif x y length sw] : glyph-construction + include : dispiro + widths.rhs sw + flat x y [heading DOWNWARD] + curl x (y - length) [heading DOWNWARD] + define [UpwardRightSerif x y length sw] : glyph-construction + include : dispiro + widths.lhs sw + flat x y [heading UPWARD] + curl x (y + length) [heading UPWARD] + define [DownwardLeftSerif x y length sw] : glyph-construction + include : dispiro + widths.lhs sw + flat x y [heading DOWNWARD] + curl x (y - length) [heading DOWNWARD] + define [UpwardLeftSerif x y length sw] : glyph-construction + include : dispiro + widths.rhs sw + flat x y [heading UPWARD] + curl x (y + length) [heading UPWARD] + + define sideSerifK 0.5 + define [AIVSerifs top _left _right] : glyph-construction + local left : fallback _left SB + local right : fallback _right RIGHTSB + if SLAB : begin + include : CenterTopSerif (left + STROKE * sideSerifK * HVCONTRAST) top JUT + tag-contour 'serifLT' + include : CenterTopSerif (right - STROKE * sideSerifK * HVCONTRAST) top JUT + tag-contour 'serifRT' + define [AIHSerifs top _left _right] : glyph-construction + local left : fallback _left SB + local right : fallback _right RIGHTSB + if SLAB : begin + include : AIVSerifs top _left _right + include : CenterBottomSerif (left + STROKE * sideSerifK * HVCONTRAST) 0 JUT + include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT + define [AINSerifs top _left _right sw xn] : glyph-construction + local left : fallback _left SB + local right : fallback _right RIGHTSB + local jut : JUT * [fallback xn 1] + if SLAB : begin + include : LeftwardTopSerif (left + sw * (sideSerifK - 0.5) * HVCONTRAST) top (jut - sw / 2 * HVCONTRAST) + include : CenterTopSerif (right - sw * sideSerifK * HVCONTRAST) top jut + include : CenterBottomSerif (left + sw * sideSerifK * HVCONTRAST) 0 jut + tag-contour 'serifLB' + #include : CenterdBottomSerif (right - STROKE * (sideSerifK - 0.5) * HVCONTRAST) 0 (JUT / 2) + define [AICyrISerifs top _left _right] : glyph-construction + local left : fallback _left SB + local right : fallback _right RIGHTSB + if SLAB : begin + include : LeftwardBottomSerif left 0 SIDEJUT + include : RightwardTopSerif right top SIDEJUT + include : CenterTopSerif (left + STROKE * sideSerifK * HVCONTRAST) top JUT + include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT + tag-contour 'serifRB' + define [AIMSerifs top _left _right] : glyph-construction + local left : fallback _left SB + local right : fallback _right RIGHTSB + if SLAB : begin + include : LeftwardTopSerif (left + STROKE * (sideSerifK - 0.5) * HVCONTRAST) top SIDEJUT + include : RightwardTopSerif (right - STROKE * (sideSerifK - 0.5) * HVCONTRAST) top SIDEJUT + include : CenterBottomSerif (left + STROKE * sideSerifK * HVCONTRAST) 0 JUT + include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT + + + define [halfXStrand _leftx lefty rightx righty turn straight tension _fine] : glyph-construction + local leftx : _leftx + (HALFSTROKE * HVCONTRAST * [if (rightx > _leftx) 1 (-1)]) + local fine : (_fine || STROKE) * 0.5 + + local turnyleft : mix lefty righty turn + local cyleft : mix turnyleft righty tension + + local straightxleft : mix leftx rightx straight + local straightyleft : mix cyleft righty straight + + include : dispiro + widths.center + flat leftx lefty [heading [if (lefty < righty) UPWARD DOWNWARD]] + curl leftx turnyleft [heading [if (lefty < righty) UPWARD DOWNWARD]] + quadcontrols 0 ((cyleft - turnyleft) / (straightyleft - turnyleft)) 24 + flat straightxleft straightyleft + curl rightx righty + end [function : set this.cleanmore true] + + + define [xStrand _leftx lefty _rightx righty turn straight tension] : glyph-construction + local middlex : mix _leftx _rightx 0.5 + local middley : mix lefty righty 0.5 + + include : halfXStrand _leftx lefty middlex middley turn straight tension + include : halfXStrand _rightx righty middlex middley turn straight tension + + define [nShoulderKnots] : params [left right [fine SHOULDERFINE] [top XH] [bottom 0] [sma SMALLSMOOTHA] [smb SMALLSMOOTHB] [stroke STROKE]] : begin + local slope : shoulderMidSlope fine stroke + local middle : [mix (left - stroke * HVCONTRAST) right 0.5] + (slope - CORRECTION_OMIDX) * stroke + return : list + flat left (top - sma - 2) [widths fine 0] + curl left (top - sma) arcvh - g4 (middle + mc) (d + O) + g4 middle (top - O) [widths.heading 0 stroke {.y (1) .x (slope)}] archv - g4 (r - OX) ymiddleb - arcvh + flat right (top - smb) + curl right bottom [heading DOWNWARD] + + define [nShoulder] : begin + local a arguments + glyph-construction + include : dispiro : nShoulderKnots.apply null a + + + define [mShoulderSpiro] : params [left right top bottom width fine] : glyph-construction + local fix : TANSLANT * STROKE * HVCONTRAST * width / STROKE + local sm : SMALLSMOOTH * 0.75 + include : spiro-outline + corner (right - width * HVCONTRAST) bottom + curl (right - width * HVCONTRAST) (top - sm + fix) + arcvh 8 'no-tiny' + g2 [mix left (right - width * HVCONTRAST) 0.5] (top - O - width) + archv 8 'no-tiny' + flat left (top - sm - fix) + corner left (top - sm - fix - 1) + corner (left - fine) (top - sm - 1) + curl (left - fine) (top - sm) + arcvh 8 'no-tiny' + g2 [mix (left - fine * HVCONTRAST) right 0.5] (top - O) + archv 8 'no-tiny' + flat right (top - sm) + corner right bottom close -define [OBarLeftShape _top _left] : glyph-construction - local top : fallback _top XH - local left : fallback _left SB - local fine SHOULDERFINE - local st : shoulderMidSlope fine nothing 1 - local sb : shoulderMidSlope fine nothing (-1) - local mt : [mix left RIGHTSB 0.5] + (st - CORRECTION_OMIDX) * STROKE - local mb : [mix left RIGHTSB 0.5] + (sb + CORRECTION_OMIDX) * STROKE - include : dispiro - widths.lhs - g4 (mt) (top - O) [heading {.y (-1) .x (-st)}] - archv - flat (left + (STROKE - fine) * HVCONTRAST) (top - SMALLSMOOTHA) [widths fine 0] - curl (left + (STROKE - fine) * HVCONTRAST) (0 + SMALLSMOOTHB) [widths fine 0] - arcvh - g4 (mb) O [widths.heading STROKE 0 {.y (1) .x (-sb)}] - archv - [if ((SMALLSMOOTHA + SMALLSMOOTHB) / top > 0.75) flat.ai flat] (RIGHTSB - OX) (0 + SMALLSMOOTHA) - [if ((SMALLSMOOTHA + SMALLSMOOTHB) / top > 0.75) curl.ai curl] (RIGHTSB - OX) (top - SMALLSMOOTHB) - arcvh - close -define [OBarRightShape top right] : glyph-construction - include : create-glyph [OBarLeftShape top (WIDTH - [fallback right RIGHTSB])] - include : FlipAround MIDDLE ([fallback top XH] / 2) + define [HBar xleft xright y _fine] : glyph-construction + include : dispiro + widths.center [fallback _fine STROKE] + flat xleft y [heading RIGHTWARD] + curl xright y [heading RIGHTWARD] -define SERIF_SHIFT_X 0.6 -define [LeftwardTopSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x + HALFSTROKE * HVCONTRAST) y [widths.heading sw 0 LEFTWARD] - curl (x - length - TANSLANT * (sw * SERIF_SHIFT_X)) y + define [HBarTop xl xr y _fine] : HBar xl xr (y - [fallback _fine STROKE] * 0.5) _fine + define [HBarBottom xl xr y _fine] : HBar xl xr (y + [fallback _fine STROKE] * 0.5) _fine + define [HOverlayBar xleft xright y s] : dispiro + widths.center [fallback s OVERLAYSTROKE] + flat xleft y + curl xright y + define [VBar x ydown yup _fine] : glyph-construction + local fine : fallback _fine STROKE + include : dispiro + widths.center fine + flat x ydown [heading [if (ydown < yup) UPWARD DOWNWARD]] + curl x yup [heading [if (ydown < yup) UPWARD DOWNWARD]] -define [LeftwardBottomSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x + HALFSTROKE * HVCONTRAST) y [widths.heading 0 sw LEFTWARD] - curl (x - length + TANSLANT * (sw * SERIF_SHIFT_X)) y + define [VBarLeft x yd yu _fine] : VBar (x + [fallback _fine STROKE] * 0.5 * HVCONTRAST) yd yu _fine + define [VBarRight x yd yu _fine] : VBar (x - [fallback _fine STROKE] * 0.5 * HVCONTRAST) yd yu _fine -define [RightwardTopSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x - HALFSTROKE * HVCONTRAST) y [widths.heading 0 sw RIGHTWARD] - curl (x + length - TANSLANT * (sw * SERIF_SHIFT_X)) y + define [VerticalHook x y extend depth fine strg] : glyph-construction + include : dispiro + widths.center [fallback fine STROKE] + flat x (y + [fallback strg 0]) [heading [if (depth > 0) DOWNWARD UPWARD]] + curl x (y - [if (depth > 0) 0.01 (-0.01)]) [heading [if (depth > 0) DOWNWARD UPWARD]] + arcvh + flat (x + extend - [if (extend > 0) 0.01 (-0.01)]) (y - depth) + curl (x + extend) (y - depth) -define [RightwardBottomSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x - HALFSTROKE * HVCONTRAST) y [widths.heading sw 0 RIGHTWARD] - curl (x + length + TANSLANT * (sw * SERIF_SHIFT_X)) y + define [LegShape] : params [[ztop nothing (xt <> top)] [zbot nothing (xs <> bottom)] xb [fine STROKE]] : glyph-construction + include : dispiro + widths.lhs fine + flat xt top [heading DOWNWARD] + curl xb (bottom + LONGJUT) + alsothruthem {{0.5 0.94}} + g4.left.end xs (bottom + fine) [heading LEFTWARD] -define [CenterTopSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x + length - TANSLANT * (sw * SERIF_SHIFT_X)) y [widths sw 0] - curl (x - length - TANSLANT * (sw * SERIF_SHIFT_X)) y + define [LeftHook x y xextend] : glyph-construction + local fine : adviceBlackness 4.25 + include : dispiro + widths.lhs fine + flat [fallback xextend : x + 1] y + curl x y + archv 8 + g4.down.end (x - LeftHook.extension) (y - HOOKX) [heading DOWNWARD] + set LeftHook.extension [Math.max (WIDTH * 0.15) ([adviceBlackness 4.25] * 1.5)] -define [CenterBottomSerif x y length _sw] : glyph-construction - local sw : fallback _sw STROKE - include : dispiro - flat (x + length + TANSLANT * (sw * SERIF_SHIFT_X)) y [widths 0 sw] - curl (x - length + TANSLANT * (sw * SERIF_SHIFT_X)) y + define [HooktopLeftBar stroke bottom] : glyph-construction + include : dispiro + widths.lhs [fallback stroke STROKE] + g4 RIGHTSB (CAP - HOOK) + hookstart CAPO + flat SB (CAP - SMALLSMOOTHA) + curl SB [fallback bottom 0] [heading DOWNWARD] -define [DownwardRightSerif x y length sw] : glyph-construction - include : dispiro - widths.rhs sw - flat x y [heading DOWNWARD] - curl x (y - length) [heading DOWNWARD] -define [UpwardRightSerif x y length sw] : glyph-construction - include : dispiro - widths.lhs sw - flat x y [heading UPWARD] - curl x (y + length) [heading UPWARD] -define [DownwardLeftSerif x y length sw] : glyph-construction - include : dispiro - widths.lhs sw - flat x y [heading DOWNWARD] - curl x (y - length) [heading DOWNWARD] -define [UpwardLeftSerif x y length sw] : glyph-construction - include : dispiro - widths.rhs sw - flat x y [heading UPWARD] - curl x (y + length) [heading UPWARD] + define [CurlyTail] : params [fine rinner xleft bottom right x2 y2 [adj 0.4] [adj2 0.4] [adj3 0]] : begin + local ltr : right > xleft + set right : right - fine * [if ltr 1 (-1)] + local mid : mix [mix xleft right 0.5] (right - rinner * [if ltr 1 (-1)]) adj + local midu : mix [mix xleft right 0.5] (right - rinner * [if ltr 1 (-1)]) adj2 + return : list + g4.[if ltr 'right' 'left'].mid (mid + CORRECTION_OMIDX * fine * adj3 * [if ltr 1 (-1)]) (bottom + fine + O) [widths [if ltr 0 fine] [if ltr fine 0]] + archv 2 + g4 right (bottom + fine + rinner - 0.1) + g4 right (bottom + fine + rinner + 0.1) + arcvh 2 + g4 mid (bottom + fine + rinner * 2 - O) + alsothruthem {{0.25 0.06} {0.52 0.25}} important + g4 x2 y2 -define sideSerifK 0.5 -define [AIVSerifs top _left _right] : glyph-construction - local left : fallback _left SB - local right : fallback _right RIGHTSB - if SLAB : begin - include : CenterTopSerif (left + STROKE * sideSerifK * HVCONTRAST) top JUT - tag-contour 'serifLT' - include : CenterTopSerif (right - STROKE * sideSerifK * HVCONTRAST) top JUT - tag-contour 'serifRT' -define [AIHSerifs top _left _right] : glyph-construction - local left : fallback _left SB - local right : fallback _right RIGHTSB - if SLAB : begin - include : AIVSerifs top _left _right - include : CenterBottomSerif (left + STROKE * sideSerifK * HVCONTRAST) 0 JUT - include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT -define [AINSerifs top _left _right sw xn] : glyph-construction - local left : fallback _left SB - local right : fallback _right RIGHTSB - local jut : JUT * [fallback xn 1] - if SLAB : begin - include : LeftwardTopSerif (left + sw * (sideSerifK - 0.5) * HVCONTRAST) top (jut - sw / 2 * HVCONTRAST) - include : CenterTopSerif (right - sw * sideSerifK * HVCONTRAST) top jut - include : CenterBottomSerif (left + sw * sideSerifK * HVCONTRAST) 0 jut - tag-contour 'serifLB' - #include : CenterdBottomSerif (right - STROKE * (sideSerifK - 0.5) * HVCONTRAST) 0 (JUT / 2) -define [AICyrISerifs top _left _right] : glyph-construction - local left : fallback _left SB - local right : fallback _right RIGHTSB - if SLAB : begin - include : LeftwardBottomSerif left 0 SIDEJUT - include : RightwardTopSerif right top SIDEJUT - include : CenterTopSerif (left + STROKE * sideSerifK * HVCONTRAST) top JUT - include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT - tag-contour 'serifRB' -define [AIMSerifs top _left _right] : glyph-construction - local left : fallback _left SB - local right : fallback _right RIGHTSB - if SLAB : begin - include : LeftwardTopSerif (left + STROKE * (sideSerifK - 0.5) * HVCONTRAST) top SIDEJUT - include : RightwardTopSerif (right - STROKE * (sideSerifK - 0.5) * HVCONTRAST) top SIDEJUT - include : CenterBottomSerif (left + STROKE * sideSerifK * HVCONTRAST) 0 JUT - include : CenterBottomSerif (right - STROKE * sideSerifK * HVCONTRAST) 0 JUT + define [HCurlyTail fine wide rinner left m1 _right x1 x2 y2] : glyph-construction + local right : _right - fine + local mid : right - rinner + O + include : dispiro + widths.rhs wide + flat left wide [heading RIGHTWARD] + curl m1 wide [heading RIGHTWARD] + archv 8 + g4 right (wide + rinner - O / 2) [widths.heading 0 fine {.x (-HVCONTRAST) .y ((wide - fine) / (wide + rinner * 2 - O))}] + arcvh 8 + g4.left.mid mid (wide + rinner * 2 - O) [heading LEFTWARD] + quadcontrols ((x1 - mid) / (x2 - mid)) 0 8 + g4 x2 y2 + define [FlatSlashShape middlex middle fine kx ky] : glyph-construction + include : dispiro + flat (middlex - LONGJUT * [fallback kx 0.8]) (middle - LONGJUT * [fallback ky 0.4]) [widths fine fine] + curl (middlex + LONGJUT * [fallback kx 0.8]) (middle + LONGJUT * [fallback ky 0.4]) -define [halfXStrand _leftx lefty rightx righty turn straight tension _fine] : glyph-construction - local leftx : _leftx + (HALFSTROKE * HVCONTRAST * [if (rightx > _leftx) 1 (-1)]) - local fine : (_fine || STROKE) * 0.5 + # Spiro shapes + define [determineMixR w v u sw] : begin + local r : piecewise + (w <= v) 0.5 + true : 1 / ([Math.pow (1 - [Math.pow (1 - v / w) SUPERNESS]) (1 / SUPERNESS)] + 1) + local idepth : w - sw + local iwidth : u * r - sw + if (iwidth > 0 && idepth > 0 && iwidth / idepth >= 2) : begin + local adjust : clamp 0.975 1 (1 - (iwidth / idepth - 2) * 0.0125) + #console.log iwidth idepth (iwidth / idepth) adjust + r = r * adjust + if (r < 0.5) : set r 0.5 + return r + + define nHookSegments 12 + define [HookShape toStraight toFinish isStart y tight s kkaf dontadjust] : begin + local atBottom : toStraight.y > y + local sw : fallback s STROKE + local ltr : if isStart (toFinish.x < toStraight.x) (toFinish.x > toStraight.x) + local dtu : if isStart (y > toFinish.y) (y < toFinish.y) + + if [not dontadjust] : begin + toFinish.x = toFinish.x + OXHOOK * [if ltr (-1) 1] * [if isStart (-1) 1] + if (atBottom && ltr && !isStart) : begin + toFinish.x = toFinish.x + TAILADJX * TANSLANT + toFinish.y = toFinish.y - TAILADJY * TANSLANT + + local w : Math.abs (toStraight.y - y) + local v : Math.abs (toFinish.y - y) + local u : Math.abs (toFinish.x - toStraight.x) + local mixr : determineMixR w v u sw + local mx ([mix toStraight.x toFinish.x mixr] + ([if (tight && tight.shift) tight.shift (1 - (tight || 0))] * [if atBottom 1 (-1)] * CORRECTION_OMIDX) * sw) + local keyKnot : g4.[if ltr "right" "left"].mid mx y [fallback kkaf : if tight [let [s : if ltr RIGHTWARD LEFTWARD] [heading {.x (s.x * [fallback tight.skew 1]) .y s.y}]] nothing] + + local faf toFinish.af + set toFinish.af : lambda [] : begin + local rad : Math.min w (mixr * u) + local skew0 : [clamp 0 w (w - v)] / rad + ([clamp 1 1.5 (mixr * u / w)] - 1) * 0.5 + local depth : v + skew0 * sw - sw + local shallowLimit (sw * 0.5) + local skew : clamp 0 (1 / 2) : skew0 + [clamp 0 shallowLimit (shallowLimit - depth)] / rad + if faf : faf.apply this arguments + this.heads-to { + .x (CONTRAST / [Math.sqrt : 1 + skew * skew] * [if dtu (-1) 1]) + .y (skew / [Math.sqrt : 1 + skew * skew] * [if ltr 1 (-1)]) + } + + local segBefore {} + local segAfter {} + foreach [j : range 1 nHookSegments] : begin + local fraction : j / nHookSegments + local fractionAfter : fraction * (1 - mixr) / mixr + local myfinal : superxy ((1 - mixr) / mixr) + segBefore.push : g4 [mix mx toStraight.x fraction] [mix y toStraight.y (1 - [superxy fraction])] unimportant + segAfter.push : g4 [mix mx toFinish.x fraction] [mix y toFinish.y ((1 - [superxy fractionAfter]) / (1 - myfinal))] unimportant + if (!tight && w < u * mixr) : set segAfter {} + if isStart + : then : return : list + segAfter.reverse + * keyKnot + * segBefore + : else : return : list + segBefore.reverse + * keyKnot + * segAfter + + define [hookstart] : params [y tight sw kkaf dontadjust] : return { + .type 'interpolate' + .af [lambda [before after] [HookShape after before true y tight sw kkaf dontadjust]] + } + define [hookend] : params [y tight sw kkaf dontadjust] : return { + .type 'interpolate' + .af [lambda [before after] [HookShape before after false y tight sw kkaf dontadjust]] + } + + define [WaveShape] : params [l r cy extendy tension sw] : glyph-construction + local cx : mix l r 0.5 + local wavex : (r - l) * tension + local endwavey : extendy * 0.97 + include : dispiro + widths.center sw + g4 l (cy - endwavey) + bezcontrols.absolute (l + wavex) (cy + extendy) (cx - wavex * 0.8) (cy + extendy) 8 important + g4 cx cy + bezcontrols.absolute (cx + wavex * 0.8) (cy - extendy) (r - wavex) (cy - extendy) 8 important + g4 r (cy + endwavey) + + define [CyrDescender x shift connex] : glyph-construction + local descenderOverflow : if SLAB SIDEJUT ((RIGHTSB - SB) * [fallback shift 0.1]) + include : VBarRight (x + descenderOverflow + 0.25 * STROKE) (HALFSTROKE - LONGJUT) STROKE + if (!SLAB && descenderOverflow > STROKE * 0.75 || connex) : include : HBarTop (x - HALFSTROKE * HVCONTRAST) (x + descenderOverflow) STROKE + + # Derived subfonts + define [refair g] : begin + foreach [j : range 0 g.contours.length] : begin + set g.contours.(j) : fairify g.contours.(j) globalTransform + return nothing + define [Fork gs ps] : begin + # BFS construct ShouldBuildList + local sbh {.} + local found true + local PENDING 1 + local CHECKED 2 + foreach [glyphid : items-of gs] : set sbh.(glyphid) PENDING + while found : begin + set found false + foreach [glyphid : items-of : Object.keys sbh] : if (sbh.(glyphid) === PENDING) : begin + set sbh.(glyphid) CHECKED + if dependencyProfile.(glyphid) : foreach [k : items-of dependencyProfile.(glyphid)] : if [not sbh.(k)] : begin + set sbh.(k) PENDING + set found true + + local shouldBuildList : Object.keys sbh :.filter ([x] => [not [not x]]) + #console.log shouldBuildList + local shouldBuildUnicodes : shouldBuildList.map ([x] => [if (glyphs.(x) && glyphs.(x).unicode) glyphs.(x).unicode.0 nothing]) + :.filter ([x] => [not [not x]]) + + local p : Object.create ps + try : begin + local forkFont : buildFont.call [TempFont] p shouldBuildList shouldBuildUnicodes + : ex + : begin + if ex.glyfMap : return ex.glyfMap + : else : throw ex + return forkFont.glyfMap + + define [Miniature] : params [glyphs crowd scale [slantAngle para.slantAngle] unfair [sbscale 0.5]] : begin + local forkedPara : Object.create para + forkedPara.stroke = [adviceBlackness crowd] / scale + forkedPara.ess = para.ess * forkedPara.stroke / para.stroke + forkedPara.dotsize = para.dotsize * forkedPara.stroke / para.stroke + forkedPara.periodsize = para.periodsize * forkedPara.stroke / para.stroke + forkedPara.sb = SB * sbscale + forkedPara.slantAngle = slantAngle + forkedPara.unfair = unfair + return : Fork glyphs forkedPara + + define [Thinner glyphs p] : begin + local forkedPara : Object.create para + forkedPara.width = WIDTH * p + forkedPara.accentx = ACCENTX * p + forkedPara.jut = JUT * p + forkedPara.longjut = LONGJUT * p + #forkedPara.hookx = HOOKX * p + return : Fork glyphs forkedPara + + define [Widen glyphs p psb] : begin + local forkedPara : Object.create para + forkedPara.width = WIDTH * p + forkedPara.sb = SB * [fallback psb p] + forkedPara.accentx = ACCENTX * p + forkedPara.jut = JUT * p + forkedPara.longjut = LONGJUT * p + forkedPara.hookx = HOOKX * p + forkedPara.smoothadjust = para.smoothadjust * p + return : Fork glyphs forkedPara + + # Composite transformations + define [FlipAround x y sx sy] : glyph-construction + apply-transform : Upright + apply-transform : Translate (-x) (-y) + apply-transform : Scale [fallback sx (-1)] [fallback sy sx (-1)] + apply-transform : Translate x y + apply-transform : Italify - local turnyleft : mix lefty righty turn - local cyleft : mix turnyleft righty tension - - local straightxleft : mix leftx rightx straight - local straightyleft : mix cyleft righty straight - - include : dispiro - widths.center - flat leftx lefty [heading [if (lefty < righty) UPWARD DOWNWARD]] - curl leftx turnyleft [heading [if (lefty < righty) UPWARD DOWNWARD]] - quadcontrols 0 ((cyleft - turnyleft) / (straightyleft - turnyleft)) 24 - flat straightxleft straightyleft - curl rightx righty - end [function : set this.cleanmore true] - - -define [xStrand _leftx lefty _rightx righty turn straight tension] : glyph-construction - local middlex : mix _leftx _rightx 0.5 - local middley : mix lefty righty 0.5 - - include : halfXStrand _leftx lefty middlex middley turn straight tension - include : halfXStrand _rightx righty middlex middley turn straight tension - -define [nShoulderKnots] : params [left right [fine SHOULDERFINE] [top XH] [bottom 0] [sma SMALLSMOOTHA] [smb SMALLSMOOTHB] [stroke STROKE]] : begin - local slope : shoulderMidSlope fine stroke - local middle : [mix (left - stroke * HVCONTRAST) right 0.5] + (slope - CORRECTION_OMIDX) * stroke - return : list - flat left (top - sma - 2) [widths fine 0] - curl left (top - sma) - arcvh - g4 middle (top - O) [widths.heading 0 stroke {.y (1) .x (slope)}] - archv - flat right (top - smb) - curl right bottom [heading DOWNWARD] - -define [nShoulder] : begin - local a arguments - glyph-construction - include : dispiro : nShoulderKnots.apply null a - - -define [mShoulderSpiro] : params [left right top bottom width fine] : glyph-construction - local fix : TANSLANT * STROKE * HVCONTRAST * width / STROKE - local sm : SMALLSMOOTH * 0.75 - include : spiro-outline - corner (right - width * HVCONTRAST) bottom - curl (right - width * HVCONTRAST) (top - sm + fix) - arcvh 8 'no-tiny' - g2 [mix left (right - width * HVCONTRAST) 0.5] (top - O - width) - archv 8 'no-tiny' - flat left (top - sm - fix) - corner left (top - sm - fix - 1) - corner (left - fine) (top - sm - 1) - curl (left - fine) (top - sm) - arcvh 8 'no-tiny' - g2 [mix (left - fine * HVCONTRAST) right 0.5] (top - O) - archv 8 'no-tiny' - flat right (top - sm) - corner right bottom - close - -define [HBar xleft xright y _fine] : glyph-construction - include : dispiro - widths.center [fallback _fine STROKE] - flat xleft y [heading RIGHTWARD] - curl xright y [heading RIGHTWARD] - -define [HBarTop xl xr y _fine] : HBar xl xr (y - [fallback _fine STROKE] * 0.5) _fine -define [HBarBottom xl xr y _fine] : HBar xl xr (y + [fallback _fine STROKE] * 0.5) _fine -define [HOverlayBar xleft xright y s] : dispiro - widths.center [fallback s OVERLAYSTROKE] - flat xleft y - curl xright y -define [VBar x ydown yup _fine] : glyph-construction - local fine : fallback _fine STROKE - include : dispiro - widths.center fine - flat x ydown [heading [if (ydown < yup) UPWARD DOWNWARD]] - curl x yup [heading [if (ydown < yup) UPWARD DOWNWARD]] - -define [VBarLeft x yd yu _fine] : VBar (x + [fallback _fine STROKE] * 0.5 * HVCONTRAST) yd yu _fine -define [VBarRight x yd yu _fine] : VBar (x - [fallback _fine STROKE] * 0.5 * HVCONTRAST) yd yu _fine - -define [VerticalHook x y extend depth fine strg] : glyph-construction - include : dispiro - widths.center [fallback fine STROKE] - flat x (y + [fallback strg 0]) [heading [if (depth > 0) DOWNWARD UPWARD]] - curl x (y - [if (depth > 0) 0.01 (-0.01)]) [heading [if (depth > 0) DOWNWARD UPWARD]] - arcvh - flat (x + extend - [if (extend > 0) 0.01 (-0.01)]) (y - depth) - curl (x + extend) (y - depth) - -define [LegShape] : params [[ztop nothing (xt <> top)] [zbot nothing (xs <> bottom)] xb [fine STROKE]] : glyph-construction - include : dispiro - widths.lhs fine - flat xt top [heading DOWNWARD] - curl xb (bottom + LONGJUT) - alsothruthem {{0.5 0.94}} - g4.left.end xs (bottom + fine) [heading LEFTWARD] - -define [LeftHook x y xextend] : glyph-construction - local fine : adviceBlackness 4.25 - include : dispiro - widths.lhs fine - flat [fallback xextend : x + 1] y - curl x y - archv 8 - g4.down.end (x - LeftHook.extension) (y - HOOKX) [heading DOWNWARD] -set LeftHook.extension [Math.max (WIDTH * 0.15) ([adviceBlackness 4.25] * 1.5)] - -define [HooktopLeftBar stroke bottom] : glyph-construction - include : dispiro - widths.lhs [fallback stroke STROKE] - g4 RIGHTSB (CAP - HOOK) - hookstart CAPO - flat SB (CAP - SMALLSMOOTHA) - curl SB [fallback bottom 0] [heading DOWNWARD] - -define [CurlyTail] : params [fine rinner xleft bottom right x2 y2 [adj 0.4] [adj2 0.4] [adj3 0]] : begin - local ltr : right > xleft - set right : right - fine * [if ltr 1 (-1)] - local mid : mix [mix xleft right 0.5] (right - rinner * [if ltr 1 (-1)]) adj - local midu : mix [mix xleft right 0.5] (right - rinner * [if ltr 1 (-1)]) adj2 - return : list - g4.[if ltr 'right' 'left'].mid (mid + CORRECTION_OMIDX * fine * adj3 * [if ltr 1 (-1)]) (bottom + fine + O) [widths [if ltr 0 fine] [if ltr fine 0]] - archv 2 - g4 right (bottom + fine + rinner - 0.1) - g4 right (bottom + fine + rinner + 0.1) - arcvh 2 - g4 mid (bottom + fine + rinner * 2 - O) - alsothruthem {{0.25 0.06} {0.52 0.25}} important - g4 x2 y2 - -define [HCurlyTail fine wide rinner left m1 _right x1 x2 y2] : glyph-construction - local right : _right - fine - local mid : right - rinner + O - include : dispiro - widths.rhs wide - flat left wide [heading RIGHTWARD] - curl m1 wide [heading RIGHTWARD] - archv 8 - g4 right (wide + rinner - O / 2) [widths.heading 0 fine {.x (-HVCONTRAST) .y ((wide - fine) / (wide + rinner * 2 - O))}] - arcvh 8 - g4.left.mid mid (wide + rinner * 2 - O) [heading LEFTWARD] - quadcontrols ((x1 - mid) / (x2 - mid)) 0 8 - g4 x2 y2 - -define [FlatSlashShape middlex middle fine kx ky] : glyph-construction - include : dispiro - flat (middlex - LONGJUT * [fallback kx 0.8]) (middle - LONGJUT * [fallback ky 0.4]) [widths fine fine] - curl (middlex + LONGJUT * [fallback kx 0.8]) (middle + LONGJUT * [fallback ky 0.4]) - -# Spiro shapes -define [determineMixR w v u sw] : begin - local r : piecewise - (w <= v) 0.5 - true : 1 / ([Math.pow (1 - [Math.pow (1 - v / w) SUPERNESS]) (1 / SUPERNESS)] + 1) - local idepth : w - sw - local iwidth : u * r - sw - if (iwidth > 0 && idepth > 0 && iwidth / idepth >= 2) : begin - local adjust : clamp 0.975 1 (1 - (iwidth / idepth - 2) * 0.0125) - #console.log iwidth idepth (iwidth / idepth) adjust - r = r * adjust - if (r < 0.5) : set r 0.5 - return r - -define nHookSegments 12 -define [HookShape toStraight toFinish isStart y tight s kkaf dontadjust] : begin - local atBottom : toStraight.y > y - local sw : fallback s STROKE - local ltr : if isStart (toFinish.x < toStraight.x) (toFinish.x > toStraight.x) - local dtu : if isStart (y > toFinish.y) (y < toFinish.y) - - if [not dontadjust] : begin - toFinish.x = toFinish.x + OXHOOK * [if ltr (-1) 1] * [if isStart (-1) 1] - if (atBottom && ltr && !isStart) : begin - toFinish.x = toFinish.x + TAILADJX * TANSLANT - toFinish.y = toFinish.y - TAILADJY * TANSLANT - - local w : Math.abs (toStraight.y - y) - local v : Math.abs (toFinish.y - y) - local u : Math.abs (toFinish.x - toStraight.x) - local mixr : determineMixR w v u sw - local mx ([mix toStraight.x toFinish.x mixr] + ([if (tight && tight.shift) tight.shift (1 - (tight || 0))] * [if atBottom 1 (-1)] * CORRECTION_OMIDX) * sw) - local keyKnot : g4.[if ltr "right" "left"].mid mx y [fallback kkaf : if tight [let [s : if ltr RIGHTWARD LEFTWARD] [heading {.x (s.x * [fallback tight.skew 1]) .y s.y}]] nothing] - - local faf toFinish.af - set toFinish.af : lambda [] : begin - local rad : Math.min w (mixr * u) - local skew0 : [clamp 0 w (w - v)] / rad + ([clamp 1 1.5 (mixr * u / w)] - 1) * 0.5 - local depth : v + skew0 * sw - sw - local shallowLimit (sw * 0.5) - local skew : clamp 0 (1 / 2) : skew0 + [clamp 0 shallowLimit (shallowLimit - depth)] / rad - if faf : faf.apply this arguments - this.heads-to { - .x (CONTRAST / [Math.sqrt : 1 + skew * skew] * [if dtu (-1) 1]) - .y (skew / [Math.sqrt : 1 + skew * skew] * [if ltr 1 (-1)]) - } - - local segBefore {} - local segAfter {} - foreach [j : range 1 nHookSegments] : begin - local fraction : j / nHookSegments - local fractionAfter : fraction * (1 - mixr) / mixr - local myfinal : superxy ((1 - mixr) / mixr) - segBefore.push : g4 [mix mx toStraight.x fraction] [mix y toStraight.y (1 - [superxy fraction])] unimportant - segAfter.push : g4 [mix mx toFinish.x fraction] [mix y toFinish.y ((1 - [superxy fractionAfter]) / (1 - myfinal))] unimportant - if (!tight && w < u * mixr) : set segAfter {} - if isStart - : then : return : list - segAfter.reverse - * keyKnot - * segBefore - : else : return : list - segBefore.reverse - * keyKnot - * segAfter - -define [hookstart] : params [y tight sw kkaf dontadjust] : return { - .type 'interpolate' - .af [lambda [before after] [HookShape after before true y tight sw kkaf dontadjust]] -} -define [hookend] : params [y tight sw kkaf dontadjust] : return { - .type 'interpolate' - .af [lambda [before after] [HookShape before after false y tight sw kkaf dontadjust]] -} - -define [WaveShape] : params [l r cy extendy tension sw] : glyph-construction - local cx : mix l r 0.5 - local wavex : (r - l) * tension - local endwavey : extendy * 0.97 - include : dispiro - widths.center sw - g4 l (cy - endwavey) - bezcontrols.absolute (l + wavex) (cy + extendy) (cx - wavex * 0.8) (cy + extendy) 8 important - g4 cx cy - bezcontrols.absolute (cx + wavex * 0.8) (cy - extendy) (r - wavex) (cy - extendy) 8 important - g4 r (cy + endwavey) - -define [CyrDescender x shift connex] : glyph-construction - local descenderOverflow : if SLAB SIDEJUT ((RIGHTSB - SB) * [fallback shift 0.1]) - include : VBarRight (x + descenderOverflow + 0.25 * STROKE) (HALFSTROKE - LONGJUT) STROKE - if (!SLAB && descenderOverflow > STROKE * 0.75 || connex) : include : HBarTop (x - HALFSTROKE * HVCONTRAST) (x + descenderOverflow) STROKE - -# Derived subfonts -define [refair g] : begin - foreach [j : range 0 g.contours.length] : begin - set g.contours.(j) : fairify g.contours.(j) globalTransform - return nothing -define [Fork gs ps] : begin - # BFS construct ShouldBuildList - local sbh {.} - local found true - local PENDING 1 - local CHECKED 2 - foreach [glyphid : items-of gs] : set sbh.(glyphid) PENDING - while found : begin - set found false - foreach [glyphid : items-of : Object.keys sbh] : if (sbh.(glyphid) === PENDING) : begin - set sbh.(glyphid) CHECKED - if dependencyProfile.(glyphid) : foreach [k : items-of dependencyProfile.(glyphid)] : if [not sbh.(k)] : begin - set sbh.(k) PENDING - set found true - - local shouldBuildList : Object.keys sbh :.filter ([x] => [not [not x]]) - #console.log shouldBuildList - local shouldBuildUnicodes : shouldBuildList.map ([x] => [if (glyphs.(x) && glyphs.(x).unicode) glyphs.(x).unicode.0 nothing]) - :.filter ([x] => [not [not x]]) - - local p : Object.create ps - try : begin - local forkFont : buildFont.call [TempFont] p shouldBuildList shouldBuildUnicodes - : ex - : begin - if ex.glyfMap : return ex.glyfMap - : else : throw ex - return forkFont.glyfMap - -define [Miniature] : params [glyphs crowd scale [slantAngle para.slantAngle] unfair [sbscale 0.5]] : begin - local forkedPara : Object.create para - forkedPara.stroke = [adviceBlackness crowd] / scale - forkedPara.ess = para.ess * forkedPara.stroke / para.stroke - forkedPara.dotsize = para.dotsize * forkedPara.stroke / para.stroke - forkedPara.periodsize = para.periodsize * forkedPara.stroke / para.stroke - forkedPara.sb = SB * sbscale - forkedPara.slantAngle = slantAngle - forkedPara.unfair = unfair - return : Fork glyphs forkedPara - -define [Thinner glyphs p] : begin - local forkedPara : Object.create para - forkedPara.width = WIDTH * p - forkedPara.accentx = ACCENTX * p - forkedPara.jut = JUT * p - forkedPara.longjut = LONGJUT * p - #forkedPara.hookx = HOOKX * p - return : Fork glyphs forkedPara - -define [Widen glyphs p psb] : begin - local forkedPara : Object.create para - forkedPara.width = WIDTH * p - forkedPara.sb = SB * [fallback psb p] - forkedPara.accentx = ACCENTX * p - forkedPara.jut = JUT * p - forkedPara.longjut = LONGJUT * p - forkedPara.hookx = HOOKX * p - forkedPara.smoothadjust = para.smoothadjust * p - return : Fork glyphs forkedPara - -# Composite transformations -define [FlipAround x y sx sy] : glyph-construction - apply-transform : Upright - apply-transform : Translate (-x) (-y) - apply-transform : Scale [fallback sx (-1)] [fallback sy sx (-1)] - apply-transform : Translate x y - apply-transform : Italify \ No newline at end of file + return [object select-variant italic-variant alias composite into-unicode turned dual vdual fwl fwr dwl dwr dwc Ring RingAt DotAt CircleRing CircleRingAt CircleDotAt OShape OBarLeftShape OBarRightShape LeftwardTopSerif LeftwardBottomSerif RightwardTopSerif RightwardBottomSerif CenterTopSerif CenterBottomSerif DownwardRightSerif UpwardRightSerif DownwardLeftSerif UpwardLeftSerif AIVSerifs AIHSerifs AINSerifs AICyrISerifs AIMSerifs halfXStrand xStrand nShoulderKnots nShoulder mShoulderSpiro HBar HBarTop HBarBottom HOverlayBar VBar VBarLeft VBarRight VerticalHook LegShape LeftHook HooktopLeftBar CurlyTail HCurlyTail FlatSlashShape determineMixR HookShape hookstart hookend WaveShape CyrDescender refair Fork Miniature Thinner Widen FlipAround] \ No newline at end of file diff --git a/glyphs/letters-unified-basic.ptl b/glyphs/letters-unified-basic.ptl index b3714a963..1d796722d 100644 --- a/glyphs/letters-unified-basic.ptl +++ b/glyphs/letters-unified-basic.ptl @@ -2,8 +2,24 @@ # UNIFIED LETTERFORMS : LATIN ORIGINALS ########################################################################################### -### I -symbol-block 'I' +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks + + ### I sketch # I.straight include markset.capital include : VBar MIDDLE 0 CAP @@ -31,8 +47,7 @@ symbol-block 'I' include : ISerifShape XH save 'smcpI' 0x26A -### dotless i, i and iota -define IotaShape : symbol-block 'i' + ### dotless i, i and iota # iota define [IotaShape top] : glyph-construction local middle MIDDLE @@ -137,8 +152,7 @@ define IotaShape : symbol-block 'i' turned nothing 0x1D09 'i' MIDDLE (XH / 2) markset.p * IotaShape -### J -symbol-block 'J' + ### J sketch # J.straight set-width WIDTH include markset.capital @@ -190,8 +204,7 @@ symbol-block 'J' alias 'cyrJe' 0x408 'J' alias 'grkJ' 0x37F 'J' -### dotless j and j -symbol-block 'j' + ### dotless j and j sketch # dotlessj.straight include markset.p local center : MIDDLE + JBALANCE + HALFSTROKE * HVCONTRAST @@ -246,8 +259,7 @@ symbol-block 'j' save 'jcurlytail' 0x29D -### L -symbol-block 'L' + ### L define [LShape top] : glyph-construction include : VBarLeft (SB * 1.5) 0 top include : HBarBottom (SB * 1.5 - O) (RIGHTSB - OX) 0 @@ -298,8 +310,7 @@ symbol-block 'L' include : LShape XH save 'smcpL' 0x29F -### l -symbol-block 'l' + ### l create-glyph 'l.straight' : glyph-construction include markset.b set currentGlyph.cmpPriority (-2) @@ -444,8 +455,7 @@ symbol-block 'l' straight.right.end (MIDDLE + HOOKX) (-HOOK) save 'looprevesh' 0x1AA -### V and v -define VShape : symbol-block 'V, v and nu' + ### V and v local cornerdist : HALFSTROKE * HVCONTRAST * [if SLAB 1.2 1] local vcurviness : if (SLAB && !para.isItalic) 0.15 0.3 define [VShape] : params [top [sw STROKE]] : glyph-construction @@ -528,8 +538,7 @@ define VShape : symbol-block 'V, v and nu' save 'nu' 0x3BD * VShape -### A -symbol-block 'A' + ### A sketch # A set-width WIDTH include markset.capital @@ -545,8 +554,7 @@ symbol-block 'A' save 'Alpha' 0x391 save 'cyrA' 0x410 turned nothing 0x2C6F 'A' MIDDLE (CAP / 2) -### a -symbol-block 'a' + ### a sketch # a.doublestorey set-width WIDTH include markset.e @@ -628,8 +636,7 @@ symbol-block 'a' turned 'turna' 0x250 'a.doublestorey' MIDDLE (XH / 2) turned nothing 0x252 'scripta' MIDDLE (XH / 2) -### W and w -symbol-block 'W' + ### W and w define [WShape top] : glyph-construction local wheight (top * 0.6) @@ -724,8 +731,7 @@ symbol-block 'W' include : WShape (CAP / 2) save 'ww' 0x2AC -### X and x -symbol-block 'X' + ### X and x sketch # X set-width WIDTH include markset.capital @@ -759,8 +765,7 @@ symbol-block 'X' composite 'cyrHadescender' glyphs.cyrHa [CyrDescender RIGHTSB] [into-unicode 0x4B2] composite 'cyrhadescender' glyphs.cyrha [CyrDescender RIGHTSB] [into-unicode 0x4B3] -### Y -symbol-block 'Y' + ### Y define [YShape top bot] : glyph-construction local cross : mix [fallback bot 0] top 0.4 include : halfXStrand SB top MIDDLE cross 0.1 0.4 0.28 @@ -806,8 +811,7 @@ symbol-block 'Y' include : YShape XH save 'smcpY' 0x28F -### y -symbol-block 'y' + ### y local px1 0.84 local py1 : linreg 18 0.8 126 0.76 STROKE local px2 0.95 @@ -944,8 +948,7 @@ symbol-block 'y' include : FlatSlashShape ([tp [Upright] glyphs.l.anchors.above].x) [mix 0 CAP 0.7] (OVERLAYSTROKE / 2) save 'lambdaslash' 0x19B -### K and k -symbol-block 'K' + ### K and k define [KShape top] : glyph-construction local turn (top * 0.99) @@ -1035,8 +1038,7 @@ symbol-block 'K' turned nothing 0x29E 'k' MIDDLE (XH / 2) markset.p -### B -symbol-block 'B' + ### B define [BShape top] : glyph-construction local bowl : top * 0.52 + HALFSTROKE local barleft SB @@ -1155,8 +1157,7 @@ symbol-block 'B' curl (SB + HALFSTROKE) 0 [heading LEFTWARD] save 'beta' 0x3B2 -### b -symbol-block 'b' + ### b sketch # b set-width WIDTH include markset.b @@ -1213,8 +1214,7 @@ symbol-block 'b' line-to (SB - O) (CAP - s * 2) reverse-last save 'zhuangtonesix' 0x185 -### D -symbol-block 'D' + ### D sketch # D set-width WIDTH include markset.capital @@ -1256,8 +1256,7 @@ symbol-block 'D' include : LeftHook SB CAP save 'Dhookleft' 0x18A -### d -symbol-block 'd' + ### d sketch # d set-width WIDTH include markset.b @@ -1325,8 +1324,7 @@ symbol-block 'd' include : DownwardLeftSerif [mix RIGHTSB SB 0.9] CAP VJUT save 'latinde' 0x18C -### P -define {PShape} : symbol-block 'P' + ### P define [PShape top _mul bp] : glyph-construction local mul : fallback _mul 1.25 local bowlTop (top * 1) @@ -1366,8 +1364,7 @@ define {PShape} : symbol-block 'P' save 'Phookleft' 0x1A4 list PShape -### p -symbol-block 'p' + ### p sketch # p set-width WIDTH include markset.p @@ -1398,8 +1395,7 @@ symbol-block 'p' include : VBar (SB + HALFSTROKE * HVCONTRAST + O) DESCENDER SMALLSMOOTHB save 'rho' 0x3C1 -### R and CyrYa -symbol-block 'R and CyrYa' + ### R and CyrYa define [RShape top] : glyph-construction local m : if SLAB (0.5 + HALFSTROKE / CAP) PBARPOS include : PShape top 1 m @@ -1486,8 +1482,7 @@ symbol-block 'R and CyrYa' save 'cyrya' 0x44F turned 'invsmcpR' 0x281 'cyrya' MIDDLE (XH / 2) -### r -symbol-block 'r' + ### r local rbar : SB + RBALANCE + STROKE * HVCONTRAST local [rBottomSerif y] : tagged 'serifLB' : CenterBottomSerif (rbar - HALFSTROKE * HVCONTRAST + RBALANCE * 0.35) y (JUT + RBALANCE * 0.65) local [rTopSerif y] : tagged 'serifLT' : LeftwardTopSerif (rbar - STROKE * HVCONTRAST) y (SIDEJUT + RBALANCE * 0.3) @@ -1569,8 +1564,7 @@ symbol-block 'r' save 'rflap' 0x27E turned nothing 0x2C79 'rrtail' MIDDLE (XH / 2) -### C and c, also cyre -define {CShape} : symbol-block 'C' + ### C and c, also cyre define [CShape top bot] : glyph-construction include : dispiro widths.lhs @@ -1730,8 +1724,7 @@ define {CShape} : symbol-block 'C' save 'sigmafinal' 0x3C2 list CShape -### G -symbol-block 'G' + ### G define [GShape top sma smb] : glyph-construction local ybar : top * 0.52 + STROKE * 0.25 include : dispiro @@ -1782,8 +1775,7 @@ symbol-block 'G' include : HOverlayBar [mix SB RIGHTSB 0.5] [mix RIGHTSB WIDTH 0.7] [mix 0 CAPMIDDLE 0.55] save 'Gbar' 0x1E4 -### g -symbol-block 'g' + ### g sketch # g.doublestorey include markset.p local obot : XH * GBARPOS - O - HALFSTROKE @@ -1879,8 +1871,7 @@ symbol-block 'g' include : HBar [mix 0 SB 0.3] [mix WIDTH RIGHTSB 0.3] glyphs.g.anchors.overlay.y [Math.min [adviceBlackness 5] (0.5 / 3 * (CAP - STROKE * 4))] save 'gbar' 0x1E5 -### O and o -symbol-block 'O' + ### O and o sketch include markset.capital @@ -1966,8 +1957,7 @@ symbol-block 'O' curl (RIGHTSB - OX) (XH / 2) [heading UPWARD] save 'olowerhalf' 0x1D17 -### Q -symbol-block 'Q' + ### Q sketch # Q set-width WIDTH @@ -1986,8 +1976,7 @@ symbol-block 'Q' save 'Q' 'Q' save 'cyrQa' 0x51A -### q -symbol-block 'q' + ### q sketch # q set-width WIDTH include markset.p @@ -2039,8 +2028,7 @@ symbol-block 'q' save 'qhooktop' 0x2A0 -### N -define {NShape} : symbol-block 'N' + ### N define [NShape top left right coward diagcoward xn] : glyph-construction local topstroke : adviceBlackness [fallback diagcoward 4] local stroke : adviceBlackness [fallback coward 1] @@ -2080,8 +2068,7 @@ define {NShape} : symbol-block 'N' save 'Nltail' 0x19D list NShape -### n -symbol-block 'n' + ### n sketch # n set-width WIDTH include markset.e @@ -2224,8 +2211,7 @@ symbol-block 'n' tag-contour 'serifLB' save 'latineta' 0x19E -### U -define {UShape} : symbol-block 'U' + ### U define [UShape top bottom stroke oper] : glyph-construction include : dispiro widths.lhs @@ -2252,8 +2238,7 @@ define {UShape} : symbol-block 'U' save 'smcpU' 0x1D1C list UShape -### u -symbol-block 'u' + ### u sketch # u set-width WIDTH include markset.e @@ -2306,8 +2291,7 @@ symbol-block 'u' include : LatinUpsilon2Shape XH SMALLSMOOTHA SMALLSMOOTHB save 'latinupsilon2' 0x28B -### M -symbol-block 'M' + ### M define [MShape top] : glyph-construction local topstroke : adviceBlackness 5 local halftopstroke : topstroke / 2 @@ -2341,8 +2325,7 @@ symbol-block 'M' include : MShape XH save 'cyrem' 0x43C -### m -symbol-block 'm' + ### m define [SmallMShape top bot] : glyph-construction local m1 : mix (SB + O) (MIDDLE + MVERTSTROKE / 2 * HVCONTRAST) 0.5 local m2 : mix (RIGHTSB - O) (MIDDLE - MVERTSTROKE / 2 * HVCONTRAST) 0.5 @@ -2399,8 +2382,7 @@ symbol-block 'm' include : VBarRight (RIGHTSB - O) DESCENDER 0 MVERTSTROKE save 'turnmleg' 0x270 -### H -symbol-block 'H' + ### H define [HShape top] : glyph-construction include : VBarLeft SB 0 top include : VBarRight RIGHTSB 0 top @@ -2429,8 +2411,7 @@ symbol-block 'H' include : HOverlayBar [mix SB 0 0.7] [mix RIGHTSB WIDTH 0.7] [mix CAPMIDDLE CAP 0.45] save 'Hbar' 0x126 -### h -symbol-block 'h' + ### h sketch # h set-width WIDTH include markset.b @@ -2533,8 +2514,7 @@ symbol-block 'h' save 'hbar' 0x127 save 'cyrtshe' 0x45B -### F -define {FShape} : symbol-block 'F' + ### F define [FShape top y] : glyph-construction include : VBarLeft (SB * 1.5) 0 [fallback top CAP] include : HBarTop (SB * 1.5 - O) RIGHTSB [fallback top CAP] @@ -2560,8 +2540,7 @@ define {FShape} : symbol-block 'F' save 'Fltail' 0x191 list FShape -### long s, and f -define {LongSShape} : symbol-block 'f' + ### long s, and f define fovershoot : fallback para.fovershoot (O * 6) sketch # longs.straight @@ -2700,7 +2679,6 @@ define {LongSShape} : symbol-block 'f' italic-variant 'f' 'f' turned 'turnf' 0x25F 'f' MIDDLE (XH / 2) markset.p - symbol-block 'compatibility ligatures' local shift (-(WIDTH * 0.055 + SB * 0.5)) local barr RIGHTSB local hbarleft (SB + shift + STROKE * [if para.slantAngle 0.5 0.25]) @@ -2749,8 +2727,7 @@ define {LongSShape} : symbol-block 'f' * {LongSShape} -### E -symbol-block 'E' + ### E define [EShape top] : glyph-construction include : FShape top include : HBarBottom (SB * 1.5 - O) RIGHTSB 0 @@ -2775,8 +2752,7 @@ symbol-block 'E' include : FlipAround MIDDLE (XH / 2) save 'smcpturnE' 0x2C7B -### e -define {SmallEShape} : symbol-block 'e' + ### e define [SmallEShape top stroke barpos curly] : glyph-construction local barbottom (top * [fallback barpos EBARPOS] - HALFSTROKE) local hookx (RIGHTSB - OXHOOK + TAILADJX * TANSLANT) @@ -2838,8 +2814,7 @@ define {SmallEShape} : symbol-block 'e' list SmallEShape -### T -symbol-block 'T' + ### T define [TShape top] : glyph-construction include : VBar MIDDLE 0 top local l : SB + OXE @@ -2897,8 +2872,7 @@ symbol-block 'T' include : VBar MIDDLE 0 XH save 'tau' 0x3C4 -### t -symbol-block 't' + ### t define tcenter : MIDDLE - TBALANCE - STROKE * 0.5 * HVCONTRAST define [SmallTShape top bot] : glyph-construction local hookx : tcenter + (WIDTH - SB * 2) * 0.8 + STROKE * 0.25 * HVCONTRAST @@ -2969,8 +2943,7 @@ symbol-block 't' include : HOverlayBar ([mix MIDDLE SB 0.7] - TBALANCE * 0.5 - STROKE * 0.25 * HVCONTRAST) ([mix MIDDLE RIGHTSB 0.7] - TBALANCE * 0.5 - STROKE * 0.25 * HVCONTRAST) [mix 0 XH 0.6] save 'tbar' 0x167 -### S and s -symbol-block 'S' + ### S and s sketch # S set-width WIDTH include markset.capital @@ -3068,8 +3041,7 @@ symbol-block 'S' curl RIGHTSB DESCENDER save 'sswash' 0x23F -### Z and z -symbol-block 'Z' + ### Z and z sketch # Z set-width WIDTH include markset.capital @@ -3219,3 +3191,5 @@ symbol-block 'Z' eject-contour 'strokeBottom' eject-contour 'serifRB' save 'zcurlytail' 0x291 + + return [object ISerifShape IotaShape LShape Belt VShape VHooktopShape WShape WHooktopShape YShape yBaseKnots SmallYShape KShape BShape ItalicCyrveShape PShape RShape CyrYaShape CShape GShape NShape UShape LatinUpsilon2Shape MShape SmallMShape HShape FShape fovershoot LongSShape EShape SmallEShape RevSmallEShape TShape SmallTShape] diff --git a/glyphs/letters-unified-extended.ptl b/glyphs/letters-unified-extended.ptl index 5901fea68..94823e5dc 100644 --- a/glyphs/letters-unified-extended.ptl +++ b/glyphs/letters-unified-extended.ptl @@ -1,33 +1,49 @@ -########################################################################################### -# UNIFIED LETTERFORMS : GREEK ORIGINALS -########################################################################################### -symbol-block 'alpha' : sketch - include markset.e - - local middle : mix SB RIGHTSB 0.42 - local fine : adviceBlackness 3.25 - local k1 0.25 - local k2 0.5 - local k3 0.35 - include : dispiro - widths.rhs fine - g4 (RIGHTSB - OX * 1.75) XH [heading DOWNWARD] - bezcontrols k1 k2 k3 1 6 - g4.left.mid (middle + CORRECTION_OMIDS) O [widths 0 STROKE] - archv - flat.ai (SB + OX * 2) SMALLSMOOTHB - curl.ai (SB + OX * 2) (XH - SMALLSMOOTHA) - arcvh - g4.right.mid (middle - CORRECTION_OMIDS) XO [widths 0 STROKE] - bezcontrols (1 - k3) 0 (1 - k1) (1 - k2) 6 - g4 (RIGHTSB - OX * 2) 0 [widths.heading 0 fine DOWNWARD] - - set-anchor 'overlay' BASE (middle - OX) (XH * OVERLAYPOS) - - save 'alpha' 0x3B1 - save 'latinalpha' 0xAB64 +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks letterBasic + + ########################################################################################### + # UNIFIED LETTERFORMS : GREEK ORIGINALS + ########################################################################################### + sketch + include markset.e + + local middle : mix SB RIGHTSB 0.42 + local fine : adviceBlackness 3.25 + local k1 0.25 + local k2 0.5 + local k3 0.35 + include : dispiro + widths.rhs fine + g4 (RIGHTSB - OX * 1.75) XH [heading DOWNWARD] + bezcontrols k1 k2 k3 1 6 + g4.left.mid (middle + CORRECTION_OMIDS) O [widths 0 STROKE] + archv + flat.ai (SB + OX * 2) SMALLSMOOTHB + curl.ai (SB + OX * 2) (XH - SMALLSMOOTHA) + arcvh + g4.right.mid (middle - CORRECTION_OMIDS) XO [widths 0 STROKE] + bezcontrols (1 - k3) 0 (1 - k1) (1 - k2) 6 + g4 (RIGHTSB - OX * 2) 0 [widths.heading 0 fine DOWNWARD] + + set-anchor 'overlay' BASE (middle - OX) (XH * OVERLAYPOS) + + save 'alpha' 0x3B1 + save 'latinalpha' 0xAB64 -symbol-block 'Gamma' define [GammaShape top] : glyph-construction include : VBarLeft (SB * 1.5) 0 top include : HBarTop (SB * 1.5 - O) (RIGHTSB - OX) top @@ -91,7 +107,7 @@ symbol-block 'Gamma' italic-variant 'cyrghayn' 0x493 -symbol-block 'gamma' + sketch # gamma include markset.p @@ -110,7 +126,7 @@ symbol-block 'gamma' g4 xmid 0 [widths.rhs : STROKE * 0.9] save 'gamma' 0x3B3 -define {LambdaShape} : symbol-block 'Lambda' + define [LambdaShape sw] : glyph-construction local TURN (CAP * 0.1) local curviness 0.2 @@ -143,9 +159,7 @@ define {LambdaShape} : symbol-block 'Lambda' save 'Lambda' 0x39B save 'latinLambda' 0x245 - list LambdaShape -symbol-block 'Delta and cyrbe' sketch # Delta include glyphs.Lambda AS_BASE include : HBar (SB + HALFSTROKE) (RIGHTSB - HALFSTROKE) HALFSTROKE @@ -209,7 +223,6 @@ symbol-block 'Delta and cyrbe' g4 (RIGHTSB - HALFSTROKE * HVCONTRAST) CAP save 'cyrbe' 0x431 -symbol-block 'epsilon and cyrze' define [SmallEpsilonShape top hook] : glyph-construction local midx : mix SB RIGHTSB 0.65 local midy : top * OVERLAYPOS @@ -286,7 +299,7 @@ symbol-block 'epsilon and cyrze' save 'revlatinepsilon' 0x25C turned 'closeepsilon' 0x29A 'closeturnepsilon' MIDDLE (XH / 2) -symbol-block 'Theta' + sketch # Theta include markset.capital include glyphs.O AS_BASE @@ -299,7 +312,7 @@ symbol-block 'Theta' include : HBar (SB + HALFSTROKE) (RIGHTSB - HALFSTROKE) CAPMIDDLE save 'theta' 0x3B8 -symbol-block 'zeta and xi' + sketch # zeta include markset.if include : HBar SB (RIGHTSB + O) (CAP - HALFSTROKE) @@ -345,33 +358,33 @@ symbol-block 'zeta and xi' curl [Math.min (RIGHTSB - (STROKE - [mix DESCENDER STROKE 0.5]) * 1.1 - 1) [mix SB RIGHTSB 0.5]] DESCENDER [heading LEFTWARD] save 'xi' 0x3BE -symbol-block 'mu' : sketch - include markset.p - include glyphs.u - include : dispiro - widths.rhs - flat SB DESCENDER [heading UPWARD] - curl SB (DESCENDER / 2) [heading UPWARD] - straight.up.end SB SMALLSMOOTHB [widths.heading 0 [adviceBlackness 4] UPWARD] - if SLAB : begin - include : LeftwardTopSerif SB XH SIDEJUT - - save 'mu' 0x3BC + sketch + include markset.p + include glyphs.u + include : dispiro + widths.rhs + flat SB DESCENDER [heading UPWARD] + curl SB (DESCENDER / 2) [heading UPWARD] + straight.up.end SB SMALLSMOOTHB [widths.heading 0 [adviceBlackness 4] UPWARD] + if SLAB : begin + include : LeftwardTopSerif SB XH SIDEJUT + + save 'mu' 0x3BC + + sketch + include markset.capital + include : HBar [mix SB RIGHTSB 0.125] [mix RIGHTSB SB 0.125] [mix 0 CAP 0.54] + include : HBar (SB + OX) (RIGHTSB - OX) (CAP - HALFSTROKE) + include : HBar (SB + OX) (RIGHTSB - OX) (0 + HALFSTROKE) + if SLAB : begin + include : DownwardLeftSerif (SB + OX) CAP VJUT + include : DownwardRightSerif (RIGHTSB - OX) CAP VJUT + include : UpwardLeftSerif (SB + OX) 0 VJUT + include : UpwardRightSerif (RIGHTSB - OX) 0 VJUT + + save 'Xi' 0x39E -symbol-block 'Xi' : sketch - include markset.capital - include : HBar [mix SB RIGHTSB 0.125] [mix RIGHTSB SB 0.125] [mix 0 CAP 0.54] - include : HBar (SB + OX) (RIGHTSB - OX) (CAP - HALFSTROKE) - include : HBar (SB + OX) (RIGHTSB - OX) (0 + HALFSTROKE) - if SLAB : begin - include : DownwardLeftSerif (SB + OX) CAP VJUT - include : DownwardRightSerif (RIGHTSB - OX) CAP VJUT - include : UpwardLeftSerif (SB + OX) 0 VJUT - include : UpwardRightSerif (RIGHTSB - OX) 0 VJUT - - save 'Xi' 0x39E -define {PiShape} : symbol-block 'Pi' define [PiShape] : params [top bottom [shrinkrate 0.05] _fine noserif] : glyph-construction local fine : fallback _fine STROKE local shrink : if (!noserif && SLAB) 0 (shrinkrate * (RIGHTSB - SB)) @@ -410,7 +423,7 @@ define {PiShape} : symbol-block 'Pi' list PiShape -define {SigmaShape} : symbol-block 'Sigma' + define [SigmaShape top bottom _fine] : glyph-construction local cor 1.15 local fine : fallback _fine STROKE @@ -441,7 +454,7 @@ define {SigmaShape} : symbol-block 'Sigma' list SigmaShape -symbol-block 'Phi, phi and varphi' + sketch # Phi include markset.capital local y1 : CAP * [if SLAB 0.175 0.125] @@ -506,7 +519,7 @@ symbol-block 'Phi, phi and varphi' save 'cyref' 0x444 save 'latinphi' 0x278 -symbol-block 'Psi' + sketch # Psi include markset.capital local y : CAP * 0.2 @@ -573,7 +586,7 @@ symbol-block 'Psi' include : tagged 'serifRT' : RightwardTopSerif RIGHTSB XH SIDEJUT save 'psi' 0x3C8 -symbol-block 'Omega' + define [OmegaShape top extend sma smb] : glyph-construction local fine : STROKE * CTHIN local x1 [mix SB RIGHTSB 0.4] @@ -612,7 +625,7 @@ symbol-block 'Omega' include : FlipAround MIDDLE (XH / 2) save 'latinupsilon1' 0x28A -symbol-block 'omega' + sketch # omega include markset.e local fine : adviceBlackness 3.25 @@ -683,11 +696,11 @@ symbol-block 'omega' end [function : set this.angles 4] save 'closeomega' 0x277 -########################################################################################### -# UNIFIED LETTERFORMS : CYRILLIC ORIGINALS -########################################################################################### + ########################################################################################### + # UNIFIED LETTERFORMS : CYRILLIC ORIGINALS + ########################################################################################### + -define {CyrYeriShape RevCyrYeriShape} : symbol-block 'CyrYeri-related' define [CyrYeriShape top _left _right _fine _jut] : glyph-construction local fine : fallback _fine STROKE local left : fallback _left SB @@ -821,7 +834,7 @@ define {CyrYeriShape RevCyrYeriShape} : symbol-block 'CyrYeri-related' save 'cyryery' 0x44B list CyrYeriShape RevCyrYeriShape -symbol-block 'CyrI' + define [CyrIShape top] : glyph-construction local topstroke : adviceBlackness 4 local halftopstroke : topstroke / 2 @@ -859,7 +872,7 @@ symbol-block 'CyrI' italic-variant 'cyri' 0x438 -symbol-block 'CyrTse' + define [CyrTseShape top] : glyph-construction include : VBarLeft SB 0 top include : HBarBottom SB RIGHTSB 0 @@ -918,7 +931,7 @@ symbol-block 'CyrTse' italic-variant 'cyrdzhe' 0x45F -symbol-block 'CyrDe' + define [CyrDeShape top] : glyph-construction local descenderOverflow : if SLAB SIDEJUT ((RIGHTSB - SB) * 0.075) local cutleft SB @@ -973,7 +986,7 @@ symbol-block 'CyrDe' italic-variant 'cyrde' 0x434 -symbol-block 'CyrEl' + define [CyrElShape top] : glyph-construction local cutleft : mix SB RIGHTSB 0.125 local cutleft2 : mix SB RIGHTSB 0.075 @@ -1000,7 +1013,7 @@ symbol-block 'CyrEl' include : CyrElShape XH save 'cyrel' 0x43B -symbol-block 'CyrZhe' + define [CyrZheShape top midtop] : glyph-construction local fine : adviceBlackness 3.3 local midx : mix SB MIDDLE 0.3 @@ -1101,7 +1114,7 @@ symbol-block 'CyrZhe' include : CyrSmallYusShape XH save 'cyrsmallyus' 0x467 -symbol-block 'CyrSha' + define [CyrShaShape top] : glyph-construction include : HBarBottom SB RIGHTSB 0 include : VBarLeft SB 0 top MVERTSTROKE @@ -1159,7 +1172,7 @@ symbol-block 'CyrSha' italic-variant 'cyrte' 0x442 -symbol-block 'CyrChe' + define [CyrCheShape top _barp] : glyph-construction local bar : top * [fallback _barp 0.5] include : VBarRight RIGHTSB 0 top @@ -1201,7 +1214,7 @@ symbol-block 'CyrChe' include : VBar MIDDLE (yc + LONGJUT * 0.8) (yc - LONGJUT * 0.8) OVERLAYSTROKE save 'cyrchevbar' 0x4B9 -symbol-block 'CyrYu' + define [CyrYuShape top xtop sma smb] : glyph-construction local xm : mix (SB + O + MVERTSTROKE * HVCONTRAST) (RIGHTSB - OX) 0.175 include : VBarLeft (SB + O) 0 xtop MVERTSTROKE @@ -1227,7 +1240,7 @@ symbol-block 'CyrYu' include : CyrYuShape XH CAP SMALLSMOOTHA SMALLSMOOTHB save 'cyryu.BGR' -symbol-block 'CyrLje and CyrNje' + define [CyrLjeShape top] : glyph-construction local xlefttop : mix SB RIGHTSB 0.075 local jut : JUT * 0.72 @@ -1273,7 +1286,7 @@ symbol-block 'CyrLje and CyrNje' include : CyrNjeShape XH save 'cyrnje' 0x45A -symbol-block 'CyrTshe and CyrDje' + sketch # cyrTshe include markset.capital @@ -1327,10 +1340,10 @@ symbol-block 'CyrTshe and CyrDje' include : VerticalHook (RIGHTSB - HALFSTROKE * HVCONTRAST) 0 (-HOOK * 1.2) HOOK save 'cyrdje' 0x452 -########################################################################################### -# UNIFIED LETTERFORMS : OTHER LATIN -########################################################################################### -symbol-block 'eszet' + ########################################################################################### + # UNIFIED LETTERFORMS : OTHER LATIN + ########################################################################################### + sketch # eszet set-width WIDTH include markset.if @@ -1382,7 +1395,7 @@ symbol-block 'eszet' g4 (RIGHTSB - ymiddle / 2 - STROKE * 0.75) (ymiddle + STROKE) [widths STROKE 0] save 'Eszet' 0x1E9E -symbol-block 'Digraphs' + sketch # AE set-width WIDTH include markset.capital @@ -1593,7 +1606,7 @@ symbol-block 'Digraphs' apply-transform : Translate (RIGHTSB - SB * 0.5 - MIDDLE - JBALANCE - HALFSTROKE * HVCONTRAST) 0 save 'ij' 0x133 -symbol-block 'Ezh' + define [EzhShape top bot pleft hookless] : glyph-construction local cor : 1.2 * HVCONTRAST local yMidBar : mix bot top 0.6 @@ -1712,7 +1725,7 @@ symbol-block 'Ezh' CurlyTail fine rinner m1 DESCENDER SB x2 y2 save 'ezhcurlytail' 0x293 -symbol-block 'Glottal stop' + sketch # glottalstop include markset.b include : dispiro @@ -1818,25 +1831,26 @@ symbol-block 'Glottal stop' include : HOverlayBar (MIDDLE - LONGJUT * 0.6) (MIDDLE + LONGJUT * 0.6) (CAP * 0.25) save 'revglottalstopbar' 0x2A2 -symbol-block 'eth' : sketch - include markset.b - - include : OShape (CAP * 0.6) 0 SB RIGHTSB - local ymiddlea : (CAP * 0.6 + SMALLSMOOTHA - SMALLSMOOTHB) / 2 - include : dispiro - widths.lhs - g4.up.start (RIGHTSB - OX) ymiddlea - quadcontrols 0 0.8 - g4 (SB + STROKE * 1.1) CAP - - include : dispiro - widths.center OVERLAYSTROKE - flat [mix SB RIGHTSB 0.1] [mix XH CAP (-0.1)] - curl [mix SB RIGHTSB 0.95] [mix XH CAP 0.3] - - save 'eth' 0xF0 -symbol-block 'Thorn' + sketch + include markset.b + + include : OShape (CAP * 0.6) 0 SB RIGHTSB + local ymiddlea : (CAP * 0.6 + SMALLSMOOTHA - SMALLSMOOTHB) / 2 + include : dispiro + widths.lhs + g4.up.start (RIGHTSB - OX) ymiddlea + quadcontrols 0 0.8 + g4 (SB + STROKE * 1.1) CAP + + include : dispiro + widths.center OVERLAYSTROKE + flat [mix SB RIGHTSB 0.1] [mix XH CAP (-0.1)] + curl [mix SB RIGHTSB 0.95] [mix XH CAP 0.3] + + save 'eth' 0xF0 + + sketch # Thorn set-width WIDTH include markset.capital @@ -1878,7 +1892,7 @@ symbol-block 'Thorn' save 'thorn' 0xFE save 'sho' 0x3F8 -symbol-block 'Hwair' + sketch # Hwair include : VBarLeft (SB + O) 0 CAP MVERTSTROKE include : HBar SB MIDDLE (CAP / 2) @@ -1918,7 +1932,7 @@ symbol-block 'Hwair' tag-contour 'serifLB' save 'hwair' 0x195 -symbol-block 'Gha' + sketch # Gha include markset.capital local abarRight : MIDDLE + MVERTSTROKE / 2 * HVCONTRAST @@ -1947,7 +1961,7 @@ symbol-block 'Gha' g4 (RIGHTSB - O * 2 - MVERTSTROKE * HVCONTRAST) XH [widths 0 MVERTSTROKE] save 'gha' 0x1A3 -symbol-block 'Wynn' + define [WynnShape bot top] : glyph-construction include : VBarLeft SB bot top include : dispiro @@ -1971,7 +1985,7 @@ symbol-block 'Wynn' include : WynnShape DESCENDER XH save 'wynn' 0x1BF -symbol-block 'Yogh' + define [YoghShape top bot] : glyph-construction include : dispiro widths.rhs @@ -1998,7 +2012,7 @@ symbol-block 'Yogh' include : YoghShape XH DESCENDER save 'yogh' 0x21D -symbol-block 'RamsHorn' + define [RamsHornShape bottom top] : glyph-construction local hf : [adviceBlackness 4] / 2 local d : hf * 2 + WIDTH * 0.05 @@ -2032,7 +2046,7 @@ symbol-block 'RamsHorn' include : RamsHornShape 0 XH save 'ramshorn' 0x264 -symbol-block 'Rhotic Tail and other phonetic letters' + define [ErTail left w dohook] : glyph-construction local right WIDTH local mid : mix left right 0.5 @@ -2077,4 +2091,6 @@ symbol-block 'Rhotic Tail and other phonetic letters' apply-transform : Translate 0 (CAP / 2) apply-transform : Italify include g - save 'bidentalpercussive' 0x2AD \ No newline at end of file + save 'bidentalpercussive' 0x2AD + + return [object LambdaShape SigmaShape PiShape] \ No newline at end of file diff --git a/glyphs/numbers.ptl b/glyphs/numbers.ptl index 0af4f2098..19bd436f2 100644 --- a/glyphs/numbers.ptl +++ b/glyphs/numbers.ptl @@ -1,5 +1,22 @@ +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + + ###### NUMBERS -symbol-block "Numbers" +export : define [apply] : begin + glyph-module-entry commonShapes + sketch # zero.unslashed include markset.capital include : OShape CAP 0 SB RIGHTSB diff --git a/glyphs/overmarks.ptl b/glyphs/overmarks.ptl index a692c89ca..a3ae43f5c 100644 --- a/glyphs/overmarks.ptl +++ b/glyphs/overmarks.ptl @@ -1,29 +1,43 @@ +$$include '../meta/macros.ptl' -### Combining marks +import 'unorm' as unorm -local markExtend (ACCENTX * 0.5) -local markHalfStroke : 0.5 * [adviceBlackness 3.375] -local markStress : markHalfStroke * 1.1 -local markFine : markHalfStroke * 0.9 +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify -local markMiddle (-MIDDLE) -local markDotsRadius : DOTRADIUS * [Math.min 1 (markStress / HALFSTROKE)] +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' -local aboveMarkTop (XH + ACCENT * 1.38) -local aboveMarkBot (XH + ACCENT * 0.35) -local aboveMarkMid [mix aboveMarkBot aboveMarkTop 0.5] +export : define [apply] : begin + glyph-module-entry commonShapes -local belowMarkBot (0 - ACCENT * 1.38) -local belowMarkTop (0 - ACCENT * 0.35) + ### Combining marks + local markExtend (ACCENTX * 0.5) + local markHalfStroke : 0.5 * [adviceBlackness 3.375] + local markStress : markHalfStroke * 1.1 + local markFine : markHalfStroke * 0.9 -local commaOvershoot : O * [linreg 16 0 90 (-1) (markHalfStroke * 2)] -local commaOvershoot2 : O * [linreg 16 1 90 (-1) (markHalfStroke * 2)] -local commaAboveRadius : 0.85 * DOTRADIUS * markHalfStroke / HALFSTROKE + local markMiddle (-MIDDLE) + local markDotsRadius : DOTRADIUS * [Math.min 1 (markStress / HALFSTROKE)] -local asciiMarkZoom : (RIGHTSB - SB) / (markExtend * 3) + local aboveMarkTop (XH + ACCENT * 1.38) + local aboveMarkBot (XH + ACCENT * 0.35) + local aboveMarkMid [mix aboveMarkBot aboveMarkTop 0.5] -### Above marks -define {TildeShape} : symbol-block 'Above marks' + local belowMarkBot (0 - ACCENT * 1.38) + local belowMarkTop (0 - ACCENT * 0.35) + + local commaOvershoot : O * [linreg 16 0 90 (-1) (markHalfStroke * 2)] + local commaOvershoot2 : O * [linreg 16 1 90 (-1) (markHalfStroke * 2)] + local commaAboveRadius : 0.85 * DOTRADIUS * markHalfStroke / HALFSTROKE + + local asciiMarkZoom : (RIGHTSB - SB) / (markExtend * 3) + + ### Above marks sketch # dotAbove set-width 0 currentGlyph.shortName = 'dot' @@ -569,12 +583,8 @@ define {TildeShape} : symbol-block 'Above marks' include : FlipAround markMiddle [mix top bot 0.5] save 'greaterAbove' 0x350 - - list - * TildeShape -### Below marks -symbol-block 'Below marks' + ### Below marks sketch # cedillaBelow set-width 0 set-anchor 'below' MARK markMiddle 0 markMiddle belowMarkBot @@ -1032,8 +1042,7 @@ symbol-block 'Below marks' set-anchor 'below' MARK markMiddle 0 markMiddle belowMarkBot save 'lrArrowBelow' 0x34E -# horn and angle marks -symbol-block 'Corner marks' + # horn and angle marks sketch # horn set-width 0 local radius : markHalfStroke * 1.5 @@ -1098,8 +1107,7 @@ symbol-block 'Corner marks' set currentGlyph.cmpPriority (-2) save 'ltailBR' 0x321 -# Overlay Marks -symbol-block 'Overlay Marks' + # Overlay Marks sketch # tildeOver set-width 0 set-anchor 'overlay' MARK markMiddle (XH / 2) markMiddle (XH / 2) @@ -1150,8 +1158,6 @@ symbol-block 'Overlay Marks' curl (RIGHTSB + O * 3 - fine - WIDTH) (XH * 0.5 + CAP * 0.6) save 'longSlashOver' 0x338 -# Double-character arcs -symbol-block 'Tie marks' local tieLeft [mix 0 markMiddle 1.25] local tieRight (-tieLeft) sketch # tieAbove @@ -1228,7 +1234,6 @@ symbol-block 'Tie marks' save 'tildeTieAbove' 0x360 -symbol-block 'Greek Polytonic Marks' define [GreekLRDoubleMark id unicode leftGlyph rightGlyph] : begin sketch # Combining double mark set-width 0 @@ -1294,4 +1299,9 @@ symbol-block 'Greek Polytonic Marks' sketch # spaced_dasiaperispomeni include glyphs.space AS_BASE include glyphs.dasiaperispomeni - save 'spaced_dasiaperispomeni' 0x1FDF \ No newline at end of file + save 'spaced_dasiaperispomeni' 0x1FDF + + return [object markExtend markHalfStroke markStress markFine + markMiddle markDotsRadius aboveMarkTop aboveMarkBot + aboveMarkMid belowMarkBot belowMarkTop commaOvershoot + commaOvershoot2 commaAboveRadius] \ No newline at end of file diff --git a/glyphs/symbol-braille.ptl b/glyphs/symbol-braille.ptl index b4e5e8214..58c719493 100755 --- a/glyphs/symbol-braille.ptl +++ b/glyphs/symbol-braille.ptl @@ -1,4 +1,22 @@ -symbol-block 'Braille Patterns' : if [not recursive] : begin +###### Brailles symbols +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks + + if recursive : return nothing local leftMiddle : MIDDLE - (0.25 * WIDTH) local rightMiddle : MIDDLE + (0.25 * WIDTH) local offsetY : 0.25 * (parenMid - parenTop) diff --git a/glyphs/symbol-geometric.ptl b/glyphs/symbol-geometric.ptl index 97e603862..f6dab9216 100644 --- a/glyphs/symbol-geometric.ptl +++ b/glyphs/symbol-geometric.ptl @@ -1,8 +1,21 @@ ###### GEOMETRIC SHAPES +$$include '../meta/macros.ptl' -### Arrowheads -define {ArrowHead ArrowShape} : symbol-block 'Arrows' +import 'unorm' as unorm +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks + ### Arrowheads define arrowWidth FULLWIDTH2 define arrowMidX : arrowWidth / 2 define arrowRSB : arrowWidth - SB @@ -105,10 +118,8 @@ define {ArrowHead ArrowShape} : symbol-block 'Arrows' arrow htArrowShape 'htarrowleft' 0x21A2 arrowRSB parenMid SB parenMid arrow htArrowShape 'htarrowright' 0x21A3 SB parenMid arrowRSB parenMid - * {ArrowHead ArrowShape} - -### Standard geometric shapes -symbol-block 'Geometric' + ### Standard geometric shapes + ### 'Geometric' define shapeWidth FULLWIDTH2 define left : mix MIDDLE SB 1.1 @@ -312,8 +323,8 @@ symbol-block 'Geometric' close save 'marksampler' 0xE09E -### Blocks -symbol-block 'Block Shapes' + ### Blocks + ### 'Block Shapes' sketch # fullblock set-width FULLWIDTH start-from 0 font.OS_2.usWinAscent @@ -383,8 +394,8 @@ symbol-block 'Block Shapes' line-to (FULLWIDTH * 0.5) (-font.OS_2.usWinDescent) save 'rightHalfBlock' 0x2590 -### Box drawing glyphs -symbol-block 'Box-Drawing' + ### Box drawing glyphs + ### 'Box-Drawing' local light : adviceBlackness 3.5 local heavy : Math.max (light * 2) (WIDTH * 0.15) local width FULLWIDTH @@ -587,8 +598,8 @@ symbol-block 'Box-Drawing' include glyphs.bd2572 save 'bd2573' 0x2573 -### POWERLINE glyphs -symbol-block 'Powerline' + ### POWERLINE glyphs + ### 'Powerline' sketch # branch local fine : adviceBlackness 3.5 local vBarPos : mix SB RIGHTSB 0.2 @@ -657,3 +668,5 @@ symbol-block 'Powerline' line-to (RIGHTSB - OX) parenBot line-to (SB + OX) parenBot save 'pwlLock' 0xE0A2 + + return [object ArrowShape] diff --git a/glyphs/symbol-letter.ptl b/glyphs/symbol-letter.ptl index 2151ba4fa..a7e426a43 100644 --- a/glyphs/symbol-letter.ptl +++ b/glyphs/symbol-letter.ptl @@ -1,7 +1,23 @@ ###### Letter-like symbols -### Currency -symbol-block 'Currency' +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks letterBasic + + ### Currency sketch # currency local sw : adviceBlackness 3.5 local radius : (RIGHTSB - SB) / 2 @@ -85,8 +101,7 @@ symbol-block 'Currency' include : HOverlayBar (SB * 0.5) (SB * 3 + STROKE * HVCONTRAST) [mix 0 XH 0.4] save 'frenchFranc' 0x20A3 -### Other -symbol-block 'Letterlike Symbols' + ### 'Letterlike Symbols' sketch # numero local fine : adviceBlackness 4.5 include : OShape XH [Math.max (fine * 2) (CAP * 0.1)] (MIDDLE + [Math.max (fine / 2) ((RIGHTSB - SB) * 0.1)]) [mix RIGHTSB WIDTH 0.5] fine (SMOOTHA * fine / STROKE) (SMOOTHB * fine / STROKE) diff --git a/glyphs/symbol-math.ptl b/glyphs/symbol-math.ptl index acbe6f2ed..62f003aab 100644 --- a/glyphs/symbol-math.ptl +++ b/glyphs/symbol-math.ptl @@ -1,7 +1,22 @@ ###### Mathematical symbols +$$include '../meta/macros.ptl' -### Letter-like -symbol-block 'Letter-like Mathematical Symbols' +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks letterBasic letterExt + + ### Letter-like sketch # micro include glyphs.mu AS_BASE if SLAB : if (!para.isItalic) : begin @@ -78,7 +93,7 @@ symbol-block 'Letter-like Mathematical Symbols' g4 SB (CAP - HOOK) save 'partial' 0x2202 -symbol-block 'Mathematical Operators' + ### Mathematical Operators sketch # mathO local sw OPERATORSTROKE local k 1 @@ -269,7 +284,7 @@ symbol-block 'Mathematical Operators' save 'ident' 0x2261 vdual 'approx' 0x2248 'sym' (equalHalfSpace * 1.75) -symbol-block 'Negative Operators' + ### 'Negative Operators' define [notGlyph newid unicode oldid top bot prop shift] : create-glyph [fallback newid : 'not' + oldid] : glyph-construction assign-unicode unicode include glyphs.(oldid) @@ -295,7 +310,7 @@ symbol-block 'Negative Operators' notGlyph.right 'notgreatereq' 0x2271 'greatereq' notGlyph.right 'nonexist' 0x2204 'exists' (CAP - DESCENDER / 2) (DESCENDER / 2) 0.4 -symbol-block 'Large Operators' + ### 'Large Operators' sketch # sum include : SigmaShape parenTop parenBot OPERATORSTROKE @@ -337,10 +352,9 @@ symbol-block 'Large Operators' save 'Cup' 0x22C3 turned 'Cap' 0x22C2 'Cup' MIDDLE parenMid -### Others -symbol-block 'Other Mathematical Operators' + ### Others alias 'mathbullet' 0x2219 'bullet' - + sketch # sqrt include : dispiro widths.center OPERATORSTROKE diff --git a/glyphs/symbol-other.ptl b/glyphs/symbol-other.ptl index 186c6fff0..103f2c182 100644 --- a/glyphs/symbol-other.ptl +++ b/glyphs/symbol-other.ptl @@ -1,6 +1,23 @@ ###### Other symbols -# IPA tonal marks -symbol-block 'Phonetic Symbols' +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks geometricSymbols + + ### # IPA tonal marks + ### symbol-block 'Phonetic Symbols' local triangleSize : Math.min (PERIODRADIUS) (XH / 5) sketch # trianglecolon @@ -25,8 +42,8 @@ symbol-block 'Phonetic Symbols' include : VBarRight [mix SB RIGHTSB 0.9] 0 CAP OPERATORSTROKE include : HBar [mix SB RIGHTSB 0.1] ([mix SB RIGHTSB 0.9] - 1) [mix (OPERATORSTROKE / 2) (CAP - OPERATORSTROKE / 2) (tone / 4)] OPERATORSTROKE -# Suit card -symbol-block 'Suit Cards' + ### # Suit card + ### symbol-block 'Suit Cards' local heartTop : mix parenMid parenTop 0.6 local heartBot : mix parenMid parenBot 0.6 @@ -80,7 +97,7 @@ symbol-block 'Suit Cards' line-to SB parenMid save 'diamond' 0x2666 -symbol-block 'Planets' + ### symbol-block 'Planets' sketch # venus local obot : operTop - RIGHTSB + SB include : OShape operTop obot SB RIGHTSB OPERATORSTROKE @@ -96,7 +113,7 @@ symbol-block 'Planets' include : ArrowShape MIDDLE (otop - OPERATORSTROKE / 3) MIDDLE operTop ((RIGHTSB - SB) * 0.4) save 'mars' 0x2642 -symbol-block 'Musical' + ### symbol-block 'Musical' sketch # quaver local fine : adviceBlackness 5 local noteSize : MIDDLE + fine / 2 - SB @@ -113,7 +130,7 @@ symbol-block 'Musical' g4 x3 y3 save 'quaver' 0x266A -symbol-block 'Metric marks' + ### symbol-block 'Metric marks' sketch # metmark include : VBar MIDDLE (-font.OS_2.usWinDescent) (font.OS_2.usWinAscent) SHOULDERFINE include : HBar MIDDLE WIDTH 0 SHOULDERFINE @@ -125,7 +142,7 @@ symbol-block 'Metric marks' include : HBar 0 MIDDLE parenBot SHOULDERFINE save 'metmark' 0xE09F -symbol-block 'Flags' + ### symbol-block 'Flags' local sw [adviceBlackness 4] local flagDown : 0.07 * (parenTop - parenBot) local delta 0.01 @@ -172,7 +189,7 @@ symbol-block 'Flags' corner SB operMid [heading LEFTWARD] save 'whiteflag' 0x2690 -symbol-block 'Other typographic symbols' + ### symbol-block 'Other typographic symbols' sketch # Kome local sw : adviceBlackness 3.75 local radius : (RIGHTSB - SB) / 2 @@ -242,8 +259,8 @@ symbol-block 'Other typographic symbols' g4 [mix SB RIGHTSB 0.9] [mix operBot operTop 0.1] save gid unicode -### Ligature-orienteds -symbol-block 'Ligature-oriented Subglyphs' : if (para.spacing > 0) : begin + ### ### Ligature-orienteds + ### symbol-block 'Ligature-oriented Subglyphs' : if (para.spacing > 0) : begin # Shifted arrowheads local arrowheadsKern : clamp 0 (WIDTH * 0.4) (WIDTH - OPERATORSTROKE * 3) sketch diff --git a/glyphs/symbol-punctuation.ptl b/glyphs/symbol-punctuation.ptl index 41067679b..6144412a6 100644 --- a/glyphs/symbol-punctuation.ptl +++ b/glyphs/symbol-punctuation.ptl @@ -1,7 +1,23 @@ -### Extended symbols -# spaces -# we set the width of emquad to 1000mem (1em) and the width of emspace to WIDTH (0.5em) -symbol-block 'Spaces' +### Punctuation symbols +$$include '../meta/macros.ptl' + +import 'unorm' as unorm + +import '../support/glyph' as Glyph +import '../support/point' as Point +import '../support/spirokit' as spirokit +import '../support/transform' as : Transform && [object [transformPoint tp] [untransform utp] inverse] +import '../support/anchor' as Anchor +import '../support/monotonic-interpolate' as smoothreg +import '../support/fairify' as fairify + +import [mix linreg clamp fallback TempFont includeGlyphPart compsiteMarkSet suggestGC] from '../support/utils' + +export : define [apply] : begin + glyph-module-entry commonShapes overmarks letterBasic + # spaces + # we set the width of emquad to 1000mem (1em) and the width of emspace to WIDTH (0.5em) + ### 'Spaces' alias 'enquad' 0x2000 'space' alias 'ensp' 0x2002 'space' alias 'threePerEmsp' 0x2004 'space' @@ -25,7 +41,7 @@ symbol-block 'Spaces' save 'emquad' 0x2001 save 'emsp' 0x2003 -symbol-block 'Brackets' + ### 'Brackets' local parenOutside 0.15 local parenInside 0.65 local bracketOutside 0.15 @@ -121,7 +137,7 @@ symbol-block 'Brackets' turned 'floorRight' 0x230B 'ceilingLeft' MIDDLE parenMid turned 'ceilingRight' 0x2309 'floorLeft' MIDDLE parenMid -symbol-block 'Small Punctuations' + ### 'Small Punctuations' sketch # period set-width WIDTH include : Ring (PERIODSIZE - O) O (MIDDLE - PERIODRADIUS + O) (MIDDLE + PERIODRADIUS - O) true @@ -174,7 +190,7 @@ symbol-block 'Small Punctuations' save 'semicolon' ';' save 'greekquestion' 0x37E -symbol-block 'Emotion Punctuations' + ### 'Emotion Punctuations' local questionBottom : Math.max (CAP * 0.3) (DOTSIZE * 1.5) sketch # question @@ -252,7 +268,7 @@ symbol-block 'Emotion Punctuations' include : HBarTop SB RIGHTSB (parenMid - XH * 0.1) OPERATORSTROKE save 'palatoalveolarclick' 0x1C2 -symbol-block 'Typographic Symbols' + ### 'Typographic Symbols' sketch # ampersand set-width WIDTH @@ -412,7 +428,7 @@ symbol-block 'Typographic Symbols' alias 'solidus' 0x2044 'slash' -symbol-block 'Dashes' + ### 'Dashes' sketch # underscore.high set-width WIDTH include : HBarBottom SB RIGHTSB 0 @@ -454,7 +470,7 @@ symbol-block 'Dashes' alias 'horizontalBar' 0x2015 'emDash' -symbol-block 'Interpuncts' + ### 'Interpuncts' sketch # interpunct set-width FULLWIDTH include : Ring (parenMid + PERIODRADIUS - O) (parenMid - PERIODRADIUS + O) (FWMIDDLE - PERIODRADIUS + O) (FWMIDDLE + PERIODRADIUS - O) true @@ -471,8 +487,8 @@ symbol-block 'Interpuncts' reverse-last save 'whitebullet' 0x25E6 -# quotation marks -symbol-block 'Quotes and Primes' + + ### 'Quotes and Primes' local quoteTop (CAP * 1.05) local quoteBottom (XH * 0.85) @@ -664,8 +680,8 @@ symbol-block 'Quotes and Primes' include : FlipAround MIDDLE parenMid save 'guillemetRight' 0xBB -# Daggers -symbol-block 'Daggers' + + ### 'Daggers' sketch # dagger include : HBar SB RIGHTSB [mix parenTop parenBot 0.33] include : VBar MIDDLE parenBot parenTop @@ -677,8 +693,7 @@ symbol-block 'Daggers' include : HBar SB RIGHTSB [mix parenTop parenBot 0.67] save 'doubledagger' 0x2021 -# Ellipsis -symbol-block 'Ellipsis' + ### 'Ellipsis' sketch # onedotLeader set-width FULLWIDTH local radius : linreg WIDTH (0.5 * [adviceBlackness 3.25] * PERIODSIZE / DOTSIZE) UPM PERIODRADIUS FULLWIDTH @@ -704,7 +719,7 @@ symbol-block 'Ellipsis' include : Ring (radius * 2 - O) O (right - radius + O) (right + radius - O) true save 'ellipsis' 0x2026 -symbol-block 'Percentages' + ### 'Percentages' sketch # percent set-width WIDTH local dotwidth ([adviceBlackness 4] * 1.5) @@ -747,7 +762,7 @@ symbol-block 'Percentages' include : VBarLeft [mix SB RIGHTSB 0.1] 0 [mix 0 CAP 0.3] dotfine save 'basepoint' 0x2031 -symbol-block "ASCII Marks" + ### "ASCII Marks" local MarkZoom : glyph-construction apply-transform : Upright apply-transform : Translate (-MIDDLE) (-XH - ACCENT) @@ -763,17 +778,16 @@ symbol-block "ASCII Marks" composite 'degree' glyphs.space glyphs.ringAbove MarkZoom [into-unicode 0xB0] -### Aliased modifer letters -alias 'mdfPrime' 0x2B9 'prime' -alias 'mdfDoublePrime' 0x2BA 'doubleprime' -alias 'mdfTurncomma' 0x2BB 'openSingleQuote' -alias 'mdfApostrophe' 0x2BC 'closeSingleQuote' -alias 'mdfRevComma' 0x2BD 'revertSingleQuote' -alias 'mdfStress' 0x2C8 'singleQuote' -turned 'mdfSecondaryStress' 0x2CC 'singleQuote' MIDDLE (XH / 2) + alias 'mdfPrime' 0x2B9 'prime' + alias 'mdfDoublePrime' 0x2BA 'doubleprime' + alias 'mdfTurncomma' 0x2BB 'openSingleQuote' + alias 'mdfApostrophe' 0x2BC 'closeSingleQuote' + alias 'mdfRevComma' 0x2BD 'revertSingleQuote' + alias 'mdfStress' 0x2C8 'singleQuote' + turned 'mdfSecondaryStress' 0x2CC 'singleQuote' MIDDLE (XH / 2) -symbol-block 'Double-width punctuations' : if (para.spacing > 0) : begin + ### 'Double-width punctuations' : if (para.spacing > 0) : begin dwc nothing 0xFF01 'exclam' dwc nothing 0xFF1A 'colon' dwc nothing 0xFF1B 'semicolon' diff --git a/makesupport.mk b/makesupport.mk index e49a0dd2b..382170e0e 100644 --- a/makesupport.mk +++ b/makesupport.mk @@ -6,30 +6,22 @@ dist : @- mkdir $@ snapshot/assets : @- mkdir $@ - + PATELC = node ./node_modules/patel/bin/patel-c -SUPPORT_FILES_FROM_PTL = support/glyph.js support/spiroexpand.js support/spirokit.js parameters.js support/anchor.js support/point.js support/transform.js support/utils.js meta/aesthetics.js meta/naming.js meta/features.js + +GLYPH_SEGMENTS = glyphs/common-shapes.js glyphs/overmarks.js glyphs/letters-unified-basic.js glyphs/letters-unified-extended.js glyphs/numbers.js glyphs/symbol-punctuation.js glyphs/symbol-math.js glyphs/symbol-letter.js glyphs/symbol-geometric.js glyphs/symbol-other.js glyphs/symbol-braille.js glyphs/autobuilds.js + +SUPPORT_FILES_FROM_PTL = support/glyph.js support/spiroexpand.js support/spirokit.js parameters.js support/anchor.js support/point.js support/transform.js support/utils.js meta/aesthetics.js meta/naming.js meta/features.js $(GLYPH_SEGMENTS) + SUPPORT_FILES = $(SUPPORT_FILES_FROM_PTL) generator.js emptyfont.toml parameters.toml support/fairify.js -GLYPH_SEGMENTS = glyphs/common-shapes.ptl glyphs/overmarks.ptl glyphs/letters-unified-basic.ptl glyphs/letters-unified-extended.ptl glyphs/numbers.ptl glyphs/symbol-punctuation.ptl glyphs/symbol-math.ptl glyphs/symbol-geometric.ptl glyphs/symbol-other.ptl glyphs/symbol-braille.ptl glyphs/symbol-letter.ptl glyphs/autobuilds.ptl SCRIPTS = $(SUPPORT_FILES) buildglyphs.js SCRIPTS_FROM_aki = $(SUPPORT_FILES_FROM_PTL) buildglyphs.js buildglyphs.js : buildglyphs.ptl $(GLYPH_SEGMENTS) $(PATELC) --strict $< -o $@ -$(SUPPORT_FILES_FROM_PTL) : +$(SUPPORT_FILES_FROM_PTL) : %.js : %.ptl meta/macros.ptl $(PATELC) --optimize --strict $< -o $@ -support/anchor.js : support/anchor.ptl -support/point.js : support/point.ptl -support/transform.js : support/transform.ptl -support/glyph.js : support/glyph.ptl -support/spirokit.js : support/spirokit.ptl -support/spiroexpand.js : support/spiroexpand.ptl -support/utils.js : support/utils.ptl -meta/aesthetics.js : meta/aesthetics.ptl -meta/naming.js : meta/naming.ptl -meta/features.js : meta/features.ptl -parameters.js : parameters.ptl cleanscripts : -@rm $(SCRIPTS_FROM_aki) diff --git a/meta/macros.ptl b/meta/macros.ptl new file mode 100644 index 000000000..5cfb4a3f0 --- /dev/null +++ b/meta/macros.ptl @@ -0,0 +1,169 @@ +### Autoarg macro +define-operator "--" 890 'right' : syntax-rules + `(@l -- @r) [atom l] : dirty `[new $NamedParameterPair$ @{".quote" [formOf l]} @r] + +define-macro params : syntax-rules + `[params @_pairs @body] : begin + local ta : env.newt + local tb : env.newt + local t : env.newt + local ps `[begin + [local @ta : {}.slice.call arguments 0] + [local @tb {}] + [for [local @t 0] (@t < @ta.length) [inc @t] : if [not : @ta.(@t) <@ $NamedParameterPair$] : @tb.push @ta.(@t)] + ] + local aps `[begin] + local dps `[begin] + local j 0 + foreach [pf : items-of : formOf _pairs] : begin + local name + if [atom pf] : then + ps.push `[local @pf : fallback @pf (@tb).(@{".quote" j})] + set name pf + : else + ps.push `[local @(pf.0) : fallback @(pf.0) (@tb).(@{".quote" j}) @(pf.1)] + set name pf.0 + aps.push `[if (@t && @t <@ $NamedParameterPair$ && @t.left == @{".quote" name}) [set @name @t.right]] + if pf.2 : dps.push `[local @(pf.2) @name] + inc j + ps.push `[foreach [@t : items-of @ta] @aps] + ps.push dps + ps.push : formOf body + return : dirty ps + +### Point macro +define-operator "<>" 800 "never" : begin + local tClass [definingEnv.newt 'class'] + local m : syntax-rules + `(@x <> @y) `[new @tClass @x @y] + + set coinit.initFn : lambda [m] : begin + set m.toPattern : lambda [form env wrapper] : match form + `(@x <> @y) : begin + local p1 [toPattern x env wrapper] + local p2 [toPattern y env wrapper] + object + whether : lambda [t] `(@t && @[p1.whether `(@t.x)] && @[p2.whether `(@t.y)]) + assign : lambda [t locallyQ] : ex `[begin + @{".preserve" [p1.assign `(@t.x) locallyQ]} + @{".preserve" [p2.assign `(@t.y) locallyQ]} + ] env + + set coinit.injectForm `[define [@tClass x y] : begin \\ + set this.x x + set this.y y + return nothing + ] + return m + +### Necessary macros +# A glyph construction is a function which "modifies" a glyph. +define-macro glyph-construction : syntax-rules + `[glyph-construction @::steps] {'.syntactic-closure' `[lambda [] [begin \\ + local currentGlyph this + begin @::[steps.map formOf] + return nothing + ]] env} +# Remap Glyph's methods to macros in order to simplify writing +define-macro set-width : syntax-rules + `[set-width @::args] {'.syntactic-closure' `[currentGlyph.set-width @::args] env} +define-macro start-from : syntax-rules + `[start-from @::args] {'.syntactic-closure' `[currentGlyph.start-from @::args] env} +define-macro line-to : syntax-rules + `[line-to @::args] {'.syntactic-closure' `[currentGlyph.line-to @::args] env} +define-macro curve-to : syntax-rules + `[curve-to @::args] {'.syntactic-closure' `[currentGlyph.curve-to @::args] env} +define-macro cubic-to : syntax-rules + `[cubic-to @::args] {'.syntactic-closure' `[currentGlyph.cubic-to @::args] env} +define-macro include : syntax-rules + `[include glyphs.(@name) @::args] : dirty `[includeGlyphPart currentGlyph glyphs @name @::args] + `[include @::args] {'.syntactic-closure' `[currentGlyph.include @::args] env} +define-macro set-anchor : syntax-rules + `[set-anchor @::args] {'.syntactic-closure' `[currentGlyph.set-anchor @::args] env} +define-macro apply-transform : syntax-rules + `[apply-transform @::args] {'.syntactic-closure' `[currentGlyph.apply-transform @::args] env} +define-macro reverse-last : syntax-rules + `[reverse-last @::args] {'.syntactic-closure' `[currentGlyph.reverse-last @::args] env} +define-macro depends-on : syntax-rules + `[depends-on @::args] {'.syntactic-closure' `[currentGlyph.depends-on @::args] env} +define-macro eject-contour : syntax-rules + `[eject-contour @::args] {'.syntactic-closure' `[currentGlyph.eject-contour @::args] env} +define-macro tag-contour : syntax-rules + `[tag-contour @::args] {'.syntactic-closure' `[currentGlyph.tag-contour @::args] env} +define-macro retag-contour : syntax-rules + `[retag-contour @::args] {'.syntactic-closure' `[currentGlyph.retag-contour @::args] env} +define-macro assign-unicode : syntax-rules + `[assign-unicode @code] {".syntactic-closure" `[begin \\ + currentGlyph.assign-unicode @code + set unicodeGlyphs.(currentGlyph.unicode.((currentGlyph.unicode.length - 1))) currentGlyph + ] env} + +###### Canvas-based mechanism +define-macro sketch : syntax-rules + `[sketch @::steps] : begin + if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 + inc externEnv.$nWFGlyphs$ + local f0 : '.' + [[env.macros.get 'input-path']].1 + '.' + local tcn {".quote" (".WF" + f0 + externEnv.$nWFGlyphs$)} + dirty `[[lambda [currentGlyph] [begin \\ + if [not currentGlyph] : return nothing + if [glyphList.(glyphList.length - 1).name === @tcn] : glyphList.pop + begin @::[steps.map formOf] + set dependencyProfile.(currentGlyph.name) : getDependencyProfile currentGlyph + return currentGlyph + ]] [create-glyph @tcn $donothing$]] + +define-macro branch : syntax-rules + `[branch @::steps] : begin + if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 + inc externEnv.$nWFGlyphs$ + local f0 : '.' + [[env.macros.get 'input-path']].1 + '.' + local tcn {".quote" (".WF" + f0 + externEnv.$nWFGlyphs$)} + dirty `[[lambda [currentGlyph] [begin \\ + if [not currentGlyph] : return nothing + if [glyphList.(glyphList.length - 1).name === @tcn] : glyphList.pop + begin @::[steps.map formOf] + set dependencyProfile.(currentGlyph.name) : getDependencyProfile currentGlyph + return currentGlyph + ]] [create-glyph @tcn [lambda : begin [this.include currentGlyph true] [set this.advanceWidth currentGlyph.advanceWidth]]]] + +define-macro save : syntax-rules + `[save @::args] : dirty `[$save$.call currentGlyph @::args] + +define-macro glyph-module-entry : syntax-rules + `[glyph-module-entry @::_opts] : begin + define optionalImports : object + commonShapes `[define [object select-variant italic-variant alias composite into-unicode turned dual vdual fwl fwr dwl dwr dwc Ring RingAt DotAt CircleRing CircleRingAt CircleDotAt OShape OBarLeftShape OBarRightShape LeftwardTopSerif LeftwardBottomSerif RightwardTopSerif RightwardBottomSerif CenterTopSerif CenterBottomSerif DownwardRightSerif UpwardRightSerif DownwardLeftSerif UpwardLeftSerif AIVSerifs AIHSerifs AINSerifs AICyrISerifs AIMSerifs halfXStrand xStrand nShoulderKnots nShoulder mShoulderSpiro HBar HBarTop HBarBottom HOverlayBar VBar VBarLeft VBarRight VerticalHook LegShape LeftHook HooktopLeftBar CurlyTail HCurlyTail FlatSlashShape determineMixR HookShape hookstart hookend WaveShape CyrDescender refair Fork Miniature Thinner Widen FlipAround] $capture.commonShapes] + + overmarks `[define [object markExtend markHalfStroke markStress markFine markMiddle markDotsRadius aboveMarkTop aboveMarkBot aboveMarkMid belowMarkBot belowMarkTop commaOvershoot commaOvershoot2 commaAboveRadius] $capture.overmarks] + + letterBasic `[define [object ISerifShape IotaShape LShape Belt VShape VHooktopShape WShape WHooktopShape YShape yBaseKnots SmallYShape KShape BShape ItalicCyrveShape PShape RShape CyrYaShape CShape GShape NShape UShape LatinUpsilon2Shape MShape SmallMShape HShape FShape fovershoot LongSShape EShape SmallEShape RevSmallEShape TShape SmallTShape] $capture.letterBasic] + + letterExt `[define [object LambdaShape SigmaShape PiShape] $capture.letterExt] + geometricSymbols `[define [object ArrowShape] $capture.geometricSymbols] + + local opts : _opts.map formOf + #console.log opts + local optionalImportStatements `[begin] + for [local j 0] (j < opts.length) [inc j] : if optionalImports.(opts.(j)) : optionalImportStatements.push optionalImports.(opts.(j)) + dirty `[begin \\ + define $capture this + define [object metrics $NamedParameterPair$ $donothing$ para recursive recursiveCodes variantSelector font glyphs glyphList unicodeGlyphs create-glyph $save$ spirofns markset MARK BASE AS_BASE ALSO_METRICS pickHash dependencyProfile getDependencyProfile buildFont newtemp tagged] $capture + define [object + UPM WIDTH SB CAP XH DESCENDER CONTRAST + parenMid parenTop parenBot operTop operBot operMid Italify Upright Scale Translate Rotate globalTransform + TANSLANT SINSLANT COSSLANT HVCONTRAST UPWARD DOWNWARD RIGHTWARD LEFTWARD + O OX OXHOOK HOOK AHOOK SHOOK RHOOK JHOOK FHOOK HOOKX SMOOTH SMALLSMOOTH STROKE DOTSIZE PERIODSIZE + BARPOS GBARPOS PBARPOS EBARPOS OVERLAYPOS FIVEBARPOS LONGJUT JUT VJUT ACCENT ACCENTX CTHIN CTHINB SLAB + TAILADJX TAILADJY LBALANCE IBALANCE JBALANCE JBALANCE2 TBALANCE TBALANCE2 RBALANCE RBALANCE2 + FBALANCE ONEBALANCE FULLWIDTH FULLWIDTH1 FULLWIDTH2 FULLWIDTH3 OXE ESS ESSQUESTION XO CAPO HALFSTROKE RIGHTSB FWRSB + MIDDLE FWMIDDLE CAPMIDDLE CAP_SMOOTH DOTRADIUS PERIODRADIUS SIDEJUT SMOOTHA SMOOTHB SMALLSMOOTHA SMALLSMOOTHB CORRECTION_OMIDX CORRECTION_OMIDS + WHITENESS adviceBlackness MVERTSTROKE OVERLAYSTROKE OPERATORSTROKE SHOULDERFINE SUPERNESS superxy + adviceSSmooth adviceGlottalStopSmooth shoulderMidSlope] metrics + define [object + g4 g2 corner flat curl close end straight + widths heading unimportant important + alsothru alsothruthem bezcontrols quadcontrols archv arcvh complexThru + dispiro spiro-outline] spirofns + * @optionalImportStatements + ] \ No newline at end of file