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  }