...

Package textmeasure

import "oss.terrastruct.com/d2/lib/textmeasure"
Overview
Index

Overview ▾

Constants

these are css values from github-markdown.css so we can accurately compute the rendered dimensions

const (
    MarkdownFontSize   = d2fonts.FONT_SIZE_M
    MarkdownLineHeight = 1.5

    PaddingLeft_ul_ol_em = 2.
    MarginBottom_ul      = 16.

    MarginTop_li_p  = 16.
    MarginTop_li_em = 0.25
    MarginBottom_p  = 16.

    LineHeight_h           = 1.25
    MarginTop_h            = 24
    MarginBottom_h         = 16
    PaddingBottom_h1_h2_em = 0.3
    BorderBottom_h1_h2     = 1

    Height_hr_em       = 0.25
    MarginTopBottom_hr = 24

    Padding_pre          = 16
    MarginBottom_pre     = 16
    LineHeight_pre       = 1.45
    FontSize_pre_code_em = 0.85

    PaddingTopBottom_code_em = 0.2
    PaddingLeftRight_code_em = 0.4

    PaddingLR_blockquote_em  = 1.
    MarginBottom_blockquote  = 16
    BorderLeft_blockquote_em = 0.25
)
const CODE_LINE_HEIGHT = 1.3
const SIZELESS_FONT_SIZE = 0
const TAB_SIZE = 4

Variables

ASCII is a set of all ASCII runes. These runes are codepoints from 32 to 127 inclusive.

var ASCII []rune

func HeaderToFontSize

func HeaderToFontSize(baseFontSize int, header string) int

func MeasureMarkdown

func MeasureMarkdown(mdText string, ruler *Ruler, fontFamily *d2fonts.FontFamily, fontSize int) (width, height int, err error)

func NewAtlas

func NewAtlas(face font.Face, runeSets ...[]rune) *atlas

NewAtlas creates a new atlas containing glyphs of the union of the given sets of runes (plus unicode.ReplacementChar) from the given font face.

Creating an atlas is rather expensive, do not create a new atlas each frame.

Do not destroy or close the font.Face after creating the atlas. atlas still uses it.

func RenderMarkdown

func RenderMarkdown(m string) (string, error)

type Ruler

Ruler allows for effiecient and convenient text drawing.

To create a Ruler object, use the New constructor:

txt := text.New(pixel.ZV, text.NewAtlas(face, text.ASCII))

As suggested by the constructor, a Ruler object is always associated with one font face and a fixed set of runes. For example, the Ruler we created above can draw text using the font face contained in the face variable and is capable of drawing ASCII characters.

Here we create a Ruler object which can draw ASCII and Katakana characters:

txt := text.New(0, text.NewAtlas(face, text.ASCII, text.RangeTable(unicode.Katakana)))

Similarly to IMDraw, Ruler functions as a buffer. It implements io.Writer interface, so writing text to it is really simple:

fmt.Print(txt, "Hello, world!")

Newlines, tabs and carriage returns are supported.

Finally, if we want the written text to show up on some other Target, we can draw it:

txt.Draw(target)

Ruler exports two important fields: Orig and Dot. Dot is the position where the next character will be written. Dot is automatically moved when writing to a Ruler object, but you can also manipulate it manually. Orig specifies the text origin, usually the top-left dot position. Dot is always aligned to Orig when writing newlines. The Clear method resets the Dot to Orig.

type Ruler struct {
    // Orig specifies the text origin, usually the top-left dot position. Dot is always aligned
    // to Orig when writing newlines.
    Orig *geo.Point

    // Dot is the position where the next character will be written. Dot is automatically moved
    // when writing to a Ruler object, but you can also manipulate it manually
    Dot *geo.Point

    // lineHeight is the vertical distance between two lines of text.
    //
    // Example:
    //   txt.lineHeight = 1.5 * txt.atlas.lineHeight
    LineHeightFactor float64
    // contains filtered or unexported fields
}

func NewRuler

func NewRuler() (*Ruler, error)

New creates a new Ruler capable of drawing runes contained in the provided atlas. Orig and Dot will be initially set to orig.

Here we create a Ruler capable of drawing ASCII characters using the Go Regular font.

ttf, err := truetype.Parse(goregular.TTF)
if err != nil {
    panic(err)
}
face := truetype.NewFace(ttf, &truetype.Options{
    Size: 14,
})
txt := text.New(orig, text.NewAtlas(face, text.ASCII))

func (*Ruler) HasFontFamilyLoaded

func (r *Ruler) HasFontFamilyLoaded(fontFamily *d2fonts.FontFamily) bool

func (*Ruler) Measure

func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int)

func (*Ruler) MeasureMono

func (t *Ruler) MeasureMono(font d2fonts.Font, s string) (width, height int)

func (*Ruler) MeasurePrecise

func (t *Ruler) MeasurePrecise(font d2fonts.Font, s string) (width, height float64)