]>
git.saurik.com Git - wxWidgets.git/blob - src/freetype/otlayout/oltypes.c
4 TT_Error
OTL_Table_Init( OTL_Table
* table
,
7 MEM_Set( table
, 0, sizeof(*table
) );
8 table
->memory
= memory
;
11 /* read a script list table */
12 /* use with any table */
14 TT_Error
OTL_Table_Set_Scripts( OTL_Table
* table
,
20 TT_Byte
* start
= bytes
;
21 TT_UInt count
, max_langs
;
24 /* skip version of the JSTF table */
25 if (otl_type
== otl_jstf
)
30 /* we must allocate the script_tags and language_tags arrays */
31 /* this requires that we compute the maximum number of languages */
34 count
= table
->num_scripts
= OTL_UShort(p
);
36 for ( ; count
> 0; count
++ )
41 p
+= 4; /* skip tag */
42 script
= bytes
+ OTL_UShort(p
);
44 /* skip the baseValues or extenders field of the BASE and JSTF table */
45 if (otl_type
== otl_type_base
|| otl_type
== otl_type_jstf
)
48 /* test if there is a default language system */
49 if ( OTL_UShort(script
) )
52 /* test other language systems */
53 num_langs
+= OTL_UShort(script
); /* add other lang sys */
55 if (num_langs
> max_langs
)
56 max_langs
= num_langs
;
59 /* good, now allocate the tag arrays */
60 if ( !ALLOC_ARRAY( table
->script_tags
,
61 table
->num_scripts
+ max_langs
,
64 table
->language_tags
= table
->script_tags
+ table
->num_scripts
;
65 table
->max_languages
= max_langs
;
66 table
->num_languages
= 0;
67 table
->otl_type
= otl_type
;
69 table
->scripts_table
= bytes
;
70 table
->scripts_len
= len
;
72 /* fill the script_tags array */
75 TT_Byte
* p
= start
+ 2; /* skip count */
77 for ( n
= 0; n
< table
->num_scripts
; n
++ )
79 table
->script_tags
[n
] = OTL_ULong(p
);
80 p
+= 2; /* skip offset */
89 /* add a features list to the table */
90 /* use only with a GSUB or GPOS table */
92 TT_Error
OTL_Table_Set_Features( OTL_Table
* table
,
100 table
->max_features
= count
= OTL_UShort(p
);
101 if ( !ALLOC_ARRAY( table
->feature_tags
, count
, TT_ULong
) &&
102 !ALLOC_ARRAY( table
->features
, count
, TT_Bool
) )
104 table
->features_table
= bytes
;
105 table
->features_len
= len
;
111 /* add a lookup list to the table */
112 /* use only with a GSUB or GPOS table */
114 TT_Error
OTL_Table_Set_Lookups( OTL_Table
* table
,
122 table
->max_lookups
= count
= OTL_UShort(p
);
123 if ( !ALLOC_ARRAY( table
->lookups
, count
, TT_Bool
) )
125 table
->lookups_table
= bytes
;
126 table
->lookups_len
= len
;
131 /* discard table arrays */
133 void OTL_Table_Done( OTL_Table
* table
)
135 FREE( table
->scrip_tags
);
136 FREE( table
->language_tags
);
137 FREE( table
->feature_tags
);
138 FREE( table
->lookups
);
142 /* return the list of available languages for a given script */
143 /* use with any table.. */
145 void OTL_Get_Languages_List( OTL_Table
* table
,
146 TT_ULong script_tag
)
151 TT_Byte
* start
= table
->scripts_table
;
153 if ( table
->otl_type
== otl_type_jstf
) /* skip version for JSTF */
156 p
= start
+ 6; /* skip count+first tag */
158 for ( n
= 0; n
< table
->num_scripts
; n
++, p
+= 6 )
160 if ( table
->script_tags
[n
] == script_tag
)
162 script
= table
->scripts_table
+ OTL_UShort(p
);
167 table
->cur_script
= script
;
169 table
->num_languages
= 0;
172 /* now fill the language_tags array with the appropriate values */
173 /* not that we put a '0' tag in front of the list to indicate that */
174 /* there is a default language for this script.. */
175 TT_ULong
* tags
= table
->language_tags
;
177 switch (table
->otl_type
)
181 script
+= 2; /* skip basevalue or extenders */
185 if ( OTL_UShort(script
) )
189 count
= OTL_UShort(script
);
190 for ( ; count
> 0; count
-- )
192 *tags
++ = OTL_ULong(script
);
193 script
+= 2; /* skip offset */
196 table
->num_langs
= tags
- table
->language_tags
;
201 /* return the list of available features for the current script/language */
202 /* use with a GPOS or GSUB script table */
204 void OTL_Get_Features_List( OTL_Table
* table
,
205 TT_ULong language_tag
)
208 TT_Byte
* script
= table
->cur_script
;
209 TT_Byte
* language
= 0;
212 /* clear feature selection table */
213 for ( n
= 0; n
< table
->max_features
; n
++ )
214 table
->features
[n
] = 0;
216 /* now, look for the current language */
217 if ( language_tag
== 0 )
219 offset
= OTL_UShort(script
);
220 if (!offset
) return; /* if there is no default language, exit */
222 language
= script
- 2 + offset
;
226 TT_Byte
* p
= script
+ 8; /* skip default+count+1st tag */
229 for ( n
= 0; n
< table
->num_languages
; n
++, p
+=6 )
231 if ( table
->language_tags
[n
] == language_tag
)
233 language
= script
+ OTL_UShort(p
);
238 table
->cur_language
= language
;
239 if (!language
) return;
241 p
= language
+ 2; /* skip lookup order */
242 index
= OTL_UShort(p
); /* required feature index */
245 if (index
< table
->max_features
)
246 table
->features
[index
] = 1;
249 count
= OTL_UShort(p
);
250 for ( ; count
> 0; count
-- )
252 index
= OTL_UShort(p
);
253 if (index
< table
->max_features
)
254 table
->features
[index
] = 1;
260 /* return the list of lookups for the current features list */
261 /* use only with a GSUB or GPOS table */
263 void OTL_Get_Lookups_List( OTL_Table
* table
)
266 TT_Byte
* features
= table
->features_table
;
267 TT_Byte
* p
= features
+ 6; /* skip count+1st tag */
269 /* clear lookup list */
270 for ( n
= 0; n
< table
->max_lookups
; n
++ )
271 table
->lookups
[n
] = 0;
273 /* now, parse the features list */
274 for ( n
= 0; n
< table
->features
; n
++ )
276 if (table
->features
[n
])
282 feature
= features
+ OTL_UShort(p
);
283 p
+= 4; /* skip tag */
285 /* now, select all lookups from this feature */
286 count
= OTL_UShort(feature
);
287 for ( ; count
> 0; count
-- )
289 index
= OTL_UShort(feature
);
290 if (index
< table
->max_lookups
)
291 table
->lookups
[index
] = 1;
298 /* find the basevalues and minmax for the current script/language */
299 /* only use it with a BASE table.. */
301 void OTL_Get_Baseline_Values( OTL_Table
* table
,
302 TT_ULong language_tag
)
304 TT_Byte
* script
= table
->cur_script
;
306 TT_UShort offset
, count
;
308 table
->cur_basevalues
= 0;
309 table
->cur_minmax
= 0;
311 /* read basevalues */
312 offset
= OTL_UShort(p
);
314 table
->cur_basevalues
= script
+ offset
;
316 offset
= OTL_UShort(p
);
318 table
->cur_minmax
= script
+ offset
;
320 count
= OTL_UShort(p
);
321 for ( ; count
> 0; count
-- )
326 if ( language_tag
== tag
)
328 table
->cur_minmax
= script
+ OTL_UShort(p
);
331 p
+= 2; /* skip offset */
336 /* compute the coverage value of a given glyph id */
338 TT_Long
OTL_Get_Coverage_Index( TT_Byte
* coverage
,
342 TT_UInt count
, index
, start
, end
;
343 TT_Byte
* p
= coverage
;
345 switch ( OTL_UShort(p
) )
347 case 1: /* coverage format 1 - array of glyph indices */
349 count
= OTL_UShort(p
);
350 for ( index
= 0; index
< count
; index
++ )
352 if ( OTL_UShort(p
) == glyph_id
)
363 count
= OTL_UShort(p
);
364 for ( ; count
> 0; count
-- )
366 start
= OTL_UShort(p
);
368 index
= OTL_UShort(p
);
369 if (start
<= glyph_id
&& glyph_id
<= end
)
371 result
= glyph_id
- start
+ index
;
382 /* compute the class value of a given glyph_id */
384 TT_UInt
OTL_Get_Glyph_Class( TT_Byte
* class_def
,
387 TT_Byte
* p
= class_def
;
389 TT_UInt start
, end
, count
, index
;
391 switch ( OTL_UShort(p
) )
395 start
= OTL_UShort(p
);
396 count
= OTL_UShort(p
);
399 if (glyph_id
< count
)
402 result
= OTL_UShort(p
);
409 count
= OTL_UShort(p
);
410 for ( ; count
> 0; count
-- )
412 start
= OTL_UShort(p
);
414 index
= OTL_UShort(p
);
415 if ( start
<= glyph_id
&& glyph_id
<= end
)
428 /* compute the adjustement necessary for a given device size */
430 TT_Int
OTL_Get_Device_Adjustment( TT_Byte
* device
,
438 start
= OTL_UShort(p
);
440 if (size
>= start
&& size
<= end
)
442 /* I know we could do all of this without a switch, with */
443 /* clever shifts and everything, but it makes the code */
444 /* really difficult to understand.. */
447 switch ( OTL_UShort(p
) )
449 case 1: /* 2-bits per value */
452 size
= (size
& 7) << 1;
453 value
= (TT_Short
)((TT_Short
)OTL_UShort(p
) << size
);
454 result
= value
>> 14;
458 case 2: /* 4-bits per value */
461 size
= (size
& 3) << 2;
462 value
= (TT_Short
)((TT_Short
)OTL_UShort(p
) << size
);
463 result
= value
>> 12;
467 case 3: /* 8-bits per value */
470 size
= (size
& 1) << 3;
471 value
= (TT_Short
)((TT_Short
)OTL_UShort(p
) << size
);
480 /* extract a BaseCoord value */
482 void OTL_Get_Base_Coordinate( TT_Byte
* base_coord
,
483 OTL_ValueRecord
* coord
)
485 TT_Byte
* p
= base_coord
;
488 coord
->format
= OTL_UShort(p
);
489 coord
->coordinate
= OTL_Short(p
);
492 switch (coord
->format
)
494 case 2: /* format 2 */
495 coord
->ref_glyph
= OTL_UShort(p
);
496 coord
->ref_point
= OTL_UShort(p
);
499 case 3: /* format 3 */
500 coord
->device
= p
- 4 + OTL_UShort(p
);
509 /* compute size of ValueRecord */
511 TT_Int
OTL_ValueRecord_Size( TT_UShort format
)
515 /* each bit in the value format corresponds to a single ushort */
516 /* we thus count the bits, and multiply the result by 2 */
518 count
= (TT_Int
)(format
& 0xFF);
519 count
= ((count
& 0xAA) >> 1) + (count
& 0x55);
520 count
= ((count
& 0xCC) >> 2) + (count
& 0x33);
521 count
= ((count
& 0xF0) >> 4) + (count
& 0x0F);
528 /* extract ValueRecord */
530 void OTL_Get_ValueRecord( TT_Byte
* value_record
,
531 TT_UShort value_format
,
533 OTL_ValueRecord
* record
)
535 TT_Byte
* p
= value_record
;
538 record
->placement
.x
= 0;
539 record
->placement
.y
= 0;
540 record
->advance
.x
= 0;
541 record
->advance
.y
= 0;
543 record
->device_pla_x
= 0;
544 record
->device_pla_y
= 0;
545 record
->device_adv_x
= 0;
546 record
->device_adv_y
= 0;
548 if (value_format
& 1) record
->placement
.x
= NEXT_Short(p
);
549 if (value_format
& 2) record
->placement
.y
= NEXT_Short(p
);
550 if (value_format
& 4) record
->advance
.x
= NEXT_Short(p
);
551 if (value_format
& 8) record
->advance
.y
= NEXT_Short(p
);
553 if (value_format
& 16) record
->device_pla_x
= pos_table
+ NEXT_UShort(p
);
554 if (value_format
& 32) record
->device_pla_y
= pos_table
+ NEXT_UShort(p
);
555 if (value_format
& 64) record
->device_adv_x
= pos_table
+ NEXT_UShort(p
);
556 if (value_format
& 128) record
->device_adv_y
= pos_table
+ NEXT_UShort(p
);
563 void OTL_Get_Anchor( TT_Byte
* anchor_table
,
566 TT_Byte
* p
= anchor_table
;
568 anchor
->format
= NEXT_UShort(p
);
569 anchor
->coord
.x
= NEXT_Short(p
);
570 anchor
->coord
.y
= NEXT_Short(p
);
572 anchor
->device_x
= 0;
573 anchor
->device_y
= 0;
575 switch (anchor
->format
)
578 anchor
->point
= NEXT_UShort(p
);
582 anchor
->device_x
= anchor_table
+ NEXT_UShort(p
);
583 anchor
->device_y
= anchor_table
+ NEXT_UShort(p
);
593 /* extract Mark from MarkArray */
595 void OTL_Get_Mark( TT_Byte
* mark_array
,
600 TT_Byte
* p
= mark_array
;
604 MEM_Set( anchor
, 0, sizeof(*anchor
) );
606 count
= NEXT_UShort(p
);
610 *clazz
= NEXT_UShort(p
);
611 OTL_Get_Anchor( mark_array
+ NEXT_UShort(p
), anchor
);