From 9424579c7514aaaebe9d90a354929d52aed57f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Thu, 23 Aug 2018 03:37:43 +0200 Subject: [PATCH] xgb-render: cleanup, tolerable glyph placement --- prototypes/xgb-xrender.go | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/prototypes/xgb-xrender.go b/prototypes/xgb-xrender.go index 5fbdf36..dba6687 100644 --- a/prototypes/xgb-xrender.go +++ b/prototypes/xgb-xrender.go @@ -53,6 +53,8 @@ type xgbCookie interface{ Check() error } // TODO: We actually need a higher-level function that also keeps track of // and loads glyphs into the X server. +// TODO: We also need a way to use kerning tables with this, inserting/removing +// advance pixels between neighboring characters. // compositeString makes an appropriate render.CompositeGlyphs request, // assuming that glyphs equal Unicode codepoints. @@ -109,8 +111,6 @@ func compositeString(c *xgb.Conn, op byte, src, dst render.Picture, } } -// --- - func main() { X, err := xgb.NewConn() if err != nil { @@ -224,12 +224,15 @@ func main() { log.Fatalln(err) } + // LCD subpixel rendering isn't supported. :( opts := &truetype.Options{ Size: 9, DPI: 96, // TODO: Take this from the screen or monitor. Hinting: font.HintingFull, } face := truetype.NewFace(f, opts) + bounds := f.Bounds(fixed.Int26_6(opts.Size * float64(opts.DPI) * + (64.0 / 72.0))) var rgbFormat render.Pictformat for _, pf := range pformats.Formats { @@ -249,17 +252,18 @@ func main() { // NOTE: A depth of 24 will not work, the server always rejects it. _ = render.CreateGlyphSet(X, gsid, rgbFormat) - //bounds := f.Bounds(c.PointToFixed(opts.Size)) - //log.Println("+%v", bounds) - // TODO: Seems like we want to use NRGBA. Or RGBA if the A is always 1. // Or implement our own image.Image for direct gamma-corrected RGB! - nrgb := image.NewRGBA(image.Rect(0, 0, 36, 36)) - //nrgb.Bounds() + nrgb := image.NewRGBA(image.Rect( + +bounds.Min.X.Floor(), + -bounds.Min.Y.Floor(), + +bounds.Max.X.Ceil(), + -bounds.Max.Y.Ceil(), + )) for r := rune(32); r < 128; r++ { dr, mask, maskp, advance, ok := face.Glyph( - fixed.P(0, 18) /* subpixel destination location */, r) + fixed.P(0, 0) /* subpixel destination location */, r) if !ok { log.Println("skip") continue @@ -270,16 +274,15 @@ func main() { } draw.Draw(nrgb, dr, mask, maskp, draw.Src) - _ = advance _ = render.AddGlyphs(X, gsid, 1, []uint32{uint32(r)}, []render.Glyphinfo{{ - Width: uint16(36), - Height: uint16(36), - X: int16(18), - Y: int16(18), - XOff: int16(18), - YOff: 0, + Width: uint16(nrgb.Rect.Size().X), + Height: uint16(nrgb.Rect.Size().Y), + X: int16(-bounds.Min.X.Floor()), + Y: int16(+bounds.Max.Y.Ceil()), + XOff: int16(advance.Ceil()), + YOff: int16(0), }}, []byte(nrgb.Pix)) } @@ -350,6 +353,9 @@ func main() { _ = compositeString(X, render.PictOpOver, whiteid, pid, 0 /* TODO: mask Pictureformat? */, gsid, 0, 0, 100, 100, fmt.Sprintf("%#06x - %#06x", start, end)) + _ = compositeString(X, render.PictOpOver, whiteid, pid, + 0 /* TODO: mask Pictureformat? */, gsid, 0, 0, 100, 150, + "The quick brown fox jumps over the lazy dog.") } for {