Skip to content

Commit

Permalink
Merge ed30f1e into c062ce1
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverpool committed May 3, 2020
2 parents c062ce1 + ed30f1e commit 012a9c1
Show file tree
Hide file tree
Showing 15 changed files with 326 additions and 278 deletions.
74 changes: 37 additions & 37 deletions fontface.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ func (family *FontFamily) Face(size float64, col color.Color, style FontStyle, v
return FontFace{
family: family,
font: font,
size: size,
style: style,
variant: variant,
color: color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)},
Size: size,
Style: style,
Variant: variant,
Color: color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)},
deco: deco,
scale: scale,
voffset: voffset,
Scale: scale,
Voffset: voffset,
fauxItalic: fauxItalic,
fauxBold: fauxBold * size * scale,
}
Expand All @@ -182,23 +182,23 @@ type FontFace struct {
family *FontFamily
font *Font

size float64
style FontStyle
variant FontVariant
color color.RGBA
Size float64
Style FontStyle
Variant FontVariant
Color color.RGBA
deco []FontDecorator

scale, voffset, fauxBold, fauxItalic float64 // consequences of font style and variant
Scale, Voffset, fauxBold, fauxItalic float64 // consequences of font style and variant
}

// Equals returns true when two font face are equal. In particular this allows two adjacent text spans that use the same decoration to allow the decoration to span both elements instead of two separately.
func (ff FontFace) Equals(other FontFace) bool {
return ff.font == other.font && ff.size == other.size && ff.style == other.style && ff.variant == other.variant && ff.color == other.color && reflect.DeepEqual(ff.deco, other.deco)
return ff.font == other.font && ff.Size == other.Size && ff.Style == other.Style && ff.Variant == other.Variant && ff.Color == other.Color && reflect.DeepEqual(ff.deco, other.deco)
}

