github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/framework/richtext/draw_gio.go (about) 1 package richtext 2 3 import ( 4 "unsafe" 5 6 "github.com/gop9/olt/framework/font" 7 8 ifont "golang.org/x/image/font" 9 10 "golang.org/x/image/math/fixed" 11 12 "github.com/gop9/olt/gio/font/opentype" 13 "github.com/gop9/olt/gio/text" 14 "github.com/gop9/olt/gio/unit" 15 ) 16 17 type fontFace struct { 18 fnt *opentype.Font 19 shaper *text.Shaper 20 size int 21 fsize fixed.Int26_6 22 metrics ifont.Metrics 23 } 24 25 func fontFace2fontFace(f *font.Face) *fontFace { 26 return (*fontFace)(unsafe.Pointer(f)) 27 } 28 29 func (face *fontFace) layout(str string, width int) *text.Layout { 30 if width < 0 { 31 width = 1e6 32 } 33 return face.shaper.Layout(face, text.Font{}, str, text.LayoutOptions{MaxWidth: width}) 34 } 35 36 func (face *fontFace) Px(v unit.Value) int { 37 return face.size 38 } 39 40 func (rtxt *RichText) calcAdvances(partial int) { 41 if rtxt.adv != nil && partial == 0 { 42 rtxt.adv = rtxt.adv[:0] 43 } 44 pos := int32(0) 45 var siter styleIterator 46 siter.Init(rtxt) 47 for _, chunk := range rtxt.chunks[partial:] { 48 // Note chunk is a copy of the element in the slice so we can modify it with impunity 49 for chunk.len() > 0 { 50 len := chunk.len() 51 if siter.styleSel.E < pos+len { 52 len = siter.styleSel.E - pos 53 } 54 55 if chunk.b != nil { 56 panic("not implemented") 57 } 58 59 txt := fontFace2fontFace(&siter.styleSel.Face).layout(chunk.s[:len], 1e6) 60 for _, line := range txt.Lines { 61 rtxt.adv = append(rtxt.adv, line.Text.Advances...) 62 } 63 64 siter.AdvanceTo(pos + len) 65 pos += len 66 chunk.s = chunk.s[len:] 67 } 68 } 69 }