示例#1
0
  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
                              FT_UInt         n_points,
                              FT_UInt         n_contours )
  {
    FT_Memory    memory  = loader->memory;
    FT_Error     error   = FT_Err_Ok;
    FT_Outline*  base    = &loader->base.outline;
    FT_Outline*  current = &loader->current.outline;
    FT_Bool      adjust  = 0;

    FT_UInt      new_max, old_max;


    /* check points & tags */
    new_max = base->n_points + current->n_points + n_points;
    old_max = loader->max_points;

    if ( new_max > old_max )
    {
      new_max = FT_PAD_CEIL( new_max, 8 );

      if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
           FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
        goto Exit;

      if ( loader->use_extra &&
           FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) )
        goto Exit;

      adjust = 1;
      loader->max_points = new_max;
    }

    /* check contours */
    old_max = loader->max_contours;
    new_max = base->n_contours + current->n_contours +
              n_contours;
    if ( new_max > old_max )
    {
      new_max = FT_PAD_CEIL( new_max, 4 );
      if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
        goto Exit;

      adjust = 1;
      loader->max_contours = new_max;
    }

    if ( adjust )
      FT_GlyphLoader_Adjust_Points( loader );

  Exit:
    return error;
  }
示例#2
0
  FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,
                                 FT_UInt         n_subs )
  {
    FT_Memory     memory = loader->memory;
    FT_Error      error  = FT_Err_Ok;
    FT_UInt       new_max, old_max;

    FT_GlyphLoad  base    = &loader->base;
    FT_GlyphLoad  current = &loader->current;


    new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
    old_max = loader->max_subglyphs;
    if ( new_max > old_max )
    {
      new_max = FT_PAD_CEIL( new_max, 2 );
      if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )
        goto Exit;

      loader->max_subglyphs = new_max;

      FT_GlyphLoader_Adjust_Subglyphs( loader );
    }

  Exit:
    return error;
  }
示例#3
0
  ps_table_add( PS_Table    table,
                FT_Int      idx,
                void*       object,
                FT_PtrDist  length )
  {
    if ( idx < 0 || idx >= table->max_elems )
    {
      FT_ERROR(( "ps_table_add: invalid index\n" ));
      return PSaux_Err_Invalid_Argument;
    }

    if ( length < 0 )
    {
      FT_ERROR(( "ps_table_add: invalid length\n" ));
      return PSaux_Err_Invalid_Argument;
    }

    /* grow the base block if needed */
    if ( table->cursor + length > table->capacity )
    {
      FT_Error   error;
      FT_Offset  new_size = table->capacity;
      FT_Long    in_offset;


      in_offset = (FT_Long)((FT_Byte*)object - table->block);
      if ( (FT_ULong)in_offset >= table->capacity )
        in_offset = -1;

      while ( new_size < table->cursor + length )
      {
        /* increase size by 25% and round up to the nearest multiple
           of 1024 */
        new_size += ( new_size >> 2 ) + 1;
        new_size  = FT_PAD_CEIL( new_size, 1024 );
      }

      error = reallocate_t1_table( table, new_size );
      if ( error )
        return error;

      if ( in_offset >= 0 )
        object = table->block + in_offset;
    }
示例#4
0
  /* ensure that a table can contain "count" elements */
  static FT_Error
  ps_hint_table_ensure( PS_Hint_Table  table,
                        FT_UInt        count,
                        FT_Memory      memory )
  {
    FT_UInt   old_max = table->max_hints;
    FT_UInt   new_max = count;
    FT_Error  error   = 0;


    if ( new_max > old_max )
    {
      /* try to grow the table */
      new_max = FT_PAD_CEIL( new_max, 8 );
      if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) )
        table->max_hints = new_max;
    }
    return error;
  }
