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

📄 ttsbit.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************/
/*                                                                         */
/*  ttsbit.c                                                               */
/*                                                                         */
/*    TrueType and OpenType embedded bitmap support (body).                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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.                                        */
/*                                                                         */
/***************************************************************************/

#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H

  /*
   *  Alas, the memory-optimized sbit loader can't be used when implementing
   *  the `old internals' hack
   */
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS

#include "ttsbit0.c"

#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */

#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttsbit.h"

#include "sferrors.h"


  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_ttsbit


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    blit_sbit                                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Blits a bitmap from an input stream into a given target.  Supports */
  /*    x and y offsets as well as byte padded lines.                      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    target      :: The target bitmap/pixmap.                           */
  /*                                                                       */
  /*    source      :: The input packed bitmap data.                       */
  /*                                                                       */
  /*    line_bits   :: The number of bits per line.                        */
  /*                                                                       */
  /*    byte_padded :: A flag which is true if lines are byte-padded.      */
  /*                                                                       */
  /*    x_offset    :: The horizontal offset.                              */
  /*                                                                       */
  /*    y_offset    :: The vertical offset.                                */
  /*                                                                       */
  /* <Note>                                                                */
  /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
  /*               the target bitmap (unlike the normal TrueType           */
  /*               convention).  A positive y offset indicates a downwards */
  /*               direction!                                              */
  /*                                                                       */
  static void
  blit_sbit( FT_Bitmap*  target,
             FT_Byte*    source,
             FT_Int      line_bits,
             FT_Bool     byte_padded,
             FT_Int      x_offset,
             FT_Int      y_offset )
  {
    FT_Byte*   line_buff;
    FT_Int     line_incr;
    FT_Int     height;

    FT_UShort  acc;
    FT_UInt    loaded;


    /* first of all, compute starting write position */
    line_incr = target->pitch;
    line_buff = target->buffer;

    if ( line_incr < 0 )
      line_buff -= line_incr * ( target->rows - 1 );

    line_buff += ( x_offset >> 3 ) + y_offset * line_incr;

    /***********************************************************************/
    /*                                                                     */
    /* We use the extra-classic `accumulator' trick to extract the bits    */
    /* from the source byte stream.                                        */
    /*                                                                     */
    /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
    /* last `loaded' bits from the input stream.  The bits are shifted to  */
    /* the upmost position in `acc'.                                       */
    /*                                                                     */
    /***********************************************************************/

    acc    = 0;  /* clear accumulator   */
    loaded = 0;  /* no bits were loaded */

    for ( height = target->rows; height > 0; height-- )
    {
      FT_Byte*  cur   = line_buff;        /* current write cursor          */
      FT_Int    count = line_bits;        /* # of bits to extract per line */
      FT_Byte   shift = (FT_Byte)( x_offset & 7 ); /* current write shift  */
      FT_Byte   space = (FT_Byte)( 8 - shift );


      /* first of all, read individual source bytes */
      if ( count >= 8 )
      {
        count -= 8;
        {
          do
          {
            FT_Byte  val;


            /* ensure that there are at least 8 bits in the accumulator */
            if ( loaded < 8 )
            {
              acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
              loaded += 8;
            }

            /* now write one byte */
            val = (FT_Byte)( acc >> 8 );
            if ( shift )
            {
              cur[0] |= (FT_Byte)( val >> shift );
              cur[1] |= (FT_Byte)( val << space );
            }
            else
              cur[0] |= val;

            cur++;
            acc   <<= 8;  /* remove bits from accumulator */
            loaded -= 8;
            count  -= 8;

          } while ( count >= 0 );
        }

        /* restore `count' to correct value */
        count += 8;
      }

      /* now write remaining bits (count < 8) */
      if ( count > 0 )
      {
        FT_Byte  val;


        /* ensure that there are at least `count' bits in the accumulator */
        if ( (FT_Int)loaded < count )
        {
          acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
          loaded += 8;
        }

        /* now write remaining bits */
        val     = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
        cur[0] |= (FT_Byte)( val >> shift );

        if ( count > space )
          cur[1] |= (FT_Byte)( val << space );

        acc   <<= count;
        loaded -= count;
      }

      /* now, skip to next line */
      if ( byte_padded )
      {
        acc    = 0;
        loaded = 0;   /* clear accumulator on byte-padded lines */
      }

      line_buff += line_incr;
    }
  }


  static const FT_Frame_Field  sbit_metrics_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_SBit_MetricsRec

    FT_FRAME_START( 8 ),
      FT_FRAME_BYTE( height ),
      FT_FRAME_BYTE( width ),

      FT_FRAME_CHAR( horiBearingX ),
      FT_FRAME_CHAR( horiBearingY ),
      FT_FRAME_BYTE( horiAdvance ),

      FT_FRAME_CHAR( vertBearingX ),
      FT_FRAME_CHAR( vertBearingY ),
      FT_FRAME_BYTE( vertAdvance ),
    FT_FRAME_END
  };


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Load_SBit_Const_Metrics                                            */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
  /*                                                                       */
  /* <Input>                                                               */
  /*    range  :: The target range.                                        */
  /*                                                                       */
  /*    stream :: The input stream.                                        */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  static FT_Error
  Load_SBit_Const_Metrics( TT_SBit_Range  range,
                           FT_Stream      stream )
  {
    FT_Error  error;


    if ( FT_READ_ULONG( range->image_size ) )
      return error;

    return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Load_SBit_Range_Codes                                              */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    range        :: The target range.                                  */
  /*                                                                       */
  /*    stream       :: The input stream.                                  */
  /*                                                                       */
  /*    load_offsets :: A flag whether to load the glyph offset table.     */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  static FT_Error
  Load_SBit_Range_Codes( TT_SBit_Range  range,
                         FT_Stream      stream,
                         FT_Bool        load_offsets )
  {
    FT_Error   error;
    FT_ULong   count, n, size;
    FT_Memory  memory = stream->memory;


    if ( FT_READ_ULONG( count ) )
      goto Exit;

    range->num_glyphs = count;

    /* Allocate glyph offsets table if needed */
    if ( load_offsets )
    {
      if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
        goto Exit;

      size = count * 4L;
    }
    else
      size = count * 2L;

    /* Allocate glyph codes table and access frame */
    if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
         FT_FRAME_ENTER( size )                     )
      goto Exit;

    for ( n = 0; n < count; n++ )
    {
      range->glyph_codes[n] = FT_GET_USHORT();

      if ( load_offsets )
        range->glyph_offsets[n] = (FT_ULong)range->image_offset +
                                  FT_GET_USHORT();
    }

    FT_FRAME_EXIT();

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Load_SBit_Range                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads a given `EBLC' index/range table.                            */
  /*                                                                       */
  /* <Input>                                                               */
  /*    range  :: The target range.                                        */
  /*                                                                       */
  /*    stream :: The input stream.                                        */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  static FT_Error
  Load_SBit_Range( TT_SBit_Range  range,
                   FT_Stream      stream )
  {
    FT_Error   error;
    FT_Memory  memory = stream->memory;


    switch( range->index_format )
    {
    case 1:   /* variable metrics with 4-byte offsets */
    case 3:   /* variable metrics with 2-byte offsets */
      {
        FT_ULong  num_glyphs, n;
        FT_Int    size_elem;
        FT_Bool   large = FT_BOOL( range->index_format == 1 );



        if ( range->last_glyph < range->first_glyph )
        {
          error = SFNT_Err_Invalid_File_Format;
          goto Exit;
        }

        num_glyphs        = range->last_glyph - range->first_glyph + 1L;
        range->num_glyphs = num_glyphs;
        num_glyphs++;                       /* XXX: BEWARE - see spec */

        size_elem = large ? 4 : 2;

        if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
             FT_FRAME_ENTER( num_glyphs * size_elem )         )
          goto Exit;

        for ( n = 0; n < num_glyphs; n++ )
          range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
                                                ( large ? FT_GET_ULONG()
                                                        : FT_GET_USHORT() ) );
        FT_FRAME_EXIT();
      }
      break;

    case 2:   /* all glyphs have identical metrics */

⌨️ 快捷键说明

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