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

📄 pshrec.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
                       FT_Memory      memory )
  {
    FT_UInt   temp;
    FT_Error  error = 0;


    /* swap index1 and index2 so that index1 < index2 */
    if ( index1 > index2 )
    {
      temp   = index1;
      index1 = index2;
      index2 = temp;
    }

    if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks )
    {
      /* we need to merge the bitsets of index1 and index2 with a */
      /* simple union                                             */
      PS_Mask  mask1  = table->masks + index1;
      PS_Mask  mask2  = table->masks + index2;
      FT_UInt  count1 = mask1->num_bits;
      FT_UInt  count2 = mask2->num_bits;
      FT_Int   delta;


      if ( count2 > 0 )
      {
        FT_UInt   pos;
        FT_Byte*  read;
        FT_Byte*  write;


        /* if "count2" is greater than "count1", we need to grow the */
        /* first bitset, and clear the highest bits                  */
        if ( count2 > count1 )
        {
          error = ps_mask_ensure( mask1, count2, memory );
          if ( error )
            goto Exit;

          for ( pos = count1; pos < count2; pos++ )
            ps_mask_clear_bit( mask1, pos );
        }

        /* merge (unite) the bitsets */
        read  = mask2->bytes;
        write = mask1->bytes;
        pos   = (FT_UInt)( ( count2 + 7 ) >> 3 );

        for ( ; pos > 0; pos-- )
        {
          write[0] = (FT_Byte)( write[0] | read[0] );
          write++;
          read++;
        }
      }

      /* Now, remove "mask2" from the list.  We need to keep the masks */
      /* sorted in order of importance, so move table elements.        */
      mask2->num_bits  = 0;
      mask2->end_point = 0;

      delta = table->num_masks - 1 - index2; /* number of masks to move */
      if ( delta > 0 )
      {
        /* move to end of table for reuse */
        PS_MaskRec  dummy = *mask2;


        ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) );

        mask2[delta] = dummy;
      }

      table->num_masks--;
    }
    else
      FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n",
                 index1, index2 ));

  Exit:
    return error;
  }


  /* Try to merge all masks in a given table.  This is used to merge */
  /* all counter masks into independent counter "paths".             */
  /*                                                                 */
  static FT_Error
  ps_mask_table_merge_all( PS_Mask_Table  table,
                           FT_Memory      memory )
  {
    FT_Int    index1, index2;
    FT_Error  error = 0;


    for ( index1 = table->num_masks - 1; index1 > 0; index1-- )
    {
      for ( index2 = index1 - 1; index2 >= 0; index2-- )
      {
        if ( ps_mask_table_test_intersect( table, index1, index2 ) )
        {
          error = ps_mask_table_merge( table, index2, index1, memory );
          if ( error )
            goto Exit;

          break;
        }
      }
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                    PS_DIMENSION MANAGEMENT                    *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  /* finalize a given dimension */
  static void
  ps_dimension_done( PS_Dimension  dimension,
                     FT_Memory     memory )
  {
    ps_mask_table_done( &dimension->counters, memory );
    ps_mask_table_done( &dimension->masks,    memory );
    ps_hint_table_done( &dimension->hints,    memory );
  }


  /* initialize a given dimension */
  static void
  ps_dimension_init( PS_Dimension  dimension )
  {
    dimension->hints.num_hints    = 0;
    dimension->masks.num_masks    = 0;
    dimension->counters.num_masks = 0;
  }


#if 0

  /* set a bit at a given index in the current hint mask */
  static FT_Error
  ps_dimension_set_mask_bit( PS_Dimension  dim,
                             FT_UInt       idx,
                             FT_Memory     memory )
  {
    PS_Mask  mask;
    FT_Error  error = 0;


    /* get last hint mask */
    error = ps_mask_table_last( &dim->masks, memory, &mask );
    if ( error )
      goto Exit;

    error = ps_mask_set_bit( mask, idx, memory );

  Exit:
    return error;
  }

#endif

  /* set the end point in a mask, called from "End" & "Reset" methods */
  static void
  ps_dimension_end_mask( PS_Dimension  dim,
                         FT_UInt       end_point )
  {
    FT_UInt  count = dim->masks.num_masks;
    PS_Mask  mask;


    if ( count > 0 )
    {
      mask            = dim->masks.masks + count - 1;
      mask->end_point = end_point;
    }
  }


  /* set the end point in the current mask, then create a new empty one */
  /* (called by "Reset" method)                                         */
  static FT_Error
  ps_dimension_reset_mask( PS_Dimension  dim,
                           FT_UInt       end_point,
                           FT_Memory     memory )
  {
    PS_Mask  mask;


    /* end current mask */
    ps_dimension_end_mask( dim, end_point );

    /* allocate new one */
    return ps_mask_table_alloc( &dim->masks, memory, &mask );
  }


  /* set a new mask, called from the "T2Stem" method */
  static FT_Error
  ps_dimension_set_mask_bits( PS_Dimension    dim,
                              const FT_Byte*  source,
                              FT_UInt         source_pos,
                              FT_UInt         source_bits,
                              FT_UInt         end_point,
                              FT_Memory       memory )
  {
    FT_Error  error = 0;


    /* reset current mask, if any */
    error = ps_dimension_reset_mask( dim, end_point, memory );
    if ( error )
      goto Exit;

    /* set bits in new mask */
    error = ps_mask_table_set_bits( &dim->masks, (FT_Byte*)source,
                                    source_pos, source_bits, memory );

  Exit:
    return error;
  }


  /* add a new single stem (called from "T1Stem" method) */
  static FT_Error
  ps_dimension_add_t1stem( PS_Dimension  dim,
                           FT_Int        pos,
                           FT_Int        len,
                           FT_Memory     memory,
                           FT_Int       *aindex )
  {
    FT_Error  error = 0;
    FT_UInt   flags = 0;


    /* detect ghost stem */
    if ( len < 0 )
    {
      flags |= PS_HINT_FLAG_GHOST;
      if ( len == -21 )
      {
        flags |= PS_HINT_FLAG_BOTTOM;
        pos   += len;
      }
      len = 0;
    }

    if ( aindex )
      *aindex = -1;

    /* now, lookup stem in the current hints table */
    {
      PS_Mask  mask;
      FT_UInt  idx;
      FT_UInt  max   = dim->hints.num_hints;
      PS_Hint  hint  = dim->hints.hints;


      for ( idx = 0; idx < max; idx++, hint++ )
      {
        if ( hint->pos == pos && hint->len == len )
          break;
      }

      /* we need to create a new hint in the table */
      if ( idx >= max )
      {
        error = ps_hint_table_alloc( &dim->hints, memory, &hint );
        if ( error )
          goto Exit;

        hint->pos   = pos;
        hint->len   = len;
        hint->flags = flags;
      }

      /* now, store the hint in the current mask */
      error = ps_mask_table_last( &dim->masks, memory, &mask );
      if ( error )
        goto Exit;

      error = ps_mask_set_bit( mask, idx, memory );
      if ( error )
        goto Exit;

      if ( aindex )
        *aindex = (FT_Int)idx;
    }

  Exit:
    return error;
  }


  /* add a "hstem3/vstem3" counter to our dimension table */
  static FT_Error
  ps_dimension_add_counter( PS_Dimension  dim,
                            FT_Int        hint1,
                            FT_Int        hint2,
                            FT_Int        hint3,
                            FT_Memory     memory )
  {
    FT_Error  error   = 0;
    FT_UInt   count   = dim->counters.num_masks;
    PS_Mask   counter = dim->counters.masks;


    /* try to find an existing counter mask that already uses */
    /* one of these stems here                                */
    for ( ; count > 0; count--, counter++ )
    {
      if ( ps_mask_test_bit( counter, hint1 ) ||
           ps_mask_test_bit( counter, hint2 ) ||
           ps_mask_test_bit( counter, hint3 ) )
        break;
    }

    /* creat a new counter when needed */
    if ( count == 0 )
    {
      error = ps_mask_table_alloc( &dim->counters, memory, &counter );
      if ( error )
        goto Exit;
    }

    /* now, set the bits for our hints in the counter mask */
    error = ps_mask_set_bit( counter, hint1, memory );
    if ( error )
      goto Exit;

    error = ps_mask_set_bit( counter, hint2, memory );
    if ( error )
      goto Exit;

    error = ps_mask_set_bit( counter, hint3, memory );
    if ( error )
      goto Exit;

  Exit:
    return error;
  }


  /* end of recording session for a given dimension */
  static FT_Error
  ps_dimension_end( PS_Dimension  dim,
                    FT_UInt       end_point,
                    FT_Memory     memory )
  {
    /* end hint mask table */
    ps_dimension_end_mask( dim, end_point );

    /* merge all counter masks into independent "paths" */
    return ps_mask_table_merge_all( &dim->counters, memory );
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                    PS_RECORDER MANAGEMENT                     *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  /* destroy hints */
  FT_LOCAL( void )
  ps_hints_done( PS_Hints  hints )
  {
    FT_Memory  memory = hints->memory;


    ps_dimension_done( &hints->dimension[0], memory );
    ps_dimension_done( &hints->dimension[1], memory );

    hints->error  = 0;
    hints->memory = 0;
  }


  FT_LOCAL( FT_Error )
  ps_hints_init( PS_Hints   hints,
                 FT_Memory  memory )
  {
    FT_MEM_ZERO( hints, sizeof ( *hints ) );
    hints->memory = memory;
    return 0;
  }


  /* initialize a hints for a new session */
  static void
  ps_hints_open( PS_Hints      hints,
                 PS_Hint_Type  hint_type )
  {
    switch ( hint_type )

⌨️ 快捷键说明

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