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

📄 pshalgo1.c

📁 一个Xpdf应用的例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//*  pshalgo1.c                                                             *//*                                                                         *//*    PostScript hinting algorithm 1 (body).                               *//*                                                                         *//*  Copyright 2001 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_OBJECTS_H#include FT_INTERNAL_DEBUG_H#include "pshalgo1.h"#undef  FT_COMPONENT#define FT_COMPONENT  trace_pshalgo1#ifdef DEBUG_HINTER  extern PSH1_Hint_Table  ps1_debug_hint_table = 0;  extern PSH1_HintFunc    ps1_debug_hint_func  = 0;#endif /************************************************************************/ /************************************************************************/ /*****                                                              *****/ /*****                 BASIC HINTS RECORDINGS                       *****/ /*****                                                              *****/ /************************************************************************/ /************************************************************************/  /* return true iff two stem hints overlap */  static FT_Int  psh1_hint_overlap( PSH1_Hint  hint1,                     PSH1_Hint  hint2 )  {    return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&             hint2->org_pos + hint2->org_len >= hint1->org_pos );  }  /* destroy hints table */  static void  psh1_hint_table_done( PSH1_Hint_Table  table,                        FT_Memory        memory )  {    FREE( table->zones );    table->num_zones = 0;    table->zone      = 0;    FREE( table->sort );    FREE( table->hints );    table->num_hints   = 0;    table->max_hints   = 0;    table->sort_global = 0;  }  /* deactivate all hints in a table */  static void  psh1_hint_table_deactivate( PSH1_Hint_Table  table )  {    FT_UInt    count = table->max_hints;    PSH1_Hint  hint  = table->hints;    for ( ; count > 0; count--, hint++ )    {      psh1_hint_deactivate( hint );      hint->order = -1;    }  }  /* internal function used to record a new hint */  static void  psh1_hint_table_record( PSH1_Hint_Table  table,                          FT_UInt          index )  {    PSH1_Hint  hint = table->hints + index;    if ( index >= table->max_hints )    {      FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));      return;    }    /* ignore active hints */    if ( psh1_hint_is_active( hint ) )      return;    psh1_hint_activate( hint );    /* now scan the current active hint set in order to determine */    /* if we are overlapping with another segment                 */    {      PSH1_Hint*  sorted = table->sort_global;      FT_UInt     count  = table->num_hints;      PSH1_Hint   hint2;      hint->parent = 0;      for ( ; count > 0; count--, sorted++ )      {        hint2 = sorted[0];        if ( psh1_hint_overlap( hint, hint2 ) )        {          hint->parent = hint2;          break;        }      }    }    if ( table->num_hints < table->max_hints )      table->sort_global[table->num_hints++] = hint;    else      FT_ERROR(( "%s.activate: too many sorted hints!  BUG!\n",                 "ps.fitter" ));  }  static void  psh1_hint_table_record_mask( PSH1_Hint_Table  table,                               PS_Mask          hint_mask )  {    FT_Int    mask = 0, val = 0;    FT_Byte*  cursor = hint_mask->bytes;    FT_UInt   index, limit;    limit = hint_mask->num_bits;    if ( limit != table->max_hints )      FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n",                 "ps.fitter", hint_mask->num_bits, table->max_hints ));    for ( index = 0; index < limit; index++ )    {      if ( mask == 0 )      {        val  = *cursor++;        mask = 0x80;      }      if ( val & mask )        psh1_hint_table_record( table, index );      mask >>= 1;    }  }  /* create hints table */  static FT_Error  psh1_hint_table_init( PSH1_Hint_Table  table,                        PS_Hint_Table    hints,                        PS_Mask_Table    hint_masks,                        PS_Mask_Table    counter_masks,                        FT_Memory        memory )  {    FT_UInt   count = hints->num_hints;    FT_Error  error;    FT_UNUSED( counter_masks );    /* allocate our tables */    if ( ALLOC_ARRAY( table->sort,  2 * count,     PSH1_Hint    ) ||         ALLOC_ARRAY( table->hints,     count,     PSH1_HintRec ) ||         ALLOC_ARRAY( table->zones, 2 * count + 1, PSH1_ZoneRec ) )      goto Exit;    table->max_hints   = count;    table->sort_global = table->sort + count;    table->num_hints   = 0;    table->num_zones   = 0;    table->zone        = 0;    /* now, initialize the "hints" array */    {      PSH1_Hint  write = table->hints;      PS_Hint    read  = hints->hints;      for ( ; count > 0; count--, write++, read++ )      {        write->org_pos = read->pos;        write->org_len = read->len;        write->flags   = read->flags;      }    }    /* we now need to determine the initial "parent" stems; first  */    /* activate the hints that are given by the initial hint masks */    if ( hint_masks )    {      FT_UInt  Count = hint_masks->num_masks;      PS_Mask  Mask  = hint_masks->masks;      table->hint_masks = hint_masks;      for ( ; Count > 0; Count--, Mask++ )        psh1_hint_table_record_mask( table, Mask );    }    /* now, do a linear parse in case some hints were left alone */    if ( table->num_hints != table->max_hints )    {      FT_UInt   Index, Count;      FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" ));      Count = table->max_hints;      for ( Index = 0; Index < Count; Index++ )        psh1_hint_table_record( table, Index );    }  Exit:    return error;  }  static void  psh1_hint_table_activate_mask( PSH1_Hint_Table  table,                                 PS_Mask          hint_mask )  {    FT_Int    mask = 0, val = 0;    FT_Byte*  cursor = hint_mask->bytes;    FT_UInt   index, limit, count;    limit = hint_mask->num_bits;    count = 0;    psh1_hint_table_deactivate( table );    for ( index = 0; index < limit; index++ )    {      if ( mask == 0 )      {        val  = *cursor++;        mask = 0x80;      }      if ( val & mask )      {        PSH1_Hint  hint = &table->hints[index];        if ( !psh1_hint_is_active( hint ) )        {          PSH1_Hint*  sort = table->sort;          FT_UInt     count2;          PSH1_Hint   hint2;          for ( count2 = count; count2 > 0; count2--, sort++ )          {            hint2 = sort[0];            if ( psh1_hint_overlap( hint, hint2 ) )            {              FT_ERROR(( "%s.activate_mask: found overlapping hints\n",                         "psf.hint" ));              break;            }          }          if ( count2 == 0 )          {            psh1_hint_activate( hint );            if ( count < table->max_hints )              table->sort[count++] = hint;            else              FT_ERROR(( "%s.activate_mask: too many active hints\n",                         "psf.hint" ));          }        }      }      mask >>= 1;    }    table->num_hints = count;    /* now, sort the hints; they are guaranteed to not overlap */    /* so we can compare their "org_pos" field directly        */    {      FT_Int      i1, i2;      PSH1_Hint   hint1, hint2;      PSH1_Hint*  sort = table->sort;      /* a simple bubble sort will do, since in 99% of cases, the hints */      /* will be already sorted; and the sort will be linear            */      for ( i1 = 1; i1 < (FT_Int)count; i1++ )      {        hint1 = sort[i1];        for ( i2 = i1 - 1; i2 >= 0; i2-- )        {          hint2 = sort[i2];          if ( hint2->org_pos < hint1->org_pos )            break;          sort[i2 + 1] = hint2;          sort[i2]     = hint1;        }      }    }  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****               HINTS GRID-FITTING AND OPTIMIZATION             *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/#ifdef DEBUG_HINTER  void  ps_simple_scale( PSH1_Hint_Table  table,                   FT_Fixed         scale,                   FT_Fixed         delta,                   FT_Int           vertical )  {    PSH1_Hint  hint;    FT_UInt    count;    for ( count = 0; count < table->num_hints; count++ )    {      hint = table->sort[count];      if ( psh1_hint_is_active( hint ) )      {        hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;        hint->cur_len = FT_MulFix( hint->org_len, scale );        if ( ps1_debug_hint_func )          ps1_debug_hint_func( hint, vertical );      }    }  }#endif  FT_LOCAL_DEF  FT_Error  psh1_hint_table_optimize( PSH1_Hint_Table  table,                            PSH_Globals      globals,                            FT_Outline*      outline,                            FT_Int           vertical )  {    PSH_Dimension  dim   = &globals->dimension[vertical];    FT_Fixed       scale = dim->scale_mult;    FT_Fixed       delta = dim->scale_delta;    FT_UNUSED( outline );#ifdef DEBUG_HINTER    if ( ps_debug_no_vert_hints && vertical )    {      ps_simple_scale( table, scale, delta, vertical );      return 0;    }    if ( ps_debug_no_horz_hints && !vertical )    {      ps_simple_scale( table, scale, delta, vertical );      return 0;    }#endif    /* XXXX: for now, we only scale the hints to test all other aspects */    /*       of the PostScript hinter                                   */    {      PSH1_Hint  hint;      FT_UInt   count;

⌨️ 快捷键说明

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