...

Source file src/golang.org/x/image/font/basicfont/basicfont.go

Documentation: golang.org/x/image/font/basicfont

     1  // Copyright 2015 The Go 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  //go:generate go run gen.go
     6  
     7  // Package basicfont provides fixed-size font faces.
     8  package basicfont // import "golang.org/x/image/font/basicfont"
     9  
    10  import (
    11  	"image"
    12  
    13  	"golang.org/x/image/font"
    14  	"golang.org/x/image/math/fixed"
    15  )
    16  
    17  // Range maps a contiguous range of runes to vertically adjacent sub-images of
    18  // a Face's Mask image. The rune range is inclusive on the low end and
    19  // exclusive on the high end.
    20  //
    21  // If Low <= r && r < High, then the rune r is mapped to the sub-image of
    22  // Face.Mask whose bounds are image.Rect(0, y*h, Face.Width, (y+1)*h),
    23  // where y = (int(r-Low) + Offset) and h = (Face.Ascent + Face.Descent).
    24  type Range struct {
    25  	Low, High rune
    26  	Offset    int
    27  }
    28  
    29  // Face7x13 is a Face derived from the public domain X11 misc-fixed font files.
    30  //
    31  // At the moment, it holds the printable characters in ASCII starting with
    32  // space, and the Unicode replacement character U+FFFD.
    33  //
    34  // Its data is entirely self-contained and does not require loading from
    35  // separate files.
    36  var Face7x13 = &Face{
    37  	Advance: 7,
    38  	Width:   6,
    39  	Height:  13,
    40  	Ascent:  11,
    41  	Descent: 2,
    42  	Mask:    mask7x13,
    43  	Ranges: []Range{
    44  		{'\u0020', '\u007f', 0},
    45  		{'\ufffd', '\ufffe', 95},
    46  	},
    47  }
    48  
    49  // Face is a basic font face whose glyphs all have the same metrics.
    50  //
    51  // It is safe to use concurrently.
    52  type Face struct {
    53  	// Advance is the glyph advance, in pixels.
    54  	Advance int
    55  	// Width is the glyph width, in pixels.
    56  	Width int
    57  	// Height is the inter-line height, in pixels.
    58  	Height int
    59  	// Ascent is the glyph ascent, in pixels.
    60  	Ascent int
    61  	// Descent is the glyph descent, in pixels.
    62  	Descent int
    63  	// Left is the left side bearing, in pixels. A positive value means that
    64  	// all of a glyph is to the right of the dot.
    65  	Left int
    66  
    67  	// Mask contains all of the glyph masks. Its width is typically the Face's
    68  	// Width, and its height a multiple of the Face's Height.
    69  	Mask image.Image
    70  	// Ranges map runes to sub-images of Mask. The rune ranges must not
    71  	// overlap, and must be in increasing rune order.
    72  	Ranges []Range
    73  }
    74  
    75  func (f *Face) Close() error                   { return nil }
    76  func (f *Face) Kern(r0, r1 rune) fixed.Int26_6 { return 0 }
    77  
    78  func (f *Face) Metrics() font.Metrics {
    79  	return font.Metrics{
    80  		Height:     fixed.I(f.Height),
    81  		Ascent:     fixed.I(f.Ascent),
    82  		Descent:    fixed.I(f.Descent),
    83  		XHeight:    fixed.I(f.Ascent),
    84  		CapHeight:  fixed.I(f.Ascent),
    85  		CaretSlope: image.Point{X: 0, Y: 1},
    86  	}
    87  }
    88  
    89  func (f *Face) Glyph(dot fixed.Point26_6, r rune) (
    90  	dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
    91  
    92  	if found, rng := f.find(r); rng != nil {
    93  		maskp.Y = (int(found-rng.Low) + rng.Offset) * (f.Ascent + f.Descent)
    94  		x := int(dot.X+32)>>6 + f.Left
    95  		y := int(dot.Y+32) >> 6
    96  		dr = image.Rectangle{
    97  			Min: image.Point{
    98  				X: x,
    99  				Y: y - f.Ascent,
   100  			},
   101  			Max: image.Point{
   102  				X: x + f.Width,
   103  				Y: y + f.Descent,
   104  			},
   105  		}
   106  
   107  		return dr, f.Mask, maskp, fixed.I(f.Advance), r == found
   108  	}
   109  	return image.Rectangle{}, nil, image.Point{}, 0, false
   110  }
   111  
   112  func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
   113  	if found, rng := f.find(r); rng != nil {
   114  		return fixed.R(0, -f.Ascent, f.Width, +f.Descent), fixed.I(f.Advance), r == found
   115  	}
   116  	return fixed.Rectangle26_6{}, 0, false
   117  }
   118  
   119  func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
   120  	if found, rng := f.find(r); rng != nil {
   121  		return fixed.I(f.Advance), r == found
   122  	}
   123  	return 0, false
   124  }
   125  
   126  func (f *Face) find(r rune) (rune, *Range) {
   127  	for {
   128  		for i, rng := range f.Ranges {
   129  			if (rng.Low <= r) && (r < rng.High) {
   130  				return r, &f.Ranges[i]
   131  			}
   132  		}
   133  		if r == '\ufffd' {
   134  			return 0, nil
   135  		}
   136  		r = '\ufffd'
   137  	}
   138  }
   139  

View as plain text