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

📄 ahglyph.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************//*                                                                         *//*  ahglyph.c                                                              *//*                                                                         *//*    Routines used to load and analyze a given glyph before hinting       *//*    (body).                                                              *//*                                                                         *//*  Copyright 2000 Catharon Productions Inc.                               *//*  Author: David Turner                                                   *//*                                                                         *//*  This file is part of the Catharon Typography Project and shall only    *//*  be used, modified, and distributed under the terms of the Catharon     *//*  Open Source License that should come with this file under the name     *//*  `CatharonLicense.txt'.  By continuing to use, modify, or distribute    *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//*  Note that this license is compatible with the FreeType license.        *//*                                                                         *//***************************************************************************/#ifdef FT_FLAT_COMPILE#include "ahglyph.h"#include "ahangles.h"#include "ahglobal.h"#else#include <autohint/ahglyph.h>#include <autohint/ahangles.h>#include <autohint/ahglobal.h>#endif#include <stdio.h>#define xxxAH_DEBUG_GLYPH  /* compute the direction value of a given vector.. */  static  AH_Direction  ah_compute_direction( FT_Pos  dx,                                      FT_Pos  dy )  {    AH_Direction  dir;    FT_Pos        ax = ABS( dx );    FT_Pos        ay = ABS( dy );    dir = ah_dir_none;    /* test for vertical direction */    if ( ax * 12 < ay )    {      dir = dy > 0 ? ah_dir_up : ah_dir_down;    }    /* test for horizontal direction */    else if ( ay * 12 < ax )    {      dir = dx > 0 ? ah_dir_right : ah_dir_left;    }    return dir;  }  /* this function is used by ah_get_orientation (see below) to test */  /* the fill direction of a given bbox extrema                      */  static  int  ah_test_extrema( FT_Outline*  outline,                        int          n )  {    FT_Vector  *prev, *cur, *next;    FT_Pos      product;    FT_Int      first, last, c;    /* we need to compute the `previous' and `next' point */    /* for these extrema                                  */    cur  = outline->points + n;    prev = cur - 1;    next = cur + 1;    first = 0;    for ( c = 0; c < outline->n_contours; c++ )    {      last  = outline->contours[c];      if ( n == first )        prev = outline->points + last;      if ( n == last )        next = outline->points + first;      first = last + 1;    }    product = FT_MulDiv( cur->x  - prev->x,  /* in.x  */                         next->y - cur->y,   /* out.y */                         0x40 )              -              FT_MulDiv( cur->y  - prev->y,  /* in.y  */                         next->x - cur->x,   /* out.x */                         0x40 );    if ( product )      product = product > 0 ? 2 : 1;    return product;  }  /* Compute the orientation of path filling.  It differs between TrueType */  /* and Type1 formats.  We could use the `ft_outline_reverse_fill' flag,  */  /* but it is better to re-compute it directly (it seems that this flag   */  /* isn't correctly set for some weird composite glyphs currently).       */  /*                                                                       */  /* We do this by computing bounding box points, and computing their      */  /* curvature.                                                            */  /*                                                                       */  /* The function returns either 1 or -1.                                  */  /*                                                                       */  static  int  ah_get_orientation( FT_Outline*  outline )  {    FT_BBox  box;    FT_BBox  indices;    int      n, last;    indices.xMin = -1;    indices.yMin = -1;    indices.xMax = -1;    indices.yMax = -1;    box.xMin = box.yMin =  32767;    box.xMax = box.yMax = -32768;    /* is it empty? */    if ( outline->n_contours < 1 )      return 1;    last = outline->contours[outline->n_contours - 1];    for ( n = 0; n <= last; n++ )    {      FT_Pos  x, y;      x = outline->points[n].x;      if ( x < box.xMin )      {        box.xMin     = x;        indices.xMin = n;      }      if ( x > box.xMax )      {        box.xMax     = x;        indices.xMax = n;      }      y = outline->points[n].y;      if ( y < box.yMin )      {        box.yMin     = y;        indices.yMin = n;      }      if ( y > box.yMax )      {        box.yMax     = y;        indices.yMax = n;      }    }    /* test orientation of the xmin */    n = ah_test_extrema( outline, indices.xMin );    if ( n )      goto Exit;    n = ah_test_extrema( outline, indices.yMin );    if ( n )      goto Exit;    n = ah_test_extrema( outline, indices.xMax );    if ( n )      goto Exit;    n = ah_test_extrema( outline, indices.yMax );    if ( !n )      n = 1;  Exit:    return n;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_new                                                     */  /*                                                                       */  /* <Description>                                                         */  /*    Creates a new and empty AH_Outline object.                         */  /*                                                                       */  FT_LOCAL_DEF  FT_Error  ah_outline_new( FT_Memory     memory,                            AH_Outline**  aoutline )  {    FT_Error     error;    AH_Outline*  outline;    if ( !ALLOC( outline, sizeof ( *outline ) ) )    {      outline->memory = memory;      *aoutline = outline;    }    return error;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_done                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Destroys a given AH_Outline object.                                */  /*                                                                       */  FT_LOCAL_DEF  void  ah_outline_done( AH_Outline*  outline )  {    FT_Memory memory = outline->memory;    FREE( outline->horz_edges );    FREE( outline->horz_segments );    FREE( outline->contours );    FREE( outline->points );    FREE( outline );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_save                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Saves the content of a given AH_Outline object into a face's glyph */  /*    slot.                                                              */  /*                                                                       */  FT_LOCAL_DEF  void  ah_outline_save( AH_Outline*  outline,                         AH_Loader*   gloader )  {    AH_Point*   point       = outline->points;    AH_Point*   point_limit = point + outline->num_points;    FT_Vector*  vec         = gloader->current.outline.points;    char*       tag         = gloader->current.outline.tags;    /* we assume that the glyph loader has already been checked for storage */    for ( ; point < point_limit; point++, vec++, tag++ )    {      vec->x = point->x;      vec->y = point->y;      if ( point->flags & ah_flah_conic )        tag[0] = FT_Curve_Tag_Conic;      else if ( point->flags & ah_flah_cubic )        tag[0] = FT_Curve_Tag_Cubic;      else        tag[0] = FT_Curve_Tag_On;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_load                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Loads an unscaled outline from a glyph slot into an AH_Outline     */  /*    object.                                                            */  /*                                                                       */  FT_LOCAL_DEF  FT_Error  ah_outline_load( AH_Outline*  outline,                             FT_Face      face )  {    FT_Memory   memory       = outline->memory;    FT_Error    error        = FT_Err_Ok;    FT_Outline* source       = &face->glyph->outline;    FT_Int      num_points   = source->n_points;    FT_Int      num_contours = source->n_contours;    AH_Point*   points;    /* check arguments */    if ( !face                                          ||         !face->size                                    ||         face->glyph->format != ft_glyph_format_outline )      return FT_Err_Invalid_Argument;    /* first of all, reallocate the contours array if necessary */    if ( num_contours > outline->max_contours )    {      FT_Int  new_contours = ( num_contours + 3 ) & -4;      if ( REALLOC_ARRAY( outline->contours, outline->max_contours,                          new_contours, AH_Point* ) )        goto Exit;      outline->max_contours = new_contours;    }    /* then, reallocate the points, segments & edges arrays if needed -- */    /* note that we reserved two additional point positions, used to     */    /* hint metrics appropriately                                        */    /*                                                                   */    if ( num_points + 2 > outline->max_points )    {      FT_Int  news = ( num_points + 2 + 7 ) & -8;      FT_Int  max  = outline->max_points;      if ( REALLOC_ARRAY( outline->points,                          max, news, AH_Point )            ||           REALLOC_ARRAY( outline->horz_edges,                          max * 2, news * 2, AH_Edge )     ||           REALLOC_ARRAY( outline->horz_segments,                          max * 2, news * 2, AH_Segment ) )        goto Exit;      /* readjust some pointers */      outline->vert_edges    = outline->horz_edges    + news;      outline->vert_segments = outline->horz_segments + news;      outline->max_points    = news;    }    outline->num_points   = num_points;    outline->num_contours = num_contours;    outline->num_hedges    = 0;    outline->num_vedges    = 0;    outline->num_hsegments = 0;    outline->num_vsegments = 0;#if 1    /* We can't rely on the value of `FT_Outline.flags' to know the fill  */    /* direction used for a glyph, given that some fonts are broken (e.g. */    /* the Arphic ones). We thus recompute it each time we need to.       */    /*                                                                    */    outline->vert_major_dir = ah_dir_up;    outline->horz_major_dir = ah_dir_left;    if ( ah_get_orientation( source ) > 1 )    {      outline->vert_major_dir = ah_dir_down;      outline->horz_major_dir = ah_dir_right;    }#else    /* Compute the vertical and horizontal major directions; this is     */    /* currently done by inspecting the `ft_outline_reverse_fill' flag.  */    /* However, some fonts have improper glyphs, and it'd be a good idea */    /* to be able to re-compute these values on the fly.                 */    outline->vert_major_dir = ah_dir_up;    outline->horz_major_dir = ah_dir_left;    if ( source->flags & ft_outline_reverse_fill )    {      outline->vert_major_dir = ah_dir_down;      outline->horz_major_dir = ah_dir_right;    }#endif /* 1 */    outline->x_scale = face->size->metrics.x_scale;    outline->y_scale = face->size->metrics.y_scale;    points = outline->points;    if ( outline->num_points == 0 )      goto Exit;    {      /* do one thing at a time -- it is easier to understand, and */      /* the code is clearer                                       */      AH_Point*  point;      AH_Point*  point_limit = points + outline->num_points;      /* compute coordinates */      {        FT_Vector*  vec     = source->points;        FT_Fixed    x_scale = outline->x_scale;        FT_Fixed    y_scale = outline->y_scale;        for ( point = points; point < point_limit; vec++, point++ )        {          point->fx = vec->x;          point->fy = vec->y;          point->ox = point->x = FT_MulFix( vec->x, x_scale );          point->oy = point->y = FT_MulFix( vec->y, y_scale );          point->flags = 0;        }      }      /* compute Bezier flags */      {        char*  tag = source->tags;        for ( point = points; point < point_limit; point++, tag++ )        {          switch ( FT_CURVE_TAG( *tag ) )          {          case FT_Curve_Tag_Conic:            point->flags = ah_flah_conic; break;          case FT_Curve_Tag_Cubic:            point->flags = ah_flah_cubic; break;          default:            ;          }        }      }      /* compute `next' and `prev' */      {        FT_Int     contour_index;        AH_Point*  prev;        AH_Point*  first;        AH_Point*  end;        contour_index = 0;        first = points;        end   = points + source->contours[0];        prev  = end;        for ( point = points; point < point_limit; point++ )        {          point->prev = prev;          if ( point < end )          {            point->next = point + 1;            prev        = point;          }          else          {            point->next = first;            contour_index++;            if ( point + 1 < point_limit )            {              end   = points + source->contours[contour_index];              first = point + 1;              prev  = end;            }          }        }      }      /* set-up the contours array */      {        AH_Point**  contour       = outline->contours;        AH_Point**  contour_limit = contour + outline->num_contours;        short*      end           = source->contours;        short       index         = 0;        for ( ; contour < contour_limit; contour++, end++ )        {          contour[0] = points + index;          index      = end[0] + 1;

⌨️ 快捷键说明

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