Example #1
0
tt_glyphzone_new( FT_Memory     memory,
                  FT_UShort     maxPoints,
                  FT_Short      maxContours,
                  TT_GlyphZone  zone )
{
    FT_Error  error;


    FT_MEM_ZERO( zone, sizeof ( *zone ) );
    zone->memory = memory;

    if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||
            FT_NEW_ARRAY( zone->cur,      maxPoints   ) ||
            FT_NEW_ARRAY( zone->orus,     maxPoints   ) ||
            FT_NEW_ARRAY( zone->tags,     maxPoints   ) ||
            FT_NEW_ARRAY( zone->contours, maxContours ) )
    {
        tt_glyphzone_done( zone );
    }
    else
    {
        zone->max_points   = maxPoints;
        zone->max_contours = maxContours;
    }

    return error;
}
Example #2
0
File: ftutil.c Project: 8l/inferno
  FT_Alloc( FT_Memory  memory,
            FT_Long    size,
            void*     *P )
  {
    FT_ASSERT( P != 0 );

    if ( size > 0 )
    {
      *P = memory->alloc( memory, size );
      if ( !*P )
      {
        FT_ERROR(( "FT_Alloc:" ));
        FT_ERROR(( " Out of memory? (%ld requested)\n",
                   size ));

        return FT_Err_Out_Of_Memory;
      }
      FT_MEM_ZERO( *P, size );
    }
    else
      *P = NULL;

    FT_TRACE7(( "FT_Alloc:" ));
    FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
                size, *P, P ));

    return FT_Err_Ok;
  }
Example #3
0
/* return the glyph's control box */
static void
ft_raster1_get_cbox( FT_Renderer   render,
                     FT_GlyphSlot  slot,
                     FT_BBox*      cbox )
{
    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );

    if ( slot->format == render->glyph_format )
        FT_Outline_Get_CBox( &slot->outline, cbox );
}
Example #4
0
  ft_mem_alloc( FT_Memory  memory,
                FT_Long    size,
                FT_Error  *p_error )
  {
    FT_Error    error;
    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );

    if ( !error && size > 0 )
      FT_MEM_ZERO( block, size );

    *p_error = error;
    return block;
  }
Example #5
0
  t42_loader_init( T42_Loader  loader,
                   T42_Face    face )
  {
    FT_UNUSED( face );

    FT_MEM_ZERO( loader, sizeof ( *loader ) );
    loader->num_glyphs = 0;
    loader->num_chars  = 0;

    /* initialize the tables -- simply set their `init' field to 0 */
    loader->encoding_table.init = 0;
    loader->charstrings.init    = 0;
    loader->glyph_names.init    = 0;
  }
Example #6
0
  static void
  cf2_outline_init( CF2_Outline  outline,
                    FT_Memory    memory,
                    FT_Error*    error )
  {
    FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );

    outline->root.memory = memory;
    outline->root.error  = error;

    outline->root.moveTo = cf2_builder_moveTo;
    outline->root.lineTo = cf2_builder_lineTo;
    outline->root.cubeTo = cf2_builder_cubeTo;
  }
Example #7
0
static FT_MemTable
ft_mem_table_new( FT_Memory  memory )
{
    FT_MemTable  table;


    table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
    if ( table == NULL )
        goto Exit;

    FT_MEM_ZERO( table, sizeof ( *table ) );

    table->size  = FT_MEM_SIZE_MIN;
    table->nodes = 0;

    table->memory = memory;

    table->memory_user = memory->user;

    table->alloc   = memory->alloc;
    table->realloc = memory->realloc;
    table->free    = memory->free;

    table->buckets = (FT_MemNode *)
                     memory->alloc( memory,
                                    table->size * sizeof ( FT_MemNode ) );
    if ( table->buckets )
        FT_MEM_ZERO( table->buckets, sizeof ( FT_MemNode ) * table->size );
    else
    {
        memory->free( memory, table );
        table = NULL;
    }

Exit:
    return table;
}
Example #8
0
static void
ft_mem_table_resize( FT_MemTable  table )
{
    FT_ULong  new_size;


    new_size = ft_mem_closest_prime( table->nodes );
    if ( new_size != table->size )
    {
        FT_MemNode*  new_buckets ;
        FT_ULong     i;


        new_buckets = (FT_MemNode *)
                      ft_mem_table_alloc( table,
                                          new_size * sizeof ( FT_MemNode ) );
        if ( new_buckets == NULL )
            return;

        FT_MEM_ZERO( new_buckets, sizeof ( FT_MemNode ) * new_size );

        for ( i = 0; i < table->size; i++ )
        {
            FT_MemNode  node, next, *pnode;
            FT_ULong    hash;


            node = table->buckets[i];
            while ( node )
            {
                next  = node->link;
                hash  = FT_MEM_VAL( node->address ) % new_size;
                pnode = new_buckets + hash;

                node->link = pnode[0];
                pnode[0]   = node;

                node = next;
            }
        }

        if ( table->buckets )
            ft_mem_table_free( table, table->buckets );

        table->buckets = new_buckets;
        table->size    = new_size;
    }
}
Example #9
0
  static void
  cff_index_done( CFF_Index  idx )
  {
    if ( idx->stream )
    {
      FT_Stream  stream = idx->stream;
      FT_Memory  memory = stream->memory;


      if ( idx->bytes )
        FT_FRAME_RELEASE( idx->bytes );

      FT_FREE( idx->offsets );
      FT_MEM_ZERO( idx, sizeof ( *idx ) );
    }
  }
Example #10
0
  static void
  cff_make_private_dict( CFF_SubFont  subfont,
                         PS_Private   priv )
  {
    CFF_Private  cpriv = &subfont->private_dict;
    FT_UInt      n, count;


    FT_MEM_ZERO( priv, sizeof ( *priv ) );

    count = priv->num_blue_values = cpriv->num_blue_values;
    for ( n = 0; n < count; n++ )
      priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];

    count = priv->num_other_blues = cpriv->num_other_blues;
    for ( n = 0; n < count; n++ )
      priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];

    count = priv->num_family_blues = cpriv->num_family_blues;
    for ( n = 0; n < count; n++ )
      priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];

    count = priv->num_family_other_blues = cpriv->num_family_other_blues;
    for ( n = 0; n < count; n++ )
      priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];

    priv->blue_scale = cpriv->blue_scale;
    priv->blue_shift = (FT_Int)cpriv->blue_shift;
    priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;

    priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;
    priv->standard_height[0] = (FT_UShort)cpriv->standard_height;

    count = priv->num_snap_widths = cpriv->num_snap_widths;
    for ( n = 0; n < count; n++ )
      priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];

    count = priv->num_snap_heights = cpriv->num_snap_heights;
    for ( n = 0; n < count; n++ )
      priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];

    priv->force_bold     = cpriv->force_bold;
    priv->language_group = cpriv->language_group;
    priv->lenIV          = cpriv->lenIV;
  }
