Initialize Tizen 2.3
[framework/graphics/freetype.git] / src / sfnt / ttsbit.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ttsbit.c                                                               */
4 /*                                                                         */
5 /*    TrueType and OpenType embedded bitmap support (body).                */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
8 /*            2010 by                                                      */
9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10 /*                                                                         */
11 /*  This file is part of the FreeType project, and may only be used,       */
12 /*  modified, and distributed under the terms of the FreeType project      */
13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
14 /*  this file you indicate that you have read the license and              */
15 /*  understand and accept it fully.                                        */
16 /*                                                                         */
17 /***************************************************************************/
18
19 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_TRUETYPE_TAGS_H
23
24   /*
25    *  Alas, the memory-optimized sbit loader can't be used when implementing
26    *  the `old internals' hack
27    */
28 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
29
30 #include "ttsbit0.c"
31
32 #else /* FT_CONFIG_OPTION_OLD_INTERNALS */
33
34 #include <ft2build.h>
35 #include FT_INTERNAL_DEBUG_H
36 #include FT_INTERNAL_STREAM_H
37 #include FT_TRUETYPE_TAGS_H
38 #include "ttsbit.h"
39
40 #include "sferrors.h"
41
42
43   /*************************************************************************/
44   /*                                                                       */
45   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
46   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
47   /* messages during execution.                                            */
48   /*                                                                       */
49 #undef  FT_COMPONENT
50 #define FT_COMPONENT  trace_ttsbit
51
52
53   /*************************************************************************/
54   /*                                                                       */
55   /* <Function>                                                            */
56   /*    blit_sbit                                                          */
57   /*                                                                       */
58   /* <Description>                                                         */
59   /*    Blits a bitmap from an input stream into a given target.  Supports */
60   /*    x and y offsets as well as byte padded lines.                      */
61   /*                                                                       */
62   /* <Input>                                                               */
63   /*    target      :: The target bitmap/pixmap.                           */
64   /*                                                                       */
65   /*    source      :: The input packed bitmap data.                       */
66   /*                                                                       */
67   /*    line_bits   :: The number of bits per line.                        */
68   /*                                                                       */
69   /*    byte_padded :: A flag which is true if lines are byte-padded.      */
70   /*                                                                       */
71   /*    x_offset    :: The horizontal offset.                              */
72   /*                                                                       */
73   /*    y_offset    :: The vertical offset.                                */
74   /*                                                                       */
75   /* <Note>                                                                */
76   /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
77   /*               the target bitmap (unlike the normal TrueType           */
78   /*               convention).  A positive y offset indicates a downwards */
79   /*               direction!                                              */
80   /*                                                                       */
81   static void
82   blit_sbit( FT_Bitmap*  target,
83              FT_Byte*    source,
84              FT_Int      line_bits,
85              FT_Bool     byte_padded,
86              FT_Int      x_offset,
87              FT_Int      y_offset,
88              FT_Int      source_height )
89   {
90     FT_Byte*   line_buff;
91     FT_Int     line_incr;
92     FT_Int     height;
93
94     FT_UShort  acc;
95     FT_UInt    loaded;
96
97
98     /* first of all, compute starting write position */
99     line_incr = target->pitch;
100     line_buff = target->buffer;
101
102     if ( line_incr < 0 )
103       line_buff -= line_incr * ( target->rows - 1 );
104
105     line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
106
107     /***********************************************************************/
108     /*                                                                     */
109     /* We use the extra-classic `accumulator' trick to extract the bits    */
110     /* from the source byte stream.                                        */
111     /*                                                                     */
112     /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
113     /* last `loaded' bits from the input stream.  The bits are shifted to  */
114     /* the upmost position in `acc'.                                       */
115     /*                                                                     */
116     /***********************************************************************/
117
118     acc    = 0;  /* clear accumulator   */
119     loaded = 0;  /* no bits were loaded */
120
121     for ( height = source_height; height > 0; height-- )
122     {
123       FT_Byte*  cur   = line_buff;        /* current write cursor          */
124       FT_Int    count = line_bits;        /* # of bits to extract per line */
125       FT_Byte   shift = (FT_Byte)( x_offset & 7 ); /* current write shift  */
126       FT_Byte   space = (FT_Byte)( 8 - shift );
127
128
129       /* first of all, read individual source bytes */
130       if ( count >= 8 )
131       {
132         count -= 8;
133         {
134           do
135           {
136             FT_Byte  val;
137
138
139             /* ensure that there are at least 8 bits in the accumulator */
140             if ( loaded < 8 )
141             {
142               acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
143               loaded += 8;
144             }
145
146             /* now write one byte */
147             val = (FT_Byte)( acc >> 8 );
148             if ( shift )
149             {
150               cur[0] |= (FT_Byte)( val >> shift );
151               cur[1] |= (FT_Byte)( val << space );
152             }
153             else
154               cur[0] |= val;
155
156             cur++;
157             acc   <<= 8;  /* remove bits from accumulator */
158             loaded -= 8;
159             count  -= 8;
160
161           } while ( count >= 0 );
162         }
163
164         /* restore `count' to correct value */
165         count += 8;
166       }
167
168       /* now write remaining bits (count < 8) */
169       if ( count > 0 )
170       {
171         FT_Byte  val;
172
173
174         /* ensure that there are at least `count' bits in the accumulator */
175         if ( (FT_Int)loaded < count )
176         {
177           acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
178           loaded += 8;
179         }
180
181         /* now write remaining bits */
182         val     = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
183         cur[0] |= (FT_Byte)( val >> shift );
184
185         if ( count > space )
186           cur[1] |= (FT_Byte)( val << space );
187
188         acc   <<= count;
189         loaded -= count;
190       }
191
192       /* now, skip to next line */
193       if ( byte_padded )
194       {
195         acc    = 0;
196         loaded = 0;   /* clear accumulator on byte-padded lines */
197       }
198
199       line_buff += line_incr;
200     }
201   }
202
203
204   static const FT_Frame_Field  sbit_metrics_fields[] =
205   {
206 #undef  FT_STRUCTURE
207 #define FT_STRUCTURE  TT_SBit_MetricsRec
208
209     FT_FRAME_START( 8 ),
210       FT_FRAME_BYTE( height ),
211       FT_FRAME_BYTE( width ),
212
213       FT_FRAME_CHAR( horiBearingX ),
214       FT_FRAME_CHAR( horiBearingY ),
215       FT_FRAME_BYTE( horiAdvance ),
216
217       FT_FRAME_CHAR( vertBearingX ),
218       FT_FRAME_CHAR( vertBearingY ),
219       FT_FRAME_BYTE( vertAdvance ),
220     FT_FRAME_END
221   };
222
223
224   /*************************************************************************/
225   /*                                                                       */
226   /* <Function>                                                            */
227   /*    Load_SBit_Const_Metrics                                            */
228   /*                                                                       */
229   /* <Description>                                                         */
230   /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
231   /*                                                                       */
232   /* <Input>                                                               */
233   /*    range  :: The target range.                                        */
234   /*                                                                       */
235   /*    stream :: The input stream.                                        */
236   /*                                                                       */
237   /* <Return>                                                              */
238   /*    FreeType error code.  0 means success.                             */
239   /*                                                                       */
240   static FT_Error
241   Load_SBit_Const_Metrics( TT_SBit_Range  range,
242                            FT_Stream      stream )
243   {
244     FT_Error  error;
245
246
247     if ( FT_READ_ULONG( range->image_size ) )
248       return error;
249
250     return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
251   }
252
253
254   /*************************************************************************/
255   /*                                                                       */
256   /* <Function>                                                            */
257   /*    Load_SBit_Range_Codes                                              */
258   /*                                                                       */
259   /* <Description>                                                         */
260   /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
261   /*                                                                       */
262   /* <Input>                                                               */
263   /*    range        :: The target range.                                  */
264   /*                                                                       */
265   /*    stream       :: The input stream.                                  */
266   /*                                                                       */
267   /*    load_offsets :: A flag whether to load the glyph offset table.     */
268   /*                                                                       */
269   /* <Return>                                                              */
270   /*    FreeType error code.  0 means success.                             */
271   /*                                                                       */
272   static FT_Error
273   Load_SBit_Range_Codes( TT_SBit_Range  range,
274                          FT_Stream      stream,
275                          FT_Bool        load_offsets )
276   {
277     FT_Error   error;
278     FT_ULong   count, n, size;
279     FT_Memory  memory = stream->memory;
280
281
282     if ( FT_READ_ULONG( count ) )
283       goto Exit;
284
285     range->num_glyphs = count;
286
287     /* Allocate glyph offsets table if needed */
288     if ( load_offsets )
289     {
290       if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
291         goto Exit;
292
293       size = count * 4L;
294     }
295     else
296       size = count * 2L;
297
298     /* Allocate glyph codes table and access frame */
299     if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
300          FT_FRAME_ENTER( size )                     )
301       goto Exit;
302
303     for ( n = 0; n < count; n++ )
304     {
305       range->glyph_codes[n] = FT_GET_USHORT();
306
307       if ( load_offsets )
308         range->glyph_offsets[n] = (FT_ULong)range->image_offset +
309                                   FT_GET_USHORT();
310     }
311
312     FT_FRAME_EXIT();
313
314   Exit:
315     return error;
316   }
317
318
319   /*************************************************************************/
320   /*                                                                       */
321   /* <Function>                                                            */
322   /*    Load_SBit_Range                                                    */
323   /*                                                                       */
324   /* <Description>                                                         */
325   /*    Loads a given `EBLC' index/range table.                            */
326   /*                                                                       */
327   /* <Input>                                                               */
328   /*    range  :: The target range.                                        */
329   /*                                                                       */
330   /*    stream :: The input stream.                                        */
331   /*                                                                       */
332   /* <Return>                                                              */
333   /*    FreeType error code.  0 means success.                             */
334   /*                                                                       */
335   static FT_Error
336   Load_SBit_Range( TT_SBit_Range  range,
337                    FT_Stream      stream )
338   {
339     FT_Error   error;
340     FT_Memory  memory = stream->memory;
341
342
343     switch( range->index_format )
344     {
345     case 1:   /* variable metrics with 4-byte offsets */
346     case 3:   /* variable metrics with 2-byte offsets */
347       {
348         FT_ULong  num_glyphs, n;
349         FT_Int    size_elem;
350         FT_Bool   large = FT_BOOL( range->index_format == 1 );
351
352
353
354         if ( range->last_glyph < range->first_glyph )
355         {
356           error = SFNT_Err_Invalid_File_Format;
357           goto Exit;
358         }
359
360         num_glyphs        = range->last_glyph - range->first_glyph + 1L;
361         range->num_glyphs = num_glyphs;
362         num_glyphs++;                       /* XXX: BEWARE - see spec */
363
364         size_elem = large ? 4 : 2;
365
366         if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
367              FT_FRAME_ENTER( num_glyphs * size_elem )         )
368           goto Exit;
369
370         for ( n = 0; n < num_glyphs; n++ )
371           range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
372                                                 ( large ? FT_GET_ULONG()
373                                                         : FT_GET_USHORT() ) );
374         FT_FRAME_EXIT();
375       }
376       break;
377
378     case 2:   /* all glyphs have identical metrics */
379       error = Load_SBit_Const_Metrics( range, stream );
380       break;
381
382     case 4:
383       error = Load_SBit_Range_Codes( range, stream, 1 );
384       break;
385
386     case 5:
387       error = Load_SBit_Const_Metrics( range, stream );
388       if ( !error )
389         error = Load_SBit_Range_Codes( range, stream, 0 );
390       break;
391
392     default:
393       error = SFNT_Err_Invalid_File_Format;
394     }
395
396   Exit:
397     return error;
398   }
399
400
401   /*************************************************************************/
402   /*                                                                       */
403   /* <Function>                                                            */
404   /*    tt_face_load_eblc                                                  */
405   /*                                                                       */
406   /* <Description>                                                         */
407   /*    Loads the table of embedded bitmap sizes for this face.            */
408   /*                                                                       */
409   /* <Input>                                                               */
410   /*    face   :: The target face object.                                  */
411   /*                                                                       */
412   /*    stream :: The input stream.                                        */
413   /*                                                                       */
414   /* <Return>                                                              */
415   /*    FreeType error code.  0 means success.                             */
416   /*                                                                       */
417   FT_LOCAL_DEF( FT_Error )
418   tt_face_load_eblc( TT_Face    face,
419                      FT_Stream  stream )
420   {
421     FT_Error   error  = SFNT_Err_Ok;
422     FT_Memory  memory = stream->memory;
423     FT_Fixed   version;
424     FT_ULong   num_strikes;
425     FT_ULong   table_base;
426
427     static const FT_Frame_Field  sbit_line_metrics_fields[] =
428     {
429 #undef  FT_STRUCTURE
430 #define FT_STRUCTURE  TT_SBit_LineMetricsRec
431
432       /* no FT_FRAME_START */
433         FT_FRAME_CHAR( ascender ),
434         FT_FRAME_CHAR( descender ),
435         FT_FRAME_BYTE( max_width ),
436
437         FT_FRAME_CHAR( caret_slope_numerator ),
438         FT_FRAME_CHAR( caret_slope_denominator ),
439         FT_FRAME_CHAR( caret_offset ),
440
441         FT_FRAME_CHAR( min_origin_SB ),
442         FT_FRAME_CHAR( min_advance_SB ),
443         FT_FRAME_CHAR( max_before_BL ),
444         FT_FRAME_CHAR( min_after_BL ),
445         FT_FRAME_CHAR( pads[0] ),
446         FT_FRAME_CHAR( pads[1] ),
447       FT_FRAME_END
448     };
449
450     static const FT_Frame_Field  strike_start_fields[] =
451     {
452 #undef  FT_STRUCTURE
453 #define FT_STRUCTURE  TT_SBit_StrikeRec
454
455       /* no FT_FRAME_START */
456         FT_FRAME_ULONG( ranges_offset ),
457         FT_FRAME_SKIP_LONG,
458         FT_FRAME_ULONG( num_ranges ),
459         FT_FRAME_ULONG( color_ref ),
460       FT_FRAME_END
461     };
462
463     static const FT_Frame_Field  strike_end_fields[] =
464     {
465       /* no FT_FRAME_START */
466         FT_FRAME_USHORT( start_glyph ),
467         FT_FRAME_USHORT( end_glyph ),
468         FT_FRAME_BYTE  ( x_ppem ),
469         FT_FRAME_BYTE  ( y_ppem ),
470         FT_FRAME_BYTE  ( bit_depth ),
471         FT_FRAME_CHAR  ( flags ),
472       FT_FRAME_END
473     };
474
475
476     face->num_sbit_strikes = 0;
477
478     /* this table is optional */
479     error = face->goto_table( face, TTAG_EBLC, stream, 0 );
480     if ( error )
481       error = face->goto_table( face, TTAG_bloc, stream, 0 );
482     if ( error )
483       goto Exit;
484
485     table_base = FT_STREAM_POS();
486     if ( FT_FRAME_ENTER( 8L ) )
487       goto Exit;
488
489     version     = FT_GET_LONG();
490     num_strikes = FT_GET_ULONG();
491
492     FT_FRAME_EXIT();
493
494     /* check version number and strike count */
495     if ( version     != 0x00020000L ||
496          num_strikes >= 0x10000L    )
497     {
498       FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
499       error = SFNT_Err_Invalid_File_Format;
500
501       goto Exit;
502     }
503
504     /* allocate the strikes table */
505     if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
506       goto Exit;
507
508     face->num_sbit_strikes = num_strikes;
509
510     /* now read each strike table separately */
511     {
512       TT_SBit_Strike  strike = face->sbit_strikes;
513       FT_ULong        count  = num_strikes;
514
515
516       if ( FT_FRAME_ENTER( 48L * num_strikes ) )
517         goto Exit;
518
519       while ( count > 0 )
520       {
521         if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike )             ||
522              FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
523              FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
524              FT_STREAM_READ_FIELDS( strike_end_fields, strike )               )
525           break;
526
527         count--;
528         strike++;
529       }
530
531       FT_FRAME_EXIT();
532     }
533
534     /* allocate the index ranges for each strike table */
535     {
536       TT_SBit_Strike  strike = face->sbit_strikes;
537       FT_ULong        count  = num_strikes;
538
539
540       while ( count > 0 )
541       {
542         TT_SBit_Range  range;
543         FT_ULong       count2 = strike->num_ranges;
544
545
546         /* read each range */
547         if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
548              FT_FRAME_ENTER( strike->num_ranges * 8L )            )
549           goto Exit;
550
551         if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
552           goto Exit;
553
554         range = strike->sbit_ranges;
555         while ( count2 > 0 )
556         {
557           range->first_glyph  = FT_GET_USHORT();
558           range->last_glyph   = FT_GET_USHORT();
559           range->table_offset = table_base + strike->ranges_offset +
560                                   FT_GET_ULONG();
561           count2--;
562           range++;
563         }
564
565         FT_FRAME_EXIT();
566
567         /* Now, read each index table */
568         count2 = strike->num_ranges;
569         range  = strike->sbit_ranges;
570         while ( count2 > 0 )
571         {
572           /* Read the header */
573           if ( FT_STREAM_SEEK( range->table_offset ) ||
574                FT_FRAME_ENTER( 8L )                  )
575             goto Exit;
576
577           range->index_format = FT_GET_USHORT();
578           range->image_format = FT_GET_USHORT();
579           range->image_offset = FT_GET_ULONG();
580
581           FT_FRAME_EXIT();
582
583           error = Load_SBit_Range( range, stream );
584           if ( error )
585             goto Exit;
586
587           count2--;
588           range++;
589         }
590
591         count--;
592         strike++;
593       }
594     }
595
596   Exit:
597     return error;
598   }
599
600
601   /*************************************************************************/
602   /*                                                                       */
603   /* <Function>                                                            */
604   /*    tt_face_free_eblc                                                  */
605   /*                                                                       */
606   /* <Description>                                                         */
607   /*    Releases the embedded bitmap tables.                               */
608   /*                                                                       */
609   /* <Input>                                                               */
610   /*    face :: The target face object.                                    */
611   /*                                                                       */
612   FT_LOCAL_DEF( void )
613   tt_face_free_eblc( TT_Face  face )
614   {
615     FT_Memory       memory       = face->root.memory;
616     TT_SBit_Strike  strike       = face->sbit_strikes;
617     TT_SBit_Strike  strike_limit = strike + face->num_sbit_strikes;
618
619
620     if ( strike )
621     {
622       for ( ; strike < strike_limit; strike++ )
623       {
624         TT_SBit_Range  range       = strike->sbit_ranges;
625         TT_SBit_Range  range_limit = range + strike->num_ranges;
626
627
628         if ( range )
629         {
630           for ( ; range < range_limit; range++ )
631           {
632             /* release the glyph offsets and codes tables */
633             /* where appropriate                          */
634             FT_FREE( range->glyph_offsets );
635             FT_FREE( range->glyph_codes );
636           }
637         }
638         FT_FREE( strike->sbit_ranges );
639         strike->num_ranges = 0;
640       }
641       FT_FREE( face->sbit_strikes );
642     }
643     face->num_sbit_strikes = 0;
644   }
645
646
647   FT_LOCAL_DEF( FT_Error )
648   tt_face_set_sbit_strike( TT_Face          face,
649                            FT_Size_Request  req,
650                            FT_ULong*        astrike_index )
651   {
652     return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
653   }
654
655
656   FT_LOCAL_DEF( FT_Error )
657   tt_face_load_strike_metrics( TT_Face           face,
658                                FT_ULong          strike_index,
659                                FT_Size_Metrics*  metrics )
660   {
661     TT_SBit_Strike  strike;
662
663
664     if ( strike_index >= face->num_sbit_strikes )
665       return SFNT_Err_Invalid_Argument;
666
667     strike = face->sbit_strikes + strike_index;
668
669     metrics->x_ppem = strike->x_ppem;
670     metrics->y_ppem = strike->y_ppem;
671
672     metrics->ascender  = strike->hori.ascender << 6;
673     metrics->descender = strike->hori.descender << 6;
674
675     /* XXX: Is this correct? */
676     metrics->max_advance = ( strike->hori.min_origin_SB  +
677                              strike->hori.max_width      +
678                              strike->hori.min_advance_SB ) << 6;
679
680     metrics->height = metrics->ascender - metrics->descender;
681
682     return SFNT_Err_Ok;
683   }
684
685
686   /*************************************************************************/
687   /*                                                                       */
688   /* <Function>                                                            */
689   /*    find_sbit_range                                                    */
690   /*                                                                       */
691   /* <Description>                                                         */
692   /*    Scans a given strike's ranges and return, for a given glyph        */
693   /*    index, the corresponding sbit range, and `EBDT' offset.            */
694   /*                                                                       */
695   /* <Input>                                                               */
696   /*    glyph_index   :: The glyph index.                                  */
697   /*                                                                       */
698   /*    strike        :: The source/current sbit strike.                   */
699   /*                                                                       */
700   /* <Output>                                                              */
701   /*    arange        :: The sbit range containing the glyph index.        */
702   /*                                                                       */
703   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
704   /*                                                                       */
705   /* <Return>                                                              */
706   /*    FreeType error code.  0 means the glyph index was found.           */
707   /*                                                                       */
708   static FT_Error
709   find_sbit_range( FT_UInt          glyph_index,
710                    TT_SBit_Strike   strike,
711                    TT_SBit_Range   *arange,
712                    FT_ULong        *aglyph_offset )
713   {
714     TT_SBit_RangeRec  *range, *range_limit;
715
716
717     /* check whether the glyph index is within this strike's */
718     /* glyph range                                           */
719     if ( glyph_index < (FT_UInt)strike->start_glyph ||
720          glyph_index > (FT_UInt)strike->end_glyph   )
721       goto Fail;
722
723     /* scan all ranges in strike */
724     range       = strike->sbit_ranges;
725     range_limit = range + strike->num_ranges;
726     if ( !range )
727       goto Fail;
728
729     for ( ; range < range_limit; range++ )
730     {
731       if ( glyph_index >= (FT_UInt)range->first_glyph &&
732            glyph_index <= (FT_UInt)range->last_glyph  )
733       {
734         FT_UShort  delta = (FT_UShort)( glyph_index - range->first_glyph );
735
736
737         switch ( range->index_format )
738         {
739         case 1:
740         case 3:
741           *aglyph_offset = range->glyph_offsets[delta];
742           break;
743
744         case 2:
745           *aglyph_offset = range->image_offset +
746                            range->image_size * delta;
747           break;
748
749         case 4:
750         case 5:
751           {
752             FT_ULong  n;
753
754
755             for ( n = 0; n < range->num_glyphs; n++ )
756             {
757               if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
758               {
759                 if ( range->index_format == 4 )
760                   *aglyph_offset = range->glyph_offsets[n];
761                 else
762                   *aglyph_offset = range->image_offset +
763                                    n * range->image_size;
764                 goto Found;
765               }
766             }
767           }
768
769         /* fall-through */
770         default:
771           goto Fail;
772         }
773
774       Found:
775         /* return successfully! */
776         *arange  = range;
777         return SFNT_Err_Ok;
778       }
779     }
780
781   Fail:
782     *arange        = 0;
783     *aglyph_offset = 0;
784
785     return SFNT_Err_Invalid_Argument;
786   }
787
788
789   /*************************************************************************/
790   /*                                                                       */
791   /* <Function>                                                            */
792   /*    tt_find_sbit_image                                                 */
793   /*                                                                       */
794   /* <Description>                                                         */
795   /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
796   /*    glyph, at a given strike.                                          */
797   /*                                                                       */
798   /* <Input>                                                               */
799   /*    face          :: The target face object.                           */
800   /*                                                                       */
801   /*    glyph_index   :: The glyph index.                                  */
802   /*                                                                       */
803   /*    strike_index  :: The current strike index.                         */
804   /*                                                                       */
805   /* <Output>                                                              */
806   /*    arange        :: The SBit range containing the glyph index.        */
807   /*                                                                       */
808   /*    astrike       :: The SBit strike containing the glyph index.       */
809   /*                                                                       */
810   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
811   /*                                                                       */
812   /* <Return>                                                              */
813   /*    FreeType error code.  0 means success.  Returns                    */
814   /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */
815   /*    glyph.                                                             */
816   /*                                                                       */
817   FT_LOCAL( FT_Error )
818   tt_find_sbit_image( TT_Face          face,
819                       FT_UInt          glyph_index,
820                       FT_ULong         strike_index,
821                       TT_SBit_Range   *arange,
822                       TT_SBit_Strike  *astrike,
823                       FT_ULong        *aglyph_offset )
824   {
825     FT_Error        error;
826     TT_SBit_Strike  strike;
827
828
829     if ( !face->sbit_strikes                        ||
830          ( face->num_sbit_strikes <= strike_index ) )
831       goto Fail;
832
833     strike = &face->sbit_strikes[strike_index];
834
835     error = find_sbit_range( glyph_index, strike,
836                              arange, aglyph_offset );
837     if ( error )
838       goto Fail;
839
840     *astrike = strike;
841
842     return SFNT_Err_Ok;
843
844   Fail:
845     /* no embedded bitmap for this glyph in face */
846     *arange        = 0;
847     *astrike       = 0;
848     *aglyph_offset = 0;
849
850     return SFNT_Err_Invalid_Argument;
851   }
852
853
854   /*************************************************************************/
855   /*                                                                       */
856   /* <Function>                                                            */
857   /*    tt_load_sbit_metrics                                               */
858   /*                                                                       */
859   /* <Description>                                                         */
860   /*    Gets the big metrics for a given SBit.                             */
861   /*                                                                       */
862   /* <Input>                                                               */
863   /*    stream      :: The input stream.                                   */
864   /*                                                                       */
865   /*    range       :: The SBit range containing the glyph.                */
866   /*                                                                       */
867   /* <Output>                                                              */
868   /*    big_metrics :: A big SBit metrics structure for the glyph.         */
869   /*                                                                       */
870   /* <Return>                                                              */
871   /*    FreeType error code.  0 means success.                             */
872   /*                                                                       */
873   /* <Note>                                                                */
874   /*    The stream cursor must be positioned at the glyph's offset within  */
875   /*    the `EBDT' table before the call.                                  */
876   /*                                                                       */
877   /*    If the image format uses variable metrics, the stream cursor is    */
878   /*    positioned just after the metrics header in the `EBDT' table on    */
879   /*    function exit.                                                     */
880   /*                                                                       */
881   FT_LOCAL( FT_Error )
882   tt_load_sbit_metrics( FT_Stream        stream,
883                         TT_SBit_Range    range,
884                         TT_SBit_Metrics  metrics )
885   {
886     FT_Error  error = SFNT_Err_Ok;
887
888
889     switch ( range->image_format )
890     {
891     case 1:
892     case 2:
893     case 8:
894       /* variable small metrics */
895       {
896         TT_SBit_SmallMetricsRec  smetrics;
897
898         static const FT_Frame_Field  sbit_small_metrics_fields[] =
899         {
900 #undef  FT_STRUCTURE
901 #define FT_STRUCTURE  TT_SBit_SmallMetricsRec
902
903           FT_FRAME_START( 5 ),
904             FT_FRAME_BYTE( height ),
905             FT_FRAME_BYTE( width ),
906             FT_FRAME_CHAR( bearingX ),
907             FT_FRAME_CHAR( bearingY ),
908             FT_FRAME_BYTE( advance ),
909           FT_FRAME_END
910         };
911
912
913         /* read small metrics */
914         if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
915           goto Exit;
916
917         /* convert it to a big metrics */
918         metrics->height       = smetrics.height;
919         metrics->width        = smetrics.width;
920         metrics->horiBearingX = smetrics.bearingX;
921         metrics->horiBearingY = smetrics.bearingY;
922         metrics->horiAdvance  = smetrics.advance;
923
924         /* these metrics are made up at a higher level when */
925         /* needed.                                          */
926         metrics->vertBearingX = 0;
927         metrics->vertBearingY = 0;
928         metrics->vertAdvance  = 0;
929       }
930       break;
931
932     case 6:
933     case 7:
934     case 9:
935       /* variable big metrics */
936       if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
937         goto Exit;
938       break;
939
940     case 5:
941     default:  /* constant metrics */
942       if ( range->index_format == 2 || range->index_format == 5 )
943         *metrics = range->metrics;
944       else
945         return SFNT_Err_Invalid_File_Format;
946    }
947
948   Exit:
949     return error;
950   }
951
952
953   /*************************************************************************/
954   /*                                                                       */
955   /* <Function>                                                            */
956   /*    crop_bitmap                                                        */
957   /*                                                                       */
958   /* <Description>                                                         */
959   /*    Crops a bitmap to its tightest bounding box, and adjusts its       */
960   /*    metrics.                                                           */
961   /*                                                                       */
962   /* <InOut>                                                               */
963   /*    map     :: The bitmap.                                             */
964   /*                                                                       */
965   /*    metrics :: The corresponding metrics structure.                    */
966   /*                                                                       */
967   static void
968   crop_bitmap( FT_Bitmap*       map,
969                TT_SBit_Metrics  metrics )
970   {
971     /***********************************************************************/
972     /*                                                                     */
973     /* In this situation, some bounding boxes of embedded bitmaps are too  */
974     /* large.  We need to crop it to a reasonable size.                    */
975     /*                                                                     */
976     /*      ---------                                                      */
977     /*      |       |                -----                                 */
978     /*      |  ***  |                |***|                                 */
979     /*      |   *   |                | * |                                 */
980     /*      |   *   |    ------>     | * |                                 */
981     /*      |   *   |                | * |                                 */
982     /*      |   *   |                | * |                                 */
983     /*      |  ***  |                |***|                                 */
984     /*      ---------                -----                                 */
985     /*                                                                     */
986     /***********************************************************************/
987
988     FT_Int    rows, count;
989     FT_Long   line_len;
990     FT_Byte*  line;
991
992
993     /***********************************************************************/
994     /*                                                                     */
995     /* first of all, check the top-most lines of the bitmap, and remove    */
996     /* them if they're empty.                                              */
997     /*                                                                     */
998     {
999       line     = (FT_Byte*)map->buffer;
1000       rows     = map->rows;
1001       line_len = map->pitch;
1002
1003
1004       for ( count = 0; count < rows; count++ )
1005       {
1006         FT_Byte*  cur   = line;
1007         FT_Byte*  limit = line + line_len;
1008
1009
1010         for ( ; cur < limit; cur++ )
1011           if ( cur[0] )
1012             goto Found_Top;
1013
1014         /* the current line was empty - skip to next one */
1015         line  = limit;
1016       }
1017
1018     Found_Top:
1019       /* check that we have at least one filled line */
1020       if ( count >= rows )
1021         goto Empty_Bitmap;
1022
1023       /* now, crop the empty upper lines */
1024       if ( count > 0 )
1025       {
1026         line = (FT_Byte*)map->buffer;
1027
1028         FT_MEM_MOVE( line, line + count * line_len,
1029                      ( rows - count ) * line_len );
1030
1031         metrics->height       = (FT_Byte)( metrics->height - count );
1032         metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
1033         metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
1034
1035         map->rows -= count;
1036         rows      -= count;
1037       }
1038     }
1039
1040     /***********************************************************************/
1041     /*                                                                     */
1042     /* second, crop the lower lines                                        */
1043     /*                                                                     */
1044     {
1045       line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
1046
1047       for ( count = 0; count < rows; count++ )
1048       {
1049         FT_Byte*  cur   = line;
1050         FT_Byte*  limit = line + line_len;
1051
1052
1053         for ( ; cur < limit; cur++ )
1054           if ( cur[0] )
1055             goto Found_Bottom;
1056
1057         /* the current line was empty - skip to previous one */
1058         line -= line_len;
1059       }
1060
1061     Found_Bottom:
1062       if ( count > 0 )
1063       {
1064         metrics->height  = (FT_Byte)( metrics->height - count );
1065         rows            -= count;
1066         map->rows       -= count;
1067       }
1068     }
1069
1070     /***********************************************************************/
1071     /*                                                                     */
1072     /* third, get rid of the space on the left side of the glyph           */
1073     /*                                                                     */
1074     do
1075     {
1076       FT_Byte*  limit;
1077
1078
1079       line  = (FT_Byte*)map->buffer;
1080       limit = line + rows * line_len;
1081
1082       for ( ; line < limit; line += line_len )
1083         if ( line[0] & 0x80 )
1084           goto Found_Left;
1085
1086       /* shift the whole glyph one pixel to the left */
1087       line  = (FT_Byte*)map->buffer;
1088       limit = line + rows * line_len;
1089
1090       for ( ; line < limit; line += line_len )
1091       {
1092         FT_Int    n, width = map->width;
1093         FT_Byte   old;
1094         FT_Byte*  cur = line;
1095
1096
1097         old = (FT_Byte)(cur[0] << 1);
1098         for ( n = 8; n < width; n += 8 )
1099         {
1100           FT_Byte  val;
1101
1102
1103           val    = cur[1];
1104           cur[0] = (FT_Byte)( old | ( val >> 7 ) );
1105           old    = (FT_Byte)( val << 1 );
1106           cur++;
1107         }
1108         cur[0] = old;
1109       }
1110
1111       map->width--;
1112       metrics->horiBearingX++;
1113       metrics->vertBearingX++;
1114       metrics->width--;
1115
1116     } while ( map->width > 0 );
1117
1118   Found_Left:
1119
1120     /***********************************************************************/
1121     /*                                                                     */
1122     /* finally, crop the bitmap width to get rid of the space on the right */
1123     /* side of the glyph.                                                  */
1124     /*                                                                     */
1125     do
1126     {
1127       FT_Int    right = map->width - 1;
1128       FT_Byte*  limit;
1129       FT_Byte   mask;
1130
1131
1132       line  = (FT_Byte*)map->buffer + ( right >> 3 );
1133       limit = line + rows * line_len;
1134       mask  = (FT_Byte)( 0x80 >> ( right & 7 ) );
1135
1136       for ( ; line < limit; line += line_len )
1137         if ( line[0] & mask )
1138           goto Found_Right;
1139
1140       /* crop the whole glyph to the right */
1141       map->width--;
1142       metrics->width--;
1143
1144     } while ( map->width > 0 );
1145
1146   Found_Right:
1147     /* all right, the bitmap was cropped */
1148     return;
1149
1150   Empty_Bitmap:
1151     map->width      = 0;
1152     map->rows       = 0;
1153     map->pitch      = 0;
1154     map->pixel_mode = FT_PIXEL_MODE_MONO;
1155   }
1156
1157
1158   static FT_Error
1159   Load_SBit_Single( FT_Bitmap*       map,
1160                     FT_Int           x_offset,
1161                     FT_Int           y_offset,
1162                     FT_Int           pix_bits,
1163                     FT_UShort        image_format,
1164                     TT_SBit_Metrics  metrics,
1165                     FT_Stream        stream )
1166   {
1167     FT_Error  error;
1168
1169
1170     /* check that the source bitmap fits into the target pixmap */
1171     if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
1172          y_offset < 0 || y_offset + metrics->height > map->rows  )
1173     {
1174       error = SFNT_Err_Invalid_Argument;
1175
1176       goto Exit;
1177     }
1178
1179     {
1180       FT_Int   glyph_width  = metrics->width;
1181       FT_Int   glyph_height = metrics->height;
1182       FT_Int   glyph_size;
1183       FT_Int   line_bits    = pix_bits * glyph_width;
1184       FT_Bool  pad_bytes    = 0;
1185
1186
1187       /* compute size of glyph image */
1188       switch ( image_format )
1189       {
1190       case 1:  /* byte-padded formats */
1191       case 6:
1192         {
1193           FT_Int  line_length;
1194
1195
1196           switch ( pix_bits )
1197           {
1198           case 1:
1199             line_length = ( glyph_width + 7 ) >> 3;
1200             break;
1201           case 2:
1202             line_length = ( glyph_width + 3 ) >> 2;
1203             break;
1204           case 4:
1205             line_length = ( glyph_width + 1 ) >> 1;
1206             break;
1207           default:
1208             line_length =   glyph_width;
1209           }
1210
1211           glyph_size = glyph_height * line_length;
1212           pad_bytes  = 1;
1213         }
1214         break;
1215
1216       case 2:
1217       case 5:
1218       case 7:
1219         line_bits  =   glyph_width  * pix_bits;
1220         glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
1221         break;
1222
1223       default:  /* invalid format */
1224         return SFNT_Err_Invalid_File_Format;
1225       }
1226
1227       /* Now read data and draw glyph into target pixmap       */
1228       if ( FT_FRAME_ENTER( glyph_size ) )
1229         goto Exit;
1230
1231       /* don't forget to multiply `x_offset' by `map->pix_bits' as */
1232       /* the sbit blitter doesn't make a difference between pixmap */
1233       /* depths.                                                   */
1234       blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
1235                  x_offset * pix_bits, y_offset, metrics->height );
1236
1237       FT_FRAME_EXIT();
1238     }
1239
1240   Exit:
1241     return error;
1242   }
1243
1244
1245   static FT_Error
1246   Load_SBit_Image( TT_SBit_Strike   strike,
1247                    TT_SBit_Range    range,
1248                    FT_ULong         ebdt_pos,
1249                    FT_ULong         glyph_offset,
1250                    FT_GlyphSlot     slot,
1251                    FT_Int           x_offset,
1252                    FT_Int           y_offset,
1253                    FT_Stream        stream,
1254                    TT_SBit_Metrics  metrics,
1255                    FT_Int           depth )
1256   {
1257     FT_Memory   memory = stream->memory;
1258     FT_Bitmap*  map    = &slot->bitmap;
1259     FT_Error    error;
1260
1261
1262     /* place stream at beginning of glyph data and read metrics */
1263     if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
1264       goto Exit;
1265
1266     error = tt_load_sbit_metrics( stream, range, metrics );
1267     if ( error )
1268       goto Exit;
1269
1270     /* This function is recursive.  At the top-level call, we  */
1271     /* compute the dimensions of the higher-level glyph to     */
1272     /* allocate the final pixmap buffer.                       */
1273     if ( depth == 0 )
1274     {
1275       FT_Long  size;
1276
1277
1278       map->width = metrics->width;
1279       map->rows  = metrics->height;
1280
1281       switch ( strike->bit_depth )
1282       {
1283       case 1:
1284         map->pixel_mode = FT_PIXEL_MODE_MONO;
1285         map->pitch      = ( map->width + 7 ) >> 3;
1286         break;
1287
1288       case 2:
1289         map->pixel_mode = FT_PIXEL_MODE_GRAY2;
1290         map->pitch      = ( map->width + 3 ) >> 2;
1291         break;
1292
1293       case 4:
1294         map->pixel_mode = FT_PIXEL_MODE_GRAY4;
1295         map->pitch      = ( map->width + 1 ) >> 1;
1296         break;
1297
1298       case 8:
1299         map->pixel_mode = FT_PIXEL_MODE_GRAY;
1300         map->pitch      = map->width;
1301         break;
1302
1303       default:
1304         return SFNT_Err_Invalid_File_Format;
1305       }
1306
1307       size = map->rows * map->pitch;
1308
1309       /* check that there is no empty image */
1310       if ( size == 0 )
1311         goto Exit;     /* exit successfully! */
1312
1313       error = ft_glyphslot_alloc_bitmap( slot, size );
1314       if (error)
1315         goto Exit;
1316     }
1317
1318     switch ( range->image_format )
1319     {
1320     case 1:  /* single sbit image - load it */
1321     case 2:
1322     case 5:
1323     case 6:
1324     case 7:
1325       return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
1326                                range->image_format, metrics, stream );
1327
1328     case 8:  /* compound format */
1329       if ( FT_STREAM_SKIP( 1L ) )
1330       {
1331         error = SFNT_Err_Invalid_Stream_Skip;
1332         goto Exit;
1333       }
1334       /* fallthrough */
1335
1336     case 9:
1337       break;
1338
1339     default: /* invalid image format */
1340       return SFNT_Err_Invalid_File_Format;
1341     }
1342
1343     /* All right, we have a compound format.  First of all, read */
1344     /* the array of elements.                                    */
1345     {
1346       TT_SBit_Component  components = NULL;
1347       TT_SBit_Component  comp;
1348       FT_UShort          num_components, count;
1349
1350
1351       if ( FT_READ_USHORT( num_components )           ||
1352            FT_NEW_ARRAY( components, num_components ) )
1353         goto Exit;
1354
1355       count = num_components;
1356
1357       if ( FT_FRAME_ENTER( 4L * num_components ) )
1358         goto Fail_Memory;
1359
1360       for ( comp = components; count > 0; count--, comp++ )
1361       {
1362         comp->glyph_code = FT_GET_USHORT();
1363         comp->x_offset   = FT_GET_CHAR();
1364         comp->y_offset   = FT_GET_CHAR();
1365       }
1366
1367       FT_FRAME_EXIT();
1368
1369       /* Now recursively load each element glyph */
1370       count = num_components;
1371       comp  = components;
1372       for ( ; count > 0; count--, comp++ )
1373       {
1374         TT_SBit_Range       elem_range;
1375         TT_SBit_MetricsRec  elem_metrics;
1376         FT_ULong            elem_offset;
1377
1378
1379         /* find the range for this element */
1380         error = find_sbit_range( comp->glyph_code,
1381                                  strike,
1382                                  &elem_range,
1383                                  &elem_offset );
1384         if ( error )
1385           goto Fail_Memory;
1386
1387         /* now load the element, recursively */
1388         error = Load_SBit_Image( strike,
1389                                  elem_range,
1390                                  ebdt_pos,
1391                                  elem_offset,
1392                                  slot,
1393                                  x_offset + comp->x_offset,
1394                                  y_offset + comp->y_offset,
1395                                  stream,
1396                                  &elem_metrics,
1397                                  depth + 1 );
1398         if ( error )
1399           goto Fail_Memory;
1400       }
1401
1402     Fail_Memory:
1403       FT_FREE( components );
1404     }
1405
1406   Exit:
1407     return error;
1408   }
1409
1410
1411   /*************************************************************************/
1412   /*                                                                       */
1413   /* <Function>                                                            */
1414   /*    tt_face_load_sbit_image                                            */
1415   /*                                                                       */
1416   /* <Description>                                                         */
1417   /*    Loads a given glyph sbit image from the font resource.  This also  */
1418   /*    returns its metrics.                                               */
1419   /*                                                                       */
1420   /* <Input>                                                               */
1421   /*    face         :: The target face object.                            */
1422   /*                                                                       */
1423   /*    strike_index :: The current strike index.                          */
1424   /*                                                                       */
1425   /*    glyph_index  :: The current glyph index.                           */
1426   /*                                                                       */
1427   /*    load_flags   :: The glyph load flags (the code checks for the flag */
1428   /*                    FT_LOAD_CROP_BITMAP).                              */
1429   /*                                                                       */
1430   /*    stream       :: The input stream.                                  */
1431   /*                                                                       */
1432   /* <Output>                                                              */
1433   /*    map          :: The target pixmap.                                 */
1434   /*                                                                       */
1435   /*    metrics      :: A big sbit metrics structure for the glyph image.  */
1436   /*                                                                       */
1437   /* <Return>                                                              */
1438   /*    FreeType error code.  0 means success.  Returns an error if no     */
1439   /*    glyph sbit exists for the index.                                   */
1440   /*                                                                       */
1441   /*  <Note>                                                               */
1442   /*    The `map.buffer' field is always freed before the glyph is loaded. */
1443   /*                                                                       */
1444   FT_LOCAL_DEF( FT_Error )
1445   tt_face_load_sbit_image( TT_Face              face,
1446                            FT_ULong             strike_index,
1447                            FT_UInt              glyph_index,
1448                            FT_UInt              load_flags,
1449                            FT_Stream            stream,
1450                            FT_Bitmap           *map,
1451                            TT_SBit_MetricsRec  *metrics )
1452   {
1453     FT_Error        error;
1454     FT_ULong        ebdt_pos, glyph_offset;
1455
1456     TT_SBit_Strike  strike;
1457     TT_SBit_Range   range;
1458
1459
1460     /* Check whether there is a glyph sbit for the current index */
1461     error = tt_find_sbit_image( face, glyph_index, strike_index,
1462                                 &range, &strike, &glyph_offset );
1463     if ( error )
1464       goto Exit;
1465
1466     /* now, find the location of the `EBDT' table in */
1467     /* the font file                                 */
1468     error = face->goto_table( face, TTAG_EBDT, stream, 0 );
1469     if ( error )
1470       error = face->goto_table( face, TTAG_bdat, stream, 0 );
1471     if ( error )
1472       goto Exit;
1473
1474     ebdt_pos = FT_STREAM_POS();
1475
1476     error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
1477                              face->root.glyph, 0, 0, stream, metrics, 0 );
1478     if ( error )
1479       goto Exit;
1480
1481     /* setup vertical metrics if needed */
1482     if ( strike->flags & 1 )
1483     {
1484       /* in case of a horizontal strike only */
1485       FT_Int  advance;
1486
1487
1488       advance = strike->hori.ascender - strike->hori.descender;
1489
1490       /* some heuristic values */
1491
1492       metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
1493       metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
1494       metrics->vertAdvance  = (FT_Char)( advance * 12 / 10 );
1495     }
1496
1497     /* Crop the bitmap now, unless specified otherwise */
1498     if ( load_flags & FT_LOAD_CROP_BITMAP )
1499       crop_bitmap( map, metrics );
1500
1501   Exit:
1502     return error;
1503   }
1504
1505 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
1506
1507
1508 /* END */