ajstarks / svgo

Go Language Library for SVG generation
Other
2.14k stars 169 forks source link

Requesting support for tspan #55

Closed Iriel closed 3 years ago

Iriel commented 3 years ago

Thanks for the useful library, one thing I found missing (and had to hack together myself) was support for tspan - as I was trying to center text with mixed styling.

This is what I ended up with in non-method form (the _svg functions are my replicas of the svgo private methods)

func startText(canvas *svg.SVG, x int, y int, s ...string) {
    _svg_printf(canvas, `<text %s %s`, _svg_loc(x, y), _svg_endstyle(s, ">"))
}

func addText(canvas *svg.SVG, t string, s ...string) {
    if len(s) == 0 {
        xml.Escape(canvas.Writer, []byte(t))
        return
    }
    _svg_printf(canvas, `<tspan %s`, _svg_endstyle(s, ">"))
    xml.Escape(canvas.Writer, []byte(t))
    _svg_printf(canvas, "</tspan>")
}

func endText(canvas *svg.SVG) {
    _svg_println(canvas, "</text>")
}
ajstarks commented 3 years ago

This looks interesting. How about:

// Textspan begins text, assuming a tspan will be included, end with TextEnd()
// Standard Reference: https://www.w3.org/TR/SVG11/text.html#TSpanElement
func (svg *SVG) Textspan(x int, y int, t string, s ...string) {
    svg.printf(`<text %s %s`, loc(x, y), endstyle(s, ">"))
    xml.Escape(svg.Writer, []byte(t))
}

// Span makes styled spanned text, should be proceeded by Textspan
// Standard Reference: https://www.w3.org/TR/SVG11/text.html#TSpanElement
func (svg *SVG) Span(t string, s ...string) {
    if len(s) == 0 {
        xml.Escape(svg.Writer, []byte(t))
        return
    }
    svg.printf(`<tspan %s`, endstyle(s, ">"))
    xml.Escape(svg.Writer, []byte(t))
    svg.printf(`</tspan>`)
}

// TextEnd ends spanned text
// Standard Reference: https://www.w3.org/TR/SVG11/text.html#TSpanElement
func (svg *SVG) TextEnd() {
    svg.println(`</text>`)
}
ajstarks commented 3 years ago

Example use:

package main

import (
    "os"

    svg "github.com/ajstarks/svgo"
)

func main() {
    width := 500
    height := 500
    canvas := svg.New(os.Stdout)
    canvas.Start(width, height)
    canvas.Circle(width/2, height/2, 100)
    canvas.Gstyle("text-anchor:middle;fill:white")
    canvas.Textspan(width/2, height/2, "Hello ", "font-size:30px")
    canvas.Span("SVG", "font-size:50px")
    canvas.TextEnd()
    canvas.Gend()
    canvas.End()
}

image

ajstarks commented 3 years ago

Added with https://github.com/ajstarks/svgo/commit/1f3ef52b4e33b96dd34ef41022003ee149f96de5

Iriel commented 3 years ago

Lovely thanks!