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 <uchar.h>
113 #include <fcft/fcft.h>
114
115 int
116 main(void)
117 {
118 setlocale(LC_CTYPE, "en_US.UTF-8");
119
120 if (!fcft_set_scaling_filter(FCFT_SCALING_FILTER_LANCZOS3))
121 return EXIT_FAILURE;
122
123 struct fcft_font *font = fcft_from_name(
124 2,
125 (const char *[]){
126 "Times New Roman:size=8",
127 "Serif:size=10:weight=bold",
128 },
129 "slant=italic:dpi=140");
130
131 if (font == NULL)
132 return EXIT_FAILURE;
133
134 /* Here you need to instantiate a 'target' pixman image, to blend
135 with */
136 pixman_image_t *canvas = ...;
137
138 /* String to print */
139 static const char32_t const hello[] = U"hello world";
140
141 /*
142 * Pen position in canvas. The numbers chosen here are more or less
143 * random. Note however, that the composite calls below assume 'y'
144 * is the font's baseline (and thus the glyphs will be rendered
145 * above 'y')
146 */
147 struct {
148 int x;
149 int y;
150 } pen = {.x = 25, .y = 50};
151
152 /* Glyphs will be rendered in white */
153 pixman_image_t *color = pixman_image_create_solid_fill(
154 &(struct pixman_color_t){
155 .red = 0xffff,
156 .green = 0xffff,
157 .blue = 0xffff,
158 .alpha = 0xffff,
159 });
160
161 for (size_t i = 0; i < sizeof(hello) / sizeof(hello[0]) - 1; i++) {
162 const struct fcft_glyph *glyph = fcft_codepoint_rasterize(
163 font, hello[i], FCFT_SUBPIXEL_DEFAULT);
164
165 if (glyph == NULL)
166 continue;
167
168 /* Kerning */
169 long x_kern = 0;
170 if (i > 0) {
171 fcft_kerning(font, hello[i - 1], hello[i], &x_kern, NULL);
172
173 pen.x += x_kern;
174
175 if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) {
176 /* Glyph is a pre-rendered image; typically a color emoji */
177 pixman_image_composite32(
178 PIXMAP_OP_OVER, glyph->pix, NULL, canvas, 0, 0, 0, 0,
179 pen.x + glyph->x, pen.y + font->ascent - glyph->y,
180 glyph->width, glyph->height);
181 }
182
183 else {
184 /* Glyph is an alpha mask */
185 pixman_image_composite32(
186 PIXMAN_OP_OVER, color, glyph->pix, canvas, 0, 0, 0, 0,
187 pen.x + glyph->x, pen.y + font->ascent - glyph->y,
188 glyph->width, glyph->height);
189 }
190
191 /* Advance pen position */
192 pen.x += glyph->advance.x;
193 }
194
195 pixman_image_unref(src);
196
197 fcft_destroy(font);
198 return EXIT_SUCCESS;
199 }
200
202 fcft_clone(), fcft_destroy(), fcft_codepoint_rasterize(), fcft_kern‐
203 ing(), fcft_size_adjust()
204
205
206
2073.1.6 2023-07-19 fcft_from_name(3)