示例#5
0
文件: pfrload.c 项目: ImageMagick/ttf
  pfr_extra_item_load_bitmap_info( FT_Byte*     p,
                                   FT_Byte*     limit,
                                   PFR_PhyFont  phy_font )
  {
    FT_Memory   memory = phy_font->memory;
    PFR_Strike  strike;
    FT_UInt     flags0;
    FT_UInt     n, count, size1;
    FT_Error    error = FT_Err_Ok;


    PFR_CHECK( 5 );

    p     += 3;  /* skip bctSize */
    flags0 = PFR_NEXT_BYTE( p );
    count  = PFR_NEXT_BYTE( p );

    /* re-allocate when needed */
    if ( phy_font->num_strikes + count > phy_font->max_strikes )
    {
      FT_UInt  new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 );


      if ( FT_RENEW_ARRAY( phy_font->strikes,
                           phy_font->num_strikes,
                           new_max ) )
        goto Exit;

      phy_font->max_strikes = new_max;
    }

    size1 = 1 + 1 + 1 + 2 + 2 + 1;
    if ( flags0 & PFR_STRIKE_2BYTE_XPPM )
      size1++;

    if ( flags0 & PFR_STRIKE_2BYTE_YPPM )
      size1++;

    if ( flags0 & PFR_STRIKE_3BYTE_SIZE )
      size1++;

    if ( flags0 & PFR_STRIKE_3BYTE_OFFSET )
      size1++;

    if ( flags0 & PFR_STRIKE_2BYTE_COUNT )
      size1++;

    strike = phy_font->strikes + phy_font->num_strikes;

    PFR_CHECK( count * size1 );

    for ( n = 0; n < count; n++, strike++ )
    {
      strike->x_ppm       = ( flags0 & PFR_STRIKE_2BYTE_XPPM )
                            ? PFR_NEXT_USHORT( p )
                            : PFR_NEXT_BYTE( p );

      strike->y_ppm       = ( flags0 & PFR_STRIKE_2BYTE_YPPM )
                            ? PFR_NEXT_USHORT( p )
                            : PFR_NEXT_BYTE( p );

      strike->flags       = PFR_NEXT_BYTE( p );

      strike->bct_size    = ( flags0 & PFR_STRIKE_3BYTE_SIZE )
                            ? PFR_NEXT_ULONG( p )
                            : PFR_NEXT_USHORT( p );

      strike->bct_offset  = ( flags0 & PFR_STRIKE_3BYTE_OFFSET )
                            ? PFR_NEXT_ULONG( p )
                            : PFR_NEXT_USHORT( p );

      strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT )
                            ? PFR_NEXT_USHORT( p )
                            : PFR_NEXT_BYTE( p );
    }

    phy_font->num_strikes += count;

  Exit:
    return error;

  Too_Short:
    error = FT_THROW( Invalid_Table );
    FT_ERROR(( "pfr_extra_item_load_bitmap_info:"
               " invalid bitmap info table\n" ));
    goto Exit;
  }
示例#6
0
  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
                              FT_UInt         n_points,
                              FT_UInt         n_contours )
  {
    FT_Memory    memory  = loader->memory;
    FT_Error     error   = FT_Err_Ok;
    FT_Outline*  base    = &loader->base.outline;
    FT_Outline*  current = &loader->current.outline;
    FT_Bool      adjust  = 0;

    FT_UInt      new_max, old_max;


    /* check points & tags */
    new_max = base->n_points + current->n_points + n_points;
    old_max = loader->max_points;

    if ( new_max > old_max )
    {
      new_max = FT_PAD_CEIL( new_max, 8 );

      if ( new_max > FT_OUTLINE_POINTS_MAX )
        return FT_Err_Array_Too_Large;

      if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
           FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
        goto Exit;

      if ( loader->use_extra )
      {
        if ( FT_RENEW_ARRAY( loader->base.extra_points,
                             old_max * 2, new_max * 2 ) )
          goto Exit;

        FT_ARRAY_MOVE( loader->base.extra_points + new_max,
                       loader->base.extra_points + old_max,
                       old_max );

        loader->base.extra_points2 = loader->base.extra_points + new_max;
      }

      adjust = 1;
      loader->max_points = new_max;
    }

    /* check contours */
    old_max = loader->max_contours;
    new_max = base->n_contours + current->n_contours +
              n_contours;
    if ( new_max > old_max )
    {
      new_max = FT_PAD_CEIL( new_max, 4 );

      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
        return FT_Err_Array_Too_Large;

      if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
        goto Exit;

      adjust = 1;
      loader->max_contours = new_max;
    }

    if ( adjust )
      FT_GlyphLoader_Adjust_Points( loader );

  Exit:
    return error;
  }
