ReactOS 0.4.16-dev-1063-gd722e70
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-2019 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
30#include <ft2build.h>
31#include FT_INTERNAL_DEBUG_H
32#include FT_INTERNAL_STREAM_H
33#include FT_TRUETYPE_TAGS_H
34#include FT_COLOR_H
35
36
37#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
38
39#include "ttcpal.h"
40
41
42 /* NOTE: These are the table sizes calculated through the specs. */
43#define CPAL_V0_HEADER_BASE_SIZE 12
44#define COLOR_SIZE 4
45
46
47 /* all data from `CPAL' not covered in FT_Palette_Data */
48 typedef struct Cpal_
49 {
50 FT_UShort version; /* Table version number (0 or 1 supported). */
51 FT_UShort num_colors; /* Total number of color records, */
52 /* combined for all palettes. */
53 FT_Byte* colors; /* RGBA array of colors */
54 FT_Byte* color_indices; /* Index of each palette's first color record */
55 /* in the combined color record array. */
56
57 /* The memory which backs up the `CPAL' table. */
58 void* table;
60
61 } Cpal;
62
63
64 /**************************************************************************
65 *
66 * The macro FT_COMPONENT is used in trace mode. It is an implicit
67 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
68 * messages during execution.
69 */
70#undef FT_COMPONENT
71#define FT_COMPONENT ttcpal
72
73
77 {
79 FT_Memory memory = face->root.memory;
80
82 FT_Byte* p = NULL;
83
84 Cpal* cpal = NULL;
85
86 FT_ULong colors_offset;
88
89
90 error = face->goto_table( face, TTAG_CPAL, stream, &table_size );
91 if ( error )
92 goto NoCpal;
93
94 if ( table_size < CPAL_V0_HEADER_BASE_SIZE )
95 goto InvalidTable;
96
98 goto NoCpal;
99
100 p = table;
101
102 if ( FT_NEW( cpal ) )
103 goto NoCpal;
104
105 cpal->version = FT_NEXT_USHORT( p );
106 if ( cpal->version > 1 )
107 goto InvalidTable;
108
109 face->palette_data.num_palette_entries = FT_NEXT_USHORT( p );
110 face->palette_data.num_palettes = FT_NEXT_USHORT( p );
111
112 cpal->num_colors = FT_NEXT_USHORT( p );
113 colors_offset = FT_NEXT_ULONG( p );
114
115 if ( CPAL_V0_HEADER_BASE_SIZE +
116 face->palette_data.num_palettes * 2U > table_size )
117 goto InvalidTable;
118
119 if ( colors_offset >= table_size )
120 goto InvalidTable;
121 if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset )
122 goto InvalidTable;
123
124 if ( face->palette_data.num_palette_entries > cpal->num_colors )
125 goto InvalidTable;
126
127 cpal->color_indices = p;
128 cpal->colors = (FT_Byte*)( table + colors_offset );
129
130 if ( cpal->version == 1 )
131 {
132 FT_ULong type_offset, label_offset, entry_label_offset;
135 FT_UShort* q;
136
137
138 if ( CPAL_V0_HEADER_BASE_SIZE +
139 face->palette_data.num_palettes * 2U +
140 3U * 4 > table_size )
141 goto InvalidTable;
142
143 p += face->palette_data.num_palettes * 2;
144
145 type_offset = FT_NEXT_ULONG( p );
146 label_offset = FT_NEXT_ULONG( p );
147 entry_label_offset = FT_NEXT_ULONG( p );
148
149 if ( type_offset )
150 {
151 if ( type_offset >= table_size )
152 goto InvalidTable;
153 if ( face->palette_data.num_palettes * 2 >
154 table_size - type_offset )
155 goto InvalidTable;
156
157 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
158 goto NoCpal;
159
160 p = table + type_offset;
161 q = array;
162 limit = q + face->palette_data.num_palettes;
163
164 while ( q < limit )
165 *q++ = FT_NEXT_USHORT( p );
166
167 face->palette_data.palette_flags = array;
168 }
169
170 if ( label_offset )
171 {
172 if ( label_offset >= table_size )
173 goto InvalidTable;
174 if ( face->palette_data.num_palettes * 2 >
175 table_size - label_offset )
176 goto InvalidTable;
177
178 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
179 goto NoCpal;
180
181 p = table + label_offset;
182 q = array;
183 limit = q + face->palette_data.num_palettes;
184
185 while ( q < limit )
186 *q++ = FT_NEXT_USHORT( p );
187
188 face->palette_data.palette_name_ids = array;
189 }
190
191 if ( entry_label_offset )
192 {
193 if ( entry_label_offset >= table_size )
194 goto InvalidTable;
195 if ( face->palette_data.num_palette_entries * 2 >
196 table_size - entry_label_offset )
197 goto InvalidTable;
198
199 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palette_entries ) )
200 goto NoCpal;
201
202 p = table + entry_label_offset;
203 q = array;
204 limit = q + face->palette_data.num_palette_entries;
205
206 while ( q < limit )
207 *q++ = FT_NEXT_USHORT( p );
208
209 face->palette_data.palette_entry_name_ids = array;
210 }
211 }
212
213 cpal->table = table;
214 cpal->table_size = table_size;
215
216 face->cpal = cpal;
217
218 /* set up default palette */
219 if ( FT_NEW_ARRAY( face->palette,
220 face->palette_data.num_palette_entries ) )
221 goto NoCpal;
222
223 if ( tt_face_palette_set( face, 0 ) )
224 goto InvalidTable;
225
226 return FT_Err_Ok;
227
228 InvalidTable:
229 error = FT_THROW( Invalid_Table );
230
231 NoCpal:
233 FT_FREE( cpal );
234
235 face->cpal = NULL;
236
237 /* arrays in `face->palette_data' and `face->palette' */
238 /* are freed in `sfnt_done_face' */
239
240 return error;
241 }
242
243
244 FT_LOCAL_DEF( void )
246 {
247 FT_Stream stream = face->root.stream;
248 FT_Memory memory = face->root.memory;
249
250 Cpal* cpal = (Cpal*)face->cpal;
251
252
253 if ( cpal )
254 {
255 FT_FRAME_RELEASE( cpal->table );
256 FT_FREE( cpal );
257 }
258 }
259
260
263 FT_UInt palette_index )
264 {
265 Cpal* cpal = (Cpal*)face->cpal;
266
268 FT_Byte* p;
269
270 FT_Color* q;
272
273 FT_UShort color_index;
274
275
276 if ( !cpal || palette_index >= face->palette_data.num_palettes )
277 return FT_THROW( Invalid_Argument );
278
279 offset = cpal->color_indices + 2 * palette_index;
280 color_index = FT_PEEK_USHORT( offset );
281
282 if ( color_index + face->palette_data.num_palette_entries >
283 cpal->num_colors )
284 return FT_THROW( Invalid_Table );
285
286 p = cpal->colors + COLOR_SIZE * color_index;
287 q = face->palette;
288 limit = q + face->palette_data.num_palette_entries;
289
290 while ( q < limit )
291 {
292 q->blue = FT_NEXT_BYTE( p );
293 q->green = FT_NEXT_BYTE( p );
294 q->red = FT_NEXT_BYTE( p );
295 q->alpha = FT_NEXT_BYTE( p );
296
297 q++;
298 }
299
300 return FT_Err_Ok;
301 }
302
303
304#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
305
306 /* ANSI C doesn't like empty source files */
307 typedef int _tt_cpal_dummy;
308
309#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
310
311/* EOF */
#define NULL
Definition: types.h:112
static const WCHAR version[]
Definition: asmname.c:66
return FT_Err_Ok
Definition: ftbbox.c:527
FT_BEGIN_HEADER struct FT_Color_ FT_Color
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:387
#define FT_THROW(e)
Definition: ftdebug.h:241
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:332
#define FT_NEW(ptr)
Definition: ftmemory.h:330
#define FT_FREE(ptr)
Definition: ftmemory.h:328
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:551
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:233
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:175
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:545
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:245
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:227
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:65
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:116
LOCAL int table_size
Definition: write.c:65
Definition: parse.h:23
int _tt_cpal_dummy
Definition: ttcpal.c:307
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:50