ttgload.c

来自「Qt/Embedded是一个多平台的C++图形用户界面应用程序框架」· C语言 代码 · 共 1,332 行 · 第 1/3 页

C
1,332
字号
    return error;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    load_truetype_glyph                                                */  /*                                                                       */  /* <Description>                                                         */  /*    Loads a given truetype glyph. Handles composites and uses a        */  /*    TT_Loader object..                                                 */  /*                                                                       */  static  TT_Error  load_truetype_glyph( TT_Loader*  loader,                                 TT_UInt     glyph_index )  {    FT_Stream    stream = loader->stream;    TT_Error     error;    TT_Face      face   = loader->face;    TT_ULong     offset;    FT_SubGlyph  subglyphs[ TT_MAX_SUBGLYPHS ];    TT_Int       num_subglyphs = 0, contours_count;    TT_UInt      index, num_points, num_contours, count;    TT_Fixed     x_scale, y_scale;    TT_ULong     ins_offset;        /* check glyph index */    index = (TT_UInt)glyph_index;    if ( index >= (TT_UInt)face->root.num_glyphs )    {      error = TT_Err_Invalid_Glyph_Index;      goto Fail;    }    loader->glyph_index = glyph_index;    num_contours = 0;    num_points   = 0;    ins_offset   = 0;        x_scale = 0x10000;    y_scale = 0x10000;    if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 )    {      x_scale = loader->size->root.metrics.x_scale;      y_scale = loader->size->root.metrics.y_scale;    }    /* get horizontal metrics */    {      TT_Short   left_bearing;      TT_UShort  advance_width;      Get_HMetrics( face, index,                    (TT_Bool)!(loader->load_flags &                                 FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH),                    &left_bearing,                    &advance_width );      loader->left_bearing = left_bearing;      loader->advance      = advance_width;    }    /* load glyph header */    offset = face->glyph_locations[index];    count  = 0;    if (index < (TT_UInt)face->num_locations-1)       count = face->glyph_locations[index+1] - offset;              if (count == 0)    {      /* as described by Frederic Loyer, these are spaces, and */      /* not the unknown glyph.                                */      loader->bbox.xMin = 0;      loader->bbox.xMax = 0;      loader->bbox.yMin = 0;      loader->bbox.yMax = 0;      loader->pp1.x = 0;      loader->pp2.x = loader->advance;      if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 )        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER      if (loader->exec)        loader->exec->glyphSize = 0;#endif      goto Load_End;    }    offset = loader->glyf_offset + offset;    /* read first glyph header */    if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) )      goto Fail;    contours_count = GET_Short();    loader->bbox.xMin = GET_Short();    loader->bbox.yMin = GET_Short();    loader->bbox.xMax = GET_Short();    loader->bbox.yMax = GET_Short();    FORGET_Frame();    FT_TRACE6(( "Glyph %ld\n", index ));    FT_TRACE6(( " # of contours : %d\n", num_contours ));    FT_TRACE6(( " xMin: %4d  xMax: %4d\n", loader->bbox.xMin,                                           loader->bbox.xMax ));    FT_TRACE6(( " yMin: %4d  yMax: %4d\n", loader->bbox.yMin,                                           loader->bbox.yMax ));    FT_TRACE6(( "-" ));    count -= 10;    if ( contours_count > loader->left_contours )    {      FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));      error = TT_Err_Too_Many_Contours;      goto Fail;    }    loader->pp1.x = loader->bbox.xMin - loader->left_bearing;    loader->pp1.y = 0;    loader->pp2.x = loader->pp1.x + loader->advance;    loader->pp2.y = 0;        if ((loader->load_flags & FT_LOAD_NO_SCALE)==0)    {      loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );      loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );    }    /*************************************************************************/    /*************************************************************************/    /*************************************************************************/    /**********************************************************************/    /* if it is a simple glyph, load it                                   */    if (contours_count >= 0)    {      TT_UInt  num_base_points;      #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER      error = Load_Simple( loader,                           count,                           contours_count,                           (TT_Bool)( loader->size &&                                      loader->size->debug ) );#else      error = Load_Simple( loader, count, contours_count, 0 );#endif                                            if ( error )        goto Fail;      /* Note: We could have put the simple loader source there */      /*       but the code is fat enough already :-)           */      num_points   = loader->zone.n_points;      num_contours = loader->zone.n_contours;            num_base_points = loader->base.n_points;      {        TT_UInt  k;        for ( k = 0; k < num_contours; k++ )          loader->zone.contours[k] += num_base_points;      }      loader->base.n_points   += num_points;      loader->base.n_contours += num_contours;      loader->zone.n_points    = 0;      loader->zone.n_contours  = 0;      loader->left_points   -= num_points;      loader->left_contours -= num_contours;    }    /*************************************************************************/    /*************************************************************************/    /*************************************************************************/    /************************************************************************/    else /* otherwise, load a composite !!                                  */    {      /* for each subglyph, read composite header */      FT_SubGlyph*  subglyph = subglyphs;            if (ACCESS_Frame(count)) goto Fail;            num_subglyphs = 0;      do      {        TT_Fixed  xx, xy, yy, yx;                subglyph->arg1 = subglyph->arg2 = 0;                subglyph->flags = GET_UShort();        subglyph->index = GET_UShort();        /* read arguments */        if (subglyph->flags & ARGS_ARE_WORDS)        {          subglyph->arg1 = GET_Short();          subglyph->arg2 = GET_Short();        }        else        {          subglyph->arg1 = GET_Char();          subglyph->arg2 = GET_Char();        }                /* read transform */        xx = yy = 0x10000;        xy = yx = 0;                if (subglyph->flags & WE_HAVE_A_SCALE)        {          xx = (TT_Fixed)GET_Short() << 2;          yy = xx;        }        else if (subglyph->flags & WE_HAVE_AN_XY_SCALE)        {          xx = (TT_Fixed)GET_Short() << 2;          yy = (TT_Fixed)GET_Short() << 2;        }        else if (subglyph->flags & WE_HAVE_A_2X2)        {          xx = (TT_Fixed)GET_Short() << 2;          xy = (TT_Fixed)GET_Short() << 2;          yx = (TT_Fixed)GET_Short() << 2;          yy = (TT_Fixed)GET_Short() << 2;        }                subglyph->transform.xx = xx;        subglyph->transform.xy = xy;        subglyph->transform.yx = yx;        subglyph->transform.yy = yy;                subglyph++;        num_subglyphs++;        if (num_subglyphs >= TT_MAX_SUBGLYPHS)          break;      }      while (subglyph[-1].flags & MORE_COMPONENTS);#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER      {        /* we must undo the ACCESS_Frame in order to point to the */        /* composite instructions, if we find some ..             */        /* we will process them later..                           */        ins_offset = FILE_Pos() + stream->cursor - stream->limit;        FORGET_Frame();      }#endif    /*************************************************************************/    /*************************************************************************/    /*************************************************************************/      /*********************************************************************/      /* Now, read each subglyph independently..                           */      {        TT_Int  n, num_base_points, num_new_points;                subglyph = subglyphs;        for ( n = 0; n < num_subglyphs; n++, subglyph++ )        {          TT_Vector  pp1, pp2;          TT_Pos     x, y;                    pp1 = loader->pp1;          pp2 = loader->pp2;          num_base_points = loader->base.n_points;                    error = load_truetype_glyph( loader, subglyph->index );          if ( subglyph->flags & USE_MY_METRICS )          {            pp1 = loader->pp1;            pp2 = loader->pp2;          }          else          {            loader->pp1 = pp1;            loader->pp2 = pp2;          }                    num_points   = loader->base.n_points;          num_contours = loader->base.n_contours;                    num_new_points = num_points - num_base_points;                    /********************************************************/          /* now perform the transform required for this subglyph */                    if ( subglyph->flags & ( WE_HAVE_A_SCALE     |                                   WE_HAVE_AN_XY_SCALE |                                   WE_HAVE_A_2X2       ) )          {            TT_Vector*  cur = loader->zone.cur;            TT_Vector*  org = loader->zone.org;            TT_Vector*  limit = cur + num_new_points;            for ( ; cur < limit; cur++, org++ )            {              TT_Pos  nx, ny;                            nx = FT_MulFix( cur->x, subglyph->transform.xx ) +                   FT_MulFix( cur->y, subglyph->transform.yx );              ny = FT_MulFix( cur->x, subglyph->transform.xy ) +                   FT_MulFix( cur->y, subglyph->transform.yy );              cur->x = nx;              cur->y = ny;              nx = FT_MulFix( org->x, subglyph->transform.xx ) +                   FT_MulFix( org->y, subglyph->transform.yx );              ny = FT_MulFix( org->x, subglyph->transform.xy ) +                   FT_MulFix( org->y, subglyph->transform.yy );              org->x = nx;              org->y = ny;            }          }          /* apply offset */          if ( !(subglyph->flags & ARGS_ARE_XY_VALUES) )          {            TT_Int   k = subglyph->arg1;            TT_UInt  l = subglyph->arg2;            if ( k >= num_base_points ||                 l >= (TT_UInt)num_new_points  )            {              error = TT_Err_Invalid_Composite;              goto Fail;            }            l += num_base_points; 	                x = loader->base.cur[k].x - loader->base.cur[l].x;            y = loader->base.cur[k].y - loader->base.cur[l].y;          }          else          {            x = subglyph->arg1;            y = subglyph->arg2;            if (!(loader->load_flags & FT_LOAD_NO_SCALE))            {              x = FT_MulFix( x, x_scale );              y = FT_MulFix( y, y_scale );                            if ( subglyph->flags & ROUND_XY_TO_GRID )	          {	            x = (x + 32) & -64;	            y = (y + 32) & -64;	          }            }          }          translate_array( num_new_points, loader->zone.cur, x, y );          cur_to_org( num_new_points, &loader->zone );        }            /*************************************************************************/    /*************************************************************************/    /*************************************************************************/        /* we have finished loading all sub-glyphs, now, look for */        /* instructions for this composite !!                     */#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER        subglyph--;        if (num_subglyphs > 0 && loader->exec && subglyph->flags & WE_HAVE_INSTR)        {          TT_UShort       n_ins;          TT_ExecContext  exec = loader->exec;          TT_UInt         n_points = loader->base.n_points;          FT_GlyphZone*   pts;          TT_Vector*      pp1;                    /* read size of instructions */          if ( FILE_Seek( ins_offset ) ||               READ_UShort(n_ins)      ) goto Fail;          FT_TRACE4(( "Instructions size = %d\n", n_ins ));              /* check it */          if ( n_ins > face->max_profile.maxSizeOfInstructions )          {            FT_TRACE0(( "Too many instructions in composite glyph %ld\n",                        subglyph->index ));            return TT_Err_Too_Many_Ins;          }               if (exec)          {          }          /* read the instructions */          if ( FILE_Read( exec->glyphIns, n_ins ) )            goto Fail;              error = TT_Set_CodeRange( exec,                                    tt_coderange_glyph,                                    exec->glyphIns,                                    n_ins );          if ( error ) goto Fail;                    /* prepare the execution context */          exec->pts   = loader->base;          pts         = &exec->pts;                pts->n_points   = num_points + 2;          pts->n_contours = num_contours;                /* add phantom points */          pp1    = pts->cur + num_points;          pp1[0] = loader->pp1;          pp1[1] = loader->pp2;                pts->tags[num_points + 1] = 0;          pts->tags[num_points + 2] = 0;                /* if hinting, round the phantom points */          if ( IS_HINTED(loader->load_flags) )          {            pp1[0].x = ((loader->pp1.x + 32) & -64);            pp1[1].x = ((loader->pp2.x + 32) & -64);          }                {            TT_UInt  k;            for ( k = 0; k < n_points; k++ )              pts->tags[k] &= FT_Curve_Tag_On;          }      

⌨️ 快捷键说明

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