示例#7
0
  /* convert a slot's glyph image into a bitmap */
  static FT_Error
  ft_smooth_render_generic( FT_Renderer       render,
                            FT_GlyphSlot      slot,
                            FT_Render_Mode    mode,
                            const FT_Vector*  origin,
                            FT_Render_Mode    required_mode )
  {
    FT_Error     error;
    FT_Outline*  outline = NULL;
    FT_BBox      cbox;
    FT_UInt      width, height, height_org, width_org, pitch;
    FT_Bitmap*   bitmap;
    FT_Memory    memory;
    FT_Int       hmul = mode == FT_RENDER_MODE_LCD;
    FT_Int       vmul = mode == FT_RENDER_MODE_LCD_V;
    FT_Pos       x_shift, y_shift, x_left, y_top;

    FT_Raster_Params  params;


    /* check glyph image format */
    if ( slot->format != render->glyph_format )
    {
      error = Smooth_Err_Invalid_Argument;
      goto Exit;
    }

    /* check mode */
    if ( mode != required_mode )
      return Smooth_Err_Cannot_Render_Glyph;

    outline = &slot->outline;

    /* translate the outline to the new origin if needed */
    if ( origin )
      FT_Outline_Translate( outline, origin->x, origin->y );

    /* compute the control box, and grid fit it */
    FT_Outline_Get_CBox( outline, &cbox );

    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
    cbox.xMax = FT_PIX_CEIL( cbox.xMax );
    cbox.yMax = FT_PIX_CEIL( cbox.yMax );

    width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
    height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
    bitmap = &slot->bitmap;
    memory = render->root.memory;

    width_org  = width;
    height_org = height;

    /* release old bitmap buffer */
    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    {
      FT_FREE( bitmap->buffer );
      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    }

    /* allocate new one */
    pitch = width;
    if ( hmul )
    {
      width = width * 3;
      pitch = FT_PAD_CEIL( width, 4 );
    }

    if ( vmul )
      height *= 3;

    x_shift = (FT_Int) cbox.xMin;
    y_shift = (FT_Int) cbox.yMin;
    x_left  = (FT_Int)( cbox.xMin >> 6 );
    y_top   = (FT_Int)( cbox.yMax >> 6 );

#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING

    if ( slot->library->lcd_filter_func )
    {
      FT_Int  extra = slot->library->lcd_extra;


      if ( hmul )
      {
        x_shift -= 64 * ( extra >> 1 );
        width   += 3 * extra;
        pitch    = FT_PAD_CEIL( width, 4 );
        x_left  -= extra >> 1;
      }

      if ( vmul )
      {
        y_shift -= 64 * ( extra >> 1 );
        height  += 3 * extra;
        y_top   += extra >> 1;
      }
    }
示例#8
0
  /* convert a slot's glyph image into a bitmap */
  static FT_Error
  ft_smooth_render_generic( FT_Renderer       render,
                            FT_GlyphSlot      slot,
                            FT_Render_Mode    mode,
                            const FT_Vector*  origin,
                            FT_Render_Mode    required_mode,
                            FT_Int            hmul,
                            FT_Int            vmul )
  {
    FT_Error     error;
    FT_Outline*  outline = NULL;
    FT_BBox      cbox;
    FT_UInt      width, height, pitch;
    FT_Bitmap*   bitmap;
    FT_Memory    memory;

    FT_Raster_Params  params;


    /* check glyph image format */
    if ( slot->format != render->glyph_format )
    {
      error = Smooth_Err_Invalid_Argument;
      goto Exit;
    }

    /* check mode */
    if ( mode != required_mode )
      return Smooth_Err_Cannot_Render_Glyph;

    outline = &slot->outline;

    /* translate the outline to the new origin if needed */
    if ( origin )
      FT_Outline_Translate( outline, origin->x, origin->y );

    /* compute the control box, and grid fit it */
    FT_Outline_Get_CBox( outline, &cbox );

    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
    cbox.xMax = FT_PIX_CEIL( cbox.xMax );
    cbox.yMax = FT_PIX_CEIL( cbox.yMax );

    width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
    height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
    bitmap = &slot->bitmap;
    memory = render->root.memory;

    /* release old bitmap buffer */
    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    {
      FT_FREE( bitmap->buffer );
      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    }

    /* allocate new one, depends on pixel format */
    pitch = width;
    if ( hmul )
    {
      width = width * hmul;
      pitch = FT_PAD_CEIL( width, 4 );
    }

    if ( vmul )
      height *= vmul;

    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
    bitmap->num_grays  = 256;
    bitmap->width      = width;
    bitmap->rows       = height;
    bitmap->pitch      = pitch;

    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
      goto Exit;

    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;

    /* translate outline to render it into the bitmap */
    FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );

    /* set up parameters */
    params.target = bitmap;
    params.source = outline;
    params.flags  = FT_RASTER_FLAG_AA;

    /* implode outline if needed */
    {
      FT_Int      n;
      FT_Vector*  vec;


      if ( hmul )
        for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
          vec->x *= hmul;

      if ( vmul )
        for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
          vec->y *= vmul;
    }

    /* render outline into the bitmap */
    error = render->raster_render( render->raster, &params );

    /* deflate outline if needed */
    {
      FT_Int      n;
      FT_Vector*  vec;


      if ( hmul )
        for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
          vec->x /= hmul;

      if ( vmul )
        for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ )
          vec->y /= vmul;
    }

    FT_Outline_Translate( outline, cbox.xMin, cbox.yMin );

    if ( error )
      goto Exit;

    slot->format      = FT_GLYPH_FORMAT_BITMAP;
    slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 );
    slot->bitmap_top  = (FT_Int)( cbox.yMax >> 6 );

  Exit:
    if ( outline && origin )
      FT_Outline_Translate( outline, -origin->x, -origin->y );

    return error;
  }