Example #11
0
  ft_mem_realloc( FT_Memory  memory,
                  FT_Long    item_size,
                  FT_Long    cur_count,
                  FT_Long    new_count,
                  void*      block,
                  FT_Error  *p_error )
  {
    FT_Error  error = FT_Err_Ok;

    block = ft_mem_qrealloc( memory, item_size,
                             cur_count, new_count, block, &error );
    if ( !error && new_count > cur_count )
      FT_MEM_ZERO( (char*)block + cur_count * item_size,
                   ( new_count - cur_count ) * item_size );

    *p_error = error;
    return block;
  }
Example #12
0
  ft_mem_realloc( FT_Memory  memory,
                  FT_Long    item_size,
                  FT_Long    cur_count,
                  FT_Long    new_count,
                  void*      block,
                  FT_Error  *p_error )
  {
    FT_Error  error = FT_Err_Ok;

    block = ft_mem_qrealloc( memory, item_size,
                             cur_count, new_count, block, &error );
    //if ( !error && new_count > cur_count )
    if ( !error && (FT_ULong)new_count > (FT_ULong)cur_count ) /* cast to ulong because otherwise the compiler may warn that it's assuming signed integers can't overflow. */
      FT_MEM_ZERO( (char*)block + cur_count * item_size,
                   ( new_count - cur_count ) * item_size );

    *p_error = error;
    return block;
  }
Example #13
0
  t1_decoder_init( T1_Decoder           decoder,
                   FT_Face              face,
                   FT_Size              size,
                   FT_GlyphSlot         slot,
                   FT_Byte**            glyph_names,
                   PS_Blend             blend,
                   FT_Bool              hinting,
                   FT_Render_Mode       hint_mode,
                   T1_Decoder_Callback  parse_callback )
  {
    FT_MEM_ZERO( decoder, sizeof ( *decoder ) );

    /* retrieve PSNames interface from list of current modules */
    {
      FT_Service_PsCMaps  psnames = 0;


      FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
      if ( !psnames )
      {
        FT_ERROR(( "t1_decoder_init: " ));
        FT_ERROR(( "the `psnames' module is not available\n" ));
        return PSaux_Err_Unimplemented_Feature;
      }

      decoder->psnames = psnames;
    }

    t1_builder_init( &decoder->builder, face, size, slot, hinting );

    decoder->num_glyphs     = (FT_UInt)face->num_glyphs;
    decoder->glyph_names    = glyph_names;
    decoder->hint_mode      = hint_mode;
    decoder->blend          = blend;
    decoder->parse_callback = parse_callback;

    decoder->funcs          = t1_decoder_funcs;

    return 0;
  }
Example #14
0
File: ftutil.c Project: 8l/inferno
  FT_Realloc( FT_Memory  memory,
              FT_Long    current,
              FT_Long    size,
              void**     P )
  {
    void*  Q;


    FT_ASSERT( P != 0 );

    /* if the original pointer is NULL, call FT_Alloc() */
    if ( !*P )
      return FT_Alloc( memory, size, P );

    /* if the new block if zero-sized, clear the current one */
    if ( size <= 0 )
    {
      FT_Free( memory, P );
      return FT_Err_Ok;
    }

    Q = memory->realloc( memory, current, size, *P );
    if ( !Q )
      goto Fail;

    if ( size > current )
      FT_MEM_ZERO( (char*)Q + current, size - current );

    *P = Q;
    return FT_Err_Ok;

  Fail:
    FT_ERROR(( "FT_Realloc:" ));
    FT_ERROR(( " Failed (current %ld, requested %ld)\n",
               current, size ));
    return FT_Err_Out_Of_Memory;
  }
