SetRunePosLR sets relative positions of each rune using a flat left-to-right text layout, based on font size info and additional extra letter and word spacing parameters (which can be negative)
(letterSpace, wordSpace, chsz float32, tabSize int)
| 313 | // left-to-right text layout, based on font size info and additional extra |
| 314 | // letter and word spacing parameters (which can be negative) |
| 315 | func (sr *Span) SetRunePosLR(letterSpace, wordSpace, chsz float32, tabSize int) { |
| 316 | if err := sr.IsValid(); err != nil { |
| 317 | // log.Println(err) |
| 318 | return |
| 319 | } |
| 320 | sr.Dir = styles.LRTB |
| 321 | sz := len(sr.Text) |
| 322 | prevR := rune(-1) |
| 323 | lspc := letterSpace |
| 324 | wspc := wordSpace |
| 325 | if tabSize == 0 { |
| 326 | tabSize = 4 |
| 327 | } |
| 328 | var fpos float32 |
| 329 | curFace := sr.Render[0].Face |
| 330 | TextFontRenderMu.Lock() |
| 331 | defer TextFontRenderMu.Unlock() |
| 332 | for i, r := range sr.Text { |
| 333 | rr := &(sr.Render[i]) |
| 334 | curFace = rr.CurFace(curFace) |
| 335 | |
| 336 | fht := math32.FromFixed(curFace.Metrics().Height) |
| 337 | if prevR >= 0 { |
| 338 | fpos += math32.FromFixed(curFace.Kern(prevR, r)) |
| 339 | } |
| 340 | rr.RelPos.X = fpos |
| 341 | rr.RelPos.Y = 0 |
| 342 | |
| 343 | if rr.Deco.HasFlag(styles.DecoSuper) { |
| 344 | rr.RelPos.Y = -0.45 * math32.FromFixed(curFace.Metrics().Ascent) |
| 345 | } |
| 346 | if rr.Deco.HasFlag(styles.DecoSub) { |
| 347 | rr.RelPos.Y = 0.15 * math32.FromFixed(curFace.Metrics().Ascent) |
| 348 | } |
| 349 | |
| 350 | // todo: could check for various types of special unicode space chars here |
| 351 | a, _ := curFace.GlyphAdvance(r) |
| 352 | a32 := math32.FromFixed(a) |
| 353 | if a32 == 0 { |
| 354 | a32 = .1 * fht // something.. |
| 355 | } |
| 356 | rr.Size = math32.Vec2(a32, fht) |
| 357 | |
| 358 | if r == '\t' { |
| 359 | col := int(math32.Ceil(fpos / chsz)) |
| 360 | curtab := col / tabSize |
| 361 | curtab++ |
| 362 | col = curtab * tabSize |
| 363 | cpos := chsz * float32(col) |
| 364 | if cpos > fpos { |
| 365 | fpos = cpos |
| 366 | } |
| 367 | } else { |
| 368 | fpos += a32 |
| 369 | if i < sz-1 { |
| 370 | fpos += lspc |
| 371 | if unicode.IsSpace(r) { |
| 372 | fpos += wspc |