...

Source file src/gonum.org/v1/plot/text/plain.go

Documentation: gonum.org/v1/plot/text

     1  // Copyright ©2020 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package text // import "gonum.org/v1/plot/text"
     6  
     7  import (
     8  	"math"
     9  	"strings"
    10  
    11  	"gonum.org/v1/plot/font"
    12  	"gonum.org/v1/plot/vg"
    13  )
    14  
    15  // Plain is a text/plain handler.
    16  type Plain struct {
    17  	Fonts *font.Cache
    18  }
    19  
    20  var _ Handler = (*Plain)(nil)
    21  
    22  // Cache returns the cache of fonts used by the text handler.
    23  func (hdlr Plain) Cache() *font.Cache {
    24  	return hdlr.Fonts
    25  }
    26  
    27  // Extents returns the Extents of a font.
    28  func (hdlr Plain) Extents(fnt font.Font) font.Extents {
    29  	face := hdlr.Fonts.Lookup(fnt, fnt.Size)
    30  	return face.Extents()
    31  }
    32  
    33  // Lines splits a given block of text into separate lines.
    34  func (hdlr Plain) Lines(txt string) []string {
    35  	txt = strings.TrimRight(txt, "\n")
    36  	return strings.Split(txt, "\n")
    37  }
    38  
    39  // Box returns the bounding box of the given non-multiline text where:
    40  //   - width is the horizontal space from the origin.
    41  //   - height is the vertical space above the baseline.
    42  //   - depth is the vertical space below the baseline, a positive number.
    43  func (hdlr Plain) Box(txt string, fnt font.Font) (width, height, depth vg.Length) {
    44  	face := hdlr.Fonts.Lookup(fnt, fnt.Size)
    45  	ext := face.Extents()
    46  	width = face.Width(txt)
    47  	height = ext.Ascent
    48  	depth = ext.Descent
    49  
    50  	return width, height, depth
    51  }
    52  
    53  // Draw renders the given text with the provided style and position
    54  // on the canvas.
    55  func (hdlr Plain) Draw(c vg.Canvas, txt string, sty Style, pt vg.Point) {
    56  	txt = strings.TrimRight(txt, "\n")
    57  	if len(txt) == 0 {
    58  		return
    59  	}
    60  
    61  	fnt := hdlr.Fonts.Lookup(sty.Font, sty.Font.Size)
    62  	c.SetColor(sty.Color)
    63  
    64  	if sty.Rotation != 0 {
    65  		c.Push()
    66  		c.Rotate(sty.Rotation)
    67  	}
    68  
    69  	sin64, cos64 := math.Sincos(sty.Rotation)
    70  	cos := vg.Length(cos64)
    71  	sin := vg.Length(sin64)
    72  	pt.X, pt.Y = pt.Y*sin+pt.X*cos, pt.Y*cos-pt.X*sin
    73  
    74  	lines := hdlr.Lines(txt)
    75  	ht := sty.Height(txt)
    76  	pt.Y += ht*vg.Length(sty.YAlign) - fnt.Extents().Ascent
    77  	for i, line := range lines {
    78  		xoffs := vg.Length(sty.XAlign) * fnt.Width(line)
    79  		n := vg.Length(len(lines) - i)
    80  		c.FillString(fnt, pt.Add(vg.Point{X: xoffs, Y: n * sty.Font.Size}), line)
    81  	}
    82  
    83  	if sty.Rotation != 0 {
    84  		c.Pop()
    85  	}
    86  }
    87  

View as plain text