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

📄 ttsbit.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
      line  = (FT_Byte*)map->buffer + ( right >> 3 );
      limit = line + rows * line_len;
      mask  = (FT_Byte)( 0x80 >> ( right & 7 ) );

      for ( ; line < limit; line += line_len )
        if ( line[0] & mask )
          goto Found_Right;

      /* crop the whole glyph to the right */
      map->width--;
      metrics->width--;

    } while ( map->width > 0 );

  Found_Right:
    /* all right, the bitmap was cropped */
    return;

  Empty_Bitmap:
    map->width      = 0;
    map->rows       = 0;
    map->pitch      = 0;
    map->pixel_mode = FT_PIXEL_MODE_MONO;
  }


  static FT_Error
  Load_SBit_Single( FT_Bitmap*       map,
                    FT_Int           x_offset,
                    FT_Int           y_offset,
                    FT_Int           pix_bits,
                    FT_UShort        image_format,
                    TT_SBit_Metrics  metrics,
                    FT_Stream        stream )
  {
    FT_Error  error;


    /* check that the source bitmap fits into the target pixmap */
    if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
         y_offset < 0 || y_offset + metrics->height > map->rows  )
    {
      error = SFNT_Err_Invalid_Argument;

      goto Exit;
    }

    {
      FT_Int   glyph_width  = metrics->width;
      FT_Int   glyph_height = metrics->height;
      FT_Int   glyph_size;
      FT_Int   line_bits    = pix_bits * glyph_width;
      FT_Bool  pad_bytes    = 0;


      /* compute size of glyph image */
      switch ( image_format )
      {
      case 1:  /* byte-padded formats */
      case 6:
        {
          FT_Int  line_length;


          switch ( pix_bits )
          {
          case 1:
            line_length = ( glyph_width + 7 ) >> 3;
            break;
          case 2:
            line_length = ( glyph_width + 3 ) >> 2;
            break;
          case 4:
            line_length = ( glyph_width + 1 ) >> 1;
            break;
          default:
            line_length =   glyph_width;
          }

          glyph_size = glyph_height * line_length;
          pad_bytes  = 1;
        }
        break;

      case 2:
      case 5:
      case 7:
        line_bits  =   glyph_width  * pix_bits;
        glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
        break;

      default:  /* invalid format */
        return SFNT_Err_Invalid_File_Format;
      }

      /* Now read data and draw glyph into target pixmap       */
      if ( FT_FRAME_ENTER( glyph_size ) )
        goto Exit;

      /* don't forget to multiply `x_offset' by `map->pix_bits' as */
      /* the sbit blitter doesn't make a difference between pixmap */
      /* depths.                                                   */
      blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
                 x_offset * pix_bits, y_offset );

      FT_FRAME_EXIT();
    }

  Exit:
    return error;
  }


  static FT_Error
  Load_SBit_Image( TT_SBit_Strike   strike,
                   TT_SBit_Range    range,
                   FT_ULong         ebdt_pos,
                   FT_ULong         glyph_offset,
                   FT_GlyphSlot     slot,
                   FT_Int           x_offset,
                   FT_Int           y_offset,
                   FT_Stream        stream,
                   TT_SBit_Metrics  metrics,
                   FT_Int           depth )
  {
    FT_Memory   memory = stream->memory;
    FT_Bitmap*  map    = &slot->bitmap;
    FT_Error    error;


    /* place stream at beginning of glyph data and read metrics */
    if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
      goto Exit;

    error = tt_load_sbit_metrics( stream, range, metrics );
    if ( error )
      goto Exit;

    /* This function is recursive.  At the top-level call, we  */
    /* compute the dimensions of the higher-level glyph to     */
    /* allocate the final pixmap buffer.                       */
    if ( depth == 0 )
    {
      FT_Long  size;


      map->width = metrics->width;
      map->rows  = metrics->height;

      switch ( strike->bit_depth )
      {
      case 1:
        map->pixel_mode = FT_PIXEL_MODE_MONO;
        map->pitch      = ( map->width + 7 ) >> 3;
        break;

      case 2:
        map->pixel_mode = FT_PIXEL_MODE_GRAY2;
        map->pitch      = ( map->width + 3 ) >> 2;
        break;

      case 4:
        map->pixel_mode = FT_PIXEL_MODE_GRAY4;
        map->pitch      = ( map->width + 1 ) >> 1;
        break;

      case 8:
        map->pixel_mode = FT_PIXEL_MODE_GRAY;
        map->pitch      = map->width;
        break;

      default:
        return SFNT_Err_Invalid_File_Format;
      }

      size = map->rows * map->pitch;

      /* check that there is no empty image */
      if ( size == 0 )
        goto Exit;     /* exit successfully! */

      error = ft_glyphslot_alloc_bitmap( slot, size );
      if (error)
        goto Exit;
    }

    switch ( range->image_format )
    {
    case 1:  /* single sbit image - load it */
    case 2:
    case 5:
    case 6:
    case 7:
      return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
                               range->image_format, metrics, stream );

    case 8:  /* compound format */
      FT_Stream_Skip( stream, 1L );
      /* fallthrough */

    case 9:
      break;

    default: /* invalid image format */
      return SFNT_Err_Invalid_File_Format;
    }

    /* All right, we have a compound format.  First of all, read */
    /* the array of elements.                                    */
    {
      TT_SBit_Component  components;
      TT_SBit_Component  comp;
      FT_UShort          num_components, count;


      if ( FT_READ_USHORT( num_components )           ||
           FT_NEW_ARRAY( components, num_components ) )
        goto Exit;

      count = num_components;

      if ( FT_FRAME_ENTER( 4L * num_components ) )
        goto Fail_Memory;

      for ( comp = components; count > 0; count--, comp++ )
      {
        comp->glyph_code = FT_GET_USHORT();
        comp->x_offset   = FT_GET_CHAR();
        comp->y_offset   = FT_GET_CHAR();
      }

      FT_FRAME_EXIT();

      /* Now recursively load each element glyph */
      count = num_components;
      comp  = components;
      for ( ; count > 0; count--, comp++ )
      {
        TT_SBit_Range       elem_range;
        TT_SBit_MetricsRec  elem_metrics;
        FT_ULong            elem_offset;


        /* find the range for this element */
        error = find_sbit_range( comp->glyph_code,
                                 strike,
                                 &elem_range,
                                 &elem_offset );
        if ( error )
          goto Fail_Memory;

        /* now load the element, recursively */
        error = Load_SBit_Image( strike,
                                 elem_range,
                                 ebdt_pos,
                                 elem_offset,
                                 slot,
                                 x_offset + comp->x_offset,
                                 y_offset + comp->y_offset,
                                 stream,
                                 &elem_metrics,
                                 depth + 1 );
        if ( error )
          goto Fail_Memory;
      }

    Fail_Memory:
      FT_FREE( components );
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_load_sbit_image                                            */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads a given glyph sbit image from the font resource.  This also  */
  /*    returns its metrics.                                               */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face         :: The target face object.                            */
  /*                                                                       */
  /*    strike_index :: The current strike index.                          */
  /*                                                                       */
  /*    glyph_index  :: The current glyph index.                           */
  /*                                                                       */
  /*    load_flags   :: The glyph load flags (the code checks for the flag */
  /*                    FT_LOAD_CROP_BITMAP).                              */
  /*                                                                       */
  /*    stream       :: The input stream.                                  */
  /*                                                                       */
  /* <Output>                                                              */
  /*    map          :: The target pixmap.                                 */
  /*                                                                       */
  /*    metrics      :: A big sbit metrics structure for the glyph image.  */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.  Returns an error if no     */
  /*    glyph sbit exists for the index.                                   */
  /*                                                                       */
  /*  <Note>                                                               */
  /*    The `map.buffer' field is always freed before the glyph is loaded. */
  /*                                                                       */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_sbit_image( TT_Face              face,
                           FT_ULong             strike_index,
                           FT_UInt              glyph_index,
                           FT_UInt              load_flags,
                           FT_Stream            stream,
                           FT_Bitmap           *map,
                           TT_SBit_MetricsRec  *metrics )
  {
    FT_Error        error;
    FT_ULong        ebdt_pos, glyph_offset;

    TT_SBit_Strike  strike;
    TT_SBit_Range   range;


    /* Check whether there is a glyph sbit for the current index */
    error = tt_find_sbit_image( face, glyph_index, strike_index,
                                &range, &strike, &glyph_offset );
    if ( error )
      goto Exit;

    /* now, find the location of the `EBDT' table in */
    /* the font file                                 */
    error = face->goto_table( face, TTAG_EBDT, stream, 0 );
    if ( error )
      error = face->goto_table( face, TTAG_bdat, stream, 0 );
    if ( error )
      goto Exit;

    ebdt_pos = FT_STREAM_POS();

    error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
                             face->root.glyph, 0, 0, stream, metrics, 0 );
    if ( error )
      goto Exit;

    /* setup vertical metrics if needed */
    if ( strike->flags & 1 )
    {
      /* in case of a horizontal strike only */
      FT_Int  advance;


      advance = strike->hori.ascender - strike->hori.descender;

      /* some heuristic values */

      metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
      metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
      metrics->vertAdvance  = (FT_Char)( advance * 12 / 10 );
    }

    /* Crop the bitmap now, unless specified otherwise */
    if ( load_flags & FT_LOAD_CROP_BITMAP )
      crop_bitmap( map, metrics );

  Exit:
    return error;
  }

#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */


/* END */

⌨️ 快捷键说明

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