Example #15
0
  static FT_Error
  ft_bitmap_assure_buffer( FT_Memory   memory,
                           FT_Bitmap*  bitmap,
                           FT_UInt     xpixels,
                           FT_UInt     ypixels )
  {
    FT_Error        error;
    int             pitch;
    int             new_pitch;
    FT_UInt         bpp;
    FT_Int          i, width, height;
    unsigned char*  buffer = NULL;


    width  = bitmap->width;
    height = bitmap->rows;
    pitch  = bitmap->pitch;
    if ( pitch < 0 )
      pitch = -pitch;

    switch ( bitmap->pixel_mode )
    {
    case FT_PIXEL_MODE_MONO:
      bpp       = 1;
      new_pitch = ( width + xpixels + 7 ) >> 3;
      break;
    case FT_PIXEL_MODE_GRAY2:
      bpp       = 2;
      new_pitch = ( width + xpixels + 3 ) >> 2;
      break;
    case FT_PIXEL_MODE_GRAY4:
      bpp       = 4;
      new_pitch = ( width + xpixels + 1 ) >> 1;
      break;
    case FT_PIXEL_MODE_GRAY:
    case FT_PIXEL_MODE_LCD:
    case FT_PIXEL_MODE_LCD_V:
      bpp       = 8;
      new_pitch = ( width + xpixels );
      break;
    default:
      return FT_THROW( Invalid_Glyph_Format );
    }

    /* if no need to allocate memory */
    if ( ypixels == 0 && new_pitch <= pitch )
    {
      /* zero the padding */
      FT_Int  bit_width = pitch * 8;
      FT_Int  bit_last  = ( width + xpixels ) * bpp;


      if ( bit_last < bit_width )
      {
        FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );
        FT_Byte*  end   = bitmap->buffer + pitch;
        FT_Int    shift = bit_last & 7;
        FT_UInt   mask  = 0xFF00U >> shift;
        FT_Int    count = height;


        for ( ; count > 0; count--, line += pitch, end += pitch )
        {
          FT_Byte*  write = line;


          if ( shift > 0 )
          {
            write[0] = (FT_Byte)( write[0] & mask );
            write++;
          }
          if ( write < end )
            FT_MEM_ZERO( write, end-write );
        }
      }
Example #16
0
  tt_face_colr_blend_layer( TT_Face       face,
                            FT_UInt       color_index,
                            FT_GlyphSlot  dstSlot,
                            FT_GlyphSlot  srcSlot )
  {
    FT_Error  error;

    FT_UInt  x, y;
    FT_Byte  b, g, r, alpha;

    FT_ULong  size;
    FT_Byte*  src;
    FT_Byte*  dst;


    if ( !dstSlot->bitmap.buffer )
    {
      /* Initialize destination of color bitmap */
      /* with the size of first component.      */
      dstSlot->bitmap_left = srcSlot->bitmap_left;
      dstSlot->bitmap_top  = srcSlot->bitmap_top;

      dstSlot->bitmap.width      = srcSlot->bitmap.width;
      dstSlot->bitmap.rows       = srcSlot->bitmap.rows;
      dstSlot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
      dstSlot->bitmap.pitch      = (int)dstSlot->bitmap.width * 4;
      dstSlot->bitmap.num_grays  = 256;

      size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch;

      error = ft_glyphslot_alloc_bitmap( dstSlot, size );
      if ( error )
        return error;

      FT_MEM_ZERO( dstSlot->bitmap.buffer, size );
    }
    else
    {
      /* Resize destination if needed such that new component fits. */
      FT_Int  x_min, x_max, y_min, y_max;


      x_min = FT_MIN( dstSlot->bitmap_left, srcSlot->bitmap_left );
      x_max = FT_MAX( dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width,
                      srcSlot->bitmap_left + (FT_Int)srcSlot->bitmap.width );

      y_min = FT_MIN( dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows,
                      srcSlot->bitmap_top - (FT_Int)srcSlot->bitmap.rows );
      y_max = FT_MAX( dstSlot->bitmap_top, srcSlot->bitmap_top );

      if ( x_min != dstSlot->bitmap_left                                 ||
           x_max != dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width ||
           y_min != dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows   ||
           y_max != dstSlot->bitmap_top                                  )
      {
        FT_Memory  memory = face->root.memory;

        FT_UInt  width = (FT_UInt)( x_max - x_min );
        FT_UInt  rows  = (FT_UInt)( y_max - y_min );
        FT_UInt  pitch = width * 4;

        FT_Byte*  buf = NULL;
        FT_Byte*  p;
        FT_Byte*  q;


        size  = rows * pitch;
        if ( FT_ALLOC( buf, size ) )
          return error;

        p = dstSlot->bitmap.buffer;
        q = buf +
            (int)pitch * ( y_max - dstSlot->bitmap_top ) +
            4 * ( dstSlot->bitmap_left - x_min );

        for ( y = 0; y < dstSlot->bitmap.rows; y++ )
        {
          FT_MEM_COPY( q, p, dstSlot->bitmap.width * 4 );

          p += dstSlot->bitmap.pitch;
          q += pitch;
        }

        ft_glyphslot_set_bitmap( dstSlot, buf );

        dstSlot->bitmap_top  = y_max;
        dstSlot->bitmap_left = x_min;

        dstSlot->bitmap.width = width;
        dstSlot->bitmap.rows  = rows;
        dstSlot->bitmap.pitch = (int)pitch;

        dstSlot->internal->flags |= FT_GLYPH_OWN_BITMAP;
        dstSlot->format           = FT_GLYPH_FORMAT_BITMAP;
      }
    }

    if ( color_index == 0xFFFF )
    {
      if ( face->have_foreground_color )
      {
        b     = face->foreground_color.blue;
        g     = face->foreground_color.green;
        r     = face->foreground_color.red;
        alpha = face->foreground_color.alpha;
      }
      else
      {
        if ( face->palette_data.palette_flags                          &&
             ( face->palette_data.palette_flags[face->palette_index] &
                 FT_PALETTE_FOR_DARK_BACKGROUND                      ) )
        {
          /* white opaque */
          b     = 0xFF;
          g     = 0xFF;
          r     = 0xFF;
          alpha = 0xFF;
        }
        else
        {
          /* black opaque */
          b     = 0x00;
          g     = 0x00;
          r     = 0x00;
          alpha = 0xFF;
        }
      }
    }
    else
    {
      b     = face->palette[color_index].blue;
      g     = face->palette[color_index].green;
      r     = face->palette[color_index].red;
      alpha = face->palette[color_index].alpha;
    }

    /* XXX Convert if srcSlot.bitmap is not grey? */
    src = srcSlot->bitmap.buffer;
    dst = dstSlot->bitmap.buffer +
          dstSlot->bitmap.pitch * ( dstSlot->bitmap_top - srcSlot->bitmap_top ) +
          4 * ( srcSlot->bitmap_left - dstSlot->bitmap_left );

    for ( y = 0; y < srcSlot->bitmap.rows; y++ )
    {
      for ( x = 0; x < srcSlot->bitmap.width; x++ )
      {
        int  aa = src[x];
        int  fa = alpha * aa / 255;

        int  fb = b * fa / 255;
        int  fg = g * fa / 255;
        int  fr = r * fa / 255;

        int  ba2 = 255 - fa;

        int  bb = dst[4 * x + 0];
        int  bg = dst[4 * x + 1];
        int  br = dst[4 * x + 2];
        int  ba = dst[4 * x + 3];


        dst[4 * x + 0] = (FT_Byte)( bb * ba2 / 255 + fb );
        dst[4 * x + 1] = (FT_Byte)( bg * ba2 / 255 + fg );
        dst[4 * x + 2] = (FT_Byte)( br * ba2 / 255 + fr );
        dst[4 * x + 3] = (FT_Byte)( ba * ba2 / 255 + fa );
      }

      src += srcSlot->bitmap.pitch;
      dst += dstSlot->bitmap.pitch;
    }

    return FT_Err_Ok;
  }
Example #17
0
  static FT_Error
  cff_index_init( CFF_Index  idx,
                  FT_Stream  stream,
                  FT_Bool    load )
  {
    FT_Error   error;
    FT_Memory  memory = stream->memory;
    FT_UShort  count;


    FT_MEM_ZERO( idx, sizeof ( *idx ) );

    idx->stream = stream;
    idx->start  = FT_STREAM_POS();
    if ( !FT_READ_USHORT( count ) &&
         count > 0                )
    {
      FT_Byte   offsize;
      FT_ULong  size;


      /* there is at least one element; read the offset size,           */
      /* then access the offset table to compute the index's total size */
      if ( FT_READ_BYTE( offsize ) )
        goto Exit;

      if ( offsize < 1 || offsize > 4 )
      {
        error = FT_Err_Invalid_Table;
        goto Exit;
      }

      idx->count    = count;
      idx->off_size = offsize;
      size          = (FT_ULong)( count + 1 ) * offsize;

      idx->data_offset = idx->start + 3 + size;

      if ( FT_STREAM_SKIP( size - offsize ) )
        goto Exit;

      size = cff_index_read_offset( idx, &error );
      if ( error )
        goto Exit;

      if ( size == 0 )
      {
        error = CFF_Err_Invalid_Table;
        goto Exit;
      }

      idx->data_size = --size;

      if ( load )
      {
        /* load the data */
        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
          goto Exit;
      }
      else
      {
        /* skip the data */
        if ( FT_STREAM_SKIP( size ) )
          goto Exit;
      }
    }

  Exit:
    if ( error )
      FT_FREE( idx->offsets );

    return error;
  }
Example #18
0
  static FT_Error
  cff_subfont_load( CFF_SubFont  font,
                    CFF_Index    idx,
                    FT_UInt      font_index,
                    FT_Stream    stream,
                    FT_ULong     base_offset )
  {
    FT_Error         error;
    CFF_ParserRec    parser;
    FT_Byte*         dict = NULL;
    FT_ULong         dict_len;
    CFF_FontRecDict  top  = &font->font_dict;
    CFF_Private      priv = &font->private_dict;


    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );

    /* set defaults */
    FT_MEM_ZERO( top, sizeof ( *top ) );

    top->underline_position  = -100L << 16;
    top->underline_thickness = 50L << 16;
    top->charstring_type     = 2;
    top->font_matrix.xx      = 0x10000L;
    top->font_matrix.yy      = 0x10000L;
    top->cid_count           = 8720;

    /* we use the implementation specific SID value 0xFFFF to indicate */
    /* missing entries                                                 */
    top->version             = 0xFFFFU;
    top->notice              = 0xFFFFU;
    top->copyright           = 0xFFFFU;
    top->full_name           = 0xFFFFU;
    top->family_name         = 0xFFFFU;
    top->weight              = 0xFFFFU;
    top->embedded_postscript = 0xFFFFU;

    top->cid_registry        = 0xFFFFU;
    top->cid_ordering        = 0xFFFFU;
    top->cid_font_name       = 0xFFFFU;

    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
    if ( !error )
      error = cff_parser_run( &parser, dict, dict + dict_len );

    cff_index_forget_element( idx, &dict );

    if ( error )
      goto Exit;

    /* if it is a CID font, we stop there */
    if ( top->cid_registry != 0xFFFFU )
      goto Exit;

    /* parse the private dictionary, if any */
    if ( top->private_offset && top->private_size )
    {
      /* set defaults */
      FT_MEM_ZERO( priv, sizeof ( *priv ) );

      priv->blue_shift       = 7;
      priv->blue_fuzz        = 1;
      priv->lenIV            = -1;
      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );

      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );

      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
           FT_FRAME_ENTER( font->font_dict.private_size )                 )
        goto Exit;

      error = cff_parser_run( &parser,
                              (FT_Byte*)stream->cursor,
                              (FT_Byte*)stream->limit );
      FT_FRAME_EXIT();
      if ( error )
        goto Exit;

      /* ensure that `num_blue_values' is even */
      priv->num_blue_values &= ~1;
    }

    /* read the local subrs, if any */
    if ( priv->local_subrs_offset )
    {
      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
                           priv->local_subrs_offset ) )
        goto Exit;

      error = cff_index_init( &font->local_subrs_index, stream, 1 );
      if ( error )
        goto Exit;

      font->num_local_subrs = font->local_subrs_index.count;
      error = cff_index_get_pointers( &font->local_subrs_index,
                                      &font->local_subrs );
      if ( error )
        goto Exit;
    }

  Exit:
    return error;
  }
