1 | /* |
2 | * Copyright © 2016 Google, Inc. |
3 | * Copyright © 2018 Ebrahim Byagowi |
4 | * |
5 | * This is part of HarfBuzz, a text shaping library. |
6 | * |
7 | * Permission is hereby granted, without written agreement and without |
8 | * license or royalty fees, to use, copy, modify, and distribute this |
9 | * software and its documentation for any purpose, provided that the |
10 | * above copyright notice and the following two paragraphs appear in |
11 | * all copies of this software. |
12 | * |
13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
15 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
16 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
17 | * DAMAGE. |
18 | * |
19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
21 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
22 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
24 | * |
25 | * Google Author(s): Sascha Brawer, Behdad Esfahbod |
26 | */ |
27 | |
28 | #include "hb-open-type.hh" |
29 | #include "hb-ot-color-cbdt-table.hh" |
30 | #include "hb-ot-color-colr-table.hh" |
31 | #include "hb-ot-color-cpal-table.hh" |
32 | #include "hb-ot-color-sbix-table.hh" |
33 | #include "hb-ot-color-svg-table.hh" |
34 | #include "hb-ot-face.hh" |
35 | #include "hb-ot.h" |
36 | |
37 | #include <stdlib.h> |
38 | #include <string.h> |
39 | |
40 | #include "hb-ot-layout.hh" |
41 | |
42 | |
43 | /** |
44 | * SECTION:hb-ot-color |
45 | * @title: hb-ot-color |
46 | * @short_description: OpenType Color Fonts |
47 | * @include: hb-ot.h |
48 | * |
49 | * Functions for fetching color-font information from OpenType font faces. |
50 | **/ |
51 | |
52 | |
53 | /* |
54 | * CPAL |
55 | */ |
56 | |
57 | |
58 | /** |
59 | * hb_ot_color_has_palettes: |
60 | * @face: a font face. |
61 | * |
62 | * Returns: whether CPAL table is available. |
63 | * |
64 | * Since: 2.1.0 |
65 | */ |
66 | hb_bool_t |
67 | hb_ot_color_has_palettes (hb_face_t *face) |
68 | { |
69 | return face->table.CPAL->has_data (); |
70 | } |
71 | |
72 | /** |
73 | * hb_ot_color_palette_get_count: |
74 | * @face: a font face. |
75 | * |
76 | * Returns: the number of color palettes in @face, or zero if @face has |
77 | * no colors. |
78 | * |
79 | * Since: 2.1.0 |
80 | */ |
81 | unsigned int |
82 | hb_ot_color_palette_get_count (hb_face_t *face) |
83 | { |
84 | return face->table.CPAL->get_palette_count (); |
85 | } |
86 | |
87 | /** |
88 | * hb_ot_color_palette_get_name_id: |
89 | * @face: a font face. |
90 | * @palette_index: the index of the color palette whose name is being requested. |
91 | * |
92 | * Retrieves the name id of a color palette. For example, a color font can |
93 | * have themed palettes like "Spring", "Summer", "Fall", and "Winter". |
94 | * |
95 | * Returns: an identifier within @face's `name` table. |
96 | * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID. |
97 | * |
98 | * Since: 2.1.0 |
99 | */ |
100 | hb_ot_name_id_t |
101 | hb_ot_color_palette_get_name_id (hb_face_t *face, |
102 | unsigned int palette_index) |
103 | { |
104 | return face->table.CPAL->get_palette_name_id (palette_index); |
105 | } |
106 | |
107 | /** |
108 | * hb_ot_color_palette_color_get_name_id: |
109 | * @face: a font face. |
110 | * @color_index: palette entry index. |
111 | * |
112 | * Returns: Name ID associated with a palette entry, e.g. eye color |
113 | * |
114 | * Since: 2.1.0 |
115 | */ |
116 | hb_ot_name_id_t |
117 | hb_ot_color_palette_color_get_name_id (hb_face_t *face, |
118 | unsigned int color_index) |
119 | { |
120 | return face->table.CPAL->get_color_name_id (color_index); |
121 | } |
122 | |
123 | /** |
124 | * hb_ot_color_palette_get_flags: |
125 | * @face: a font face |
126 | * @palette_index: the index of the color palette whose flags are being requested |
127 | * |
128 | * Returns: the flags for the requested color palette. |
129 | * |
130 | * Since: 2.1.0 |
131 | */ |
132 | hb_ot_color_palette_flags_t |
133 | hb_ot_color_palette_get_flags (hb_face_t *face, |
134 | unsigned int palette_index) |
135 | { |
136 | return face->table.CPAL->get_palette_flags (palette_index); |
137 | } |
138 | |
139 | /** |
140 | * hb_ot_color_palette_get_colors: |
141 | * @face: a font face. |
142 | * @palette_index:the index of the color palette whose colors |
143 | * are being requested. |
144 | * @start_offset: the index of the first color being requested. |
145 | * @color_count: (inout) (optional): on input, how many colors |
146 | * can be maximally stored into the @colors array; |
147 | * on output, how many colors were actually stored. |
148 | * @colors: (array length=color_count) (out) (optional): |
149 | * an array of #hb_color_t records. After calling |
150 | * this function, @colors will be filled with |
151 | * the palette colors. If @colors is NULL, the function |
152 | * will just return the number of total colors |
153 | * without storing any actual colors; this can be used |
154 | * for allocating a buffer of suitable size before calling |
155 | * hb_ot_color_palette_get_colors() a second time. |
156 | * |
157 | * Retrieves the colors in a color palette. |
158 | * |
159 | * Returns: the total number of colors in the palette. |
160 | * |
161 | * Since: 2.1.0 |
162 | */ |
163 | unsigned int |
164 | hb_ot_color_palette_get_colors (hb_face_t *face, |
165 | unsigned int palette_index, |
166 | unsigned int start_offset, |
167 | unsigned int *colors_count /* IN/OUT. May be NULL. */, |
168 | hb_color_t *colors /* OUT. May be NULL. */) |
169 | { |
170 | return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors); |
171 | } |
172 | |
173 | |
174 | /* |
175 | * COLR |
176 | */ |
177 | |
178 | /** |
179 | * hb_ot_color_has_layers: |
180 | * @face: a font face. |
181 | * |
182 | * Returns: whether COLR table is available. |
183 | * |
184 | * Since: 2.1.0 |
185 | */ |
186 | hb_bool_t |
187 | hb_ot_color_has_layers (hb_face_t *face) |
188 | { |
189 | return face->table.COLR->has_data (); |
190 | } |
191 | |
192 | /** |
193 | * hb_ot_color_glyph_get_layers: |
194 | * @face: a font face. |
195 | * @glyph: a layered color glyph id. |
196 | * @start_offset: starting offset of layers. |
197 | * @count: (inout) (optional): gets number of layers available to be written on buffer |
198 | * and returns number of written layers. |
199 | * @layers: (array length=count) (out) (optional): layers buffer to buffer. |
200 | * |
201 | * Returns: Total number of layers a layered color glyph have. |
202 | * |
203 | * Since: 2.1.0 |
204 | */ |
205 | unsigned int |
206 | hb_ot_color_glyph_get_layers (hb_face_t *face, |
207 | hb_codepoint_t glyph, |
208 | unsigned int start_offset, |
209 | unsigned int *count, /* IN/OUT. May be NULL. */ |
210 | hb_ot_color_layer_t *layers /* OUT. May be NULL. */) |
211 | { |
212 | return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers); |
213 | } |
214 | |
215 | |
216 | /* |
217 | * SVG |
218 | */ |
219 | |
220 | /** |
221 | * hb_ot_color_has_svg: |
222 | * @face: a font face. |
223 | * |
224 | * Check whether @face has SVG glyph images. |
225 | * |
226 | * Returns true if available, false otherwise. |
227 | * |
228 | * Since: 2.1.0 |
229 | */ |
230 | hb_bool_t |
231 | hb_ot_color_has_svg (hb_face_t *face) |
232 | { |
233 | return face->table.SVG->has_data (); |
234 | } |
235 | |
236 | /** |
237 | * hb_ot_color_glyph_reference_svg: |
238 | * @face: a font face. |
239 | * @glyph: a svg glyph index. |
240 | * |
241 | * Get SVG document for a glyph. The blob may be either plain text or gzip-encoded. |
242 | * |
243 | * Returns: (transfer full): respective svg blob of the glyph, if available. |
244 | * |
245 | * Since: 2.1.0 |
246 | */ |
247 | hb_blob_t * |
248 | hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) |
249 | { |
250 | return face->table.SVG->reference_blob_for_glyph (glyph); |
251 | } |
252 | |
253 | |
254 | /* |
255 | * PNG: CBDT or sbix |
256 | */ |
257 | |
258 | /** |
259 | * hb_ot_color_has_png: |
260 | * @face: a font face. |
261 | * |
262 | * Check whether @face has PNG glyph images (either CBDT or sbix tables). |
263 | * |
264 | * Returns true if available, false otherwise. |
265 | * |
266 | * Since: 2.1.0 |
267 | */ |
268 | hb_bool_t |
269 | hb_ot_color_has_png (hb_face_t *face) |
270 | { |
271 | return face->table.CBDT->has_data () || face->table.sbix->has_data (); |
272 | } |
273 | |
274 | /** |
275 | * hb_ot_color_glyph_reference_png: |
276 | * @font: a font object, not face. upem should be set on |
277 | * that font object if one wants to get optimal png blob, otherwise |
278 | * return the biggest one |
279 | * @glyph: a glyph index. |
280 | * |
281 | * Get PNG image for a glyph. |
282 | * |
283 | * Returns: (transfer full): respective PNG blob of the glyph, if available. |
284 | * |
285 | * Since: 2.1.0 |
286 | */ |
287 | hb_blob_t * |
288 | hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) |
289 | { |
290 | hb_blob_t *blob = hb_blob_get_empty (); |
291 | |
292 | if (font->face->table.sbix->has_data ()) |
293 | blob = font->face->table.sbix->reference_png (font, glyph, nullptr, nullptr, nullptr); |
294 | |
295 | if (!blob->length && font->face->table.CBDT->has_data ()) |
296 | blob = font->face->table.CBDT->reference_png (font, glyph); |
297 | |
298 | return blob; |
299 | } |
300 | |