git clone https://git.lucas.co/go_mono.git
font/basicfont/basicfont.go (3.7K)
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 }