1fcft_from_name(3) fcft fcft_from_name(3)
2
3
4
6 fcft_from_name - instantiate a new font
7
9 #include <fcft/fcft.h>
10
11 struct fcft_font *fcft_from_name(
12 size_t count, const char *names[static count], const char *at‐
13 tributes);
14
16 fcft_from_name() instantiates a new fcft font object from the FontCon‐
17 fig formatted font names. The first element in names is the primary
18 font, and the remaining elements (if any) are fallback fonts.
19
20 You must supply at least one font name.
21
22 All aspects of the font (size, DPI, variant etc) are configured through
23 the font name, using colon separated attribute=value pairs (e.g.
24 "Serif:size=26:slant=italic").
25
26 attributes is a convenient way to apply a set of attributes to all
27 fonts in names. attributes may be NULL, in which case no extra at‐
28 tributes are appended to the strings in names.
29
30 The primary font will be instantiated immediately, and any failure to
31 do so will result in an error. Fallback fonts are instantiated on de‐
32 mand, and any failure to do so will result in the that fallback font
33 being ignored, and the next one in the list is tried instead.
34
36 On success, fcft_from_name() returns a pointer to an allocated
37 fcft_font object. On error, NULL is returned.
38
39 struct fcft_font {
40 int height;
41 int descent;
42 int ascent;
43
44 struct {
45 int x;
46 int y;
47 } max_advance;
48
49 struct {
50 int x;
51 int y;
52 } space_advance;
53
54 struct {
55 int position;
56 int thickness;
57 } underline;
58
59 struct {
60 int position;
61 int thickness;
62 } strikeout;
63 };
64
65 height is the line height, in pixels.
66
67 descent is the distance between the baseline and the font's lowest de‐
68 scending glyph, in pixels. In fcft's case, it is generally positive (a
69 negative value means the descent stretches up from the baseline).
70
71 ascent is the distance between the baseline and the font's highest as‐
72 cending glyph, in pixels. Generally a positive number (a negative value
73 means the ascent stretches down below the baseline).
74
75 ascent + descent is often the same as height, but not necessarily.
76 height may be larger, meaning the font intentionally adds extra (verti‐
77 cal) space between lines. Or it may be smaller, in which case lines
78 overlap.
79
80 max_advance is the amount, in pixels, the font's widest glyph advances
81 the pen position; x for a horizontal layout, and y for a vertical lay‐
82 out.
83
84 space_advance is the amount, in pixels, the glyph for space (0x20) ad‐
85 vances the pen position; x for a horizontal layout, and y for a verti‐
86 cal layout.
87
88 underline describes how to render underlines. position is the distance,
89 in pixels, from the baseline. A positive value means above the base‐
90 line, and a negative value means below the baseline. thickness is the
91 line's thickness, in pixels.
92
93 strikeout describes how to render strikeouts. See underline for a de‐
94 scription of its members.
95
97 In this example, we instantiate Times New Roman at a point size of 8 as
98 the primary font.
99
100 We also tell it to use Serif Bold (point size 10) as a fallback font
101 (note that it is usually better to let FontConfig handle fallback to
102 generic fonts like this).
103
104 Furthermore, both fonts will be Italic, and will be using DPI=140.
105
106 We then proceed to render the string hello world. You are assumed to
107 know how to create and use a pixman image. This example only shows how
108 one can use fcft to instantiate a font, rasterize glyphs and then blend
109 them onto a target pixman image.
110
111 #include <stdlib.h>
112 #include <wchar.h>
113 #include <fcft/fcft.h>
114
115 int
116 main(void)
117 {
118 if (!fcft_set_scaling_filter(FCFT_SCALING_FILTER_LANCZOS3))
119 return EXIT_FAILURE;
120
121 struct fcft_font *font = fcft_from_name(
122 2,
123 (const char *[]){
124 "Times New Roman:size=8",
125 "Serif:size=10:weight=bold",
126 },
127 "slant=italic:dpi=140");
128
129 if (font == NULL)
130 return EXIT_FAILURE;
131
132 /* Here you need to instantiate a 'target' pixman image, to blend
133 with */
134 pixman_image_t *canvas = ...;
135
136 /* String to print */
137 static const wchar_t *const hello = L"hello world";
138
139 /*
140 * Pen position in canvas. The numbers chosen here are more or less
141 * random. Note however, that the composite calls below assume 'y'
142 * is the font's baseline (and thus the glyphs will be rendered
143 * above 'y')
144 */
145 struct {
146 int x;
147 int y;
148 } pen = {.x = 25, .y = 50};
149
150 /* Glyphs will be rendered in white */
151 pixman_image_t *color = pixman_image_create_solid_fill(
152 &(struct pixman_color_t){
153 .red = 0xffff,
154 .green = 0xffff,
155 .blue = 0xffff,
156 .alpha = 0xffff,
157 });
158
159 for (size_t i = 0; i < wcslen(hello); i++) {
160 const struct fcft_glyph *glyph = fcft_glyph_rasterize(
161 font, hello[i], FCFT_SUBPIXEL_DEFAULT);
162
163 if (glyph == NULL)
164 continue;
165
166 /* Kerning */
167 long x_kern = 0;
168 if (i > 0) {
169 fcft_kerning(font, hello[i - 1], hello[i], &x_kern, NULL);
170
171 pen.x += x_kern;
172
173 if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) {
174 /* Glyph is a pre-rendered image; typically a color emoji */
175 pixman_image_composite32(
176 PIXMAP_OP_OVER, glyph->pix, NULL, canvas, 0, 0, 0, 0,
177 pen.x + glyph->x, pen.y + font->ascent - glyph->y,
178 glyph->width, glyph->height);
179 }
180
181 else {
182 /* Glyph is an alpha mask */
183 pixman_image_composite32(
184 PIXMAN_OP_OVER, color, glyph->pix, canvas, 0, 0, 0, 0,
185 pen.x + glyph->x, pen.y + font->ascent - glyph->y,
186 glyph->width, glyph->height);
187 }
188
189 /* Advance pen position */
190 pen.x += glyph->advance.x;
191 }
192
193 pixman_image_unref(src);
194
195 fcft_destroy(font);
196 return EXIT_SUCCESS;
197 }
198
200 fcft_clone(3), fcft_destroy(3), fcft_glyph_rasterize(3), fcft_kern‐
201 ing(3), fcft_size_adjust(3)
202
203
204
2052.3.3 2021-04-14 fcft_from_name(3)