// Info returns the font name, size and style.
func (ff FontFace) Info() (name string, size float64, style FontStyle, variant FontVariant) {
return ff.font.name, ff.size, ff.style, ff.variant
// Name returns the name of the underlying font
func (ff FontFace) Name() string {
return ff.font.name
}

// FontMetrics contains a number of metrics that define a font face.
Expand All @@ -214,9 +214,9 @@ type FontMetrics struct {
// Metrics returns the font metrics. See https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png for an explanation of the different metrics.
func (ff FontFace) Metrics() FontMetrics {
buffer := &sfnt.Buffer{}
m, _ := ff.font.sfnt.Metrics(buffer, toI26_6(ff.size*ff.scale), font.HintingNone)
m, _ := ff.font.sfnt.Metrics(buffer, toI26_6(ff.Size*ff.Scale), font.HintingNone)
return FontMetrics{
Size: ff.size,
Size: ff.Size,
LineHeight: math.Abs(fromI26_6(m.Height)),
Ascent: math.Abs(fromI26_6(m.Ascent)),
Descent: math.Abs(fromI26_6(m.Descent)),
Expand All @@ -238,7 +238,7 @@ func (ff FontFace) Kerning(rPrev, rNext rune) float64 {
return 0.0
}

kern, err := ff.font.sfnt.Kern(buffer, prevIndex, nextIndex, toI26_6(ff.size*ff.scale), font.HintingNone)
kern, err := ff.font.sfnt.Kern(buffer, prevIndex, nextIndex, toI26_6(ff.Size*ff.Scale), font.HintingNone)
if err == nil {
return fromI26_6(kern)
}
Expand All @@ -257,12 +257,12 @@ func (ff FontFace) TextWidth(s string) float64 {
}

if i != 0 {
kern, err := ff.font.sfnt.Kern(buffer, prevIndex, index, toI26_6(ff.size*ff.scale), font.HintingNone)
kern, err := ff.font.sfnt.Kern(buffer, prevIndex, index, toI26_6(ff.Size*ff.Scale), font.HintingNone)
if err == nil {
w += fromI26_6(kern)
}
}
advance, err := ff.font.sfnt.GlyphAdvance(buffer, index, toI26_6(ff.size*ff.scale), font.HintingNone)
advance, err := ff.font.sfnt.GlyphAdvance(buffer, index, toI26_6(ff.Size*ff.Scale), font.HintingNone)
if err == nil {
w += fromI26_6(advance)
}
Expand Down Expand Up @@ -294,7 +294,7 @@ func (ff FontFace) ToPath(s string) (*Path, float64) {
return p, 0.0
}

segments, err := ff.font.sfnt.LoadGlyph(buffer, index, toI26_6(ff.size*ff.scale), nil)
segments, err := ff.font.sfnt.LoadGlyph(buffer, index, toI26_6(ff.Size*ff.Scale), nil)
if err != nil {
return p, 0.0
}
Expand All @@ -308,26 +308,26 @@ func (ff FontFace) ToPath(s string) (*Path, float64) {
}
end = fromP26_6(segment.Args[0])
end.X += ff.fauxItalic * -end.Y
p.MoveTo(x+end.X, ff.voffset-end.Y)
p.MoveTo(x+end.X, ff.Voffset-end.Y)
start0 = end
case sfnt.SegmentOpLineTo:
end = fromP26_6(segment.Args[0])
end.X += ff.fauxItalic * -end.Y
p.LineTo(x+end.X, ff.voffset-end.Y)
p.LineTo(x+end.X, ff.Voffset-end.Y)
case sfnt.SegmentOpQuadTo:
cp := fromP26_6(segment.Args[0])
end = fromP26_6(segment.Args[1])
cp.X += ff.fauxItalic * -cp.Y
end.X += ff.fauxItalic * -end.Y
p.QuadTo(x+cp.X, ff.voffset-cp.Y, x+end.X, ff.voffset-end.Y)
p.QuadTo(x+cp.X, ff.Voffset-cp.Y, x+end.X, ff.Voffset-end.Y)
case sfnt.SegmentOpCubeTo:
cp1 := fromP26_6(segment.Args[0])
cp2 := fromP26_6(segment.Args[1])
end = fromP26_6(segment.Args[2])
cp1.X += ff.fauxItalic * -cp1.Y
cp2.X += ff.fauxItalic * -cp2.Y
end.X += ff.fauxItalic * -end.Y
p.CubeTo(x+cp1.X, ff.voffset-cp1.Y, x+cp2.X, ff.voffset-cp2.Y, x+end.X, ff.voffset-end.Y)
p.CubeTo(x+cp1.X, ff.Voffset-cp1.Y, x+cp2.X, ff.Voffset-cp2.Y, x+end.X, ff.Voffset-end.Y)
}
}
if !p.Empty() && start0.Equals(end) {
Expand All @@ -338,12 +338,12 @@ func (ff FontFace) ToPath(s string) (*Path, float64) {
}

if i != 0 {
kern, err := ff.font.sfnt.Kern(buffer, prevIndex, index, toI26_6(ff.size*ff.scale), font.HintingNone)
kern, err := ff.font.sfnt.Kern(buffer, prevIndex, index, toI26_6(ff.Size*ff.Scale), font.HintingNone)
if err == nil {
x += fromI26_6(kern)
}
}
advance, err := ff.font.sfnt.GlyphAdvance(buffer, index, toI26_6(ff.size*ff.scale), font.HintingNone)
advance, err := ff.font.sfnt.GlyphAdvance(buffer, index, toI26_6(ff.Size*ff.Scale), font.HintingNone)
if err == nil {
x += fromI26_6(advance)
}
Expand All @@ -352,26 +352,26 @@ func (ff FontFace) ToPath(s string) (*Path, float64) {
return p, x
}

func (ff FontFace) boldness() int {
func (ff FontFace) Boldness() int {
boldness := 400
if ff.style&FontExtraLight == FontExtraLight {
if ff.Style&FontExtraLight == FontExtraLight {
boldness = 100
} else if ff.style&FontLight == FontLight {
} else if ff.Style&FontLight == FontLight {
boldness = 200
} else if ff.style&FontBook == FontBook {
} else if ff.Style&FontBook == FontBook {
boldness = 300
} else if ff.style&FontMedium == FontMedium {
} else if ff.Style&FontMedium == FontMedium {
boldness = 500
} else if ff.style&FontSemibold == FontSemibold {
} else if ff.Style&FontSemibold == FontSemibold {
boldness = 600
} else if ff.style&FontBold == FontBold {
} else if ff.Style&FontBold == FontBold {
boldness = 700
} else if ff.style&FontBlack == FontBlack {
} else if ff.Style&FontBlack == FontBlack {
boldness = 800
} else if ff.style&FontExtraBlack == FontExtraBlack {
} else if ff.Style&FontExtraBlack == FontExtraBlack {
boldness = 900
}
if ff.variant&FontSubscript != 0 || ff.variant&FontSuperscript != 0 {
if ff.Variant&FontSubscript != 0 || ff.Variant&FontSuperscript != 0 {
boldness += 300
if 1000 < boldness {
boldness = 1000
Expand Down
8 changes: 4 additions & 4 deletions fontface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ func TestFontFamily(t *testing.T) {

face := family.Face(12.0*ptPerMm, Black, FontRegular, FontNormal)
test.Float(t, face.fauxBold, 0.0)
test.T(t, face.boldness(), 400)
test.T(t, face.Boldness(), 400)

face = family.Face(12.0*ptPerMm, Black, FontBold|FontItalic, FontNormal)
test.Float(t, face.fauxBold, 0.24)
test.Float(t, face.fauxItalic, 0.3)
test.T(t, face.boldness(), 700)
test.T(t, face.Boldness(), 700)

face = family.Face(12.0*ptPerMm, Black, FontBold|FontItalic, FontSubscript)
test.Float(t, face.voffset, -12.0*0.33)
test.Float(t, face.Voffset, -12.0*0.33)
test.Float(t, face.fauxBold, 0.48*0.583)
test.Float(t, face.fauxItalic, 0.3)
test.T(t, face.boldness(), 1000)
test.T(t, face.Boldness(), 1000)
}

func TestFontFace(t *testing.T) {
Expand Down
44 changes: 22 additions & 22 deletions path.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (p *Path) Equals(q *Path) bool {
return false
}
for i := 0; i < len(p.d); i++ {
if !equal(p.d[i], q.d[i]) {
if !Equal(p.d[i], q.d[i]) {
return false
}
}
Expand Down Expand Up @@ -119,7 +119,7 @@ func (p *Path) Join(q *Path) *Path {
return q
}

if !equal(p.d[len(p.d)-3], q.d[1]) || !equal(p.d[len(p.d)-2], q.d[2]) {
if !Equal(p.d[len(p.d)-3], q.d[1]) || !Equal(p.d[len(p.d)-2], q.d[2]) {
return p.Append(q)
}

Expand Down Expand Up @@ -187,7 +187,7 @@ func (p *Path) Coords() []Point {
for i := 0; i < len(p.d); {
cmd := p.d[i]
i += cmdLen(cmd)
if cmd != closeCmd || !equal(coords[len(coords)-1].X, p.d[i-3]) || !equal(coords[len(coords)-1].Y, p.d[i-2]) {
if cmd != closeCmd || !Equal(coords[len(coords)-1].X, p.d[i-3]) || !Equal(coords[len(coords)-1].Y, p.d[i-2]) {
coords = append(coords, Point{p.d[i-3], p.d[i-2]})
}
}
Expand Down Expand Up @@ -220,7 +220,7 @@ func (p *Path) LineTo(x, y float64) *Path {
if cmdLen(lineToCmd) < len(p.d) {
prevStart = Point{p.d[len(p.d)-cmdLen(lineToCmd)-3], p.d[len(p.d)-cmdLen(lineToCmd)-2]}
}
if equal(end.Sub(start).AngleBetween(start.Sub(prevStart)), 0.0) {
if Equal(end.Sub(start).AngleBetween(start.Sub(prevStart)), 0.0) {
p.d[len(p.d)-3] = x
p.d[len(p.d)-2] = y
return p
Expand All @@ -243,7 +243,7 @@ func (p *Path) QuadTo(cpx, cpy, x, y float64) *Path {
end := Point{x, y}
if start.Equals(end) && start.Equals(cp) {
return p
} else if !start.Equals(end) && equal(end.Sub(start).AngleBetween(cp.Sub(start)), 0.0) && equal(end.Sub(start).AngleBetween(end.Sub(cp)), 0.0) {
} else if !start.Equals(end) && Equal(end.Sub(start).AngleBetween(cp.Sub(start)), 0.0) && Equal(end.Sub(start).AngleBetween(end.Sub(cp)), 0.0) {
return p.LineTo(end.X, end.Y)
}

Expand All @@ -264,7 +264,7 @@ func (p *Path) CubeTo(cpx1, cpy1, cpx2, cpy2, x, y float64) *Path {
end := Point{x, y}
if start.Equals(end) && start.Equals(cp1) && start.Equals(cp2) {
return p
} else if !start.Equals(end) && equal(end.Sub(start).AngleBetween(cp1.Sub(start)), 0.0) && equal(end.Sub(start).AngleBetween(end.Sub(cp1)), 0.0) && equal(end.Sub(start).AngleBetween(cp2.Sub(start)), 0.0) && equal(end.Sub(start).AngleBetween(end.Sub(cp2)), 0.0) {
} else if !start.Equals(end) && Equal(end.Sub(start).AngleBetween(cp1.Sub(start)), 0.0) && Equal(end.Sub(start).AngleBetween(end.Sub(cp1)), 0.0) && Equal(end.Sub(start).AngleBetween(cp2.Sub(start)), 0.0) && Equal(end.Sub(start).AngleBetween(end.Sub(cp2)), 0.0) {
return p.LineTo(end.X, end.Y)
}

Expand All @@ -287,7 +287,7 @@ func (p *Path) ArcTo(rx, ry, rot float64, large, sweep bool, x, y float64) *Path
if start.Equals(end) {
return p
}
if equal(rx, 0.0) || equal(ry, 0.0) {
if Equal(rx, 0.0) || Equal(ry, 0.0) {
return p.LineTo(end.X, end.Y)
}

Expand Down Expand Up @@ -340,7 +340,7 @@ func (p *Path) Arc(rx, ry, rot, theta0, theta1 float64) *Path {
startOpposite := center.Sub(p0)
p.ArcTo(rx, ry, rot, large, sweep, startOpposite.X, startOpposite.Y)
p.ArcTo(rx, ry, rot, large, sweep, start.X, start.Y)
if equal(math.Mod(dtheta, 2.0*math.Pi), 0.0) {
if Equal(math.Mod(dtheta, 2.0*math.Pi), 0.0) {
return p
}
}
Expand All @@ -357,7 +357,7 @@ func (p *Path) Close() *Path {
} else if p.d[len(p.d)-1] == moveToCmd {
p.d = p.d[:len(p.d)-cmdLen(moveToCmd)]
return p
} else if p.d[len(p.d)-1] == lineToCmd && equal(p.d[len(p.d)-3], end.X) && equal(p.d[len(p.d)-2], end.Y) {
} else if p.d[len(p.d)-1] == lineToCmd && Equal(p.d[len(p.d)-3], end.X) && Equal(p.d[len(p.d)-2], end.Y) {
p.d[len(p.d)-1] = closeCmd
p.d[len(p.d)-cmdLen(lineToCmd)] = closeCmd
return p
Expand All @@ -367,7 +367,7 @@ func (p *Path) Close() *Path {
if cmdLen(lineToCmd) < len(p.d) {
prevStart = Point{p.d[len(p.d)-cmdLen(lineToCmd)-3], p.d[len(p.d)-cmdLen(lineToCmd)-2]}
}
if equal(end.Sub(start).AngleBetween(start.Sub(prevStart)), 0.0) {
if Equal(end.Sub(start).AngleBetween(start.Sub(prevStart)), 0.0) {
p.d[len(p.d)-cmdLen(lineToCmd)] = closeCmd
p.d[len(p.d)-3] = end.X
p.d[len(p.d)-2] = end.Y
Expand Down Expand Up @@ -409,7 +409,7 @@ func (p *Path) simplifyToCoords() []Point {
coords = append(coords, coord)
}
i += cmdLen(cmd)
if cmd != closeCmd || !equal(coords[len(coords)-1].X, p.d[i-3]) || !equal(coords[len(coords)-1].Y, p.d[i-2]) {
if cmd != closeCmd || !Equal(coords[len(coords)-1].X, p.d[i-3]) || !Equal(coords[len(coords)-1].Y, p.d[i-2]) {
coords = append(coords, Point{p.d[i-3], p.d[i-2]})
}
}
Expand Down Expand Up @@ -984,7 +984,7 @@ func (p *Path) SplitAt(ts ...float64) []*Path {
q.MoveTo(r0.X, r0.Y)
j++
}
if !equal(t0, 1.0) {
if !Equal(t0, 1.0) {
q.QuadTo(r1.X, r1.Y, r2.X, r2.Y)
}
T += dT
Expand Down Expand Up @@ -1019,7 +1019,7 @@ func (p *Path) SplitAt(ts ...float64) []*Path {
q.MoveTo(r0.X, r0.Y)
j++
}
if !equal(t0, 1.0) {
if !Equal(t0, 1.0) {
q.CubeTo(r1.X, r1.Y, r2.X, r2.Y, r3.X, r3.Y)
}
T += dT
Expand Down Expand Up @@ -1054,7 +1054,7 @@ func (p *Path) SplitAt(ts ...float64) []*Path {
nextLarge = large2
j++
}
if !equal(startTheta, theta2) {
if !Equal(startTheta, theta2) {
q.ArcTo(rx, ry, phi*180.0/math.Pi, nextLarge, sweep, end.X, end.Y)
}
T += dT
Expand Down Expand Up @@ -1134,15 +1134,15 @@ func dashCanonical(offset float64, d []float64) (float64, []float64) {

// remove zeros except first and last
for i := 1; i < len(d)-1; i++ {
if equal(d[i], 0.0) {
if Equal(d[i], 0.0) {
d[i-1] += d[i+1]
d = append(d[:i], d[i+2:]...)
i--
}
}

// remove first zero, collapse with second and last
if equal(d[0], 0.0) {
if Equal(d[0], 0.0) {
if len(d) < 3 {
return 0.0, []float64{0.0}
}
Expand All @@ -1152,7 +1152,7 @@ func dashCanonical(offset float64, d []float64) (float64, []float64) {
}

// remove last zero, collapse with fist and second to last
if equal(d[len(d)-1], 0.0) {
if Equal(d[len(d)-1], 0.0) {
if len(d) < 3 {
return 0.0, []float64{}
}
Expand All @@ -1163,7 +1163,7 @@ func dashCanonical(offset float64, d []float64) (float64, []float64) {

// if there are zeros or negatives, don't draw any dashes
for i := 0; i < len(d); i++ {
if d[i] < 0.0 || equal(d[i], 0.0) {
if d[i] < 0.0 || Equal(d[i], 0.0) {
return 0.0, []float64{0.0}
}
}
Expand All @@ -1173,7 +1173,7 @@ REPEAT:
for len(d)%2 == 0 {
mid := len(d) / 2
for i := 0; i < mid; i++ {
if !equal(d[i], d[mid+i]) {
if !Equal(d[i], d[mid+i]) {
break REPEAT
}
}
Expand Down Expand Up @@ -1594,11 +1594,11 @@ func (p *Path) ToSVG() string {
case lineToCmd:
xStart, yStart := x, y
x, y = p.d[i+1], p.d[i+2]
if equal(x, xStart) && equal(y, yStart) {
if Equal(x, xStart) && Equal(y, yStart) {
// nothing
} else if equal(x, xStart) {
} else if Equal(x, xStart) {
fmt.Fprintf(&sb, "V%v", num(y))
} else if equal(y, yStart) {
} else if Equal(y, yStart) {
fmt.Fprintf(&sb, "H%v", num(x))
} else {
fmt.Fprintf(&sb, "L%v %v", num(x), num(y))
Expand Down
2 changes: 1 addition & 1 deletion path_intersection.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ func intersectionLineLine(a0, a1, b0, b1 Point) (Point, bool) {
da := a1.Sub(a0)
db := b1.Sub(b0)
div := da.PerpDot(db)
if equal(div, 0.0) {
if Equal(div, 0.0) {
return Point{}, false
}

Expand Down

0 comments on commit 012a9c1

Please sign in to comment.