text.go raw

   1  // SPDX-License-Identifier: Unlicense OR MIT
   2  
   3  package text
   4  
   5  import (
   6  	"io"
   7  
   8  	"golang.org/x/image/math/fixed"
   9  
  10  	"github.com/p9c/p9/pkg/gel/gio/op"
  11  )
  12  
  13  // A Line contains the measurements of a line of text.
  14  type Line struct {
  15  	Layout Layout
  16  	// Width is the width of the line.
  17  	Width fixed.Int26_6
  18  	// Ascent is the height above the baseline.
  19  	Ascent fixed.Int26_6
  20  	// Descent is the height below the baseline, including
  21  	// the line gap.
  22  	Descent fixed.Int26_6
  23  	// Bounds is the visible bounds of the line.
  24  	Bounds fixed.Rectangle26_6
  25  }
  26  
  27  type Layout struct {
  28  	Text     string
  29  	Advances []fixed.Int26_6
  30  }
  31  
  32  // Style is the font style.
  33  type Style int
  34  
  35  // Weight is a font weight, in CSS units subtracted 400 so the zero value
  36  // is normal text weight.
  37  type Weight int
  38  
  39  // Font specify a particular typeface variant, style and weight.
  40  type Font struct {
  41  	Typeface Typeface
  42  	Variant  Variant
  43  	Style    Style
  44  	// Weight is the text weight. If zero, Normal is used instead.
  45  	Weight Weight
  46  }
  47  
  48  // Face implements text layout and shaping for a particular font. All
  49  // methods must be safe for concurrent use.
  50  type Face interface {
  51  	Layout(ppem fixed.Int26_6, maxWidth int, txt io.Reader) ([]Line, error)
  52  	Shape(ppem fixed.Int26_6, str Layout) op.CallOp
  53  }
  54  
  55  // Typeface identifies a particular typeface design. The empty
  56  // string denotes the default typeface.
  57  type Typeface string
  58  
  59  // Variant denotes a typeface variant such as "Mono" or "Smallcaps".
  60  type Variant string
  61  
  62  type Alignment uint8
  63  
  64  const (
  65  	Start Alignment = iota
  66  	End
  67  	Middle
  68  )
  69  
  70  const (
  71  	Regular Style = iota
  72  	Italic
  73  )
  74  
  75  const (
  76  	Normal Weight = 400 - 400
  77  	Medium Weight = 500 - 400
  78  	Bold   Weight = 600 - 400
  79  )
  80  
  81  func (a Alignment) String() string {
  82  	switch a {
  83  	case Start:
  84  		return "Start"
  85  	case End:
  86  		return "End"
  87  	case Middle:
  88  		return "Middle"
  89  	default:
  90  		panic("unreachable")
  91  	}
  92  }
  93