Example #19
0
pcf_load_font( FT_Stream  stream,
               PCF_Face   face )
{
    FT_Error   error  = PCF_Err_Ok;
    FT_Memory  memory = FT_FACE(face)->memory;
    FT_Bool    hasBDFAccelerators;


    error = pcf_read_TOC( stream, face );
    if ( error )
        goto Exit;

    error = pcf_get_properties( stream, face );
    if ( error )
        goto Exit;

    /* Use the old accelerators if no BDF accelerators are in the file. */
    hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
                         face->toc.count,
                         PCF_BDF_ACCELERATORS );
    if ( !hasBDFAccelerators )
    {
        error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
        if ( error )
            goto Exit;
    }

    /* metrics */
    error = pcf_get_metrics( stream, face );
    if ( error )
        goto Exit;

    /* bitmaps */
    error = pcf_get_bitmaps( stream, face );
    if ( error )
        goto Exit;

    /* encodings */
    error = pcf_get_encodings( stream, face );
    if ( error )
        goto Exit;

    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
    if ( hasBDFAccelerators )
    {
        error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
        if ( error )
            goto Exit;
    }

    /* XXX: TO DO: inkmetrics and glyph_names are missing */

    /* now construct the face object */
    {
        FT_Face       root = FT_FACE( face );
        PCF_Property  prop;


        root->num_faces  = 1;
        root->face_index = 0;
        root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
                           FT_FACE_FLAG_HORIZONTAL  |
                           FT_FACE_FLAG_FAST_GLYPHS;

        if ( face->accel.constantWidth )
            root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

        root->style_flags = 0;
        prop = pcf_find_property( face, "SLANT" );
        if ( prop != NULL )
            if ( prop->isString )
                if ( ( *(prop->value.atom) == 'O' ) ||
                        ( *(prop->value.atom) == 'o' ) ||
                        ( *(prop->value.atom) == 'I' ) ||
                        ( *(prop->value.atom) == 'i' ) )
                    root->style_flags |= FT_STYLE_FLAG_ITALIC;

        prop = pcf_find_property( face, "WEIGHT_NAME" );
        if ( prop != NULL )
            if ( prop->isString )
                if ( ( *(prop->value.atom) == 'B' ) ||
                        ( *(prop->value.atom) == 'b' ) )
                    root->style_flags |= FT_STYLE_FLAG_BOLD;

        root->style_name = (char *)"Regular";

        if ( root->style_flags & FT_STYLE_FLAG_BOLD ) {
            if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
                root->style_name = (char *)"Bold Italic";
            else
                root->style_name = (char *)"Bold";
        }
        else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
            root->style_name = (char *)"Italic";

        prop = pcf_find_property( face, "FAMILY_NAME" );
        if ( prop != NULL )
        {
            if ( prop->isString )
            {
                int  l = ft_strlen( prop->value.atom ) + 1;


                if ( FT_NEW_ARRAY( root->family_name, l ) )
                    goto Exit;
                ft_strcpy( root->family_name, prop->value.atom );
            }
        }
        else
            root->family_name = 0;

        /* Note: We shift all glyph indices by +1 since we must
         * respect the convention that glyph 0 always corresponds
         * to the "missing glyph".
         *
         * This implies bumping the number of "available" glyphs by 1.
         */
        root->num_glyphs = face->nmetrics + 1;

        root->num_fixed_sizes = 1;
        if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
            goto Exit;

        {
            FT_Bitmap_Size*  bsize = root->available_sizes;


            FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );

            prop = pcf_find_property( face, "PIXEL_SIZE" );
            if ( prop != NULL )
                bsize->height = (FT_Short)prop->value.integer;

            prop = pcf_find_property( face, "AVERAGE_WIDTH" );
            if ( prop != NULL )
                bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 );

            prop = pcf_find_property( face, "POINT_SIZE" );
            if ( prop != NULL )
                /* convert from 722,7 decipoints to 72 points per inch */
                bsize->size =
                    (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L );

            prop = pcf_find_property( face, "RESOLUTION_X" );
            if ( prop != NULL )
                bsize->x_ppem =
                    (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 );

            prop = pcf_find_property( face, "RESOLUTION_Y" );
            if ( prop != NULL )
                bsize->y_ppem =
                    (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 );

            if ( bsize->height == 0 )
                bsize->height = (FT_Short)( ( bsize->y_ppem + 32 ) / 64 );

            if ( bsize->height == 0 )
                bsize->height = 12;
        }

        /* set up charset */
        {
            PCF_Property  charset_registry = 0, charset_encoding = 0;


            charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
            charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );

            if ( ( charset_registry != NULL ) &&
                    ( charset_encoding != NULL ) )
            {
                if ( ( charset_registry->isString ) &&
                        ( charset_encoding->isString ) )
                {
                    if ( FT_NEW_ARRAY( face->charset_encoding,
                                       ft_strlen( charset_encoding->value.atom ) + 1 ) )
                        goto Exit;

                    if ( FT_NEW_ARRAY( face->charset_registry,
                                       ft_strlen( charset_registry->value.atom ) + 1 ) )
                        goto Exit;

                    ft_strcpy( face->charset_registry, charset_registry->value.atom );
                    ft_strcpy( face->charset_encoding, charset_encoding->value.atom );
                }
            }
        }
    }

