1 /***************************************************************************/
5 /* TrueType and OpenType embedded bitmap support (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
16 /***************************************************************************/
19 #include FT_INTERNAL_DEBUG_H
20 #include FT_INTERNAL_STREAM_H
21 #include FT_TRUETYPE_TAGS_H
24 * Alas, the memory-optimized sbit loader can't be used when implementing
25 * the `old internals' hack
27 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
31 #else /* FT_CONFIG_OPTION_OLD_INTERNALS */
34 #include FT_INTERNAL_DEBUG_H
35 #include FT_INTERNAL_STREAM_H
36 #include FT_TRUETYPE_TAGS_H
42 /*************************************************************************/
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
49 #define FT_COMPONENT trace_ttsbit
52 /*************************************************************************/
58 /* Blits a bitmap from an input stream into a given target. Supports */
59 /* x and y offsets as well as byte padded lines. */
62 /* target :: The target bitmap/pixmap. */
64 /* source :: The input packed bitmap data. */
66 /* line_bits :: The number of bits per line. */
68 /* byte_padded :: A flag which is true if lines are byte-padded. */
70 /* x_offset :: The horizontal offset. */
72 /* y_offset :: The vertical offset. */
75 /* IMPORTANT: The x and y offsets are relative to the top corner of */
76 /* the target bitmap (unlike the normal TrueType */
77 /* convention). A positive y offset indicates a downwards */
81 blit_sbit( FT_Bitmap
* target
,
87 FT_Int source_height
)
97 /* first of all, compute starting write position */
98 line_incr
= target
->pitch
;
99 line_buff
= target
->buffer
;
102 line_buff
-= line_incr
* ( target
->rows
- 1 );
104 line_buff
+= ( x_offset
>> 3 ) + y_offset
* line_incr
;
106 /***********************************************************************/
108 /* We use the extra-classic `accumulator' trick to extract the bits */
109 /* from the source byte stream. */
111 /* Namely, the variable `acc' is a 16-bit accumulator containing the */
112 /* last `loaded' bits from the input stream. The bits are shifted to */
113 /* the upmost position in `acc'. */
115 /***********************************************************************/
117 acc
= 0; /* clear accumulator */
118 loaded
= 0; /* no bits were loaded */
120 for ( height
= source_height
; height
> 0; height
-- )
122 FT_Byte
* cur
= line_buff
; /* current write cursor */
123 FT_Int count
= line_bits
; /* # of bits to extract per line */
124 FT_Byte shift
= (FT_Byte
)( x_offset
& 7 ); /* current write shift */
125 FT_Byte space
= (FT_Byte
)( 8 - shift
);
128 /* first of all, read individual source bytes */
138 /* ensure that there are at least 8 bits in the accumulator */
141 acc
|= (FT_UShort
)((FT_UShort
)*source
++ << ( 8 - loaded
));
145 /* now write one byte */
146 val
= (FT_Byte
)( acc
>> 8 );
149 cur
[0] |= (FT_Byte
)( val
>> shift
);
150 cur
[1] |= (FT_Byte
)( val
<< space
);
156 acc
<<= 8; /* remove bits from accumulator */
160 } while ( count
>= 0 );
163 /* restore `count' to correct value */
167 /* now write remaining bits (count < 8) */
173 /* ensure that there are at least `count' bits in the accumulator */
174 if ( (FT_Int
)loaded
< count
)
176 acc
|= (FT_UShort
)((FT_UShort
)*source
++ << ( 8 - loaded
));
180 /* now write remaining bits */
181 val
= (FT_Byte
)( ( (FT_Byte
)( acc
>> 8 ) ) & ~( 0xFF >> count
) );
182 cur
[0] |= (FT_Byte
)( val
>> shift
);
185 cur
[1] |= (FT_Byte
)( val
<< space
);
191 /* now, skip to next line */
195 loaded
= 0; /* clear accumulator on byte-padded lines */
198 line_buff
+= line_incr
;
203 static const FT_Frame_Field sbit_metrics_fields
[] =
206 #define FT_STRUCTURE TT_SBit_MetricsRec
209 FT_FRAME_BYTE( height
),
210 FT_FRAME_BYTE( width
),
212 FT_FRAME_CHAR( horiBearingX
),
213 FT_FRAME_CHAR( horiBearingY
),
214 FT_FRAME_BYTE( horiAdvance
),
216 FT_FRAME_CHAR( vertBearingX
),
217 FT_FRAME_CHAR( vertBearingY
),
218 FT_FRAME_BYTE( vertAdvance
),
223 /*************************************************************************/
226 /* Load_SBit_Const_Metrics */
229 /* Loads the metrics for `EBLC' index tables format 2 and 5. */
232 /* range :: The target range. */
234 /* stream :: The input stream. */
237 /* FreeType error code. 0 means success. */
240 Load_SBit_Const_Metrics( TT_SBit_Range range
,
246 if ( FT_READ_ULONG( range
->image_size
) )
249 return FT_STREAM_READ_FIELDS( sbit_metrics_fields
, &range
->metrics
);
253 /*************************************************************************/
256 /* Load_SBit_Range_Codes */
259 /* Loads the range codes for `EBLC' index tables format 4 and 5. */
262 /* range :: The target range. */
264 /* stream :: The input stream. */
266 /* load_offsets :: A flag whether to load the glyph offset table. */
269 /* FreeType error code. 0 means success. */
272 Load_SBit_Range_Codes( TT_SBit_Range range
,
274 FT_Bool load_offsets
)
277 FT_ULong count
, n
, size
;
278 FT_Memory memory
= stream
->memory
;
281 if ( FT_READ_ULONG( count
) )
284 range
->num_glyphs
= count
;
286 /* Allocate glyph offsets table if needed */
289 if ( FT_NEW_ARRAY( range
->glyph_offsets
, count
) )
297 /* Allocate glyph codes table and access frame */
298 if ( FT_NEW_ARRAY ( range
->glyph_codes
, count
) ||
299 FT_FRAME_ENTER( size
) )
302 for ( n
= 0; n
< count
; n
++ )
304 range
->glyph_codes
[n
] = FT_GET_USHORT();
307 range
->glyph_offsets
[n
] = (FT_ULong
)range
->image_offset
+
318 /*************************************************************************/
321 /* Load_SBit_Range */
324 /* Loads a given `EBLC' index/range table. */
327 /* range :: The target range. */
329 /* stream :: The input stream. */
332 /* FreeType error code. 0 means success. */
335 Load_SBit_Range( TT_SBit_Range range
,
339 FT_Memory memory
= stream
->memory
;
342 switch( range
->index_format
)
344 case 1: /* variable metrics with 4-byte offsets */
345 case 3: /* variable metrics with 2-byte offsets */
347 FT_ULong num_glyphs
, n
;
349 FT_Bool large
= FT_BOOL( range
->index_format
== 1 );
353 if ( range
->last_glyph
< range
->first_glyph
)
355 error
= SFNT_Err_Invalid_File_Format
;
359 num_glyphs
= range
->last_glyph
- range
->first_glyph
+ 1L;
360 range
->num_glyphs
= num_glyphs
;
361 num_glyphs
++; /* XXX: BEWARE - see spec */
363 size_elem
= large
? 4 : 2;
365 if ( FT_NEW_ARRAY( range
->glyph_offsets
, num_glyphs
) ||
366 FT_FRAME_ENTER( num_glyphs
* size_elem
) )
369 for ( n
= 0; n
< num_glyphs
; n
++ )
370 range
->glyph_offsets
[n
] = (FT_ULong
)( range
->image_offset
+
371 ( large
? FT_GET_ULONG()
372 : FT_GET_USHORT() ) );
377 case 2: /* all glyphs have identical metrics */
378 error
= Load_SBit_Const_Metrics( range
, stream
);
382 error
= Load_SBit_Range_Codes( range
, stream
, 1 );
386 error
= Load_SBit_Const_Metrics( range
, stream
);
388 error
= Load_SBit_Range_Codes( range
, stream
, 0 );
392 error
= SFNT_Err_Invalid_File_Format
;
400 /*************************************************************************/
403 /* tt_face_load_eblc */
406 /* Loads the table of embedded bitmap sizes for this face. */
409 /* face :: The target face object. */
411 /* stream :: The input stream. */
414 /* FreeType error code. 0 means success. */
416 FT_LOCAL_DEF( FT_Error
)
417 tt_face_load_eblc( TT_Face face
,
421 FT_Memory memory
= stream
->memory
;
423 FT_ULong num_strikes
;
426 static const FT_Frame_Field sbit_line_metrics_fields
[] =
429 #define FT_STRUCTURE TT_SBit_LineMetricsRec
431 /* no FT_FRAME_START */
432 FT_FRAME_CHAR( ascender
),
433 FT_FRAME_CHAR( descender
),
434 FT_FRAME_BYTE( max_width
),
436 FT_FRAME_CHAR( caret_slope_numerator
),
437 FT_FRAME_CHAR( caret_slope_denominator
),
438 FT_FRAME_CHAR( caret_offset
),
440 FT_FRAME_CHAR( min_origin_SB
),
441 FT_FRAME_CHAR( min_advance_SB
),
442 FT_FRAME_CHAR( max_before_BL
),
443 FT_FRAME_CHAR( min_after_BL
),
444 FT_FRAME_CHAR( pads
[0] ),
445 FT_FRAME_CHAR( pads
[1] ),
449 static const FT_Frame_Field strike_start_fields
[] =
452 #define FT_STRUCTURE TT_SBit_StrikeRec
454 /* no FT_FRAME_START */
455 FT_FRAME_ULONG( ranges_offset
),
457 FT_FRAME_ULONG( num_ranges
),
458 FT_FRAME_ULONG( color_ref
),
462 static const FT_Frame_Field strike_end_fields
[] =
464 /* no FT_FRAME_START */
465 FT_FRAME_USHORT( start_glyph
),
466 FT_FRAME_USHORT( end_glyph
),
467 FT_FRAME_BYTE ( x_ppem
),
468 FT_FRAME_BYTE ( y_ppem
),
469 FT_FRAME_BYTE ( bit_depth
),
470 FT_FRAME_CHAR ( flags
),
475 face
->num_sbit_strikes
= 0;
477 /* this table is optional */
478 error
= face
->goto_table( face
, TTAG_EBLC
, stream
, 0 );
480 error
= face
->goto_table( face
, TTAG_bloc
, stream
, 0 );
484 table_base
= FT_STREAM_POS();
485 if ( FT_FRAME_ENTER( 8L ) )
488 version
= FT_GET_LONG();
489 num_strikes
= FT_GET_ULONG();
493 /* check version number and strike count */
494 if ( version
!= 0x00020000L
||
495 num_strikes
>= 0x10000L
)
497 FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
498 error
= SFNT_Err_Invalid_File_Format
;
503 /* allocate the strikes table */
504 if ( FT_NEW_ARRAY( face
->sbit_strikes
, num_strikes
) )
507 face
->num_sbit_strikes
= num_strikes
;
509 /* now read each strike table separately */
511 TT_SBit_Strike strike
= face
->sbit_strikes
;
512 FT_ULong count
= num_strikes
;
515 if ( FT_FRAME_ENTER( 48L * num_strikes
) )
520 if ( FT_STREAM_READ_FIELDS( strike_start_fields
, strike
) ||
521 FT_STREAM_READ_FIELDS( sbit_line_metrics_fields
, &strike
->hori
) ||
522 FT_STREAM_READ_FIELDS( sbit_line_metrics_fields
, &strike
->vert
) ||
523 FT_STREAM_READ_FIELDS( strike_end_fields
, strike
) )
533 /* allocate the index ranges for each strike table */
535 TT_SBit_Strike strike
= face
->sbit_strikes
;
536 FT_ULong count
= num_strikes
;
542 FT_ULong count2
= strike
->num_ranges
;
545 /* read each range */
546 if ( FT_STREAM_SEEK( table_base
+ strike
->ranges_offset
) ||
547 FT_FRAME_ENTER( strike
->num_ranges
* 8L ) )
550 if ( FT_NEW_ARRAY( strike
->sbit_ranges
, strike
->num_ranges
) )
553 range
= strike
->sbit_ranges
;
556 range
->first_glyph
= FT_GET_USHORT();
557 range
->last_glyph
= FT_GET_USHORT();
558 range
->table_offset
= table_base
+ strike
->ranges_offset
+
566 /* Now, read each index table */
567 count2
= strike
->num_ranges
;
568 range
= strike
->sbit_ranges
;
571 /* Read the header */
572 if ( FT_STREAM_SEEK( range
->table_offset
) ||
573 FT_FRAME_ENTER( 8L ) )
576 range
->index_format
= FT_GET_USHORT();
577 range
->image_format
= FT_GET_USHORT();
578 range
->image_offset
= FT_GET_ULONG();
582 error
= Load_SBit_Range( range
, stream
);
600 /*************************************************************************/
603 /* tt_face_free_eblc */
606 /* Releases the embedded bitmap tables. */
609 /* face :: The target face object. */
612 tt_face_free_eblc( TT_Face face
)
614 FT_Memory memory
= face
->root
.memory
;
615 TT_SBit_Strike strike
= face
->sbit_strikes
;
616 TT_SBit_Strike strike_limit
= strike
+ face
->num_sbit_strikes
;
621 for ( ; strike
< strike_limit
; strike
++ )
623 TT_SBit_Range range
= strike
->sbit_ranges
;
624 TT_SBit_Range range_limit
= range
+ strike
->num_ranges
;
629 for ( ; range
< range_limit
; range
++ )
631 /* release the glyph offsets and codes tables */
632 /* where appropriate */
633 FT_FREE( range
->glyph_offsets
);
634 FT_FREE( range
->glyph_codes
);
637 FT_FREE( strike
->sbit_ranges
);
638 strike
->num_ranges
= 0;
640 FT_FREE( face
->sbit_strikes
);
642 face
->num_sbit_strikes
= 0;
646 FT_LOCAL_DEF( FT_Error
)
647 tt_face_set_sbit_strike( TT_Face face
,
649 FT_ULong
* astrike_index
)
651 return FT_Match_Size( (FT_Face
)face
, req
, 0, astrike_index
);
655 FT_LOCAL_DEF( FT_Error
)
656 tt_face_load_strike_metrics( TT_Face face
,
657 FT_ULong strike_index
,
658 FT_Size_Metrics
* metrics
)
660 TT_SBit_Strike strike
;
663 if ( strike_index
>= face
->num_sbit_strikes
)
664 return SFNT_Err_Invalid_Argument
;
666 strike
= face
->sbit_strikes
+ strike_index
;
668 metrics
->x_ppem
= strike
->x_ppem
;
669 metrics
->y_ppem
= strike
->y_ppem
;
671 metrics
->ascender
= strike
->hori
.ascender
<< 6;
672 metrics
->descender
= strike
->hori
.descender
<< 6;
674 /* XXX: Is this correct? */
675 metrics
->max_advance
= ( strike
->hori
.min_origin_SB
+
676 strike
->hori
.max_width
+
677 strike
->hori
.min_advance_SB
) << 6;
679 metrics
->height
= metrics
->ascender
- metrics
->descender
;
685 /*************************************************************************/
688 /* find_sbit_range */
691 /* Scans a given strike's ranges and return, for a given glyph */
692 /* index, the corresponding sbit range, and `EBDT' offset. */
695 /* glyph_index :: The glyph index. */
697 /* strike :: The source/current sbit strike. */
700 /* arange :: The sbit range containing the glyph index. */
702 /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
705 /* FreeType error code. 0 means the glyph index was found. */
708 find_sbit_range( FT_UInt glyph_index
,
709 TT_SBit_Strike strike
,
710 TT_SBit_Range
*arange
,
711 FT_ULong
*aglyph_offset
)
713 TT_SBit_RangeRec
*range
, *range_limit
;
716 /* check whether the glyph index is within this strike's */
718 if ( glyph_index
< (FT_UInt
)strike
->start_glyph
||
719 glyph_index
> (FT_UInt
)strike
->end_glyph
)
722 /* scan all ranges in strike */
723 range
= strike
->sbit_ranges
;
724 range_limit
= range
+ strike
->num_ranges
;
728 for ( ; range
< range_limit
; range
++ )
730 if ( glyph_index
>= (FT_UInt
)range
->first_glyph
&&
731 glyph_index
<= (FT_UInt
)range
->last_glyph
)
733 FT_UShort delta
= (FT_UShort
)( glyph_index
- range
->first_glyph
);
736 switch ( range
->index_format
)
740 *aglyph_offset
= range
->glyph_offsets
[delta
];
744 *aglyph_offset
= range
->image_offset
+
745 range
->image_size
* delta
;
754 for ( n
= 0; n
< range
->num_glyphs
; n
++ )
756 if ( (FT_UInt
)range
->glyph_codes
[n
] == glyph_index
)
758 if ( range
->index_format
== 4 )
759 *aglyph_offset
= range
->glyph_offsets
[n
];
761 *aglyph_offset
= range
->image_offset
+
762 n
* range
->image_size
;
774 /* return successfully! */
784 return SFNT_Err_Invalid_Argument
;
788 /*************************************************************************/
791 /* tt_find_sbit_image */
794 /* Checks whether an embedded bitmap (an `sbit') exists for a given */
795 /* glyph, at a given strike. */
798 /* face :: The target face object. */
800 /* glyph_index :: The glyph index. */
802 /* strike_index :: The current strike index. */
805 /* arange :: The SBit range containing the glyph index. */
807 /* astrike :: The SBit strike containing the glyph index. */
809 /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */
812 /* FreeType error code. 0 means success. Returns */
813 /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */
817 tt_find_sbit_image( TT_Face face
,
819 FT_ULong strike_index
,
820 TT_SBit_Range
*arange
,
821 TT_SBit_Strike
*astrike
,
822 FT_ULong
*aglyph_offset
)
825 TT_SBit_Strike strike
;
828 if ( !face
->sbit_strikes
||
829 ( face
->num_sbit_strikes
<= strike_index
) )
832 strike
= &face
->sbit_strikes
[strike_index
];
834 error
= find_sbit_range( glyph_index
, strike
,
835 arange
, aglyph_offset
);
844 /* no embedded bitmap for this glyph in face */
849 return SFNT_Err_Invalid_Argument
;
853 /*************************************************************************/
856 /* tt_load_sbit_metrics */
859 /* Gets the big metrics for a given SBit. */
862 /* stream :: The input stream. */
864 /* range :: The SBit range containing the glyph. */
867 /* big_metrics :: A big SBit metrics structure for the glyph. */
870 /* FreeType error code. 0 means success. */
873 /* The stream cursor must be positioned at the glyph's offset within */
874 /* the `EBDT' table before the call. */
876 /* If the image format uses variable metrics, the stream cursor is */
877 /* positioned just after the metrics header in the `EBDT' table on */
881 tt_load_sbit_metrics( FT_Stream stream
,
883 TT_SBit_Metrics metrics
)
885 FT_Error error
= SFNT_Err_Ok
;
888 switch ( range
->image_format
)
893 /* variable small metrics */
895 TT_SBit_SmallMetricsRec smetrics
;
897 static const FT_Frame_Field sbit_small_metrics_fields
[] =
900 #define FT_STRUCTURE TT_SBit_SmallMetricsRec
903 FT_FRAME_BYTE( height
),
904 FT_FRAME_BYTE( width
),
905 FT_FRAME_CHAR( bearingX
),
906 FT_FRAME_CHAR( bearingY
),
907 FT_FRAME_BYTE( advance
),
912 /* read small metrics */
913 if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields
, &smetrics
) )
916 /* convert it to a big metrics */
917 metrics
->height
= smetrics
.height
;
918 metrics
->width
= smetrics
.width
;
919 metrics
->horiBearingX
= smetrics
.bearingX
;
920 metrics
->horiBearingY
= smetrics
.bearingY
;
921 metrics
->horiAdvance
= smetrics
.advance
;
923 /* these metrics are made up at a higher level when */
925 metrics
->vertBearingX
= 0;
926 metrics
->vertBearingY
= 0;
927 metrics
->vertAdvance
= 0;
934 /* variable big metrics */
935 if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields
, metrics
) )
940 default: /* constant metrics */
941 if ( range
->index_format
== 2 || range
->index_format
== 5 )
942 *metrics
= range
->metrics
;
944 return SFNT_Err_Invalid_File_Format
;
952 /*************************************************************************/
958 /* Crops a bitmap to its tightest bounding box, and adjusts its */
962 /* map :: The bitmap. */
964 /* metrics :: The corresponding metrics structure. */
967 crop_bitmap( FT_Bitmap
* map
,
968 TT_SBit_Metrics metrics
)
970 /***********************************************************************/
972 /* In this situation, some bounding boxes of embedded bitmaps are too */
973 /* large. We need to crop it to a reasonable size. */
979 /* | * | ------> | * | */
983 /* --------- ----- */
985 /***********************************************************************/
992 /***********************************************************************/
994 /* first of all, check the top-most lines of the bitmap, and remove */
995 /* them if they're empty. */
998 line
= (FT_Byte
*)map
->buffer
;
1000 line_len
= map
->pitch
;
1003 for ( count
= 0; count
< rows
; count
++ )
1005 FT_Byte
* cur
= line
;
1006 FT_Byte
* limit
= line
+ line_len
;
1009 for ( ; cur
< limit
; cur
++ )
1013 /* the current line was empty - skip to next one */
1018 /* check that we have at least one filled line */
1019 if ( count
>= rows
)
1022 /* now, crop the empty upper lines */
1025 line
= (FT_Byte
*)map
->buffer
;
1027 FT_MEM_MOVE( line
, line
+ count
* line_len
,
1028 ( rows
- count
) * line_len
);
1030 metrics
->height
= (FT_Byte
)( metrics
->height
- count
);
1031 metrics
->horiBearingY
= (FT_Char
)( metrics
->horiBearingY
- count
);
1032 metrics
->vertBearingY
= (FT_Char
)( metrics
->vertBearingY
- count
);
1039 /***********************************************************************/
1041 /* second, crop the lower lines */
1044 line
= (FT_Byte
*)map
->buffer
+ ( rows
- 1 ) * line_len
;
1046 for ( count
= 0; count
< rows
; count
++ )
1048 FT_Byte
* cur
= line
;
1049 FT_Byte
* limit
= line
+ line_len
;
1052 for ( ; cur
< limit
; cur
++ )
1056 /* the current line was empty - skip to previous one */
1063 metrics
->height
= (FT_Byte
)( metrics
->height
- count
);
1069 /***********************************************************************/
1071 /* third, get rid of the space on the left side of the glyph */
1078 line
= (FT_Byte
*)map
->buffer
;
1079 limit
= line
+ rows
* line_len
;
1081 for ( ; line
< limit
; line
+= line_len
)
1082 if ( line
[0] & 0x80 )
1085 /* shift the whole glyph one pixel to the left */
1086 line
= (FT_Byte
*)map
->buffer
;
1087 limit
= line
+ rows
* line_len
;
1089 for ( ; line
< limit
; line
+= line_len
)
1091 FT_Int n
, width
= map
->width
;
1093 FT_Byte
* cur
= line
;
1096 old
= (FT_Byte
)(cur
[0] << 1);
1097 for ( n
= 8; n
< width
; n
+= 8 )
1103 cur
[0] = (FT_Byte
)( old
| ( val
>> 7 ) );
1104 old
= (FT_Byte
)( val
<< 1 );
1111 metrics
->horiBearingX
++;
1112 metrics
->vertBearingX
++;
1115 } while ( map
->width
> 0 );
1119 /***********************************************************************/
1121 /* finally, crop the bitmap width to get rid of the space on the right */
1122 /* side of the glyph. */
1126 FT_Int right
= map
->width
- 1;
1131 line
= (FT_Byte
*)map
->buffer
+ ( right
>> 3 );
1132 limit
= line
+ rows
* line_len
;
1133 mask
= (FT_Byte
)( 0x80 >> ( right
& 7 ) );
1135 for ( ; line
< limit
; line
+= line_len
)
1136 if ( line
[0] & mask
)
1139 /* crop the whole glyph to the right */
1143 } while ( map
->width
> 0 );
1146 /* all right, the bitmap was cropped */
1153 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
1158 Load_SBit_Single( FT_Bitmap
* map
,
1162 FT_UShort image_format
,
1163 TT_SBit_Metrics metrics
,
1169 /* check that the source bitmap fits into the target pixmap */
1170 if ( x_offset
< 0 || x_offset
+ metrics
->width
> map
->width
||
1171 y_offset
< 0 || y_offset
+ metrics
->height
> map
->rows
)
1173 error
= SFNT_Err_Invalid_Argument
;
1179 FT_Int glyph_width
= metrics
->width
;
1180 FT_Int glyph_height
= metrics
->height
;
1182 FT_Int line_bits
= pix_bits
* glyph_width
;
1183 FT_Bool pad_bytes
= 0;
1186 /* compute size of glyph image */
1187 switch ( image_format
)
1189 case 1: /* byte-padded formats */
1198 line_length
= ( glyph_width
+ 7 ) >> 3;
1201 line_length
= ( glyph_width
+ 3 ) >> 2;
1204 line_length
= ( glyph_width
+ 1 ) >> 1;
1207 line_length
= glyph_width
;
1210 glyph_size
= glyph_height
* line_length
;
1218 line_bits
= glyph_width
* pix_bits
;
1219 glyph_size
= ( glyph_height
* line_bits
+ 7 ) >> 3;
1222 default: /* invalid format */
1223 return SFNT_Err_Invalid_File_Format
;
1226 /* Now read data and draw glyph into target pixmap */
1227 if ( FT_FRAME_ENTER( glyph_size
) )
1230 /* don't forget to multiply `x_offset' by `map->pix_bits' as */
1231 /* the sbit blitter doesn't make a difference between pixmap */
1233 blit_sbit( map
, (FT_Byte
*)stream
->cursor
, line_bits
, pad_bytes
,
1234 x_offset
* pix_bits
, y_offset
, metrics
->height
);
1245 Load_SBit_Image( TT_SBit_Strike strike
,
1246 TT_SBit_Range range
,
1248 FT_ULong glyph_offset
,
1253 TT_SBit_Metrics metrics
,
1256 FT_Memory memory
= stream
->memory
;
1257 FT_Bitmap
* map
= &slot
->bitmap
;
1261 /* place stream at beginning of glyph data and read metrics */
1262 if ( FT_STREAM_SEEK( ebdt_pos
+ glyph_offset
) )
1265 error
= tt_load_sbit_metrics( stream
, range
, metrics
);
1269 /* This function is recursive. At the top-level call, we */
1270 /* compute the dimensions of the higher-level glyph to */
1271 /* allocate the final pixmap buffer. */
1277 map
->width
= metrics
->width
;
1278 map
->rows
= metrics
->height
;
1280 switch ( strike
->bit_depth
)
1283 map
->pixel_mode
= FT_PIXEL_MODE_MONO
;
1284 map
->pitch
= ( map
->width
+ 7 ) >> 3;
1288 map
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
1289 map
->pitch
= ( map
->width
+ 3 ) >> 2;
1293 map
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
1294 map
->pitch
= ( map
->width
+ 1 ) >> 1;
1298 map
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
1299 map
->pitch
= map
->width
;
1303 return SFNT_Err_Invalid_File_Format
;
1306 size
= map
->rows
* map
->pitch
;
1308 /* check that there is no empty image */
1310 goto Exit
; /* exit successfully! */
1312 error
= ft_glyphslot_alloc_bitmap( slot
, size
);
1317 switch ( range
->image_format
)
1319 case 1: /* single sbit image - load it */
1324 return Load_SBit_Single( map
, x_offset
, y_offset
, strike
->bit_depth
,
1325 range
->image_format
, metrics
, stream
);
1327 case 8: /* compound format */
1328 if ( FT_STREAM_SKIP( 1L ) )
1330 error
= SFNT_Err_Invalid_Stream_Skip
;
1338 default: /* invalid image format */
1339 return SFNT_Err_Invalid_File_Format
;
1342 /* All right, we have a compound format. First of all, read */
1343 /* the array of elements. */
1345 TT_SBit_Component components
;
1346 TT_SBit_Component comp
;
1347 FT_UShort num_components
, count
;
1350 if ( FT_READ_USHORT( num_components
) ||
1351 FT_NEW_ARRAY( components
, num_components
) )
1354 count
= num_components
;
1356 if ( FT_FRAME_ENTER( 4L * num_components
) )
1359 for ( comp
= components
; count
> 0; count
--, comp
++ )
1361 comp
->glyph_code
= FT_GET_USHORT();
1362 comp
->x_offset
= FT_GET_CHAR();
1363 comp
->y_offset
= FT_GET_CHAR();
1368 /* Now recursively load each element glyph */
1369 count
= num_components
;
1371 for ( ; count
> 0; count
--, comp
++ )
1373 TT_SBit_Range elem_range
;
1374 TT_SBit_MetricsRec elem_metrics
;
1375 FT_ULong elem_offset
;
1378 /* find the range for this element */
1379 error
= find_sbit_range( comp
->glyph_code
,
1386 /* now load the element, recursively */
1387 error
= Load_SBit_Image( strike
,
1392 x_offset
+ comp
->x_offset
,
1393 y_offset
+ comp
->y_offset
,
1402 FT_FREE( components
);
1410 /*************************************************************************/
1413 /* tt_face_load_sbit_image */
1416 /* Loads a given glyph sbit image from the font resource. This also */
1417 /* returns its metrics. */
1420 /* face :: The target face object. */
1422 /* strike_index :: The current strike index. */
1424 /* glyph_index :: The current glyph index. */
1426 /* load_flags :: The glyph load flags (the code checks for the flag */
1427 /* FT_LOAD_CROP_BITMAP). */
1429 /* stream :: The input stream. */
1432 /* map :: The target pixmap. */
1434 /* metrics :: A big sbit metrics structure for the glyph image. */
1437 /* FreeType error code. 0 means success. Returns an error if no */
1438 /* glyph sbit exists for the index. */
1441 /* The `map.buffer' field is always freed before the glyph is loaded. */
1443 FT_LOCAL_DEF( FT_Error
)
1444 tt_face_load_sbit_image( TT_Face face
,
1445 FT_ULong strike_index
,
1446 FT_UInt glyph_index
,
1450 TT_SBit_MetricsRec
*metrics
)
1453 FT_ULong ebdt_pos
, glyph_offset
;
1455 TT_SBit_Strike strike
;
1456 TT_SBit_Range range
;
1459 /* Check whether there is a glyph sbit for the current index */
1460 error
= tt_find_sbit_image( face
, glyph_index
, strike_index
,
1461 &range
, &strike
, &glyph_offset
);
1465 /* now, find the location of the `EBDT' table in */
1467 error
= face
->goto_table( face
, TTAG_EBDT
, stream
, 0 );
1469 error
= face
->goto_table( face
, TTAG_bdat
, stream
, 0 );
1473 ebdt_pos
= FT_STREAM_POS();
1475 error
= Load_SBit_Image( strike
, range
, ebdt_pos
, glyph_offset
,
1476 face
->root
.glyph
, 0, 0, stream
, metrics
, 0 );
1480 /* setup vertical metrics if needed */
1481 if ( strike
->flags
& 1 )
1483 /* in case of a horizontal strike only */
1487 advance
= strike
->hori
.ascender
- strike
->hori
.descender
;
1489 /* some heuristic values */
1491 metrics
->vertBearingX
= (FT_Char
)(-metrics
->width
/ 2 );
1492 metrics
->vertBearingY
= (FT_Char
)( ( advance
- metrics
->height
) / 2 );
1493 metrics
->vertAdvance
= (FT_Char
)( advance
* 12 / 10 );
1496 /* Crop the bitmap now, unless specified otherwise */
1497 if ( load_flags
& FT_LOAD_CROP_BITMAP
)
1498 crop_bitmap( map
, metrics
);
1504 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */