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 */
66hb_bool_t
67hb_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 */
81unsigned int
82hb_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 */
100hb_ot_name_id_t
101hb_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 */
116hb_ot_name_id_t
117hb_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 */
132hb_ot_color_palette_flags_t
133hb_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 */
163unsigned int
164hb_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 */
186hb_bool_t
187hb_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 */
205unsigned int
206hb_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 */
230hb_bool_t
231hb_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 */
247hb_blob_t *
248hb_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 */
268hb_bool_t
269hb_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 */
287hb_blob_t *
288hb_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