diff --git a/changes/3.0.0-rc.3.md b/changes/3.0.0-rc.3.md index f645fa485..5bb40acd6 100644 --- a/changes/3.0.0-rc.3.md +++ b/changes/3.0.0-rc.3.md @@ -1,2 +1,6 @@ * Fix shape of `smcpGhooktop` (U+029B) and `uogonek.withoutBar`. * Make the dotless `i` and `j` CCMP feature work for more related characters and stylized forms. + * Fix substitution of i-ogonek and upper combining marks. + * Fix broken shape of tildes. + * Fix broken degree-C and degree-F ligature. + * Fix broken cup (`∪`) and cap (`∩`) symbol. diff --git a/glyphs/autobuild-accents.ptl b/glyphs/autobuild-accents.ptl index 59a801ba4..0d277de21 100644 --- a/glyphs/autobuild-accents.ptl +++ b/glyphs/autobuild-accents.ptl @@ -17,8 +17,9 @@ glyph-block AutoBuild-Accents : begin foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true # replace dotted-i and dotted-j with dotless equalivents - if (hasMarkAbove && parts.0.dotlessGlyph && glyphs.(parts.0.dotlessGlyph)) : begin - set parts.0 glyphs.(parts.0.dotlessGlyph) + if (hasMarkAbove && parts.0.related && parts.0.related.dotless) : begin + local dotless glyphs.(parts.0.related.dotless) + if dotless : set parts.0 dotless # replace below marks with trailing marks if parts.0.anchors.lf : parts.forEach iotaBelowToLF @@ -60,6 +61,7 @@ glyph-block AutoBuild-Accents : begin 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 @@ -80,35 +82,71 @@ glyph-block AutoBuild-Accents : begin : else : foreach code [range 0x0000 0xFFFF] : buildForCode code suggestGC - local {glyphName code parts} {} + local s_code nothing + local s_parts nothing define construction : glyph-construction - if code : assign-unicode code - include parts.0 AS_BASE - set-width parts.0.advanceWidth + if s_code : assign-unicode s_code + include s_parts.0 AS_BASE + set-width s_parts.0.advanceWidth - local names {parts.0.name} - foreach part [items-of : parts.slice 1] : if part : begin + local names {s_parts.0.name} + foreach part [items-of : s_parts.slice 1] : if part : begin include part names.push part.name if (part.name === 'rtailBR') : eject-contour 'serifRB' - define [cfv glyphName _pa] : if (!recursive && _pa.0.featureSelector) : begin + define [GlyphProcShared origGlyphName relation parts] : begin + local base parts.0 + local origBase base + local marks : parts.slice 1 + local targetGlyphName : origGlyphName + [if relation ("." + relation) ""] + if (relation && base.related && base.related.(relation)) + set base glyphs.(base.related.(relation)) + + return { origBase base marks targetGlyphName } + + define [RootGlyphProc origGlyphName relation code parts] : begin + local { origBase base marks targetGlyphName } : GlyphProcShared origGlyphName relation parts + if (relation && base === origBase) : return nothing + + set s_code : if relation null code + set s_parts { base :: marks } + create-glyph targetGlyphName construction + + define [VariantGlyphProc origGlyphName relation _pa] : if (!recursive) : begin + local { origBase base marks targetGlyphName } : GlyphProcShared origGlyphName relation parts + if (relation && base === origBase) : return nothing + + if [not base.featureSelector] : return nothing local h {.} - foreach [feature : items-of : Object.keys _pa.0.featureSelector] : begin - local variant _pa.0.featureSelector.(feature) + foreach [feature : items-of : Object.keys base.featureSelector] : begin + local variant base.featureSelector.(feature) local variantRoot glyphs.(variant) if variantRoot : begin - set parts {variantRoot :: [_pa.slice 1]} - set code null - create-glyph (glyphName + '.' + feature) construction + set s_code null + set s_parts { variantRoot :: marks } + create-glyph (targetGlyphName + '.' + feature) construction - set h.(feature) (glyphName + '.' + feature) - if glyphs.(glyphName) : set glyphs.(glyphName).featureSelector h + set h.(feature) (targetGlyphName + '.' + feature) + + if glyphs.(targetGlyphName) : set glyphs.(targetGlyphName).featureSelector h + + define [LinkRelatedGlyph origGlyphName relation] : begin + if [not relation] : return nothing + if [not glyphs.(origGlyphName)] : return nothing + + local targetGlyphName : origGlyphName + [if relation ("." + relation) ""] + if [not glyphs.(targetGlyphName)] : return nothing + + if [not glyphs.(origGlyphName).related] : set glyphs.(origGlyphName).related {.} + set glyphs.(origGlyphName).related.(relation) targetGlyphName foreach [_id : items-of : Object.keys foundDecompositions] : begin - set {glyphName code parts} foundDecompositions.(_id) - create-glyph glyphName construction - cfv glyphName parts + local {glyphName code parts} foundDecompositions.(_id) + foreach [relation : items-of {null 'dotless'}] : begin + RootGlyphProc glyphName relation code parts + VariantGlyphProc glyphName relation parts + LinkRelatedGlyph glyphName relation suggestGC @@ -196,48 +234,48 @@ define customDecompositions : object ."\u04AB" "\u0441\u0327" # Spacing modifers - ."\u02CB" " \u0300" - ."\u02CA" " \u0301" - ."\u02C6" " \u0302" - ."\u02DC" " \u0303" - ."\u00AF" " \u0304" - ."\u02C9" " \u0304" - ."\u02D8" " \u0306" - ."\u02D9" " \u0307" - ."\u00A8" " \u0308" - ."\u02DA" " \u030A" - ."\u02C7" " \u030C" - ."\u00B8" " \u0327" - ."\u02CD" " \u0331" - ."\u02CE" " \u0316" - ."\u02CF" " \u0317" - ."\u02D2" " \u0339" - ."\u02D3" " \u031C" - ."\u02D4" " \u031D" - ."\u02D5" " \u031E" - ."\u02D6" " \u031F" - ."\u02D7" " \u0320" - ."\u02DB" " \u0328" - ."\u02DD" " \u030B" - ."\u02DF" " \u033D" - ."\u02EC" " \u032C" - ."\u02ED" " \u033F" - ."\u02F3" " \u0325" - ."\u02F7" " \u0330" + ."\u02CB" "\uE09D\u0300" + ."\u02CA" "\uE09D\u0301" + ."\u02C6" "\uE09D\u0302" + ."\u02DC" "\uE09D\u0303" + ."\u00AF" "\uE09D\u0304" + ."\u02C9" "\uE09D\u0304" + ."\u02D8" "\uE09D\u0306" + ."\u02D9" "\uE09D\u0307" + ."\u00A8" "\uE09D\u0308" + ."\u02DA" "\uE09D\u030A" + ."\u02C7" "\uE09D\u030C" + ."\u00B8" "\uE09D\u0327" + ."\u02CD" "\uE09D\u0331" + ."\u02CE" "\uE09D\u0316" + ."\u02CF" "\uE09D\u0317" + ."\u02D2" "\uE09D\u0339" + ."\u02D3" "\uE09D\u031C" + ."\u02D4" "\uE09D\u031D" + ."\u02D5" "\uE09D\u031E" + ."\u02D6" "\uE09D\u031F" + ."\u02D7" "\uE09D\u0320" + ."\u02DB" "\uE09D\u0328" + ."\u02DD" "\uE09D\u030B" + ."\u02DF" "\uE09D\u033D" + ."\u02EC" "\uE09D\u032C" + ."\u02ED" "\uE09D\u033F" + ."\u02F3" "\uE09D\u0325" + ."\u02F7" "\uE09D\u0330" - ."\u1FED" " \u0308\u0300" - ."\u1FEE" " \u0308\u0301" - ."\u1FEF" " \u0300" - ."\u1FFD" " \u0301" - ."\u1FFE" " \u0314" - ."\u1FBD" " \u0313" - ."\u1FBE" " \u0345" - ."\u1FBF" " \u0313" - ."\u1FC0" " \u0342" - ."\u1FC1" " \u0308\u0342" - ."\u0384" " \u0301" - ."\u0385" " \u0308\u0301" - ."\u037A" " \u0345" + ."\u1FED" "\uE09D\u0308\u0300" + ."\u1FEE" "\uE09D\u0308\u0301" + ."\u1FEF" "\uE09D\u0300" + ."\u1FFD" "\uE09D\u0301" + ."\u1FFE" "\uE09D\u0314" + ."\u1FBD" "\uE09D\u0313" + ."\u1FBE" "\uE09D\u0345" + ."\u1FBF" "\uE09D\u0313" + ."\u1FC0" "\uE09D\u0342" + ."\u1FC1" "\uE09D\u0308\u0342" + ."\u0384" "\uE09D\u0301" + ."\u0385" "\uE09D\u0308\u0301" + ."\u037A" "\uE09D\u0345" # Suppress incorrect slashed arrows... so far ."\u219A" "" diff --git a/glyphs/autobuild-enclosure.ptl b/glyphs/autobuild-enclosure.ptl index f22915677..5b58474a0 100644 --- a/glyphs/autobuild-enclosure.ptl +++ b/glyphs/autobuild-enclosure.ptl @@ -332,8 +332,8 @@ glyph-block AutoBuild-Enclosure : begin list 0x1F12F {'turnC'} WIDE-WIDTH-2 list 0xAE {'R'} WIDE-WIDTH-2 list 0x2117 {'P'} WIDE-WIDTH-2 - list 0x24EA {'zero'} WIDE-WIDTH-1 - compositions.push { null {'space'} WIDE-WIDTH-1 } + list 0x24EA {'zero.lnum'} WIDE-WIDTH-1 + compositions.push { null {'markBaseSpace'} WIDE-WIDTH-1 } foreach [j : range 1 till 9] : compositions.push : list 0x2460 + j - 1 digitGlyphNames j @@ -344,7 +344,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "Double-digit circled" local compositions : list - compositions.push { null {'space'} WIDE-WIDTH-1 } + compositions.push { null {'markBaseSpace'} WIDE-WIDTH-1 } foreach [j : range 10 till 20] : compositions.push : list 0x2460 + j - 1 digitGlyphNames j @@ -361,7 +361,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "Single-digit inset circled" local compositions : list - list 0x24FF {'zero'} WIDE-WIDTH-1 + list 0x24FF {'zero.lnum'} WIDE-WIDTH-1 foreach [j : range 1 till 9] : compositions.push : list 0x2776 + j - 1 digitGlyphNames j @@ -383,7 +383,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "boxed" local compositions {} - compositions.push { null {'space'} WIDE-WIDTH-1 } + compositions.push { null {'markBaseSpace'} WIDE-WIDTH-1 } foreach [j : range 0 26] : compositions.push {(0x1F130 + j) {unicodeGlyphs.(['A'.charCodeAt 0] + j).name} WIDE-WIDTH-1} createBoxedGlyphs 1 compositions @@ -401,7 +401,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "Single-digit double circled" local compositions {} - compositions.push { null {'space'} WIDE-WIDTH-1 } + compositions.push { null {'markBaseSpace'} WIDE-WIDTH-1 } foreach [j : range 1 till 9] : compositions.push : list 0x24F5 + j - 1 digitGlyphNames j @@ -410,7 +410,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "Double-digit double circled" local compositions {} - compositions.push { null {'space'} WIDE-WIDTH-1 } + compositions.push { null {'markBaseSpace'} WIDE-WIDTH-1 } foreach [j : range 10 till 10] : compositions.push : list 0x24F5 + j - 1 digitGlyphNames j @@ -437,7 +437,7 @@ glyph-block AutoBuild-Enclosure : begin if [not recursive] : do "Single-digit dotted" local compositions : list - list 0x1F100 {'zero'} WIDE-WIDTH-1 + list 0x1F100 {'zero.lnum'} WIDE-WIDTH-1 foreach [j : range 1 till 9] : compositions.push : list 0x2488 + j - 1 digitGlyphNames j diff --git a/glyphs/autobuild-transformed.ptl b/glyphs/autobuild-transformed.ptl index c2e8f3f02..ef1855f18 100644 --- a/glyphs/autobuild-transformed.ptl +++ b/glyphs/autobuild-transformed.ptl @@ -94,16 +94,16 @@ glyph-block Autobuild-Transformed : begin set-anchor 'above' MARK markMiddle XH markMiddle aboveMarkTop if [not recursive] : 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 0x2070 'zero.lnum' + list 0x00B9 'one.lnum' + list 0x00B2 'two.lnum' + list 0x00B3 'three.lnum' + list 0x2074 'four.lnum' + list 0x2075 'five.lnum' + list 0x2076 'six.lnum' + list 0x2077 'seven.lnum' + list 0x2078 'eight.lnum' + list 0x2079 'nine.lnum' list 0x02B0 'h' list 0x02B1 'hhooktop' list 0x02B2 'j' @@ -241,16 +241,16 @@ glyph-block Autobuild-Transformed : begin save 'ordmasculine' 0xBA if [not recursive] : 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 0x2080 'zero.lnum' + list 0x2081 'one.lnum' + list 0x2082 'two.lnum' + list 0x2083 'three.lnum' + list 0x2084 'four.lnum' + list 0x2085 'five.lnum' + list 0x2086 'six.lnum' + list 0x2087 'seven.lnum' + list 0x2088 'eight.lnum' + list 0x2089 'nine.lnum' list 0x2090 'a' list 0x2091 'e' list 0x2092 'o' @@ -364,6 +364,7 @@ glyph-block Autobuild-Transformed : begin glyphs -- pendingGlyphs crowd -- 4 scale -- (scaleFactor + 0.05) + foreach {unicode numid denid height} [items-of records] : do local dist : XH * (1 - scaleFactor - closing) @@ -395,31 +396,31 @@ glyph-block Autobuild-Transformed : begin define [createPowerlineStacks records] : createFracImpl '.pwlStack' records 0 0.6 0.15 if [not recursive] : 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' + list 0x00BC 'one.lnum' 'four.lnum' + list 0x00BD 'one.lnum' 'two.lnum' + list 0x00BE 'three.lnum' 'four.lnum' + list 0x2150 'one.lnum' 'seven.lnum' + list 0x2151 'one.lnum' 'nine.lnum' + list 0x2152 'one.lnum' 'ten' + list 0x2153 'one.lnum' 'three.lnum' + list 0x2154 'two.lnum' 'three.lnum' + list 0x2155 'one.lnum' 'five.lnum' + list 0x2156 'two.lnum' 'five.lnum' + list 0x2157 'three.lnum' 'five.lnum' + list 0x2158 'four.lnum' 'five.lnum' + list 0x2159 'one.lnum' 'six.lnum' + list 0x215A 'five.lnum' 'six.lnum' + list 0x215B 'one.lnum' 'eight.lnum' + list 0x215C 'three.lnum' 'eight.lnum' + list 0x215D 'five.lnum' 'eight.lnum' + list 0x215E 'seven.lnum' 'eight.lnum' + list 0x2189 'zero.lnum' 'three.lnum' # care-of list 0x2100 'largescripta' 'C' list 0x2105 'C' 'O' list 0x2106 'C' 'U' # fraction bar - list null 'space' 'space' + list null 'markBaseSpace' 'markBaseSpace' if [not recursive] : createPowerlineStacks : list # Powerline LN symbol diff --git a/glyphs/common-shapes.ptl b/glyphs/common-shapes.ptl index 54ac936fa..2838269e0 100644 --- a/glyphs/common-shapes.ptl +++ b/glyphs/common-shapes.ptl @@ -776,12 +776,13 @@ glyph-block CommonShapes : begin define [WithDerivatives sourceGid dstGid Fn] : if glyphs.(sourceGid) : begin create-glyph dstGid : glyph-construction : include : Fn sourceGid null if (glyphs.(sourceGid) && glyphs.(dstGid)) : begin + local glyphDst glyphs.(dstGid) local fs : queryFeatureSelector sourceGid para local fs_i : queryFeatureSelector sourceGid para dstGid foreach [{k gid} : pairs-of fs] : begin - create-glyph fs_i.(k) : glyph-construction - include : Fn gid k - set glyphs.(dstGid).featureSelector fs_i + create-glyph fs_i.(k) : glyph-construction : include : Fn gid k + if [not glyphDst.featureSelector] : set glyphDst.featureSelector {.} + set glyphDst.featureSelector.(k) fs_i.(k) glyph-block-export queryFeatureSelector select-variant italic-variant alias composite into-unicode turned dual hcombine vdual vcombine Rect Ring RingAt DotAt CircleRing CircleRingAt CircleDotAt OShape OShapeOutline 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 hookstart hookend CyrDescender Fork Miniature Thinner Widen FlipAround ScaleAround Realign ForceUpright Overlay diagCor CreateWaveShape NameUni PointingTo WithDerivatives diff --git a/glyphs/letters-unified-basic.ptl b/glyphs/letters-unified-basic.ptl index ea5b136b0..4924c1022 100644 --- a/glyphs/letters-unified-basic.ptl +++ b/glyphs/letters-unified-basic.ptl @@ -64,7 +64,8 @@ glyph-block LetterUnified-Basic : begin lambda [src sel] : glyph-construction include glyphs.(src) AS_BASE include glyphs.dotAbove - set currentGlyph.dotlessGlyph src + if [not currentGlyph.related] : set currentGlyph.related {.} + set currentGlyph.related.dotless src if [not sel] : assign-unicode unicode ### dotless i, i and iota @@ -388,6 +389,15 @@ glyph-block LetterUnified-Basic : begin save 'Lslash' 0x141 + sketch # LTildeOver + include glyphs.L AS_BASE + include : create-glyph : glyph-construction + include glyphs.tildeAbove + apply-transform : Upright + apply-transform : Translate (SB * 1.5 + STROKE * HVCONTRAST / 2 - markMiddle) (CAP * 0.525 - [mix aboveMarkBot aboveMarkTop 0.5]) + apply-transform : Italify + save 'LTildeOver' 0x2C62 + sketch # Ldot include glyphs.L AS_BASE include : Ring ([mix STROKE CAP 0.5] + DOTRADIUS) ([mix STROKE CAP 0.5] - DOTRADIUS) ([mix SB RIGHTSB 0.65] - DOTRADIUS) ([mix SB RIGHTSB 0.65] + DOTRADIUS) @@ -3160,6 +3170,7 @@ glyph-block LetterUnified-Basic : begin set-width WIDTH include MarkSet.capital include : NShape CAP SB RIGHTSB + set-anchor 'trailing' BASE (RIGHTSB - markHalfStroke) 0 save 'N' 'N' save 'Nu' 0x39D @@ -3197,6 +3208,7 @@ glyph-block LetterUnified-Basic : begin : else : include : tagged 'serifRB' : CenterBottomSerif (RIGHTSB - HALFSTROKE * HVCONTRAST) 0 JUT if (!para.isItalic) : begin include : tagged 'serifLB' : CenterBottomSerif (SB + HALFSTROKE * HVCONTRAST) 0 JUT + set-anchor 'trailing' BASE (RIGHTSB - markHalfStroke) 0 save 'n' 'n' save 'cyrpe.italic' @@ -3952,6 +3964,7 @@ glyph-block LetterUnified-Basic : begin set-width WIDTH include MarkSet.capital include : EShape CAP + set-anchor 'trailing' BASE (RIGHTSB - markHalfStroke) 0 save 'E' 'E' save 'Epsilon' 0x395 save 'cyrIe' 0x415 diff --git a/glyphs/numbers.ptl b/glyphs/numbers.ptl index f27816d03..b8206131f 100644 --- a/glyphs/numbers.ptl +++ b/glyphs/numbers.ptl @@ -64,7 +64,6 @@ glyph-block Numbers : begin select-variant 'zero.lnum' '0' (follow -- 'zero') select-variant 'zero.onum' (follow -- 'zero') - alias 'zero' nothing 'zero.lnum' define [OneShape top] : glyph-construction include : VBar (MIDDLE + ONEBALANCE) 0 top @@ -95,8 +94,6 @@ glyph-block Numbers : begin select-variant 'one.lnum' '1' (follow -- 'one') select-variant 'one.onum' (follow -- 'one') - alias 'one' nothing 'one.lnum' - define [TwoShape top] : glyph-construction @@ -124,7 +121,6 @@ glyph-block Numbers : begin include : TwoShape XH save 'two.onum' - alias 'two' nothing 'two.lnum' define [ThreeShape top] : glyph-construction local barcenter : top * BARPOS @@ -167,7 +163,7 @@ glyph-block Numbers : begin select-variant 'three.lnum' '3' (follow -- 'three') select-variant 'three.onum' (follow -- 'three') - alias 'three' nothing 'three.lnum' + define [FourShape top] : glyph-construction local bar (top * 0.4) @@ -188,7 +184,6 @@ glyph-block Numbers : begin include MarkSet.capital include : FourShape CAP save 'four.lnum' '4' - save 'four' sketch # four.onum include MarkSet.p include : FourShape (XH - DESCENDER) @@ -220,7 +215,6 @@ glyph-block Numbers : begin include MarkSet.capital include : FiveShape CAP FIVEBARPOS save 'five.lnum' '5' - save 'five' sketch # five.onum include MarkSet.p include : FiveShape (XH - DESCENDER) FIVEBARPOS @@ -257,7 +251,7 @@ glyph-block Numbers : begin g4 ([mix SB RIGHTSB 0.85] - HALFSTROKE * HVCONTRAST) CAP save 'six.lnum' '6' save 'six.onum' - save 'six' + define [SevenShape top] : glyph-construction include : HBarTop (SB + OXE) RIGHTSB top @@ -289,7 +283,7 @@ glyph-block Numbers : begin select-variant 'seven.lnum' '7' (follow -- 'seven') select-variant 'seven.onum' (follow -- 'seven') - alias 'seven' nothing 'seven.lnum' + local EightPr : linreg 18 0.85 120 0.975 STROKE define [EightShape top] : begin @@ -317,7 +311,7 @@ glyph-block Numbers : begin include : EightShape CAP save 'eight.lnum' '8' save 'eight.onum' - save 'eight' + # There is an "eight without lower contour" shape used for /propto sketch # rotetedpropto @@ -365,7 +359,7 @@ glyph-block Numbers : begin include MarkSet.capital include : NineShape CAP save 'nine.lnum' '9' - save 'nine' + sketch include MarkSet.p include : NineShape (XH - DESCENDER) @@ -375,8 +369,8 @@ glyph-block Numbers : begin sketch # ten include MarkSet.capital set-width : WIDTH * 2 - include glyphs.one + include glyphs.'one.lnum' apply-transform : Translate (-WIDTH) 0 - include glyphs.zero + include glyphs.'zero.lnum' apply-transform : Translate WIDTH 0 save 'ten' diff --git a/glyphs/overmarks.ptl b/glyphs/overmarks.ptl index 56e9a63be..057d3944d 100644 --- a/glyphs/overmarks.ptl +++ b/glyphs/overmarks.ptl @@ -1,7 +1,10 @@ $$include '../meta/macros.ptl' +import '../support/transform' as : Transform && [object [transformPoint tp]] +import [curveToContour OffsetCurve] from '../support/curve-util' import [mix linreg clamp fallback] from '../support/utils' import [designParameters] from '../meta/aesthetics' +import [CubicBezierCurve autoQuadify] from "primitive-quadify-off-curves" glyph-module @@ -202,14 +205,16 @@ glyph-block Overmarks : begin local tildeWave : [linreg hsvhThin 2.925 hsvhHeav 2.375 hsvh] * [linreg defaultHvc 1 4.35 1.1 hvc] local tildeWaveX 0.51 - include : dispiro - widths.center (hs * 2 / CONTRAST) - g2 leftEnd tbot - bezcontrols.absolute - * [mix leftEnd rightEnd tildeWaveX]; * [mix tbot ttop tildeWave] - * [mix leftEnd rightEnd (1 - tildeWaveX)]; * [mix tbot ttop (1 - tildeWave)] - * 256; * important; * g2 - g2 rightEnd ttop + define z1 : tp currentGlyph.gizmo : object [x leftEnd] [y tbot] + define z2 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd tildeWaveX] [y : mix tbot ttop tildeWave] + define z3 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd (1 - tildeWaveX)] [y : mix tbot ttop (1 - tildeWave)] + define z4 : tp currentGlyph.gizmo : object [x rightEnd] [y ttop] + define bone : new CubicBezierCurve z1 z2 z3 z4 + + define inner : curveToContour [new OffsetCurve bone (+hs) HVCONTRAST] (1 / 256) + define outer : curveToContour [new OffsetCurve bone (-hs) HVCONTRAST] (1 / 256) + + currentGlyph.contours.push : inner.concat [outer.reverse] sketch # tildeAbove set-width 0 @@ -611,15 +616,11 @@ glyph-block Overmarks : begin save 'cedillaBelow' 0x327 - sketch # ogonekBelow - set-width 0 - + define [OgonekBelowShape] : glyph-construction local fine : markHalfStroke * [linreg 16 1 90 0.25 (markHalfStroke * 2)] local ogonekBot : [mix belowMarkTop belowMarkBot 0.75] + markStress * 2 local ogonekLeft : markMiddle + ogonekBot * 0.5 local ogonekRight : markMiddle + markExtend * 0.85 - set-anchor 'below' MARK markMiddle 0 markMiddle belowMarkBot - include : dispiro g4.left.start markMiddle O [widths 0 (fine * 2)] #archv @@ -628,8 +629,19 @@ glyph-block Overmarks : begin flat (markMiddle + markExtend * 0.25) ogonekBot [widths 0 (markStress * 2)] curl ogonekRight ogonekBot [heading RIGHTWARD] + sketch # ogonekBelow + set-width 0 + include : OgonekBelowShape + set-anchor 'below' MARK markMiddle 0 markMiddle belowMarkBot save 'ogonekBelow' 0x328 + sketch # ogonekAbove + set-width 0 + include : OgonekBelowShape + include : FlipAround markMiddle (XH / 2) + set-anchor 'above' MARK markMiddle XH markMiddle aboveMarkTop + save 'ogonekAbove' 0x1DCE + sketch # ogonekTR set-width 0 include glyphs.ogonekBelow @@ -1315,7 +1327,7 @@ glyph-block Overmarks : begin save id sketch # Spaced double mark - include glyphs.space AS_BASE + include glyphs.markBaseSpace AS_BASE include glyphs.(id) save ('spaced' + id) unicode @@ -1342,7 +1354,7 @@ glyph-block Overmarks : begin save 'psiliperispomeni' sketch # spaced_psiliperispomeni - include glyphs.space AS_BASE + include glyphs.markBaseSpace AS_BASE include glyphs.psiliperispomeni save 'spaced_psiliperispomeni' 0x1FCF @@ -1363,7 +1375,7 @@ glyph-block Overmarks : begin save 'dasiaperispomeni' sketch # spaced_dasiaperispomeni - include glyphs.space AS_BASE + include glyphs.markBaseSpace AS_BASE include glyphs.dasiaperispomeni save 'spaced_dasiaperispomeni' 0x1FDF diff --git a/glyphs/space.ptl b/glyphs/space.ptl index 15b889016..01c99a4ae 100644 --- a/glyphs/space.ptl +++ b/glyphs/space.ptl @@ -26,6 +26,12 @@ glyph-block Symbol-Mosaic-NotDef : begin set currentGlyph.cmpPriority (-100) save 'nbsp' 0xA0 + sketch # markBaseSpace + local df : DivFrame para.diversityI + set-width df.width + include df.markSet.e + save 'markBaseSpace' 0xE09D + sketch # en-space local df : DivFrame 1 set-width df.width diff --git a/glyphs/symbol-math.ptl b/glyphs/symbol-math.ptl index 5cffa5208..44200496f 100644 --- a/glyphs/symbol-math.ptl +++ b/glyphs/symbol-math.ptl @@ -73,14 +73,14 @@ glyph-block Symbol-Math-Letter-Like : begin if [not recursive] : for-width-kinds WIDE-WIDTH-1 : do local s : (RIGHTSB - SB - O * 4 + (MosaicWidth - WIDTH) * 0.5) / CAP local df : Miniature - glyphs -- {'eight' 'rotetedpropto'} + glyphs -- {'eight.lnum' 'rotetedpropto'} crowd -- 4 scale -- s slantAngle -- 0 sketch # infty set-width MosaicWidth - include df.eight + include df.'eight.lnum' apply-transform : Translate (-(WIDTH / 2)) (-CAP / 2) apply-transform : Rotate (Math.PI / 2) apply-transform : Scale s @@ -498,7 +498,7 @@ glyph-block Symbol-Math-VAndCup : begin turned 'doubleWedge' 0x2A53 'doubleVee' MIDDLE symbolMid sketch # cup - include : UShape operTop operBot OPERATORSTROKE true + include : UShape [DivFrame 1] operTop operBot OPERATORSTROKE true save 'cup' 0x222A branch include : DotAt MIDDLE (operBot + SMOOTH) [Math.min DOTRADIUS ((RIGHTSB - SB - OPERATORSTROKE * HVCONTRAST * 2) * (1 / 3))] diff --git a/glyphs/symbol-punctuation.ptl b/glyphs/symbol-punctuation.ptl index 1c92a0855..93636597c 100644 --- a/glyphs/symbol-punctuation.ptl +++ b/glyphs/symbol-punctuation.ptl @@ -1206,7 +1206,7 @@ glyph-block Symbol-Punctuation : begin composite 'asciicaret.low' glyphs.'asciicaret.high' [Upright] [Translate 0 (symbolMid - XH - ACCENT)] [Italify] MarkSet.plus select-variant 'asciicaret' '^' - composite 'degree' glyphs.space glyphs.ringAbove MarkZoom [into-unicode 0xB0] + composite 'degree' glyphs.markBaseSpace glyphs.ringAbove MarkZoom [into-unicode 0xB0] alias 'mdfPrime' 0x2B9 'prime' alias 'mdfDoublePrime' 0x2BA 'doubleprime' diff --git a/images/charvars.png b/images/charvars.png index 4b84db2d3..37966a6c9 100644 Binary files a/images/charvars.png and b/images/charvars.png differ diff --git a/images/languages.png b/images/languages.png index f2eebaa3b..1aab9b6d9 100644 Binary files a/images/languages.png and b/images/languages.png differ diff --git a/images/ligations.png b/images/ligations.png index 5a8a0bc1a..df9f9fb29 100644 Binary files a/images/ligations.png and b/images/ligations.png differ diff --git a/images/matrix.png b/images/matrix.png index b8c51a426..260dc4906 100644 Binary files a/images/matrix.png and b/images/matrix.png differ diff --git a/images/preview-all.png b/images/preview-all.png index c910b6d15..bff29c579 100644 Binary files a/images/preview-all.png and b/images/preview-all.png differ diff --git a/images/stylesets.png b/images/stylesets.png index ef6b0269d..595d483bd 100644 Binary files a/images/stylesets.png and b/images/stylesets.png differ diff --git a/images/weights.png b/images/weights.png index 3ff6e3ced..5221db7bd 100644 Binary files a/images/weights.png and b/images/weights.png differ diff --git a/otl/gsub-ccmp.ptl b/otl/gsub-ccmp.ptl index 68d973727..834f2d92c 100644 --- a/otl/gsub-ccmp.ptl +++ b/otl/gsub-ccmp.ptl @@ -14,9 +14,9 @@ export : define [buildCCMP sink glyphs markGlyphs] : begin foreach [{gid, g} : pairs-of glyphs] : if (gid.(0) !== ".") : begin if g.anchors.trailing : groupTR.push gid if g.anchors.lf : groupLF.push gid - if g.dotlessGlyph : begin + if (g.related && g.related.dotless) : begin dotlessFrom.push gid - dotlessTo.push g.dotlessGlyph + dotlessTo.push g.related.dotless define [IotaLF] : {'iotaBelow'} ~> {'iotaLF'} define [OgonekTrailing] : {'ogonekBelow'} ~> {'ogonekTR'} diff --git a/otl/gsub-pairing.ptl b/otl/gsub-pairing.ptl index 7ba2fa29e..6bc827297 100644 --- a/otl/gsub-pairing.ptl +++ b/otl/gsub-pairing.ptl @@ -1,5 +1,6 @@ import [add-common-feature add-feature add-lookup] from "./table-util" +# Name-driven feature pairs export : define [buildPairFeature sink tag1 tag2 glyphs glyphList] : begin local mapTag2 {.} local mapTag1 {.} diff --git a/otl/index.ptl b/otl/index.ptl index 738dec0e2..e088c7018 100644 --- a/otl/index.ptl +++ b/otl/index.ptl @@ -22,6 +22,8 @@ define [buildGSUB para glyphs glyphList markGlyphs] : begin define gsub : CreateEmptyTable set gsub.lookupDep {} + buildLOCL gsub para + buildPairFeature gsub 'lnum' 'onum' glyphs glyphList if (!para.forceMonospace || para.spacing > 0) : begin buildPairFeature gsub 'hwid' 'fwid' glyphs glyphList @@ -37,7 +39,6 @@ define [buildGSUB para glyphs glyphList markGlyphs] : begin buildLigations gsub plm glyphs buildCVSS gsub para glyphList - buildLOCL gsub para set gsub.lookupOrder : topsort gsub.lookupDep return gsub diff --git a/package.json b/package.json index e954e320d..a6a64b775 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iosevka", - "version": "3.0.0-rc.2", + "version": "3.0.0-rc.3", "main": "./generate.js", "engines": { "node": ">=8.4.0" diff --git a/support/curve-util.js b/support/curve-util.js new file mode 100644 index 000000000..af8f3483d --- /dev/null +++ b/support/curve-util.js @@ -0,0 +1,66 @@ +"use strict"; + +const quadify = require("primitive-quadify-off-curves"); + +exports.OffsetCurve = class OffsetCurve { + constructor(bone, offset, contrast) { + this.bone = bone; + this.offset = offset; + this.contrast = contrast; + } + eval(t) { + const c = this.bone.eval(t); + const d = this.bone.derivative(t); + const absD = Math.hypot(d.x, d.y); + return { + x: c.x - (d.y / absD) * this.offset * this.contrast, + y: c.y + (d.x / absD) * this.offset + }; + } + derivative(t) { + const DELTA = 1 / 0x10000; + const forward = this.eval(t + DELTA); + const backward = this.eval(t - DELTA); + return { + x: (forward.x - backward.x) / (2 * DELTA), + y: (forward.y - backward.y) / (2 * DELTA) + }; + } +}; + +exports.curveToContour = function(curve, err) { + let exitPoints = []; + const z0 = curve.eval(0); + const z1 = curve.eval(1); + exitPoints.push({ + x: z0.x, + y: z0.y, + cubic: false, + on: true + }); + const offPoints = quadify.autoQuadify(curve, err || 1); + for (let k = 0; k < offPoints.length; k++) { + const z = offPoints[k]; + if (k > 0) { + const z0 = offPoints[k - 1]; + exitPoints.push({ + x: (z.x + z0.x) / 2, + y: (z.y + z0.y) / 2, + on: true + }); + } + exitPoints.push({ + x: z.x, + y: z.y, + cubic: false, + on: false + }); + } + exitPoints.push({ + x: z1.x, + y: z1.y, + cubic: false, + on: true + }); + return exitPoints; +}; diff --git a/verdafile.js b/verdafile.js index 4e6cf0ec6..2f50f15d6 100644 --- a/verdafile.js +++ b/verdafile.js @@ -680,14 +680,14 @@ const UtilScriptFiles = computed("util-script-files", async target => { return [...js, ...ejs, ...md]; }); const ScriptFiles = computed.group("script-files", async (target, ext) => { - const [gen, meta, glyphs, support] = await target.need( + const ss = await target.need( ScriptsUnder(ext, `gen`), ScriptsUnder(ext, `glyphs`), ScriptsUnder(ext, `meta`), ScriptsUnder(ext, `otl`), ScriptsUnder(ext, `support`) ); - return [...gen, ...meta, ...glyphs, ...support]; + return ss.reduce((a, b) => [...a, ...b]); }); const JavaScriptFromPtl = computed("scripts-js-from-ptl", async target => { const [ptl] = await target.need(ScriptFiles("ptl"));