36#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
42#define CPAL_V0_HEADER_BASE_SIZE 12U
53 FT_Byte* color_indices;
70#define FT_COMPONENT ttcpal
73 FT_LOCAL_DEF( FT_Error )
74 tt_face_load_cpal( TT_Face face,
78 FT_Memory memory = face->root.memory;
80 FT_Byte* table = NULL;
85 FT_ULong colors_offset;
89 error = face->goto_table( face, TTAG_CPAL, stream, &table_size );
93 if ( table_size < CPAL_V0_HEADER_BASE_SIZE )
96 if ( FT_FRAME_EXTRACT( table_size, table ) )
101 if ( FT_NEW( cpal ) )
104 cpal->version = FT_NEXT_USHORT( p );
105 if ( cpal->version > 1 )
108 face->palette_data.num_palette_entries = FT_NEXT_USHORT( p );
109 face->palette_data.num_palettes = FT_NEXT_USHORT( p );
111 cpal->num_colors = FT_NEXT_USHORT( p );
112 colors_offset = FT_NEXT_ULONG( p );
114 if ( CPAL_V0_HEADER_BASE_SIZE +
115 face->palette_data.num_palettes * 2U > table_size )
118 if ( colors_offset >= table_size )
120 if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset )
123 if ( face->palette_data.num_palette_entries > cpal->num_colors )
126 cpal->color_indices = p;
127 cpal->colors = (FT_Byte*)( table + colors_offset );
129 if ( cpal->version == 1 )
131 FT_ULong type_offset, label_offset, entry_label_offset;
132 FT_UShort* array = NULL;
137 if ( CPAL_V0_HEADER_BASE_SIZE +
138 face->palette_data.num_palettes * 2U +
139 3U * 4 > table_size )
142 p += face->palette_data.num_palettes * 2U;
144 type_offset = FT_NEXT_ULONG( p );
145 label_offset = FT_NEXT_ULONG( p );
146 entry_label_offset = FT_NEXT_ULONG( p );
150 if ( type_offset >= table_size )
152 if ( face->palette_data.num_palettes * 2U >
153 table_size - type_offset )
156 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
159 p = table + type_offset;
161 limit = q + face->palette_data.num_palettes;
164 *q++ = FT_NEXT_USHORT( p );
166 face->palette_data.palette_flags = array;
171 if ( label_offset >= table_size )
173 if ( face->palette_data.num_palettes * 2U >
174 table_size - label_offset )
177 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
180 p = table + label_offset;
182 limit = q + face->palette_data.num_palettes;
185 *q++ = FT_NEXT_USHORT( p );
187 face->palette_data.palette_name_ids = array;
190 if ( entry_label_offset )
192 if ( entry_label_offset >= table_size )
194 if ( face->palette_data.num_palette_entries * 2U >
195 table_size - entry_label_offset )
198 if ( FT_QNEW_ARRAY( array, face->palette_data.num_palette_entries ) )
201 p = table + entry_label_offset;
203 limit = q + face->palette_data.num_palette_entries;
206 *q++ = FT_NEXT_USHORT( p );
208 face->palette_data.palette_entry_name_ids = array;
213 cpal->table_size = table_size;
218 if ( FT_NEW_ARRAY( face->palette,
219 face->palette_data.num_palette_entries ) )
222 if ( tt_face_palette_set( face, 0 ) )
228 error = FT_THROW( Invalid_Table );
231 FT_FRAME_RELEASE( table );
244 tt_face_free_cpal( TT_Face face )
246 FT_Stream stream = face->root.stream;
247 FT_Memory memory = face->root.memory;
249 Cpal* cpal = (Cpal*)face->cpal;
254 FT_FRAME_RELEASE( cpal->table );
260 FT_LOCAL_DEF( FT_Error )
261 tt_face_palette_set( TT_Face face,
262 FT_UInt palette_index )
264 Cpal* cpal = (Cpal*)face->cpal;
272 FT_UShort color_index;
275 if ( !cpal || palette_index >= face->palette_data.num_palettes )
276 return FT_THROW( Invalid_Argument );
278 offset = cpal->color_indices + 2 * palette_index;
279 color_index = FT_PEEK_USHORT( offset );
281 if ( color_index + face->palette_data.num_palette_entries >
283 return FT_THROW( Invalid_Table );
285 p = cpal->colors + COLOR_SIZE * color_index;
287 limit = q + face->palette_data.num_palette_entries;
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 );
306 typedef int tt_cpal_dummy_;