11package render
22
33import (
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.
9899func (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
151150func 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-
159154type singleFontMap struct {
160155 face * font.Face
161156}
0 commit comments