2015-03-17 23 views
13

Sto provando a renderizzare del testo su un png in un progetto Golang usando freetype/truetype. Come puoi vedere dall'allegato, sto provando a rendere 4 lettere in colonne - ogni lettera centrata nella colonna. Ho usato l'api TrueType per ottenere limiti e larghezze dei glifi, ma non sono stato in grado di convertirli per darmi un offset preciso per ciascun glifo. Ad esempio con il glifo O, dato il carattere che utilizzo. Ottengo le seguenti dimensioni:Allineare il testo in golang con Truetype

Hmetric {AdvanceWidth:543 LeftSideBearing:36} Bounds {XMin:0 YMin:-64 XMax:512 YMax:704} Advance width: 512

Con l'ultima dimensione di essere tornato da GlyphBuf.

ho reso usando il seguente:

size := 125.00 tileOffset := (int(tileWidth) * i) + int(tileWidth/2) pt := freetype.Pt(tileOffset, (imgH-newCharHeight)-int(size))

Come posso usare le dimensioni dei glifi restituiti da TrueType per compensare correttamente le lettere? Ho provato a utilizzare AdvanceWidth come codice in this plotinum dettagliato (riga 160) ma ciò non mi dà un risultato coerente su tutti gli glifi.

Example of rendering

+1

Eh ... è buffo che stavamo cercando in questo al mio lavoro la settimana scorsa. Ogni font ha proprietà di ascesa e discesa ... sporgenza/underhang, ecc. Fondamentalmente, hai bisogno di un'API che ti dia le dimensioni senza la salita .. quindi puoi posizionarlo correttamente. Gioca con il metodo 'Extents' in quell'API e le proprietà Ascent and Descent. Ti fornirò una risposta adeguata quando avrò una pausa oggi –

+1

Apoplogies - la mia terminologia è disattivata - Ascent e Descent riguardano il posizionamento verticale .. quello di cui hai bisogno è l'Advance o il Bounds di ciascun personaggio. Non penso che potresti condividere uno snippet completo usando 'AdvanceWidth'? –

risposta

8

Come suggerito da Simon la soluzione corretta è quella di utilizzare AdvanceWidth:

enter image description here

Crude esempio:

package main 

import (
    "flag" 
    "fmt" 
    "io/ioutil" 
    "log" 
    "image" 
    "bufio" 
    "image/draw" 
    "image/png" 
    "image/color" 
    "github.com/golang/freetype/truetype" 
    "golang.org/x/image/font" 
    "github.com/golang/freetype" 
    "os" 
) 

var (
    dpi  = flag.Float64("dpi", 72, "screen resolution in Dots Per Inch") 
    fontfile = flag.String("fontfile", "/usr/share/fonts/liberation/LiberationSerif-Regular.ttf", "filename of the ttf font") 
    hinting = flag.String("hinting", "none", "none | full") 
    size  = flag.Float64("size", 125, "font size in points") 
    spacing = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)") 
    wonb  = flag.Bool("whiteonblack", false, "white text on a black background") 
    text  = string("JOJO") 
) 


func main() { 
    flag.Parse() 
    fmt.Printf("Loading fontfile %q\n", *fontfile) 
    b, err := ioutil.ReadFile(*fontfile) 
    if err != nil { 
     log.Println(err) 
     return 
    } 
    f, err := truetype.Parse(b) 
    if err != nil { 
     log.Println(err) 
     return 
    } 

    // Freetype context 
    fg, bg := image.Black, image.White 
    rgba := image.NewRGBA(image.Rect(0, 0, 1000, 200)) 
    draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src) 
    c := freetype.NewContext() 
    c.SetDPI(*dpi) 
    c.SetFont(f) 
    c.SetFontSize(*size) 
    c.SetClip(rgba.Bounds()) 
    c.SetDst(rgba) 
    c.SetSrc(fg) 
    switch *hinting { 
    default: 
     c.SetHinting(font.HintingNone) 
    case "full": 
     c.SetHinting(font.HintingFull) 
    } 

    // Make some background 

    // Draw the guidelines. 
    ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff} 
    for rcount := 0; rcount < 4; rcount ++ { 
     for i := 0; i < 200; i++ { 
      rgba.Set(250*rcount, i, ruler) 
     } 
    } 

    // Truetype stuff 
    opts := truetype.Options{} 
    opts.Size = 125.0 
    face := truetype.NewFace(f, &opts) 


    // Calculate the widths and print to image 
    for i, x := range(text) { 
     awidth, ok := face.GlyphAdvance(rune(x)) 
     if ok != true { 
      log.Println(err) 
      return 
     } 
     iwidthf := int(float64(awidth)/64) 
     fmt.Printf("%+v\n", iwidthf) 

     pt := freetype.Pt(i*250+(125-iwidthf/2), 128) 
     c.DrawString(string(x), pt) 
     fmt.Printf("%+v\n", awidth) 
    } 


    // Save that RGBA image to disk. 
    outFile, err := os.Create("out.png") 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    defer outFile.Close() 
    bf := bufio.NewWriter(outFile) 
    err = png.Encode(bf, rgba) 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    err = bf.Flush() 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    fmt.Println("Wrote out.png OK.") 


} 
+0

È possibile in Vai calcolare l'Ascent/Descent o un Rectangin Rectangle per una stringa resa in un font TrueType? – Aaron

+0

Grazie per il buon esempio. Puoi spiegare queste due linee: 'iwidthf: = int (float64 (awidth)/64)' e 'pt: = freetype.Pt (i * 250 + (125-iwidthf/2), 128)' - quali sono i costanti lì? – kirhgoff

Problemi correlati