示例#9
0
  ah_outline_load( AH_Outline  outline,
                   FT_Fixed    x_scale,
                   FT_Fixed    y_scale,
                   FT_Face     face )
  {
    FT_Memory    memory       = outline->memory;
    FT_Error     error        = AH_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 AH_Err_Invalid_Argument;

    /* first of all, reallocate the contours array if necessary */
    if ( num_contours > outline->max_contours )
    {
      FT_Int  new_contours = FT_PAD_CEIL( num_contours, 4 );


      if ( FT_RENEW_ARRAY( outline->contours,
                           outline->max_contours,
                           new_contours ) )
        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 = FT_PAD_CEIL( num_points + 2, 8 );
      FT_Int  max  = outline->max_points;


      if ( FT_RENEW_ARRAY( outline->points,        max,     news     ) ||
           FT_RENEW_ARRAY( outline->horz_edges,    max * 2, news * 2 ) ||
           FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) )
        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;

    /* 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;
    }

    outline->x_scale = x_scale;
    outline->y_scale = 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;


        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_FLAG_CONIC;
            break;
          case FT_CURVE_TAG_CUBIC:
            point->flags = AH_FLAG_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      idx           = 0;


        for ( ; contour < contour_limit; contour++, end++ )
        {
          contour[0] = points + idx;
          idx        = (short)( end[0] + 1 );
        }
      }

      /* compute directions of in & out vectors */
      {
        for ( point = points; point < point_limit; point++ )
        {
          AH_Point   prev;
          AH_Point   next;
          FT_Vector  ivec, ovec;


          prev   = point->prev;
          ivec.x = point->fx - prev->fx;
          ivec.y = point->fy - prev->fy;

          point->in_dir = ah_compute_direction( ivec.x, ivec.y );

          next   = point->next;
          ovec.x = next->fx - point->fx;
          ovec.y = next->fy - point->fy;

          point->out_dir = ah_compute_direction( ovec.x, ovec.y );

#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
          if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
          {
          Is_Weak_Point:
            point->flags |= AH_FLAG_WEAK_INTERPOLATION;
          }
          else if ( point->out_dir == point->in_dir )
          {
            AH_Angle  angle_in, angle_out, delta;


            if ( point->out_dir != AH_DIR_NONE )
              goto Is_Weak_Point;

            angle_in  = ah_angle( &ivec );
            angle_out = ah_angle( &ovec );
            delta     = angle_in - angle_out;

            if ( delta > AH_PI )
              delta = AH_2PI - delta;

            if ( delta < 0 )
              delta = -delta;

            if ( delta < 2 )
              goto Is_Weak_Point;
          }
          else if ( point->in_dir == -point->out_dir )
            goto Is_Weak_Point;
#endif
        }
      }
    }

  Exit:
    return error;
  }