diff --git a/font-src/gen/finalize/glyphs.js b/font-src/gen/finalize/glyphs.js index d3588a9b0..295b529bc 100644 --- a/font-src/gen/finalize/glyphs.js +++ b/font-src/gen/finalize/glyphs.js @@ -63,7 +63,6 @@ function regulateSimpleGlyph(g, skew) { function simplifyContours(source) { const sink = new FairizedShapeSink(); - TypoGeom.ShapeConv.transferGenericShape( TypoGeom.Fairize.fairizeBezierShape( TypoGeom.Boolean.removeOverlap( @@ -89,9 +88,7 @@ class FairizedShapeSink { if (this.lastContour.length > 2) { const zFirst = this.lastContour[0], zLast = this.lastContour[this.lastContour.length - 1]; - if (zFirst.on && zLast.on && zFirst.x === zLast.x && zFirst.y === zLast.y) { - this.lastContour.pop(); - } + if (isOccurrent(zFirst, zLast)) this.lastContour.pop(); this.contours.push(this.lastContour); } this.lastContour = []; @@ -101,7 +98,7 @@ class FairizedShapeSink { this.lineTo(x, y); } lineTo(x, y) { - const z = Point.cornerFromXY(x, y).round(CurveUtil.RECIP_GEOMETRY_PRECISION); + const z = Point.fromXY(Point.Type.Corner, x, y).round(CurveUtil.RECIP_GEOMETRY_PRECISION); while (this.lastContour.length >= 2) { const a = this.lastContour[this.lastContour.length - 2], b = this.lastContour[this.lastContour.length - 1]; @@ -117,15 +114,25 @@ class FairizedShapeSink { const offPoints = TypoGeom.Quadify.auto(arc, 1, 16); if (offPoints) { for (const z of offPoints) - this.lastContour.push(Point.offFrom(z).round(CurveUtil.RECIP_GEOMETRY_PRECISION)); + this.lastContour.push( + Point.from(Point.Type.Quadratic, z).round(CurveUtil.RECIP_GEOMETRY_PRECISION) + ); } this.lineTo(x, y); } } +function isOccurrent(zFirst, zLast) { + return ( + zFirst.type === Point.Type.Corner && + zLast.type === Point.Type.Corner && + zFirst.x === zLast.x && + zFirst.y === zLast.y + ); +} function isLineExtend(a, b, c) { return ( - a.on && - c.on && + a.type === Point.Type.Corner && + c.type === Point.Type.Corner && ((aligned(a.x, b.x, c.x) && between(a.y, b.y, c.y)) || (aligned(a.y, b.y, c.y) && between(a.x, b.x, c.x))) ); diff --git a/font-src/gen/otd-conv/glyphs.js b/font-src/gen/otd-conv/glyphs.js index 5c31c0cc1..bfb52eeca 100644 --- a/font-src/gen/otd-conv/glyphs.js +++ b/font-src/gen/otd-conv/glyphs.js @@ -1,4 +1,5 @@ const { Ot } = require("ot-builder"); +const Point = require("../../support/point"); class NamedGlyphStore { constructor() { @@ -48,7 +49,9 @@ class NamedGlyphStore { Ot.Glyph.Point.create( z.x, z.y, - z.on ? Ot.Glyph.PointType.Corner : Ot.Glyph.PointType.Quad + z.type === Point.Type.Quadratic + ? Ot.Glyph.PointType.Quad + : Ot.Glyph.PointType.Corner ) ); } diff --git a/font-src/glyphs/common/shapes.ptl b/font-src/glyphs/common/shapes.ptl index b9134015c..e5326d2a7 100644 --- a/font-src/glyphs/common/shapes.ptl +++ b/font-src/glyphs/common/shapes.ptl @@ -669,12 +669,6 @@ glyph-block CommonShapes : begin define [WithTransform tfm gr] : glyph-proc : include : new-glyph : composite-proc gr tfm - define [ReverseContours gr] : begin - local g : new-glyph gr - if g.contours : foreach contour [items-of g.contours] - contour.reverse - return g - define [clear-anchors] : glyph-proc set currentGlyph.markAnchors {.} set currentGlyph.markBnchors {.} @@ -688,4 +682,4 @@ glyph-block CommonShapes : begin corner [mix x1 x2 (-k)] [mix y1 y2 (-k)] corner [mix x1 x2 (1+k)] [mix y1 y2 (1+k)] - glyph-block-export Rect SquareAt Ring RingAt DotAt RingStroke RingStrokeAt DotStrokeAt CircleRing CircleRingAt CircleDotAt OShape OShapeOutline OBarLeftShape OBarRightShape LeftwardTopSerif LeftwardBottomSerif RightwardTopSerif RightwardBottomSerif CenterTopSerif CenterBottomSerif DownwardRightSerif UpwardRightSerif DownwardLeftSerif UpwardLeftSerif AIVSerifs AIHSerifs AINSerifs AICyrISerifs AIMSerifs HBar HBarTop HBarBottom HOverlayBar VBar VBarLeft VBarRight VerticalHook LegShape LeftHook HooktopLeftBar FlatSlashShape hookstart hookend CyrDescender CyrLeftDescender FlipAround ScaleAround Realign ForceUpright DiagCor CreateWaveShape NameUni PointingTo WithAIHSerifsMask WithTransform ReverseContours clear-anchors OBarLeftToothlessShape OBarLeftRoundedShape OBarRightToothlessShape OBarRightRoundedShape AsRadical ExtLineCenter DiagCorDs HCrossBar + glyph-block-export Rect SquareAt Ring RingAt DotAt RingStroke RingStrokeAt DotStrokeAt CircleRing CircleRingAt CircleDotAt OShape OShapeOutline OBarLeftShape OBarRightShape LeftwardTopSerif LeftwardBottomSerif RightwardTopSerif RightwardBottomSerif CenterTopSerif CenterBottomSerif DownwardRightSerif UpwardRightSerif DownwardLeftSerif UpwardLeftSerif AIVSerifs AIHSerifs AINSerifs AICyrISerifs AIMSerifs HBar HBarTop HBarBottom HOverlayBar VBar VBarLeft VBarRight VerticalHook LegShape LeftHook HooktopLeftBar FlatSlashShape hookstart hookend CyrDescender CyrLeftDescender FlipAround ScaleAround Realign ForceUpright DiagCor CreateWaveShape NameUni PointingTo WithAIHSerifsMask WithTransform clear-anchors OBarLeftToothlessShape OBarLeftRoundedShape OBarRightToothlessShape OBarRightRoundedShape AsRadical ExtLineCenter DiagCorDs HCrossBar diff --git a/font-src/glyphs/letter/cyrillic.ptl b/font-src/glyphs/letter/cyrillic.ptl index f1e99d422..5523a1b79 100644 --- a/font-src/glyphs/letter/cyrillic.ptl +++ b/font-src/glyphs/letter/cyrillic.ptl @@ -74,12 +74,12 @@ glyph-block Letter-Cyrillic-Yeri : begin include [refer-glyph 'cyrl/Yeri'] AS_BASE eject-contour 'serifYeriLT' local s : Math.max Stroke (XH * 0.1) - include : ReverseContours : spiro-outline - corner (SB - O) CAP + include : spiro-outline corner SB CAP - corner (SB - s) (CAP - s) - corner SB (CAP - s * 2) + corner (SB - O) CAP corner (SB - O) (CAP - s * 2) + corner SB (CAP - s * 2) + corner (SB - s) (CAP - s) create-glyph 'latinDe' 0x18B : glyph-proc include : MarkSet.capital @@ -370,8 +370,8 @@ glyph-block Letter-Cyrillic-El : begin include : VBarRight cutright 0 top include : HBar cutleft cutright (top - HalfStroke) include : LegShape - ztop -- [Point.cornerFromXY cutleft top] - zbot -- [Point.cornerFromXY [mix SB 0 [if SLAB 1 0.75]] 0] + ztop -- [Point.fromXY Point.Type.Corner cutleft top] + zbot -- [Point.fromXY Point.Type.Corner [mix SB 0 [if SLAB 1 0.75]] 0] xb -- cutleft2 if SLAB : begin include : RightwardTopSerif cutright top SideJut @@ -396,21 +396,25 @@ glyph-block Letter-Cyrillic-Zhe : begin define [CyrZheShape top midtop df] : glyph-proc local fine : AdviceStroke 3.3 df.div local midx : mix df.leftSB df.middle 0.3 - define [CyrAngleShape] : glyph-proc + define [CyrAngleShape] : begin local cor HVContrast local overshoot : if SLAB 0 (O * 3 * df.div) - include : ReverseContours : spiro-outline + return : spiro-outline corner (df.leftSB + overshoot) 0 corner (df.leftSB + fine * cor + overshoot) 0 corner (midx + fine * cor) (top / 2) corner (df.leftSB + fine * cor + overshoot) top corner (df.leftSB + overshoot) top corner midx (top / 2) - include : CyrAngleShape - include : FlipAround df.middle (top / 2) - include : CyrAngleShape - include : VBar df.middle 0 midtop fine - include : HBar midx (df.width - midx) (top / 2) fine + + include : union + new-glyph : glyph-proc + include : CyrAngleShape + include : FlipAround df.middle (top / 2) + CyrAngleShape + VBar df.middle 0 midtop fine + HBar midx (df.width - midx) (top / 2) fine + if SLAB : begin define fineK 0.1 include : LeftwardTopSerif (df.leftSB + fine * fineK) top SideJut @@ -789,8 +793,8 @@ glyph-block Letter-Cyrillic-Lje : begin local jut : Jut * 0.72 set-width df.width include : LegShape - ztop -- [Point.cornerFromXY xlefttop top] - zbot -- [Point.cornerFromXY [mix l 0 [if SLAB 1 0.75]] 0] + ztop -- [Point.fromXY Point.Type.Corner xlefttop top] + zbot -- [Point.fromXY Point.Type.Corner [mix l 0 [if SLAB 1 0.75]] 0] xb -- [mix l r 0.025] fine -- MVertStroke include : CyrYeriShape top diff --git a/font-src/glyphs/letter/greek.ptl b/font-src/glyphs/letter/greek.ptl index 27102fc5a..9249aafae 100644 --- a/font-src/glyphs/letter/greek.ptl +++ b/font-src/glyphs/letter/greek.ptl @@ -587,18 +587,18 @@ glyph-block Letter-Greek-Upper-Sigma : begin glyph-block-export SigmaShape define [SigmaShape] : params [df top bottom fine [noSerif false] [offsetLeft 0]] : glyph-proc local cor : DiagCor (top - bottom) (df.rightSB - df.leftSB) - - include : HBarTop (offsetLeft + df.leftSB) df.rightSB top fine - include : HBarBottom (offsetLeft + df.leftSB) df.rightSB bottom fine - local midx : df.middle - fine / 2 - include : ReverseContours : spiro-outline - corner (df.leftSB + offsetLeft) (bottom + fine) - corner (df.leftSB + offsetLeft + fine * cor) (bottom + fine) - corner (midx + offsetLeft + fine * cor) [mix bottom top 0.5] - corner (df.leftSB + offsetLeft + fine * cor) (top - fine) - corner (df.leftSB + offsetLeft) (top - fine) - corner (midx + offsetLeft) [mix bottom top 0.5] + + include : union + HBarTop (offsetLeft + df.leftSB) df.rightSB top fine + HBarBottom (offsetLeft + df.leftSB) df.rightSB bottom fine + spiro-outline + corner (df.leftSB + offsetLeft) (bottom + fine) + corner (df.leftSB + offsetLeft + fine * cor) (bottom + fine) + corner (midx + offsetLeft + fine * cor) [mix bottom top 0.5] + corner (df.leftSB + offsetLeft + fine * cor) (top - fine) + corner (df.leftSB + offsetLeft) (top - fine) + corner (midx + offsetLeft) [mix bottom top 0.5] if (!noSerif && SLAB) : begin include : DownwardRightSerif df.rightSB top VJut diff --git a/font-src/glyphs/letter/latin.ptl b/font-src/glyphs/letter/latin.ptl index 2648d03e1..51de00c05 100644 --- a/font-src/glyphs/letter/latin.ptl +++ b/font-src/glyphs/letter/latin.ptl @@ -1998,7 +1998,7 @@ glyph-block Letter-Latin-Lower-Y : begin eject-contour 'serifRT' include : yBaseSerif top bottom - define [SmallLambdaShape top bottom] : ReverseContours : glyph-proc + define [SmallLambdaShape top bottom] : union : glyph-proc set currentGlyph.gizmo : Italify (-para.slopeAngle) include : SmallYShape top bottom set currentGlyph.gizmo : Italify (+para.slopeAngle) @@ -2095,14 +2095,22 @@ glyph-block Letter-Latin-Lower-Y : begin create-glyph 'grek/lambda.straight' : glyph-proc include : MarkSet.b include : [GenSmallYShape true false true].SmallLambdaShape CAP 0 - set-base-anchor 'overlay' Middle (XH / 2) - create-derived 'lambdaSlash.straight' : LambdaBarOverlayShape create-glyph 'grek/lambda.curly' : glyph-proc include : MarkSet.b include : [GenSmallYShape false false true].SmallLambdaShape CAP 0 - set-base-anchor 'overlay' Middle (XH / 2) - create-derived 'lambdaSlash.curly' : LambdaBarOverlayShape + + create-glyph 'lambdaSlash.straight' : glyph-proc + include : MarkSet.b + include : union + refer-glyph 'grek/lambda.straight' + LambdaBarOverlayShape + + create-glyph 'lambdaSlash.curly' : glyph-proc + include : MarkSet.b + include : union + refer-glyph 'grek/lambda.curly' + LambdaBarOverlayShape select-variant 'grek/lambda' 0x3BB select-variant 'lambdaSlash' 0x19B (follow -- 'grek/lambda') @@ -2737,12 +2745,12 @@ glyph-block Letter-Latin-Lower-B : begin include [refer-glyph src] AS_BASE eject-contour 'serifLT' local s : Math.max (XH * 0.1) Stroke - include : ReverseContours : spiro-outline - corner (SB - O) CAP + include : spiro-outline corner SB CAP - corner (SB - s) (CAP - s) - corner SB (CAP - s * 2) + corner (SB - O) CAP corner (SB - O) (CAP - s * 2) + corner SB (CAP - s * 2) + corner (SB - s) (CAP - s) glyph-block-import Letter-Blackboard : BBS BBD BBBarLeft create-glyph 'mathbb/b' 0x1D553 : glyph-proc @@ -6791,11 +6799,11 @@ glyph-block Letter-Latin-Z : begin include : tagged 'strokeTop' : HBarTop SB RightSB CAP - include : ReverseContours : spiro-outline + include : spiro-outline corner SB Stroke - corner (SB + Stroke * cor) Stroke - corner RightSB (CAP - Stroke) corner (RightSB - Stroke * cor) (CAP - Stroke) + corner RightSB (CAP - Stroke) + corner (SB + Stroke * cor) Stroke include : tagged 'strokeBottom' : HBarBottom SB RightSB 0 @@ -6814,11 +6822,11 @@ glyph-block Letter-Latin-Z : begin include : tagged 'strokeTop' : HBarTop SB RightSB XH - include : ReverseContours : spiro-outline + include : spiro-outline corner SB Stroke - corner (SB + Stroke * cor) Stroke - corner RightSB (XH - Stroke) corner (RightSB - Stroke * cor) (XH - Stroke) + corner RightSB (XH - Stroke) + corner (SB + Stroke * cor) Stroke include : tagged 'strokeBottom' : HBarBottom SB RightSB 0 if SLAB : begin @@ -6926,20 +6934,20 @@ glyph-block Letter-Latin-Z : begin include : MarkSet.if local cor : 1.15 * HVContrast - include : HBarTop SB RightSB CAP + include : union + HBarTop SB RightSB CAP + spiro-outline + corner SB 0 + corner (SB + Stroke * cor) 0 + corner RightSB (CAP - Stroke) + corner (RightSB - Stroke * cor) (CAP - Stroke) + dispiro + widths.lhs + g4 SB 0 + alsoThru 0.36 0.6 important + flat (RightSB - 1) Descender + curl RightSB Descender - include : ReverseContours : spiro-outline - corner SB 0 - corner (SB + Stroke * cor) 0 - corner RightSB (CAP - Stroke) - corner (RightSB - Stroke * cor) (CAP - Stroke) - - include : dispiro - widths.lhs - g4 SB 0 - alsoThru 0.36 0.6 important - flat (RightSB - 1) Descender - curl RightSB Descender if SLAB : begin include : DownwardLeftSerif SB CAP VJut @@ -6947,20 +6955,19 @@ glyph-block Letter-Latin-Z : begin include : MarkSet.p local cor : 1.2 * HVContrast - include : HBarTop SB RightSB XH - - include : ReverseContours : spiro-outline - corner SB 0 - corner (SB + Stroke * cor) 0 - corner RightSB (XH - Stroke) - corner (RightSB - Stroke * cor) (XH - Stroke) - - include : dispiro - widths.lhs - g4 (SB - OXHook) 0 - alsoThru 0.36 0.6 important - flat (RightSB - 1) Descender - curl RightSB Descender + include : union + HBarTop SB RightSB XH + spiro-outline + corner SB 0 + corner (SB + Stroke * cor) 0 + corner RightSB (XH - Stroke) + corner (RightSB - Stroke * cor) (XH - Stroke) + dispiro + widths.lhs + g4 (SB - OXHook) 0 + alsoThru 0.36 0.6 important + flat (RightSB - 1) Descender + curl RightSB Descender if SLAB : begin include : DownwardLeftSerif SB XH VJut @@ -7406,27 +7413,26 @@ glyph-block Letter-Latin-Ezh : begin local ezhLeft : mix SB RightSB [fallback pleft 0.2] local ezhRight : mix SB RightSB [fallback pright 0.925] - include : HBarTop SB ezhRight top - - include : ReverseContours : spiro-outline - corner ezhLeft yMidBar - corner (ezhLeft + Stroke * cor) (yMidBar - HalfStroke) - corner (ezhLeft + Stroke * cor) yMidBar - corner ezhRight (top - Stroke) - corner (ezhRight - Stroke * cor) (top - Stroke) - - include : dispiro - widths.rhs - flat ezhLeft yMidBar [heading Rightward] - curl (Middle - CorrectionOMidS) yMidBar - archv - if hookless - : then : list - g4.down.mid (RightSB - OX) [mix yMidBar bot hookless] [heading Downward] - : else : list - g4 (RightSB - OX) [mix yMidBar bot : SmallSmoothB / (SmallSmoothA + SmallSmoothB)] - hookend bot - g4 SB (bot + Hook * (top - bot) / [fallback para.cap0 CAP]) + include : union + HBarTop SB ezhRight top + spiro-outline + corner ezhLeft yMidBar + corner (ezhLeft + Stroke * cor) (yMidBar - HalfStroke) + corner (ezhLeft + Stroke * cor) yMidBar + corner ezhRight (top - Stroke) + corner (ezhRight - Stroke * cor) (top - Stroke) + dispiro + widths.rhs + flat ezhLeft yMidBar [heading Rightward] + curl (Middle - CorrectionOMidS) yMidBar + archv + if hookless + : then : list + g4.down.mid (RightSB - OX) [mix yMidBar bot hookless] [heading Downward] + : else : list + g4 (RightSB - OX) [mix yMidBar bot : SmallSmoothB / (SmallSmoothA + SmallSmoothB)] + hookend bot + g4 SB (bot + Hook * (top - bot) / [fallback para.cap0 CAP]) if SLAB : begin include : DownwardLeftSerif SB top VJut diff --git a/font-src/glyphs/symbol/math.ptl b/font-src/glyphs/symbol/math.ptl index a85adfac6..ee34f1fbf 100644 --- a/font-src/glyphs/symbol/math.ptl +++ b/font-src/glyphs/symbol/math.ptl @@ -3,6 +3,7 @@ $$include '../../meta/macros.ptl' import [mix linreg clamp fallback] from '../../support/utils' import [DesignParameters] from '../../meta/aesthetics' +import '../../support/point' as Point glyph-module @@ -1442,14 +1443,15 @@ glyph-block Symbol-Math-APL : begin local corners : new-glyph : glyph-proc set this.gizmo : Translate 0 0 - foreach [c : items-of overlay.contours] : foreach [z : items-of c] : if z.on : do - define x z.x - define y z.y - include : spiro-outline - corner (x - sw) (y - sw) - corner (x + sw) (y - sw) - corner (x + sw) (y + sw) - corner (x - sw) (y + sw) + foreach [c : items-of overlay.contours] : foreach [z : items-of c] : do + if (z.type === Point.Type.Corner) : begin + define x z.x + define y z.y + include : spiro-outline + corner (x - sw) (y - sw) + corner (x + sw) (y - sw) + corner (x + sw) (y + sw) + corner (x - sw) (y + sw) foreach [r : range (0 - segs) till (segs)] : foreach [c : range (0 - segs) till (segs)] : do define dx : r / segs * sw diff --git a/font-src/glyphs/symbol/punctuation.ptl b/font-src/glyphs/symbol/punctuation.ptl index 63997873c..249fb3c95 100644 --- a/font-src/glyphs/symbol/punctuation.ptl +++ b/font-src/glyphs/symbol/punctuation.ptl @@ -966,11 +966,11 @@ glyph-block Symbol-Punctuation-Slashes-And-Number-Sign : begin local t : fallback _t ParenTop local b : fallback _b ParenBot local cor : (1 / 2) * HVContrast / [Math.sqrt (1 - [Math.pow ((r - l - Stroke) / (t - b)) 2])] - include : ReverseContours : spiro-outline - corner (l - w * cor) b - corner (l + w * cor) b - corner (r + w * cor) t + include : spiro-outline corner (r - w * cor) t + corner (r + w * cor) t + corner (l + w * cor) b + corner (l - w * cor) b create-glyph 'slash' '/' : glyph-proc include : SlashShape slashDefautLeft slashDefaultRight diff --git a/font-src/kits/boole-kit.ptl b/font-src/kits/boole-kit.ptl index 4c8d5c3e9..ea72af56d 100644 --- a/font-src/kits/boole-kit.ptl +++ b/font-src/kits/boole-kit.ptl @@ -12,6 +12,11 @@ export : define [SetupBuilders args] : begin if (k.length == 0) : return g local contourArcs : getArcsFromProc this k.0 + if (k.length === 1) : set contourArcs : TypoGeom.Boolean.removeOverlap + begin contourArcs + begin TypoGeom.Boolean.PolyFillType.pftNonZero + begin CurveUtil.BOOLE_RESOLUTION + foreach [item : items-of : k.slice 1] : begin set contourArcs : TypoGeom.Boolean.combine operator begin contourArcs diff --git a/font-src/meta/aesthetics.ptl b/font-src/meta/aesthetics.ptl index 245a00390..fa2025895 100644 --- a/font-src/meta/aesthetics.ptl +++ b/font-src/meta/aesthetics.ptl @@ -48,15 +48,15 @@ export : define [calculateMetrics para] : begin define HVContrast : Contrast * CosSlope + SinSlope * TanSlope # Orient parameters - define Upward : new Point (-HVContrast) 0 - define Downward : new Point HVContrast 0 - define Rightward : new Point TanSlope 1 - define Leftward : new Point (- TanSlope) (-1) + define Upward : new Point Point.Type.Corner (-HVContrast) 0 + define Downward : new Point Point.Type.Corner HVContrast 0 + define Rightward : new Point Point.Type.Corner TanSlope 1 + define Leftward : new Point Point.Type.Corner (- TanSlope) (-1) - define [UpwardT] : new Point (-HVContrast) 0 - define [DownwardT] : new Point HVContrast 0 - define [RightwardT] : new Point this.gizmo.yx 1 - define [LeftwardT] : new Point (- this.gizmo.yx) (-1) + define [UpwardT] : new Point Point.Type.Corner (-HVContrast) 0 + define [DownwardT] : new Point Point.Type.Corner HVContrast 0 + define [RightwardT] : new Point Point.Type.Corner this.gizmo.yx 1 + define [LeftwardT] : new Point Point.Type.Corner (- this.gizmo.yx) (-1) # Style parameters define O para.overshoot diff --git a/font-src/meta/macros.ptl b/font-src/meta/macros.ptl index d4491505a..6551c5916 100644 --- a/font-src/meta/macros.ptl +++ b/font-src/meta/macros.ptl @@ -130,7 +130,7 @@ define-macro glyph-block-import : syntax-rules HBarTop HBarBottom HOverlayBar VBar VBarLeft VBarRight VerticalHook LegShape LeftHook HooktopLeftBar FlatSlashShape hookstart hookend CyrDescender CyrLeftDescender FlipAround ScaleAround Realign ForceUpright DiagCor CreateWaveShape NameUni PointingTo - WithAIHSerifsMask WithTransform ReverseContours clear-anchors OBarLeftToothlessShape + WithAIHSerifsMask WithTransform clear-anchors OBarLeftToothlessShape OBarLeftRoundedShape OBarRightToothlessShape OBarRightRoundedShape AsRadical ExtLineCenter DiagCorDs HCrossBar] diff --git a/font-src/support/curve-util.js b/font-src/support/curve-util.js index 42f1487f3..78ff46127 100644 --- a/font-src/support/curve-util.js +++ b/font-src/support/curve-util.js @@ -34,47 +34,6 @@ exports.OffsetCurve = class OffsetCurve { } }; -exports.convertContourToCubic = function convertContourToCubic(contour) { - if (!contour || !contour.length) return []; - - const newContour = []; - let z0 = contour[0]; - newContour.push(Point.cornerFrom(z0)); - - for (let j = 1; j < contour.length; j++) { - const z = contour[j]; - if (z.on) { - newContour.push(Point.cornerFrom(z)); - z0 = z; - } else if (z.cubic) { - const z1 = z; - const z2 = contour[j + 1]; - const z3 = contour[j + 2]; - - newContour.push(Point.cubicOffFrom(z1)); - newContour.push(Point.cubicOffFrom(z2)); - newContour.push(Point.cornerFrom(z3)); - - z0 = z3; - j += 2; - } else { - const zc = z; - let zf = contour[j + 1] || contour[0]; - const zfIsCorner = zf.on; - if (!zfIsCorner) zf = Point.cornerFrom(zc).mix(0.5, zf); - - newContour.push(Point.cubicOffFrom(z0).mix(2 / 3, zc)); - newContour.push(Point.cubicOffFrom(zf).mix(2 / 3, zc)); - newContour.push(Point.cornerFrom(zf)); - - z0 = zf; - if (zfIsCorner) j++; - } - } - - return newContour; -}; - exports.convertShapeToArcs = function convertShapeToArcs(shape) { return shape.map(convertContourToArcs); }; @@ -83,48 +42,55 @@ function convertContourToArcs(contour) { if (!contour || !contour.length) return []; const newContour = []; - let z0 = Point.cornerFrom(contour[0]); + let z0 = Point.from(Point.Type.Corner, contour[0]); for (let j = 1; j < contour.length; j++) { const z = contour[j]; - if (z.on) { - newContour.push( - TypoGeom.Arcs.Bez3.fromStraightSegment( - new TypoGeom.Arcs.StraightSegment(z0, Point.cornerFrom(z)) - ) - ); - z0 = z; - } else if (z.cubic) { - const z1 = z; - const z2 = contour[j + 1]; - const z3 = contour[j + 2]; - newContour.push( - new TypoGeom.Arcs.Bez3( - z0, - Point.cubicOffFrom(z1), - Point.cubicOffFrom(z2), - Point.cornerFrom(z3) - ) - ); - z0 = z3; - j += 2; - } else { - const zc = z; - let zf = contour[j + 1] || contour[0]; - const zfIsCorner = zf.on; - if (!zfIsCorner) zf = Point.cornerFrom(zc).mix(0.5, zf); + switch (z.type) { + case Point.Type.CubicStart: { + const z1 = z; + const z2 = contour[j + 1]; + const z3 = contour[j + 2]; + newContour.push( + new TypoGeom.Arcs.Bez3( + z0, + Point.from(Point.Type.CubicStart, z1), + Point.from(Point.Type.CubicEnd, z2), + Point.from(Point.Type.Corner, z3) + ) + ); + z0 = z3; + j += 2; + break; + } + case Point.Type.Quadratic: { + const zc = z; + let zf = contour[j + 1] || contour[0]; + const zfIsCorner = zf.type === Point.Type.contour; + if (!zfIsCorner) zf = Point.from(Point.Type.Corner, zc).mix(0.5, zf); - newContour.push( - new TypoGeom.Arcs.Bez3( - z0, - Point.cubicOffFrom(z0).mix(2 / 3, zc), - Point.cubicOffFrom(zf).mix(2 / 3, zc), - Point.cornerFrom(zf) - ) - ); + newContour.push( + new TypoGeom.Arcs.Bez3( + z0, + Point.from(Point.Type.CubicStart, z0).mix(2 / 3, zc), + Point.from(Point.Type.CubicEnd, zf).mix(2 / 3, zc), + Point.from(Point.Type.Corner, zf) + ) + ); - z0 = zf; - if (zfIsCorner) j++; + z0 = zf; + if (zfIsCorner) j++; + break; + } + default: { + newContour.push( + TypoGeom.Arcs.Bez3.fromStraightSegment( + new TypoGeom.Arcs.StraightSegment(z0, Point.from(Point.Type.Corner, z)) + ) + ); + z0 = z; + break; + } } } @@ -146,18 +112,18 @@ exports.BezToContoursSink = class BezToContoursSink { } moveTo(x, y) { this.endShape(); - this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y)); } lineTo(x, y) { - this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y)); } curveTo(xc, yc, x, y) { - this.lastContour.push(Point.transformedXY(this.gizmo, xc, yc, false, false)); - this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Quadratic, xc, yc)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y)); } cubicTo(x1, y1, x2, y2, x, y) { - this.lastContour.push(Point.transformedXY(this.gizmo, x1, y1, false, true)); - this.lastContour.push(Point.transformedXY(this.gizmo, x2, y2, false, true)); - this.lastContour.push(Point.transformedXY(this.gizmo, x, y, true)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.CubicStart, x1, y1)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.CubicEnd, x2, y2)); + this.lastContour.push(Point.transformedXY(this.gizmo, Point.Type.Corner, x, y)); } }; diff --git a/font-src/support/glyph.js b/font-src/support/glyph.js index 488a5079c..d2e3113fd 100644 --- a/font-src/support/glyph.js +++ b/font-src/support/glyph.js @@ -216,7 +216,7 @@ module.exports = class Glyph { for (let k = 0; k < c1.length; k++) { const z1 = c1[k], z2 = c2[k]; - if (z1.x !== z2.x || z1.y !== z2.y || z1.on !== z2.on) return; + if (z1.x !== z2.x || z1.y !== z2.y || z1.type !== z2.type) return; } } this.semanticInclusions = [ diff --git a/font-src/support/point.js b/font-src/support/point.js index e1f15acaf..0d195daed 100644 --- a/font-src/support/point.js +++ b/font-src/support/point.js @@ -1,71 +1,63 @@ "use strict"; -module.exports = class Point { - constructor(x, y, on, cubic) { +class Point { + constructor(type, x, y) { + this.type = type; this.x = x; this.y = y; - this.on = on; - this.cubic = cubic; + } + get on() { + throw new Error("Unreachable"); + } + get cubic() { + throw new Error("Unreachable"); } add(z2) { return this.addScale(1, z2); } addScale(scale, z2) { - return new Point(this.x + scale * z2.x, this.y + scale * z2.y, this.on, this.cubic); + return new Point(this.type, this.x + scale * z2.x, this.y + scale * z2.y); } mix(scale, z2) { return new Point( + this.type, this.x + scale * (z2.x - this.x), - this.y + scale * (z2.y - this.y), - this.on, - this.cubic + this.y + scale * (z2.y - this.y) ); } scale(t) { - return new Point(t * this.x, t * this.y, this.on, this.cubic); + return new Point(this.type, t * this.x, t * this.y); } round(d) { - return new Point( - Math.round(d * this.x) / d, - Math.round(d * this.y) / d, - this.on, - this.cubic - ); + return new Point(this.type, Math.round(d * this.x) / d, Math.round(d * this.y) / d); } - static from(z, on, cubic) { - return new Point(z.x || 0, z.y || 0, on, cubic); + static from(type, z) { + return new Point(type, z.x || 0, z.y || 0); } - static cornerFrom(z) { - return new Point(z.x || 0, z.y || 0, true, false); - } - static offFrom(z) { - return new Point(z.x || 0, z.y || 0, false, false); - } - static cubicOffFrom(z) { - return new Point(z.x || 0, z.y || 0, false, true); - } - static cornerFromXY(x, y) { - return new Point(x || 0, y || 0, true, false); - } - static offFromXY(x, y) { - return new Point(x || 0, y || 0, false, false); - } - static cubicOffFromXY(x, y) { - return new Point(x || 0, y || 0, false, true); + static fromXY(type, x, y) { + return new Point(type, x || 0, y || 0); } static transformed(tfm, z) { - return Point.transformedXY(tfm, z.x, z.y, z.on, z.cubic); + return Point.transformedXY(tfm, z.type, z.x, z.y); } - static transformedXY(tfm, x, y, on, cubic) { + static transformedXY(tfm, type, x, y) { return new Point( + type, x * tfm.xx + y * tfm.yx + tfm.x || 0, - x * tfm.xy + y * tfm.yy + tfm.y || 0, - on, - cubic + x * tfm.xy + y * tfm.yy + tfm.y || 0 ); } static translated(z, dx, dy) { - return new Point(z.x + dx || 0, z.y + dy || 0, z.on, z.cubic); + return new Point(z.type, z.x + dx || 0, z.y + dy || 0); } +} + +Point.Type = { + Corner: 0, + CubicStart: 1, + CubicEnd: 2, + Quadratic: 3 }; + +module.exports = Point;