Exit:
    if ( error )
    {
        /* this is done to respect the behaviour of the original */
        /* PCF font driver.                                      */
        error = PCF_Err_Invalid_File_Format;
    }

    return error;
}
Example #20
0
  static FT_Error
  cff_subfont_load( CFF_SubFont  font,
                    CFF_Index    idx,
                    FT_UInt      font_index,
                    FT_Stream    stream,
                    FT_ULong     base_offset )
  {
    FT_Error         error;
    CFF_ParserRec    parser;
    FT_Byte*         dict;
    FT_ULong         dict_len;
    CFF_FontRecDict  top  = &font->font_dict;
    CFF_Private      priv = &font->private_dict;


    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );

    /* set defaults */
    FT_MEM_ZERO( top, sizeof ( *top ) );

    top->underline_position  = -100L << 16;
    top->underline_thickness = 50L << 16;
    top->charstring_type     = 2;
    top->font_matrix.xx      = 0x10000L;
    top->font_matrix.yy      = 0x10000L;
    top->cid_count           = 8720;

    error = cff_index_access_element( idx, font_index, &dict, &dict_len ) ||
            cff_parser_run( &parser, dict, dict + dict_len );

    cff_index_forget_element( idx, &dict );

    if ( error )
      goto Exit;

    /* if it is a CID font, we stop there */
    if ( top->cid_registry )
      goto Exit;

    /* parse the private dictionary, if any */
    if ( top->private_offset && top->private_size )
    {
      /* set defaults */
      FT_MEM_ZERO( priv, sizeof ( *priv ) );

      priv->blue_shift       = 7;
      priv->blue_fuzz        = 1;
      priv->lenIV            = -1;
      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );

      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );

      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
           FT_FRAME_ENTER( font->font_dict.private_size )                 )
        goto Exit;

      error = cff_parser_run( &parser,
                              (FT_Byte*)stream->cursor,
                              (FT_Byte*)stream->limit );
      FT_FRAME_EXIT();
      if ( error )
        goto Exit;
    }

    /* read the local subrs, if any */
    if ( priv->local_subrs_offset )
    {
      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
                           priv->local_subrs_offset ) )
        goto Exit;

      error = cff_new_index( &font->local_subrs_index, stream, 1 );
      if ( error )
        goto Exit;

      font->num_local_subrs = font->local_subrs_index.count;
      error = cff_index_get_pointers( &font->local_subrs_index,
                                      &font->local_subrs );
      if ( error )
        goto Exit;
    }

  Exit:
    return error;
  }
Example #21
0
  cff_size_init( CFF_Size  size )
  {
    FT_Error           error = 0;
    PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );


    if ( funcs )
    {
      PSH_Globals    globals;
      CFF_Face       face    = (CFF_Face)size->face;
      CFF_Font       font    = (CFF_FontRec *)face->extra.data;
      CFF_SubFont    subfont = &font->top_font;

      CFF_Private    cpriv   = &subfont->private_dict;
      PS_PrivateRec  priv;


      /* IMPORTANT: The CFF and Type1 private dictionaries have    */
      /*            slightly different structures; we need to      */
      /*            synthetize a type1 dictionary on the fly here. */

      {
        FT_UInt  n, count;


        FT_MEM_ZERO( &priv, sizeof ( priv ) );

        count = priv.num_blue_values = cpriv->num_blue_values;
        for ( n = 0; n < count; n++ )
          priv.blue_values[n] = (FT_Short)cpriv->blue_values[n];

        count = priv.num_other_blues = cpriv->num_other_blues;
        for ( n = 0; n < count; n++ )
          priv.other_blues[n] = (FT_Short)cpriv->other_blues[n];

        count = priv.num_family_blues = cpriv->num_family_blues;
        for ( n = 0; n < count; n++ )
          priv.family_blues[n] = (FT_Short)cpriv->family_blues[n];

        count = priv.num_family_other_blues = cpriv->num_family_other_blues;
        for ( n = 0; n < count; n++ )
          priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];

        priv.blue_scale = cpriv->blue_scale;
        priv.blue_shift = (FT_Int)cpriv->blue_shift;
        priv.blue_fuzz  = (FT_Int)cpriv->blue_fuzz;

        priv.standard_width[0]  = (FT_UShort)cpriv->standard_width;
        priv.standard_height[0] = (FT_UShort)cpriv->standard_height;

        count = priv.num_snap_widths = cpriv->num_snap_widths;
        for ( n = 0; n < count; n++ )
          priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n];

        count = priv.num_snap_heights = cpriv->num_snap_heights;
        for ( n = 0; n < count; n++ )
          priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n];

        priv.force_bold     = cpriv->force_bold;
        priv.language_group = cpriv->language_group;
        priv.lenIV          = cpriv->lenIV;
      }

      error = funcs->create( size->face->memory, &priv, &globals );
      if ( !error )
        size->internal = (FT_Size_Internal)(void*)globals;
    }

    return error;
  }
