ReactOS 0.4.16-dev-2358-g0df3463
ttcpal.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ttcpal.c
4 *
5 * TrueType and OpenType color palette support (body).
6 *
7 * Copyright (C) 2018-2020 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
11 *
12 * This file is part of the FreeType project, and may only be used,
13 * modified, and distributed under the terms of the FreeType project
14 * license, LICENSE.TXT. By continuing to use, modify, or distribute
15 * this file you indicate that you have read the license and
16 * understand and accept it fully.
17 *
18 */
19
20
21 /**************************************************************************
22 *
23 * `CPAL' table specification:
24 *
25 * https://www.microsoft.com/typography/otspec/cpal.htm
26 *
27 */
28
29
32#include <freetype/tttags.h>
33#include <freetype/ftcolor.h>
34
35
36#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
37
38#include "ttcpal.h"
39
40
41 /* NOTE: These are the table sizes calculated through the specs. */
42#define CPAL_V0_HEADER_BASE_SIZE 12U
43#define COLOR_SIZE 4U
44
45
46 /* all data from `CPAL' not covered in FT_Palette_Data */
47 typedef struct Cpal_
48 {
49 FT_UShort version; /* Table version number (0 or 1 supported). */
50 FT_UShort num_colors; /* Total number of color records, */
51 /* combined for all palettes. */
52 FT_Byte* colors; /* RGBA array of colors */
53 FT_Byte* color_indices; /* Index of each palette's first color record */
54 /* in the combined color record array. */
55
56 /* The memory which backs up the `CPAL' table. */
57 void* table;
59
60 } Cpal;
61
62
63 /**************************************************************************
64 *
65 * The macro FT_COMPONENT is used in trace mode. It is an implicit
66 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
67 * messages during execution.
68 */
69#undef FT_COMPONENT
70#define FT_COMPONENT ttcpal
71
72
76 {
78 FT_Memory memory = face->root.memory;
79
81 FT_Byte* p = NULL;
82
83 Cpal* cpal = NULL;
84
85 FT_ULong colors_offset;
87
88
89 error = face->goto_table( face, TTAG_CPAL, stream, &table_size );
90 if ( error )
91 goto NoCpal;
92
93 if ( table_size < CPAL_V0_HEADER_BASE_SIZE )
94 goto InvalidTable;
95
97 goto NoCpal;
98
99 p = table;
100
101 if ( FT_NEW( cpal ) )
102 goto NoCpal;
103
104 cpal->version = FT_NEXT_USHORT( p );
105 if ( cpal->version > 1 )
106 goto InvalidTable;
107
108 face->palette_data.num_palette_entries = FT_NEXT_USHORT( p );
109 face->palette_data.num_palettes = FT_NEXT_USHORT( p );
110
111 cpal->num_colors = FT_NEXT_USHORT( p );
112 colors_offset = FT_NEXT_ULONG( p );
113
114 if ( CPAL_V0_HEADER_BASE_SIZE +
115 face->palette_data.num_palettes * 2U > table_size )
116 goto InvalidTable;
117
118 if ( colors_offset >= table_size )
119 goto InvalidTable;
120 if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset )
121 goto InvalidTable;
122
123 if ( face->palette_data.num_palette_entries > cpal->num_colors )
124 goto InvalidTable;
125
126 cpal->color_indices = p;
127 cpal->colors = (FT_Byte*)( table + colors_offset );
128
129 if ( cpal->version == 1 )
130 {
131 FT_ULong type_offset, label_offset, entry_label_offset;
134 FT_UShort* q;
135
136
137 if ( CPAL_V0_HEADER_BASE_SIZE +
138 face->palette_data.num_palettes * 2U +
139 3U * 4 > table_size )
140 goto InvalidTable;
141
142 p += face->palette_data.num_palettes * 2U;
143
144 type_offset = FT_NEXT_ULONG( p );
145 label_offset = FT_NEXT_ULONG( p );
146 entry_label_offset = FT_NEXT_ULONG( p );
147
148 if ( type_offset )
149 {
150 if ( type_offset >= table_size )
151 goto InvalidTable;
152 if ( face->palette_data.num_palettes * 2U >
153 table_size - type_offset )
154 goto InvalidTable;
155
156 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
157 goto NoCpal;
158
159 p = table + type_offset;
160 q = array;
161 limit = q + face->palette_data.num_palettes;
162
163 while ( q < limit )
164 *q++ = FT_NEXT_USHORT( p );
165
166 face->palette_data.palette_flags = array;
167 }
168
169 if ( label_offset )
170 {
171 if ( label_offset >= table_size )
172 goto InvalidTable;
173 if ( face->palette_data.num_palettes * 2U >
174 table_size - label_offset )
175 goto InvalidTable;
176
177 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
178 goto NoCpal;
179
180 p = table + label_offset;
181 q = array;
182 limit = q + face->palette_data.num_palettes;
183
184 while ( q < limit )
185 *q++ = FT_NEXT_USHORT( p );
186
187 face->palette_data.palette_name_ids = array;
188 }
189
190 if ( entry_label_offset )
191 {
192 if ( entry_label_offset >= table_size )
193 goto InvalidTable;
194 if ( face->palette_data.num_palette_entries * 2U >
195 table_size - entry_label_offset )
196 goto InvalidTable;
197
198 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palette_entries ) )
199 goto NoCpal;
200
201 p = table + entry_label_offset;
202 q = array;
203 limit = q + face->palette_data.num_palette_entries;
204
205 while ( q < limit )
206 *q++ = FT_NEXT_USHORT( p );
207
208 face->palette_data.palette_entry_name_ids = array;
209 }
210 }
211
212 cpal->table = table;
213 cpal->table_size = table_size;
214
215 face->cpal = cpal;
216
217 /* set up default palette */
218 if ( FT_NEW_ARRAY( face->palette,
219 face->palette_data.num_palette_entries ) )
220 goto NoCpal;
221
222 if ( tt_face_palette_set( face, 0 ) )
223 goto InvalidTable;
224
225 return FT_Err_Ok;
226
227 InvalidTable:
228 error = FT_THROW( Invalid_Table );
229
230 NoCpal:
232 FT_FREE( cpal );
233
234 face->cpal = NULL;
235
236 /* arrays in `face->palette_data' and `face->palette' */
237 /* are freed in `sfnt_done_face' */
238
239 return error;
240 }
241
242
243 FT_LOCAL_DEF( void )
245 {
246 FT_Stream stream = face->root.stream;
247 FT_Memory memory = face->root.memory;
248
249 Cpal* cpal = (Cpal*)face->cpal;
250
251
252 if ( cpal )
253 {
254 FT_FRAME_RELEASE( cpal->table );
255 FT_FREE( cpal );
256 }
257 }
258
259
262 FT_UInt palette_index )
263 {
264 Cpal* cpal = (Cpal*)face->cpal;
265
267 FT_Byte* p;
268
269 FT_Color* q;
271
272 FT_UShort color_index;
273
274
275 if ( !cpal || palette_index >= face->palette_data.num_palettes )
276 return FT_THROW( Invalid_Argument );
277
278 offset = cpal->color_indices + 2 * palette_index;
279 color_index = FT_PEEK_USHORT( offset );
280
281 if ( color_index + face->palette_data.num_palette_entries >
282 cpal->num_colors )
283 return FT_THROW( Invalid_Table );
284
285 p = cpal->colors + COLOR_SIZE * color_index;
286 q = face->palette;
287 limit = q + face->palette_data.num_palette_entries;
288
289 while ( q < limit )
290 {
291 q->blue = FT_NEXT_BYTE( p );
292 q->green = FT_NEXT_BYTE( p );
293 q->red = FT_NEXT_BYTE( p );
294 q->alpha = FT_NEXT_BYTE( p );
295
296 q++;
297 }
298
299 return FT_Err_Ok;
300 }
301
302
303#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
304
305 /* ANSI C doesn't like empty source files */
306 typedef int _tt_cpal_dummy;
307
308#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
309
310/* EOF */
#define FT_LOCAL_DEF(x)
#define NULL
Definition: types.h:112
static const WCHAR version[]
Definition: asmname.c:66
return FT_Err_Ok
Definition: ftbbox.c:526
FT_BEGIN_HEADER struct FT_Color_ FT_Color
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
#define FT_NEW(ptr)
Definition: ftmemory.h:339
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:350
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:562
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:244
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:186
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:556
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:256
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:238
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
unsigned short FT_UShort
Definition: fttypes.h:209
unsigned int FT_UInt
Definition: fttypes.h:231
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLintptr offset
Definition: glext.h:5920
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLint limit
Definition: glext.h:10326
GLfloat GLfloat p
Definition: glext.h:8902
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:122
LOCAL int table_size
Definition: write.c:65
Definition: undname.c:54
Definition: parse.h:23
int _tt_cpal_dummy
Definition: ttcpal.c:306
FT_BEGIN_HEADER tt_face_load_cpal(TT_Face face, FT_Stream stream)
tt_face_palette_set(TT_Face face, FT_UInt palette_index)
tt_face_free_cpal(TT_Face face)
#define TTAG_CPAL
Definition: tttags.h:49