ttsbit.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:52k
源码类别:

其他游戏

开发平台:

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