Example #22
0
cid_parser_new( CID_Parser*    parser,
                FT_Stream      stream,
                FT_Memory      memory,
                PSAux_Service  psaux )
{
    FT_Error  error;
    FT_ULong  base_offset, offset, ps_len;
    FT_Byte   *cur, *limit;
    FT_Byte   *arg1, *arg2;


    FT_MEM_ZERO( parser, sizeof ( *parser ) );
    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );

    parser->stream = stream;

    base_offset = FT_STREAM_POS();

    /* first of all, check the font format in the header */
    if ( FT_FRAME_ENTER( 31 ) )
        goto Exit;

    if ( ft_strncmp( (char *)stream->cursor,
                     "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
    {
        FT_TRACE2(( "  not a CID-keyed font\n" ));
        error = FT_THROW( Unknown_File_Format );
    }

    FT_FRAME_EXIT();
    if ( error )
        goto Exit;

Again:
    /* now, read the rest of the file until we find */
    /* `StartData' or `/sfnts'                      */
    {
        FT_Byte   buffer[256 + 10];
        FT_ULong  read_len = 256 + 10;
        FT_Byte*  p        = buffer;


        for ( offset = FT_STREAM_POS(); ; offset += 256 )
        {
            FT_ULong  stream_len;


            stream_len = stream->size - FT_STREAM_POS();
            if ( stream_len == 0 )
            {
                FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
                error = FT_THROW( Invalid_File_Format );
                goto Exit;
            }

            read_len = FT_MIN( read_len, stream_len );
            if ( FT_STREAM_READ( p, read_len ) )
                goto Exit;

            if ( read_len < 256 )
                p[read_len]  = '\0';

            limit = p + read_len - 10;

            for ( p = buffer; p < limit; p++ )
            {
                if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
                {
                    /* save offset of binary data after `StartData' */
                    offset += (FT_ULong)( p - buffer + 10 );
                    goto Found;
                }
                else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
                {
                    offset += (FT_ULong)( p - buffer + 7 );
                    goto Found;
                }
            }

            FT_MEM_MOVE( buffer, p, 10 );
            read_len = 256;
            p = buffer + 10;
        }
    }

Found:
    /* We have found the start of the binary data or the `/sfnts' token. */
    /* Now rewind and extract the frame corresponding to this PostScript */
    /* section.                                                          */

    ps_len = offset - base_offset;
    if ( FT_STREAM_SEEK( base_offset )                  ||
            FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
        goto Exit;

    parser->data_offset    = offset;
    parser->postscript_len = ps_len;
    parser->root.base      = parser->postscript;
    parser->root.cursor    = parser->postscript;
    parser->root.limit     = parser->root.cursor + ps_len;
    parser->num_dict       = -1;

    /* Finally, we check whether `StartData' or `/sfnts' was real --  */
    /* it could be in a comment or string.  We also get the arguments */
    /* of `StartData' to find out whether the data is represented in  */
    /* binary or hex format.                                          */

    arg1 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );
    arg2 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );

    limit = parser->root.limit;
    cur   = parser->root.cursor;

    while ( cur < limit )
    {
        if ( parser->root.error )
        {
            error = parser->root.error;
            goto Exit;
        }

        if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
        {
            if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
            {
                FT_Long  tmp = ft_atol( (const char *)arg2 );


                if ( tmp < 0 )
                {
                    FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
                    error = FT_THROW( Invalid_File_Format );
                }
                else
                    parser->binary_length = (FT_ULong)tmp;
            }

            goto Exit;
        }
        else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
        {
            FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
            error = FT_THROW( Unknown_File_Format );
            goto Exit;
        }

        cid_parser_skip_PS_token( parser );
        cid_parser_skip_spaces  ( parser );
        arg1 = arg2;
        arg2 = cur;
        cur  = parser->root.cursor;
    }

    /* we haven't found the correct `StartData'; go back and continue */
    /* searching                                                      */
    FT_FRAME_RELEASE( parser->postscript );
    if ( !FT_STREAM_SEEK( offset ) )
        goto Again;

Exit:
    return error;
}
Example #23
0
  cid_parser_new( CID_Parser*    parser,
                  FT_Stream      stream,
                  FT_Memory      memory,
                  PSAux_Service  psaux )
  {
    FT_Error  error;
    FT_ULong  base_offset, offset, ps_len;
    FT_Byte   buffer[256 + 10];
    FT_Int    buff_len;
    FT_Byte   *cur, *limit;
    FT_Byte   *arg1, *arg2;


    FT_MEM_ZERO( parser, sizeof ( *parser ) );
    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );

    parser->stream = stream;

    base_offset = FT_STREAM_POS();

    /* first of all, check the font format in the header */
    if ( FT_FRAME_ENTER( 31 ) )
      goto Exit;

    if ( ft_strncmp( (char *)stream->cursor,
                     "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
    {
      FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
      error = CID_Err_Unknown_File_Format;
    }

    FT_FRAME_EXIT();
    if ( error )
      goto Exit;

  Again:
    /* now, read the rest of the file until we find a `StartData' */
    buff_len = 256;
    for (;;)
    {
      FT_Byte*  p;
      FT_ULong  top_position;


      /* fill input buffer */
      limit     = buffer + 256;
      buff_len -= 256;
      if ( buff_len > 0 )
        FT_MEM_MOVE( buffer, limit, buff_len );

      p = buffer + buff_len;

      if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) )
        goto Exit;

      top_position = FT_STREAM_POS() - buff_len;
      buff_len     = 256 + 10;

      /* look for `StartData' */
      for ( p = buffer; p < limit; p++ )
      {
        if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
        {
          /* save offset of binary data after `StartData' */
          offset = (FT_ULong)( top_position - ( limit - p ) + 10 );
          goto Found;
        }
      }
    }

  Found:
    /* we have found the start of the binary data.  We will now     */
    /* rewind and extract the frame corresponding to the PostScript */
    /* section                                                      */

    ps_len = offset - base_offset;
    if ( FT_STREAM_SEEK( base_offset )                  ||
         FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
      goto Exit;

    parser->data_offset    = offset;
    parser->postscript_len = ps_len;
    parser->root.base      = parser->postscript;
    parser->root.cursor    = parser->postscript;
    parser->root.limit     = parser->root.cursor + ps_len;
    parser->num_dict       = -1;

    /* Finally, we check whether `StartData' was real -- it could be  */
    /* in a comment or string.  We also get its arguments to find out */
    /* whether the data is represented in binary or hex format.       */

    arg1 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );
    arg2 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );

    limit = parser->root.limit;
    cur   = parser->root.cursor;

    while ( cur < limit )
    {
      if ( parser->root.error )
        break;

      if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
      {
        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
          parser->binary_length = ft_atol( (const char *)arg2 );

        limit = parser->root.limit;
        cur   = parser->root.cursor;
        goto Exit;
      }

      cid_parser_skip_PS_token( parser );
      cid_parser_skip_spaces  ( parser );
      arg1 = arg2;
      arg2 = cur;
      cur  = parser->root.cursor;
    }

    /* we haven't found the correct `StartData'; go back and continue */
    /* searching                                                      */
    FT_FRAME_RELEASE( parser->postscript );
    if ( !FT_STREAM_SEEK( offset ) )
      goto Again;

  Exit:
    return error;
  }
