Skip to content

Commit 35796c2

Browse files
authored
Merge pull request #28 from redawl/golang_x_vector
Use golang.org/x/image/vector directly
2 parents 38500c1 + 67a5132 commit 35796c2

5 files changed

Lines changed: 19 additions & 24 deletions

File tree

bitmap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func (r *Renderer) drawBitmap(g shaping.Glyph, bitmap font.GlyphBitmap, img draw
4141
}
4242

4343
if bitmap.Outline != nil {
44-
r.drawOutline(g, *bitmap.Outline, r.filler, r.fillerScale, x, y)
44+
r.drawOutline(*bitmap.Outline, r.fillerScale, x, y)
4545
}
4646
return nil
4747
}

render.go

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package render
22

33
import (
4+
"image"
45
"image/color"
56
"image/draw"
67
"math"
@@ -9,8 +10,8 @@ import (
910
"github.com/go-text/typesetting/font"
1011
"github.com/go-text/typesetting/font/opentype"
1112
"github.com/go-text/typesetting/shaping"
12-
"github.com/srwiley/rasterx"
1313
"golang.org/x/image/math/fixed"
14+
"golang.org/x/image/vector"
1415
)
1516

1617
// Renderer defines a type that can render strings to a bitmap canvas.
@@ -30,7 +31,7 @@ type Renderer struct {
3031
segmenter shaping.Segmenter
3132
shaper shaping.HarfbuzzShaper
3233
wrapper shaping.LineWrapper
33-
filler *rasterx.Filler
34+
rasterizer *vector.Rasterizer
3435
fillerScale float32
3536
}
3637

@@ -96,17 +97,16 @@ func (r *Renderer) DrawStringAt(str string, img draw.Image, x, y int, face *font
9697
// Note that startX and startY are not multiplied by the `PixScale` value as they refer to output coordinates.
9798
// The return value is the X pixel position of the end of the drawn string.
9899
func (r *Renderer) DrawShapedRunAt(run shaping.Output, img draw.Image, startX, startY int) int {
100+
if r.rasterizer == nil {
101+
r.rasterizer = &vector.Rasterizer{}
102+
}
103+
r.rasterizer.Reset(img.Bounds().Dx(), img.Bounds().Dy())
99104
if r.PixScale == 0 {
100105
r.PixScale = 1
101106
}
102107
scale := r.FontSize * r.PixScale / float32(run.Face.Upem())
103108
r.fillerScale = scale
104109

105-
b := img.Bounds()
106-
scanner := rasterx.NewScannerGV(b.Dx(), b.Dy(), img, b)
107-
f := rasterx.NewFiller(b.Dx(), b.Dy(), scanner)
108-
r.filler = f
109-
f.SetColor(r.Color)
110110
x := float32(startX)
111111
y := float32(startY)
112112
for _, g := range run.Glyphs {
@@ -115,7 +115,7 @@ func (r *Renderer) DrawShapedRunAt(run shaping.Output, img draw.Image, startX, s
115115
data := run.Face.GlyphData(g.GlyphID)
116116
switch format := data.(type) {
117117
case font.GlyphOutline:
118-
r.drawOutline(g, format, f, scale, xPos, yPos)
118+
r.drawOutline(format, scale, xPos, yPos)
119119
case font.GlyphBitmap:
120120
_ = r.drawBitmap(g, format, img, xPos, yPos)
121121
case font.GlyphSVG:
@@ -124,38 +124,33 @@ func (r *Renderer) DrawShapedRunAt(run shaping.Output, img draw.Image, startX, s
124124

125125
x += fixed266ToFloat(g.Advance) * r.PixScale
126126
}
127-
f.Draw()
128-
r.filler = nil
127+
r.rasterizer.Draw(img, img.Bounds(), image.NewUniform(r.Color), image.Point{})
129128
return int(math.Ceil(float64(x)))
130129
}
131130

132-
func (r *Renderer) drawOutline(g shaping.Glyph, bitmap font.GlyphOutline, f *rasterx.Filler, scale float32, x, y float32) {
131+
func (r *Renderer) drawOutline(bitmap font.GlyphOutline, scale float32, x, y float32) {
132+
raster := r.rasterizer
133133
for _, s := range bitmap.Segments {
134134
switch s.Op {
135135
case opentype.SegmentOpMoveTo:
136-
f.Start(fixed.Point26_6{X: floatToFixed266(s.Args[0].X*scale + x), Y: floatToFixed266(-s.Args[0].Y*scale + y)})
136+
raster.MoveTo(s.Args[0].X*scale+x, -s.Args[0].Y*scale+y)
137137
case opentype.SegmentOpLineTo:
138-
f.Line(fixed.Point26_6{X: floatToFixed266(s.Args[0].X*scale + x), Y: floatToFixed266(-s.Args[0].Y*scale + y)})
138+
raster.LineTo(s.Args[0].X*scale+x, -s.Args[0].Y*scale+y)
139139
case opentype.SegmentOpQuadTo:
140-
f.QuadBezier(fixed.Point26_6{X: floatToFixed266(s.Args[0].X*scale + x), Y: floatToFixed266(-s.Args[0].Y*scale + y)},
141-
fixed.Point26_6{X: floatToFixed266(s.Args[1].X*scale + x), Y: floatToFixed266(-s.Args[1].Y*scale + y)})
140+
raster.QuadTo(s.Args[0].X*scale+x, -s.Args[0].Y*scale+y, s.Args[1].X*scale+x, -s.Args[1].Y*scale+y)
142141
case opentype.SegmentOpCubeTo:
143-
f.CubeBezier(fixed.Point26_6{X: floatToFixed266(s.Args[0].X*scale + x), Y: floatToFixed266(-s.Args[0].Y*scale + y)},
144-
fixed.Point26_6{X: floatToFixed266(s.Args[1].X*scale + x), Y: floatToFixed266(-s.Args[1].Y*scale + y)},
145-
fixed.Point26_6{X: floatToFixed266(s.Args[2].X*scale + x), Y: floatToFixed266(-s.Args[2].Y*scale + y)})
142+
raster.CubeTo(s.Args[0].X*scale+x, -s.Args[0].Y*scale+y,
143+
s.Args[1].X*scale+x, -s.Args[1].Y*scale+y,
144+
s.Args[2].X*scale+x, -s.Args[2].Y*scale+y)
146145
}
147146
}
148-
f.Stop(true)
147+
raster.ClosePath()
149148
}
150149

151150
func fixed266ToFloat(i fixed.Int26_6) float32 {
152151
return float32(float64(i) / 64)
153152
}
154153

155-
func floatToFixed266(f float32) fixed.Int26_6 {
156-
return fixed.Int26_6(int(float64(f) * 64))
157-
}
158-
159154
type singleFontMap struct {
160155
face *font.Face
161156
}

testdata/mixed_ltr_rtl.png

-65 Bytes
Loading

testdata/out.png

-111 Bytes
Loading

testdata/out_hindi.png

9 Bytes
Loading

0 commit comments

Comments
 (0)