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

📄 ttgload.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * *  ttgload.c                                                   1.0 * *    TrueType Glyph Loader. * *  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. * ******************************************************************/#include "tttypes.h"#include "ttdebug.h"#include "ttcalc.h"#include "ttfile.h"#include "tttables.h"#include "ttobjs.h"#include "ttgload.h"#include "ttmemory.h"#include "tttags.h"#include "ttload.h"/* required by the tracing mode */#undef  TT_COMPONENT#define TT_COMPONENT  trace_gload/* composite font flags */#define ARGS_ARE_WORDS       0x001#define ARGS_ARE_XY_VALUES   0x002#define ROUND_XY_TO_GRID     0x004#define WE_HAVE_A_SCALE      0x008/* reserved                  0x010 */#define MORE_COMPONENTS      0x020#define WE_HAVE_AN_XY_SCALE  0x040#define WE_HAVE_A_2X2        0x080#define WE_HAVE_INSTR        0x100#define USE_MY_METRICS       0x200/********************************************************//* Return horizontal or vertical metrics in font units  *//* for a given glyph.  The metrics are the left side    *//* bearing (resp. top side bearing) and advance width   *//* (resp. advance height).                              *//*                                                      *//* This function will much probably move to another     *//* component in the short future, but I haven't decided *//* which yet...                                         */  LOCAL_FUNC  void  TT_Get_Metrics( TT_Horizontal_Header*  header,                        UShort                 index,                        Short*                 bearing,                        UShort*                advance )  {    PLongMetrics  longs_m;    UShort  k = header->number_Of_HMetrics;    if ( index < k )    {      longs_m = (PLongMetrics)header->long_metrics + index;      *bearing = longs_m->bearing;      *advance = longs_m->advance;    }    else    {      *bearing = ((PShortMetrics)header->short_metrics)[index - k];      *advance = ((PLongMetrics)header->long_metrics)[k - 1].advance;    }  }/********************************************************//* Return horizontal metrics in font units for a given  *//* glyph.  If `check' is true, take care of mono-spaced *//* fonts by returning the advance width max.            */  static void Get_HMetrics( PFace    face,                            UShort   index,                            Bool     check,                            Short*   lsb,                            UShort*  aw )  {    TT_Get_Metrics( &face->horizontalHeader, index, lsb, aw );    if ( check && face->postscript.isFixedPitch )      *aw = face->horizontalHeader.advance_Width_Max;  }/********************************************************//* Return advance width table for a given pixel size    *//* if it is found in the font's `hdmx' table (if any).  */  static PByte  Get_Advance_Widths( PFace   face,                                    UShort  ppem )  {    UShort  n;    for ( n = 0; n < face->hdmx.num_records; n++ )      if ( face->hdmx.records[n].ppem == ppem )        return face->hdmx.records[n].widths;    return NULL;  }/********************************************************//* Copy current glyph into original one.                */#define cur_to_org( n, zone ) \          MEM_Copy( (zone)->org, (zone)->cur, (n) * sizeof ( TT_Vector ) )/********************************************************//* copy original glyph into current one                 */#define org_to_cur( n, zone ) \          MEM_Copy( (zone)->cur, (zone)->org, (n) * sizeof ( TT_Vector ) )/********************************************************//* translate an array of coordinates                    */  static void  translate_array( UShort     n,                                TT_Vector* coords,                                TT_Pos     delta_x,                                TT_Pos     delta_y )  {    UShort  k;    if ( delta_x )      for ( k = 0; k < n; k++ )        coords[k].x += delta_x;    if ( delta_y )      for ( k = 0; k < n; k++ )        coords[k].y += delta_y;  }/********************************************************//* mount one zone on top of another                     */  static void  mount_zone( PGlyph_Zone  source,                           PGlyph_Zone  target )  {    UShort  np;    Short   nc;    np = source->n_points;    nc = source->n_contours;    target->org   = source->org + np;    target->cur   = source->cur + np;    target->touch = source->touch + np;    target->contours = source->contours + nc;    target->n_points   = 0;    target->n_contours = 0;  }/******************************************************************* * *  Function:  Load_Simple_Glyph * ******************************************************************/  static TT_Error  Load_Simple_Glyph( PExecution_Context  exec,                                      TT_Stream           input,                                      Short               n_contours,                                      Short               left_contours,                                      UShort              left_points,                                      UShort              load_flags,                                      PSubglyph_Record    subg )  {    DEFINE_LOAD_LOCALS( input );    PGlyph_Zone  pts;    Short        k;    UShort       j;    UShort       n_points, n_ins;    PFace        face;    Byte*        flag;    TT_Vector*   vec;    TT_F26Dot6   x, y;    face = exec->face;    /* simple check */    if ( n_contours > left_contours )    {      PTRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",                   subg->index, n_contours, left_contours ));      return TT_Err_Too_Many_Contours;    }    /* preparing the execution context */    mount_zone( &subg->zone, &exec->pts );    /* reading the contours endpoints */    if ( ACCESS_Frame( (n_contours + 1) * 2L ) )      return error;    PTRACE4(( " Contour endpoints:" ));    for ( k = 0; k < n_contours; k++ )    {      exec->pts.contours[k] = GET_UShort();      PTRACE4(( " %d", exec->pts.contours[k] ));    }    PTRACE4(( "\n" ));    if ( n_contours > 0 )      n_points = exec->pts.contours[n_contours - 1] + 1;    else      n_points = 0;    n_ins = GET_UShort();    FORGET_Frame();    if ( n_points > left_points )    {      PTRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index ));      return TT_Err_Too_Many_Points;    }    /* loading instructions */    PTRACE4(( " Instructions size: %d\n", n_ins ));    if ( n_ins > face->maxProfile.maxSizeOfInstructions )    {      PTRACE0(( "ERROR: Too many instructions!\n" ));      return TT_Err_Too_Many_Ins;    }    if ( FILE_Read( exec->glyphIns, n_ins ) )      return error;    if ( (error = Set_CodeRange( exec,                                 TT_CodeRange_Glyph,                                 exec->glyphIns,                                 n_ins )) != TT_Err_Ok )      return error;    /* read the flags */    if ( CHECK_ACCESS_Frame( n_points * 5L ) )      return error;    j    = 0;    flag = exec->pts.touch;    while ( j < n_points )    {      Byte  c, cnt;      flag[j] = c = GET_Byte();      j++;      if ( c & 8 )      {        cnt = GET_Byte();        while( cnt > 0 )        {          flag[j++] = c;          cnt--;        }      }    }    /* read the X */    x    = 0;    vec  = exec->pts.org;    for ( j = 0; j < n_points; j++ )    {      if ( flag[j] & 2 )      {        if ( flag[j] & 16 )          x += GET_Byte();        else          x -= GET_Byte();      }      else      {        if ( (flag[j] & 16) == 0 )          x += GET_Short();      }      vec[j].x = x;    }   /* read the Y */    y    = 0;    for ( j = 0; j < n_points; j++ )    {      if ( flag[j] & 4 )      {        if ( flag[j] & 32 )          y += GET_Byte();        else          y -= GET_Byte();      }      else      {        if ( (flag[j] & 32) == 0 )          y += GET_Short();      }      vec[j].y = y;    }    FORGET_Frame();    /* Now add the two shadow points at n and n + 1.    */    /* We need the left side bearing and advance width. */    /* pp1 = xMin - lsb */    vec[n_points].x = subg->metrics.bbox.xMin - subg->metrics.horiBearingX;    vec[n_points].y = 0;    /* pp2 = pp1 + aw */    vec[n_points+1].x = vec[n_points].x + subg->metrics.horiAdvance;    vec[n_points+1].y = 0;    /* clear the touch flags */    for ( j = 0; j < n_points; j++ )      exec->pts.touch[j] &= TT_Flag_On_Curve;    exec->pts.touch[n_points    ] = 0;    exec->pts.touch[n_points + 1] = 0;    /* Note that we return two more points that are not */    /* part of the glyph outline.                       */    n_points += 2;    /* now eventually scale and hint the glyph */    pts = &exec->pts;    pts->n_points   = n_points;    pts->n_contours = n_contours;    if ( (load_flags & TTLOAD_SCALE_GLYPH) == 0 )    {      /* no scaling, just copy the orig arrays into the cur ones */      org_to_cur( n_points, pts );    }    else    {     /* first scale the glyph points */      for ( j = 0; j < n_points; j++ )      {        pts->org[j].x = Scale_X( &exec->metrics, pts->org[j].x );        pts->org[j].y = Scale_Y( &exec->metrics, pts->org[j].y );      }      /* if hinting, round pp1, and shift the glyph accordingly */      if ( subg->is_hinted )      {        x = pts->org[n_points - 2].x;        x = ((x+32) & -64) - x;        translate_array( n_points, pts->org, x, 0 );        org_to_cur( n_points, pts );        pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64;        /* now consider hinting */        if ( n_ins > 0 )        {          exec->is_composite     = FALSE;          exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC;          error = Context_Run( exec, FALSE );          if (error && exec->pedantic_hinting)            return error;        }      }      else        org_to_cur( n_points, pts );    }    /* save glyph phantom points */    if (!subg->preserve_pps)    {      subg->pp1 = pts->cur[n_points - 2];      subg->pp2 = pts->cur[n_points - 1];    }    return TT_Err_Ok;  }/******************************************************************* * *  Function    :  Load_Composite_End * ******************************************************************/  static  TT_Error  Load_Composite_End( UShort              n_points,                                Short               n_contours,                                PExecution_Context  exec,                                PSubglyph_Record    subg,                                UShort              load_flags,                                TT_Stream           input )  {    DEFINE_LOAD_LOCALS( input );    UShort       k, n_ins;    PGlyph_Zone  pts;    if ( subg->is_hinted                    &&         subg->element_flag & WE_HAVE_INSTR )    {      if ( ACCESS_Frame( 2L ) )        return error;      n_ins = GET_UShort();     /* read size of instructions */      FORGET_Frame();      PTRACE4(( " Instructions size: %d\n", n_ins ));

⌨️ 快捷键说明

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