Example #24
0
  static FT_Error
  cff_charset_load( CFF_Charset  charset,
                    FT_UInt      num_glyphs,
                    FT_Stream    stream,
                    FT_ULong     base_offset,
                    FT_ULong     offset,
                    FT_Bool      invert )
  {
    FT_Memory  memory = stream->memory;
    FT_Error   error  = CFF_Err_Ok;
    FT_UShort  glyph_sid;


    /* If the the offset is greater than 2, we have to parse the */
    /* charset table.                                            */
    if ( offset > 2 )
    {
      FT_UInt  j;


      charset->offset = base_offset + offset;

      /* Get the format of the table. */
      if ( FT_STREAM_SEEK( charset->offset ) ||
           FT_READ_BYTE( charset->format )   )
        goto Exit;

      /* Allocate memory for sids. */
      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
        goto Exit;

      /* assign the .notdef glyph */
      charset->sids[0] = 0;

      switch ( charset->format )
      {
      case 0:
        if ( num_glyphs > 0 )
        {
          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
            goto Exit;

          for ( j = 1; j < num_glyphs; j++ )
            charset->sids[j] = FT_GET_USHORT();

          FT_FRAME_EXIT();
        }
        break;

      case 1:
      case 2:
        {
          FT_UInt  nleft;
          FT_UInt  i;


          j = 1;

          while ( j < num_glyphs )
          {
            /* Read the first glyph sid of the range. */
            if ( FT_READ_USHORT( glyph_sid ) )
              goto Exit;

            /* Read the number of glyphs in the range.  */
            if ( charset->format == 2 )
            {
              if ( FT_READ_USHORT( nleft ) )
                goto Exit;
            }
            else
            {
              if ( FT_READ_BYTE( nleft ) )
                goto Exit;
            }

            /* Fill in the range of sids -- `nleft + 1' glyphs. */
            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
              charset->sids[j] = glyph_sid;
          }
        }
        break;

      default:
        FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
        error = CFF_Err_Invalid_File_Format;
        goto Exit;
      }
    }
    else
    {
      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
      /* CFF specification intimates the following:                   */
      /*                                                              */
      /* In order to use a predefined charset, the following must be  */
      /* true: The charset constructed for the glyphs in the font's   */
      /* charstrings dictionary must match the predefined charset in  */
      /* the first num_glyphs.                                        */

      charset->offset = offset;  /* record charset type */

      switch ( (FT_UInt)offset )
      {
      case 0:
        if ( num_glyphs > 229 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe ISO-Latin)!\n" ));
          error = CFF_Err_Invalid_File_Format;
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory. */
        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );

        break;

      case 1:
        if ( num_glyphs > 166 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe Expert)!\n" ));
          error = CFF_Err_Invalid_File_Format;
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory.     */
        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );

        break;

      case 2:
        if ( num_glyphs > 87 )
        {
          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
                     "predefined charset (Adobe Expert Subset)!\n" ));
          error = CFF_Err_Invalid_File_Format;
          goto Exit;
        }

        /* Allocate memory for sids. */
        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
          goto Exit;

        /* Copy the predefined charset into the allocated memory.     */
        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );

        break;

      default:
        error = CFF_Err_Invalid_File_Format;
        goto Exit;
      }
    }

    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
    if ( invert )
    {
      FT_UInt    i;
      FT_UShort  max_cid = 0;


      for ( i = 0; i < num_glyphs; i++ )
        if ( charset->sids[i] > max_cid )
          max_cid = charset->sids[i];
      max_cid++;

      if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
        goto Exit;
      FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid );

      for ( i = 0; i < num_glyphs; i++ )
        charset->cids[charset->sids[i]] = i;
    }

  Exit:
    /* Clean up if there was an error. */
    if ( error )
    {
      FT_FREE( charset->sids );
      FT_FREE( charset->cids );
      charset->format = 0;
      charset->offset = 0;
      charset->sids   = 0;
    }

    return error;
  }
Example #25
0
  static FT_Error
  cff_new_index( CFF_Index  idx,
                 FT_Stream  stream,
                 FT_Bool    load )
  {
    FT_Error   error;
    FT_Memory  memory = stream->memory;
    FT_UShort  count;


    FT_MEM_ZERO( idx, sizeof ( *idx ) );

    idx->stream = stream;
    if ( !FT_READ_USHORT( count ) &&
         count > 0                )
    {
      FT_Byte*   p;
      FT_Byte    offsize;
      FT_ULong   data_size;
      FT_ULong*  poff;


      /* there is at least one element; read the offset size,           */
      /* then access the offset table to compute the index's total size */
      if ( FT_READ_BYTE( offsize ) )
        goto Exit;

      idx->stream   = stream;
      idx->count    = count;
      idx->off_size = offsize;
      data_size     = (FT_ULong)( count + 1 ) * offsize;

      if ( FT_NEW_ARRAY( idx->offsets, count + 1 ) ||
           FT_FRAME_ENTER( data_size )             )
        goto Exit;

      poff = idx->offsets;
      p    = (FT_Byte*)stream->cursor;

      for ( ; (FT_Short)count >= 0; count-- )
      {
        poff[0] = cff_get_offset( p, offsize );
        poff++;
        p += offsize;
      }

      FT_FRAME_EXIT();

      idx->data_offset = FT_STREAM_POS();
      data_size        = poff[-1] - 1;

      if ( load )
      {
        /* load the data */
        if ( FT_FRAME_EXTRACT( data_size, idx->bytes ) )
          goto Exit;
      }
      else
      {
        /* skip the data */
        if ( FT_STREAM_SKIP( data_size ) )
          goto Exit;
      }
    }

  Exit:
    if ( error )
      FT_FREE( idx->offsets );

    return error;
  }
Example #26
0
  pcf_load_font( FT_Stream  stream,
                 PCF_Face   face )
  {
    FT_Error   error  = PCF_Err_Ok;
    FT_Memory  memory = FT_FACE(face)->memory;
    FT_Bool    hasBDFAccelerators;


    error = pcf_read_TOC( stream, face );
    if ( error )
      goto Exit;

    error = pcf_get_properties( stream, face );
    if ( error )
      goto Exit;

    /* Use the old accelerators if no BDF accelerators are in the file. */
    hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
                                             face->toc.count,
                                             PCF_BDF_ACCELERATORS );
    if ( !hasBDFAccelerators )
    {
      error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
      if ( error )
        goto Exit;
    }

    /* metrics */
    error = pcf_get_metrics( stream, face );
    if ( error )
      goto Exit;

    /* bitmaps */
    error = pcf_get_bitmaps( stream, face );
    if ( error )
      goto Exit;

    /* encodings */
    error = pcf_get_encodings( stream, face );
    if ( error )
      goto Exit;

    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
    if ( hasBDFAccelerators )
    {
      error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
      if ( error )
        goto Exit;
    }

    /* XXX: TO DO: inkmetrics and glyph_names are missing */

    /* now construct the face object */
    {
      FT_Face       root = FT_FACE( face );
      PCF_Property  prop;


      root->num_faces  = 1;
      root->face_index = 0;
      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
                         FT_FACE_FLAG_HORIZONTAL  |
                         FT_FACE_FLAG_FAST_GLYPHS;

      if ( face->accel.constantWidth )
        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

      if ( ( error = pcf_interpret_style( face ) ) != 0 )
         goto Exit;

      prop = pcf_find_property( face, "FAMILY_NAME" );
      if ( prop && prop->isString )
      {
        if ( FT_STRDUP( root->family_name, prop->value.atom ) )
          goto Exit;
      }
      else
        root->family_name = NULL;

      /*
       * Note: We shift all glyph indices by +1 since we must
       * respect the convention that glyph 0 always corresponds
       * to the `missing glyph'.
       *
       * This implies bumping the number of `available' glyphs by 1.
       */
      root->num_glyphs = face->nmetrics + 1;

      root->num_fixed_sizes = 1;
      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
        goto Exit;

      {
        FT_Bitmap_Size*  bsize = root->available_sizes;
        FT_Short         resolution_x = 0, resolution_y = 0;


        FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );

#if 0
        bsize->height = face->accel.maxbounds.ascent << 6;
#endif
        bsize->height = (FT_Short)( face->accel.fontAscent +
                                    face->accel.fontDescent );

        prop = pcf_find_property( face, "AVERAGE_WIDTH" );
        if ( prop )
          bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 );
        else
          bsize->width = (FT_Short)( bsize->height * 2/3 );

        prop = pcf_find_property( face, "POINT_SIZE" );
        if ( prop )
          /* convert from 722.7 decipoints to 72 points per inch */
          bsize->size =
            (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L );

        prop = pcf_find_property( face, "PIXEL_SIZE" );
        if ( prop )
          bsize->y_ppem = (FT_Short)prop->value.integer << 6;

        prop = pcf_find_property( face, "RESOLUTION_X" );
        if ( prop )
          resolution_x = (FT_Short)prop->value.integer;

        prop = pcf_find_property( face, "RESOLUTION_Y" );
        if ( prop )
          resolution_y = (FT_Short)prop->value.integer;

        if ( bsize->y_ppem == 0 )
        {
          bsize->y_ppem = bsize->size;
          if ( resolution_y )
            bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
        }
        if ( resolution_x && resolution_y )
          bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
        else
          bsize->x_ppem = bsize->y_ppem;
      }

      /* set up charset */
      {
        PCF_Property  charset_registry = 0, charset_encoding = 0;


        charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
        charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );

        if ( charset_registry && charset_registry->isString &&
             charset_encoding && charset_encoding->isString )
        {
          if ( FT_STRDUP( face->charset_encoding,
                          charset_encoding->value.atom ) ||
               FT_STRDUP( face->charset_registry,
                          charset_registry->value.atom ) )
            goto Exit;
        }
      }
    }

  Exit:
    if ( error )
    {
      /* This is done to respect the behaviour of the original */
      /* PCF font driver.                                      */
      error = PCF_Err_Invalid_File_Format;
    }

    return error;
  }
