Further cleanup of point types
This commit is contained in:
parent
82cea0e06d
commit
e58a6965db
14 changed files with 231 additions and 252 deletions
|
@ -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)))
|
||||
);
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 : union
|
||||
new-glyph : glyph-proc
|
||||
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
|
||||
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
|
||||
|
|
|
@ -587,12 +587,12 @@ 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
|
||||
|
||||
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]
|
||||
|
|
|
@ -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 : ReverseContours : spiro-outline
|
||||
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)
|
||||
|
||||
include : dispiro
|
||||
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,15 +6955,14 @@ glyph-block Letter-Latin-Z : begin
|
|||
include : MarkSet.p
|
||||
local cor : 1.2 * HVContrast
|
||||
|
||||
include : HBarTop SB RightSB XH
|
||||
|
||||
include : ReverseContours : spiro-outline
|
||||
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)
|
||||
|
||||
include : dispiro
|
||||
dispiro
|
||||
widths.lhs
|
||||
g4 (SB - OXHook) 0
|
||||
alsoThru 0.36 0.6 important
|
||||
|
@ -7406,16 +7413,15 @@ 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
|
||||
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)
|
||||
|
||||
include : dispiro
|
||||
dispiro
|
||||
widths.rhs
|
||||
flat ezhLeft yMidBar [heading Rightward]
|
||||
curl (Middle - CorrectionOMidS) yMidBar
|
||||
|
|
|
@ -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,7 +1443,8 @@ 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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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) {
|
||||
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.cubicOffFrom(z1),
|
||||
Point.cubicOffFrom(z2),
|
||||
Point.cornerFrom(z3)
|
||||
Point.from(Point.Type.CubicStart, z1),
|
||||
Point.from(Point.Type.CubicEnd, z2),
|
||||
Point.from(Point.Type.Corner, z3)
|
||||
)
|
||||
);
|
||||
z0 = z3;
|
||||
j += 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case Point.Type.Quadratic: {
|
||||
const zc = z;
|
||||
let zf = contour[j + 1] || contour[0];
|
||||
const zfIsCorner = zf.on;
|
||||
if (!zfIsCorner) zf = Point.cornerFrom(zc).mix(0.5, zf);
|
||||
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)
|
||||
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++;
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue