⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftxsbit.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * *  ftxsbit.c * *    Embedded bitmap API extension * *  Copyright 1996-1999 by *  David Turner, Robert Wilhelm, and Werner Lemberg. * *  This file is part of the FreeType project, and may only be used *  modified and distributed under the terms of the FreeType project *  license, LICENSE.TXT.  By continuing to use, modify, or distribute *  this file you indicate that you have read the license and *  understand and accept it fully. * * *  This extension is used to load the embedded bitmaps present *  in certain TrueType files. * ******************************************************************/#include "ftxsbit.h"#include "ttobjs.h"#include "ttfile.h"#include "ttload.h"#include "ttmemory.h"#include "tttags.h"#include "ttextend.h"#include "ttdebug.h"#define SBIT_ID  Build_Extension_ID( 's', 'b', 'i', 't' )/* Required by the tracing mode */#undef  TT_COMPONENT#define TT_COMPONENT  trace_bitmap/* In all functions, the stream is taken from the 'face' object */#define DEFINE_LOCALS           DEFINE_LOAD_LOCALS( face->stream )#define DEFINE_LOCALS_WO_FRAME  DEFINE_LOAD_LOCALS_WO_FRAME( face->stream )/*************************** * * miscellaneous functions * ***************************//******************************************************************* * *  Function:  Load_BitmapData * *  Bit-aligned bitmap data -> Byte-aligned bitmap data when pad is 0 * ******************************************************************/  static  TT_Error  Load_BitmapData( TT_SBit_Image*  image,                             Int             image_size,                             Byte            x_offset,                             Byte            y_offset,                             UShort          source_width,                             UShort          source_height,                             Bool            byte_padded )  {    DEFINE_LOCALS;    Int     count;   /* number of bits left in rows              */    Int     loaded;  /* number of bits loaded in the accumulator */    UShort  buff;    /* accumulator                              */    PByte   line;     /* target write cursor */    PByte   limit;    if ( ( y_offset + source_height > image->map.rows ) ||         ( x_offset + source_width > image->map.width ) )      return TT_Err_Invalid_Argument;    if ( ACCESS_Frame( image_size ) )      return error;    buff   = 0;    loaded = 0;    line   = (PByte)image->map.bitmap +               y_offset * image->map.cols;    limit  = (PByte)image->map.bitmap +               ( y_offset + source_height ) * image->map.cols;    for ( ; line < limit; line += image->map.cols )    {      PByte  ptr;      ptr   = line + x_offset / 8;      count = source_width;      /* We may assume that `loaded' is less than 8 */      buff  >>= x_offset % 8;      loaded += x_offset % 8;      /* first of all, read all consecutive bytes */      while ( count >= 8 )      {        if ( loaded < 8 )        {          buff   |= ((UShort)GET_Byte()) << (8 - loaded);          loaded += 8;        }        *ptr++ |= (Byte)(buff >> 8);        buff  <<= 8;        loaded -= 8;        count  -= 8;      }      /* now write remaining bits (i.e. end of line with count < 8) */      if ( count > 0 )      {        if ( loaded < count )        {          buff   |= ((UShort)GET_Byte()) << (8 - loaded);          loaded += 8;        }        *ptr   |= ((Byte)(buff >> 8)) & ~(0xFF >> count);        buff  <<= count;        loaded -= count;      }      if ( byte_padded )      {        buff   = 0;        loaded = 0;      }    }    FORGET_Frame();    return TT_Err_Ok;  }/******************************************************************* * *  Function:  Crop_Bitmap * ******************************************************************/  static  void  Crop_Bitmap( TT_SBit_Image*  image )  {    /*******************************************************/    /* In the following situation, some bounding boxes of  */    /* embedded bitmaps are too large.  We need to crop it */    /* to a reasonable size.                               */    /*                                                     */    /*      ---------                                      */    /*      |       |                -----                 */    /*      |  ***  |                |***|                 */    /*      |   *   |    ----->      | * |                 */    /*      |   *   |                | * |                 */    /*      |   *   |                | * |                 */    /*      |   *   |                | * |                 */    /*      |  ***  |                |***|                 */    /*      ---------                -----                 */    /*                                                     */    /*******************************************************/    Int    rows, count;    Long   line_len;    PByte  line;    /********************************************************************/    /*                                                                  */    /* first of all, check the top-most lines of the bitmap and remove  */    /* them if they're empty.                                           */    /*                                                                  */    {      line     = (PByte)image->map.bitmap;      rows     = image->map.rows;      line_len = image->map.cols;      for ( count = 0; count < rows; count++ )      {        PByte  cur   = line;        PByte  limit = line + line_len;        for ( ; cur < limit; cur++ )          if ( cur[0] )            goto Found_Top;        /* the current line was empty -- skip to next one */        line = limit;      }    Found_Top:      /* check that we have at least one filled line */      if ( count >= rows )        goto Empty_Bitmap;      /* now, crop the empty upper lines */      if ( count > 0 )      {        line = (PByte)image->map.bitmap;        MEM_Move( line, line + count*line_len, (rows-count) * line_len );        image->metrics.bbox.yMax    -= count;        image->metrics.vertBearingY -= count;        image->metrics.horiBearingY -= count;        image->map.rows             -= count;        rows                        -= count;      }    }    /*******************************************************************/    /*                                                                 */    /* second, crop the lower lines                                    */    /*                                                                 */    {      line = (PByte)image->map.bitmap + (rows-1) * line_len;      for ( count = 0; count < rows; count++ )      {        PByte  cur   = line;        PByte  limit = line + line_len;        for ( ; cur < limit; cur++ )          if ( cur[0] )            goto Found_Bottom;        /* the current line was empty -- skip to previous one */        line -= line_len;      }    Found_Bottom:      if ( count > 0 )      {        image->metrics.bbox.yMin += count;        image->map.rows          -= count;        rows                     -= count;      }    }    /*******************************************************************/    /*                                                                 */    /* third, get rid of the space on the left side of the glyph       */    /*                                                                 */    do    {      PByte  limit;      line  = (PByte)image->map.bitmap;      limit = line + rows * line_len;      for ( ; line < limit; line += line_len )        if ( line[0] & 0x80 )          goto Found_Left;      /* shift the whole glyph one pixel to the left */      line  = (PByte)image->map.bitmap;      limit = line + rows * line_len;      for ( ; line < limit; line += line_len )      {        Int    n, width = image->map.width;        Byte   old;        PByte  cur = line;        old = cur[0] << 1;        for ( n = 8; n < width; n += 8 )        {          Byte  val;          val    = cur[1];          cur[0] = old | (val >> 7);          old    = val << 1;          cur++;        }        cur[0] = old;      }      image->map.width--;      image->metrics.horiBearingX++;      image->metrics.vertBearingX++;      image->metrics.bbox.xMin++;    } while ( image->map.width > 0 );  Found_Left:    /*********************************************************************/    /*                                                                   */    /* finally, crop the bitmap width to get rid of the space on the     */    /* right side of the glyph.                                          */    /*                                                                   */    do    {      Int    right = image->map.width-1;      PByte  limit;      Byte   mask;      line  = (PByte)image->map.bitmap + (right >> 3);      limit = line + rows*line_len;      mask  = 0x80 >> (right & 7);      for ( ; line < limit; line += line_len )        if ( line[0] & mask )          goto Found_Right;      /* crop the whole glyph on the right */      image->map.width--;      image->metrics.bbox.xMax--;    } while ( image->map.width > 0 );  Found_Right:    /* all right, the bitmap was cropped */    return;  Empty_Bitmap:    image->map.width = 0;    image->map.rows  = 0;    image->map.cols  = 0;    image->map.size  = 0;  }/************* * * Main body * *************/  static  TT_Error  Load_Range_Codes( TT_SBit_Range*  range,                              PFace           face,                              Bool            load_offsets )  {    DEFINE_LOCALS;    ULong  count, n, size;    (void)face;    /* read glyph count */    if ( ACCESS_Frame( 4L ) )      goto Exit;    count = GET_ULong();    FORGET_Frame();    range->num_glyphs = count;    /* Allocate glyph offsets table if needed */    if ( load_offsets )    {      if ( ALLOC_ARRAY( range->glyph_offsets, count, ULong ) )        goto Exit;      size = count * 4L;    }    else      size = count * 2L;    /* Allocate glyph codes table and access frame */    if ( ALLOC_ARRAY ( range->glyph_codes, count, UShort ) ||         ACCESS_Frame( size )                              )      goto Exit;    for ( n = 0; n < count; n++ )    {      range->glyph_codes[n] = GET_UShort();      if ( load_offsets )        range->glyph_offsets[n] = (ULong)range->image_offset + GET_UShort();    }    FORGET_Frame();  Exit:    return error;  }  static  TT_Error  Load_SBit_Range( TT_SBit_Strike*  strike,                             TT_SBit_Range*   range,                             PFace            face )  {    DEFINE_LOCALS;    UShort  format;    (void)face;    (void)strike;    format = range->index_format;    PTRACE6(( "Index Format: %d\n", format ));    switch( format )    {    case 1:   /* variable metrics with 4-byte offsets */    case 3:   /* variable metrics with 2-byte offsets */      {        UShort  num_glyphs, size_elem;        Bool    large = (format == 1);        ULong*  cur;        num_glyphs = range->last_glyph - range->first_glyph + 1;        PTRACE5(( "  num glyphs: %hu\n", num_glyphs ));        range->num_glyphs = num_glyphs;        num_glyphs++;  /* BEWARE */        size_elem = large ? 4 : 2;        if ( ALLOC_ARRAY( range->glyph_offsets, num_glyphs, ULong ) ||             ACCESS_Frame( num_glyphs * size_elem )                 )          return error;        cur = range->glyph_offsets;        while ( num_glyphs > 0 )        {          cur[0] = (TT_ULong)( range->image_offset +                               (large ? GET_ULong() : GET_UShort()) );          PTRACE7(( "  offset: %d\n", cur[0] ));          cur++;          num_glyphs--;        }        FORGET_Frame();      }      break;    case 2:   /* all glyphs have identical metrics */    case 4:    case 5:      {        error = 0;        if ( format != 4 )  /* read constant metrics, formats 2 and 5 */        {          TT_SBit_Metrics*  metrics;          if ( ACCESS_Frame( 12L ) )            return error;          range->image_size = GET_ULong();          metrics           = &range->metrics;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -