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
hb_ot_color_has_palettes(hb_face_t * face)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
hb_ot_color_palette_get_count(hb_face_t * face)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
hb_ot_color_palette_get_name_id(hb_face_t * face,unsigned int palette_index)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
hb_ot_color_palette_color_get_name_id(hb_face_t * face,unsigned int color_index)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
hb_ot_color_palette_get_flags(hb_face_t * face,unsigned int palette_index)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
hb_ot_color_palette_get_colors(hb_face_t * face,unsigned int palette_index,unsigned int start_offset,unsigned int * colors_count,hb_color_t * colors)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
hb_ot_color_has_layers(hb_face_t * face)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
hb_ot_color_glyph_get_layers(hb_face_t * face,hb_codepoint_t glyph,unsigned int start_offset,unsigned int * count,hb_ot_color_layer_t * layers)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
hb_ot_color_has_svg(hb_face_t * face)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 *
hb_ot_color_glyph_reference_svg(hb_face_t * face,hb_codepoint_t glyph)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
hb_ot_color_has_png(hb_face_t * face)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 *
hb_ot_color_glyph_reference_png(hb_font_t * font,hb_codepoint_t glyph)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