| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- package render
- import (
- "bytes"
- "image"
- "image/draw"
- "io"
- "github.com/go-text/typesetting/opentype/api"
- "github.com/go-text/typesetting/shaping"
- "github.com/srwiley/oksvg"
- "github.com/srwiley/rasterx"
- )
- func (r *Renderer) drawSVG(g shaping.Glyph, svg api.GlyphSVG, img draw.Image, x, y float32) error {
- pixWidth := int(fixed266ToFloat(g.Width) * r.PixScale)
- pixHeight := int(fixed266ToFloat(-g.Height) * r.PixScale)
- pix, err := renderSVGStream(bytes.NewReader(svg.Source), pixWidth, pixHeight)
- if err != nil {
- return err
- }
- rect := image.Rect(int(fixed266ToFloat(g.XBearing)*r.PixScale), int(fixed266ToFloat(-g.YBearing)*r.PixScale),
- pixWidth, pixHeight)
- draw.Draw(img, rect.Add(image.Point{X: int(x), Y: int(y)}), pix, image.Point{}, draw.Over)
- // ignore the svg.Outline shapes, as they are a fallback which we won't use
- return nil
- }
- func renderSVGStream(stream io.Reader, width, height int) (*image.NRGBA, error) {
- icon, err := oksvg.ReadIconStream(stream)
- if err != nil {
- return nil, err
- }
- iconAspect := float32(icon.ViewBox.W / icon.ViewBox.H)
- viewAspect := float32(width) / float32(height)
- imgW, imgH := width, height
- if viewAspect > iconAspect {
- imgW = int(float32(height) * iconAspect)
- } else if viewAspect < iconAspect {
- imgH = int(float32(width) / iconAspect)
- }
- icon.SetTarget(icon.ViewBox.X, icon.ViewBox.Y, float64(imgW), float64(imgH))
- out := image.NewNRGBA(image.Rect(0, 0, imgW, imgH))
- scanner := rasterx.NewScannerGV(int(icon.ViewBox.W), int(icon.ViewBox.H), out, out.Bounds())
- raster := rasterx.NewDasher(width, height, scanner)
- icon.Draw(raster, 1)
- return out, nil
- }
|