Example #27
0
  cid_parser_new( CID_Parser*    parser,
                  FT_Stream      stream,
                  FT_Memory      memory,
                  PSAux_Service  psaux )
  {
    FT_Error  error;
    FT_ULong  base_offset, offset, ps_len;
    FT_Byte   *cur, *limit;
    FT_Byte   *arg1, *arg2;


    FT_MEM_ZERO( parser, sizeof ( *parser ) );
    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );

    parser->stream = stream;

    base_offset = FT_STREAM_POS();

    /* first of all, check the font format in the header */
    if ( FT_FRAME_ENTER( 31 ) )
      goto Exit;

    if ( ft_strncmp( (char *)stream->cursor,
                     "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
    {
      FT_TRACE2(( "  not a CID-keyed font\n" ));
      error = FT_THROW( Unknown_File_Format );
    }

    FT_FRAME_EXIT();
    if ( error )
      goto Exit;

  Again:
    /* now, read the rest of the file until we find */
    /* `StartData' or `/sfnts'                      */
    {
      /*
       * The algorithm is as follows (omitting the case with less than 256
       * bytes to fill for simplicity).
       *
       * 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
       *
       * 2. Search for the STARTDATA and SFNTS strings at positions
       *    buffer[0], buffer[1], ...,
       *    buffer[255 + STARTDATA_LEN - SFNTS_LEN].
       *
       * 3. Move the last STARTDATA_LEN bytes to buffer[0].
       *
       * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
       *
       * 5. Repeat with step 2.
       *
       */
      FT_Byte  buffer[256 + STARTDATA_LEN + 1];

      /* values for the first loop */
      FT_ULong  read_len    = 256 + STARTDATA_LEN;
      FT_ULong  read_offset = 0;
      FT_Byte*  p           = buffer;


      for ( offset = FT_STREAM_POS(); ; offset += 256 )
      {
        FT_ULong  stream_len;


        stream_len = stream->size - FT_STREAM_POS();

        read_len = FT_MIN( read_len, stream_len );
        if ( FT_STREAM_READ( p, read_len ) )
          goto Exit;

        /* ensure that we do not compare with data beyond the buffer */
        p[read_len] = '\0';

        limit = p + read_len - SFNTS_LEN;

        for ( p = buffer; p < limit; p++ )
        {
          if ( p[0] == 'S'                                           &&
               ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
          {
            /* save offset of binary data after `StartData' */
            offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN;
            goto Found;
          }
          else if ( p[1] == 's'                                   &&
                    ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
          {
            offset += (FT_ULong)( p - buffer ) + SFNTS_LEN;
            goto Found;
          }
        }

        if ( read_offset + read_len < STARTDATA_LEN )
        {
          FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Exit;
        }

        FT_MEM_MOVE( buffer,
                     buffer + read_offset + read_len - STARTDATA_LEN,
                     STARTDATA_LEN );

        /* values for the next loop */
        read_len    = 256;
        read_offset = STARTDATA_LEN;
        p           = buffer + read_offset;
      }
    }

  Found:
    /* We have found the start of the binary data or the `/sfnts' token. */
    /* Now rewind and extract the frame corresponding to this PostScript */
    /* section.                                                          */

    ps_len = offset - base_offset;
    if ( FT_STREAM_SEEK( base_offset )                  ||
         FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
      goto Exit;

    parser->data_offset    = offset;
    parser->postscript_len = ps_len;
    parser->root.base      = parser->postscript;
    parser->root.cursor    = parser->postscript;
    parser->root.limit     = parser->root.cursor + ps_len;
    parser->num_dict       = -1;

    /* Finally, we check whether `StartData' or `/sfnts' was real --  */
    /* it could be in a comment or string.  We also get the arguments */
    /* of `StartData' to find out whether the data is represented in  */
    /* binary or hex format.                                          */

    arg1 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );
    arg2 = parser->root.cursor;
    cid_parser_skip_PS_token( parser );
    cid_parser_skip_spaces  ( parser );

    limit = parser->root.limit;
    cur   = parser->root.cursor;

    while ( cur <= limit - SFNTS_LEN )
    {
      if ( parser->root.error )
      {
        error = parser->root.error;
        goto Exit;
      }

      if ( cur[0] == 'S'                                           &&
           cur <= limit - STARTDATA_LEN                            &&
           ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
      {
        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
        {
          FT_Long  tmp = ft_strtol( (const char *)arg2, NULL, 10 );


          if ( tmp < 0 )
          {
            FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
            error = FT_THROW( Invalid_File_Format );
          }
          else
            parser->binary_length = (FT_ULong)tmp;
        }

        goto Exit;
      }
      else if ( cur[1] == 's'                                   &&
                ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
      {
        FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
        error = FT_THROW( Unknown_File_Format );
        goto Exit;
      }

      cid_parser_skip_PS_token( parser );
      cid_parser_skip_spaces  ( parser );
      arg1 = arg2;
      arg2 = cur;
      cur  = parser->root.cursor;
    }

    /* we haven't found the correct `StartData'; go back and continue */
    /* searching                                                      */
    FT_FRAME_RELEASE( parser->postscript );
    if ( !FT_STREAM_SEEK( offset ) )
      goto Again;

  Exit:
    return error;
  }