Ejemplo n.º 1
0
  static void
  af_warper_compute_line_best( AF_Warper     warper,
                               FT_Fixed      scale,
                               FT_Pos        delta,
                               FT_Pos        xx1,
                               FT_Pos        xx2,
                               AF_WarpScore  base_distort,
                               AF_Segment    segments,
                               FT_UInt       num_segments )
  {
    FT_Int        idx_min, idx_max, idx0;
    FT_UInt       nn;
    AF_WarpScore  scores[65];


    for ( nn = 0; nn < 65; nn++ )
      scores[nn] = 0;

    idx0 = xx1 - warper->t1;

    /* compute minimum and maximum indices */
    {
      FT_Pos  xx1min = warper->x1min;
      FT_Pos  xx1max = warper->x1max;
      FT_Pos  w      = xx2 - xx1;


      if ( xx1min + w < warper->x2min )
        xx1min = warper->x2min - w;

      xx1max = warper->x1max;
      if ( xx1max + w > warper->x2max )
        xx1max = warper->x2max - w;

      idx_min = xx1min - warper->t1;
      idx_max = xx1max - warper->t1;

      if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
      {
        FT_TRACE5(( "invalid indices:\n"
                    "  min=%d max=%d, xx1=%ld xx2=%ld,\n"
                    "  x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
                    idx_min, idx_max, xx1, xx2,
                    warper->x1min, warper->x1max,
                    warper->x2min, warper->x2max ));
        return;
      }
    }

    for ( nn = 0; nn < num_segments; nn++ )
    {
      FT_Pos  len = segments[nn].max_coord - segments[nn].min_coord;
      FT_Pos  y0  = FT_MulFix( segments[nn].pos, scale ) + delta;
      FT_Pos  y   = y0 + ( idx_min - idx0 );
      FT_Int  idx;


      /* score the length of the segments for the given range */
      for ( idx = idx_min; idx <= idx_max; idx++, y++ )
        scores[idx] += af_warper_weights[y & 63] * len;
    }

    /* find best score */
    {
      FT_Int  idx;


      for ( idx = idx_min; idx <= idx_max; idx++ )
      {
        AF_WarpScore  score = scores[idx];
        AF_WarpScore  distort = base_distort + ( idx - idx0 );


        if ( score > warper->best_score         ||
             ( score == warper->best_score    &&
               distort < warper->best_distort ) )
        {
          warper->best_score   = score;
          warper->best_distort = distort;
          warper->best_scale   = scale;
          warper->best_delta   = delta + ( idx - idx0 );
        }
      }
    }
  }
Ejemplo n.º 2
0
tt_face_init( FT_Stream      stream,
              FT_Face        ttface,      /* TT_Face */
              FT_Int         face_index,
              FT_Int         num_params,
              FT_Parameter*  params )
{
    FT_Error      error;
    FT_Library    library;
    SFNT_Service  sfnt;
    TT_Face       face = (TT_Face)ttface;


    FT_TRACE2(( "TTF driver\n" ));

    library = ttface->driver->root.library;

    sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
    if ( !sfnt )
    {
        FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
        error = FT_THROW( Missing_Module );
        goto Exit;
    }

    /* create input stream from resource */
    if ( FT_STREAM_SEEK( 0 ) )
        goto Exit;

    /* check that we have a valid TrueType file */
    error = sfnt->init_face( stream, face, face_index, num_params, params );

    /* Stream may have changed. */
    stream = face->root.stream;

    if ( error )
        goto Exit;

    /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
    /* The 0x00020000 tag is completely undocumented; some fonts from   */
    /* Arphic made for Chinese Windows 3.1 have this.                   */
    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
            face->format_tag != 0x00020000L &&    /* CJK fonts for Win 3.1 */
            face->format_tag != TTAG_true   )     /* Mac fonts */
    {
        FT_TRACE2(( "  not a TTF font\n" ));
        goto Bad_Format;
    }

#ifdef TT_USE_BYTECODE_INTERPRETER
    ttface->face_flags |= FT_FACE_FLAG_HINTER;
#endif

    /* If we are performing a simple font format check, exit immediately. */
    if ( face_index < 0 )
        return FT_Err_Ok;

    /* Load font directory */
    error = sfnt->load_face( stream, face, face_index, num_params, params );
    if ( error )
        goto Exit;

    if ( tt_check_trickyness( ttface ) )
        ttface->face_flags |= FT_FACE_FLAG_TRICKY;

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

    if ( FT_IS_SCALABLE( ttface ) )
    {

#ifdef FT_CONFIG_OPTION_INCREMENTAL

        if ( !ttface->internal->incremental_interface )
            error = tt_face_load_loca( face, stream );
        if ( !error )
            error = tt_face_load_cvt( face, stream );
        if ( !error )
            error = tt_face_load_fpgm( face, stream );
        if ( !error )
            error = tt_face_load_prep( face, stream );

        /* Check the scalable flag based on `loca'. */
        if ( !ttface->internal->incremental_interface &&
                ttface->num_fixed_sizes                  &&
                face->glyph_locations                    &&
                tt_check_single_notdef( ttface )         )
        {
            FT_TRACE5(( "tt_face_init:"
                        " Only the `.notdef' glyph has an outline.\n"
                        "             "
                        " Resetting scalable flag to FALSE.\n" ));

            ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
        }

#else /* !FT_CONFIG_OPTION_INCREMENTAL */

        if ( !error )
            error = tt_face_load_loca( face, stream );
        if ( !error )
            error = tt_face_load_cvt( face, stream );
        if ( !error )
            error = tt_face_load_fpgm( face, stream );
        if ( !error )
            error = tt_face_load_prep( face, stream );

        /* Check the scalable flag based on `loca'. */
        if ( ttface->num_fixed_sizes          &&
                face->glyph_locations            &&
                tt_check_single_notdef( ttface ) )
        {
            FT_TRACE5(( "tt_face_init:"
                        " Only the `.notdef' glyph has an outline.\n"
                        "             "
                        " Resetting scalable flag to FALSE.\n" ));

            ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
        }

#endif /* !FT_CONFIG_OPTION_INCREMENTAL */

    }

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

    {
        FT_Int  instance_index = face_index >> 16;


        if ( FT_HAS_MULTIPLE_MASTERS( ttface ) &&
                instance_index > 0                )
        {
            error = TT_Get_MM_Var( face, NULL );
            if ( error )
                goto Exit;

            if ( face->blend->mmvar->namedstyle )
            {
                FT_Memory  memory = ttface->memory;

                FT_Var_Named_Style*  named_style;
                FT_String*           style_name;


                /* in `face_index', the instance index starts with value 1 */
                named_style = face->blend->mmvar->namedstyle + instance_index - 1;
                error = sfnt->get_name( face,
                                        (FT_UShort)named_style->strid,
                                        &style_name );
                if ( error )
                    goto Exit;

                /* set style name; if already set, replace it */
                if ( face->root.style_name )
                    FT_FREE( face->root.style_name );
                face->root.style_name = style_name;

                /* finally, select the named instance */
                error = TT_Set_Var_Design( face,
                                           face->blend->mmvar->num_axis,
                                           named_style->coords );
                if ( error )
                    goto Exit;
            }
        }
    }

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */

    /* initialize standard glyph loading routines */
    TT_Init_Glyph_Loading( face );

Exit:
    return error;

Bad_Format:
    error = FT_THROW( Unknown_File_Format );
    goto Exit;
}
Ejemplo n.º 3
0
  FT_Outline_Decompose( FT_Outline*              outline,
                        const FT_Outline_Funcs*  func_interface,
                        void*                    user )
  {
#undef SCALED
#define SCALED( x )  ( ( (x) << shift ) - delta )

    FT_Vector   v_last;
    FT_Vector   v_control;
    FT_Vector   v_start;

    FT_Vector*  point;
    FT_Vector*  limit;
    char*       tags;

    FT_Error    error;

    FT_Int   n;         /* index of contour in outline     */
    FT_UInt  first;     /* index of first point in contour */
    FT_Int   tag;       /* current point's state           */

    FT_Int   shift;
    FT_Pos   delta;


    if ( !outline || !func_interface )
      return FT_Err_Invalid_Argument;

    shift = func_interface->shift;
    delta = func_interface->delta;
    first = 0;

    for ( n = 0; n < outline->n_contours; n++ )
    {
      FT_Int  last;  /* index of last point in contour */


      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));

      last = outline->contours[n];
      if ( last < 0 )
        goto Invalid_Outline;
      limit = outline->points + last;

      v_start   = outline->points[first];
      v_start.x = SCALED( v_start.x );
      v_start.y = SCALED( v_start.y );

      v_last   = outline->points[last];
      v_last.x = SCALED( v_last.x );
      v_last.y = SCALED( v_last.y );

      v_control = v_start;

      point = outline->points + first;
      tags  = outline->tags   + first;
      tag   = FT_CURVE_TAG( tags[0] );

      /* A contour cannot start with a cubic control point! */
      if ( tag == FT_CURVE_TAG_CUBIC )
        goto Invalid_Outline;

      /* check first point to determine origin */
      if ( tag == FT_CURVE_TAG_CONIC )
      {
        /* first point is conic control.  Yes, this happens. */
        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
        {
          /* start at last point if it is on the curve */
          v_start = v_last;
          limit--;
        }
        else
        {
          /* if both first and last points are conic,         */
          /* start at their middle and record its position    */
          /* for closure                                      */
          v_start.x = ( v_start.x + v_last.x ) / 2;
          v_start.y = ( v_start.y + v_last.y ) / 2;

          v_last = v_start;
        }
        point--;
        tags--;
      }

      FT_TRACE5(( "  move to (%.2f, %.2f)\n",
                  v_start.x / 64.0, v_start.y / 64.0 ));
      error = func_interface->move_to( &v_start, user );
      if ( error )
        goto Exit;

      while ( point < limit )
      {
        point++;
        tags++;

        tag = FT_CURVE_TAG( tags[0] );
        switch ( tag )
        {
        case FT_CURVE_TAG_ON:  /* emit a single line_to */
          {
            FT_Vector  vec;


            vec.x = SCALED( point->x );
            vec.y = SCALED( point->y );

            FT_TRACE5(( "  line to (%.2f, %.2f)\n",
                        vec.x / 64.0, vec.y / 64.0 ));
            error = func_interface->line_to( &vec, user );
            if ( error )
              goto Exit;
            continue;
          }

        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */
          v_control.x = SCALED( point->x );
          v_control.y = SCALED( point->y );

        Do_Conic:
          if ( point < limit )
          {
            FT_Vector  vec;
            FT_Vector  v_middle;


            point++;
            tags++;
            tag = FT_CURVE_TAG( tags[0] );

            vec.x = SCALED( point->x );
            vec.y = SCALED( point->y );

            if ( tag == FT_CURVE_TAG_ON )
            {
              FT_TRACE5(( "  conic to (%.2f, %.2f)"
                          " with control (%.2f, %.2f)\n",
                          vec.x / 64.0, vec.y / 64.0,
                          v_control.x / 64.0, v_control.y / 64.0 ));
              error = func_interface->conic_to( &v_control, &vec, user );
              if ( error )
                goto Exit;
              continue;
            }

            if ( tag != FT_CURVE_TAG_CONIC )
              goto Invalid_Outline;

            v_middle.x = ( v_control.x + vec.x ) / 2;
            v_middle.y = ( v_control.y + vec.y ) / 2;

            FT_TRACE5(( "  conic to (%.2f, %.2f)"
                        " with control (%.2f, %.2f)\n",
                        v_middle.x / 64.0, v_middle.y / 64.0,
                        v_control.x / 64.0, v_control.y / 64.0 ));
            error = func_interface->conic_to( &v_control, &v_middle, user );
            if ( error )
              goto Exit;

            v_control = vec;
            goto Do_Conic;
          }

          FT_TRACE5(( "  conic to (%.2f, %.2f)"
                      " with control (%.2f, %.2f)\n",
                      v_start.x / 64.0, v_start.y / 64.0,
                      v_control.x / 64.0, v_control.y / 64.0 ));
          error = func_interface->conic_to( &v_control, &v_start, user );
          goto Close;

        default:  /* FT_CURVE_TAG_CUBIC */
          {
            FT_Vector  vec1, vec2;


            if ( point + 1 > limit                             ||
                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
              goto Invalid_Outline;

            point += 2;
            tags  += 2;

            vec1.x = SCALED( point[-2].x );
            vec1.y = SCALED( point[-2].y );

            vec2.x = SCALED( point[-1].x );
            vec2.y = SCALED( point[-1].y );

            if ( point <= limit )
            {
              FT_Vector  vec;


              vec.x = SCALED( point->x );
              vec.y = SCALED( point->y );

              FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
                          vec.x / 64.0, vec.y / 64.0,
                          vec1.x / 64.0, vec1.y / 64.0,
                          vec2.x / 64.0, vec2.y / 64.0 ));
              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
              if ( error )
                goto Exit;
              continue;
            }

            FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
                        v_start.x / 64.0, v_start.y / 64.0,
                        vec1.x / 64.0, vec1.y / 64.0,
                        vec2.x / 64.0, vec2.y / 64.0 ));
            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
            goto Close;
          }
        }
      }

      /* close the contour with a line segment */
      FT_TRACE5(( "  line to (%.2f, %.2f)\n",
                  v_start.x / 64.0, v_start.y / 64.0 ));
      error = func_interface->line_to( &v_start, user );

    Close:
      if ( error )
        goto Exit;

      first = last + 1;
    }

    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
    return FT_Err_Ok;

  Exit:
    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
    return error;

  Invalid_Outline:
    return FT_Err_Invalid_Outline;
  }
Ejemplo n.º 4
0
  static FT_Error
  pcf_get_encodings( FT_Stream  stream,
                     PCF_Face   face )
  {
    FT_Error      error  = PCF_Err_Ok;
    FT_Memory     memory = FT_FACE(face)->memory;
    FT_ULong      format, size;
    int           firstCol, lastCol;
    int           firstRow, lastRow;
    int           nencoding, encodingOffset;
    int           i, j;
    PCF_Encoding  tmpEncoding, encoding = 0;


    error = pcf_seek_to_table_type( stream,
                                    face->toc.tables,
                                    face->toc.count,
                                    PCF_BDF_ENCODINGS,
                                    &format,
                                    &size );
    if ( error )
      return error;

    error = FT_Stream_EnterFrame( stream, 14 );
    if ( error )
      return error;

    format = FT_GET_ULONG_LE();

    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
    {
      firstCol          = FT_GET_SHORT();
      lastCol           = FT_GET_SHORT();
      firstRow          = FT_GET_SHORT();
      lastRow           = FT_GET_SHORT();
      face->defaultChar = FT_GET_SHORT();
    }
    else
    {
      firstCol          = FT_GET_SHORT_LE();
      lastCol           = FT_GET_SHORT_LE();
      firstRow          = FT_GET_SHORT_LE();
      lastRow           = FT_GET_SHORT_LE();
      face->defaultChar = FT_GET_SHORT_LE();
    }

    FT_Stream_ExitFrame( stream );

    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
      return PCF_Err_Invalid_File_Format;

    FT_TRACE4(( "pdf_get_encodings:\n" ));

    FT_TRACE4(( "  firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
                firstCol, lastCol, firstRow, lastRow ));

    nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );

    if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) )
      return PCF_Err_Out_Of_Memory;

    error = FT_Stream_EnterFrame( stream, 2 * nencoding );
    if ( error )
      goto Bail;

    for ( i = 0, j = 0 ; i < nencoding; i++ )
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        encodingOffset = FT_GET_SHORT();
      else
        encodingOffset = FT_GET_SHORT_LE();

      if ( encodingOffset != -1 )
      {
        tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
                                 firstRow ) * 256 ) +
                               ( ( i % ( lastCol - firstCol + 1 ) ) +
                                 firstCol );

        tmpEncoding[j].glyph = (FT_Short)encodingOffset;

        FT_TRACE5(( "  code %d (0x%04X): idx %d\n",
                    tmpEncoding[j].enc, tmpEncoding[j].enc,
                    tmpEncoding[j].glyph ));

        j++;
      }
    }
    FT_Stream_ExitFrame( stream );

    if ( FT_NEW_ARRAY( encoding, j ) )
      goto Bail;

    for ( i = 0; i < j; i++ )
    {
      encoding[i].enc   = tmpEncoding[i].enc;
      encoding[i].glyph = tmpEncoding[i].glyph;
    }

    face->nencodings = j;
    face->encodings  = encoding;
    FT_FREE( tmpEncoding );

    return error;

  Bail:
    FT_FREE( encoding );
    FT_FREE( tmpEncoding );
    return error;
  }
Ejemplo n.º 5
0
  cff_get_advances( FT_Face    face,
                    FT_UInt    start,
                    FT_UInt    count,
                    FT_Int32   flags,
                    FT_Fixed*  advances )
  {
    FT_UInt       nn;
    FT_Error      error = FT_Err_Ok;
    FT_GlyphSlot  slot  = face->glyph;


    if ( FT_IS_SFNT( face ) )
    {
      /* OpenType 1.7 mandates that the data from `hmtx' table be used; */
      /* it is no longer necessary that those values are identical to   */
      /* the values in the `CFF' table                                  */

      TT_Face   ttface = (TT_Face)face;
      FT_Short  dummy;


      if ( flags & FT_LOAD_VERTICAL_LAYOUT )
      {
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
        /* no fast retrieval for blended MM fonts without VVAR table */
        if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
             !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
          return FT_THROW( Unimplemented_Feature );
#endif

        /* check whether we have data from the `vmtx' table at all; */
        /* otherwise we extract the info from the CFF glyphstrings  */
        /* (instead of synthesizing a global value using the `OS/2' */
        /* table)                                                   */
        if ( !ttface->vertical_info )
          goto Missing_Table;

        for ( nn = 0; nn < count; nn++ )
        {
          FT_UShort  ah;


          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
                                                       1,
                                                       start + nn,
                                                       &dummy,
                                                       &ah );

          FT_TRACE5(( "  idx %d: advance height %d font unit%s\n",
                      start + nn,
                      ah,
                      ah == 1 ? "" : "s" ));
          advances[nn] = ah;
        }
      }
      else
      {
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
        /* no fast retrieval for blended MM fonts without HVAR table */
        if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
             !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
          return FT_THROW( Unimplemented_Feature );
#endif

        /* check whether we have data from the `hmtx' table at all */
        if ( !ttface->horizontal.number_Of_HMetrics )
          goto Missing_Table;

        for ( nn = 0; nn < count; nn++ )
        {
          FT_UShort  aw;


          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
                                                       0,
                                                       start + nn,
                                                       &dummy,
                                                       &aw );

          FT_TRACE5(( "  idx %d: advance width %d font unit%s\n",
                      start + nn,
                      aw,
                      aw == 1 ? "" : "s" ));
          advances[nn] = aw;
        }
      }

      return error;
    }

  Missing_Table:
    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;

    for ( nn = 0; nn < count; nn++ )
    {
      error = cff_glyph_load( slot, face->size, start + nn, flags );
      if ( error )
        break;

      advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
                     ? slot->linearVertAdvance
                     : slot->linearHoriAdvance;
    }

    return error;
  }
Ejemplo n.º 6
0
  static FT_Error
  pcf_get_bitmaps( FT_Stream  stream,
                   PCF_Face   face )
  {
    FT_Error   error  = PCF_Err_Ok;
    FT_Memory  memory = FT_FACE(face)->memory;
    FT_Long*   offsets;
    FT_Long    bitmapSizes[GLYPHPADOPTIONS];
    FT_ULong   format, size;
    int        nbitmaps, i, sizebitmaps = 0;


    error = pcf_seek_to_table_type( stream,
                                    face->toc.tables,
                                    face->toc.count,
                                    PCF_BITMAPS,
                                    &format,
                                    &size );
    if ( error )
      return error;

    error = FT_Stream_EnterFrame( stream, 8 );
    if ( error )
      return error;

    format = FT_GET_ULONG_LE();
    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
      nbitmaps  = FT_GET_ULONG();
    else
      nbitmaps  = FT_GET_ULONG_LE();

    FT_Stream_ExitFrame( stream );

    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
      return PCF_Err_Invalid_File_Format;

    FT_TRACE4(( "pcf_get_bitmaps:\n" ));

    FT_TRACE4(( "  number of bitmaps: %d\n", nbitmaps ));

    if ( nbitmaps != face->nmetrics )
      return PCF_Err_Invalid_File_Format;

    if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
      return error;

    for ( i = 0; i < nbitmaps; i++ )
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_LONG( offsets[i] );
      else
        (void)FT_READ_LONG_LE( offsets[i] );

      FT_TRACE5(( "  bitmap %d: offset %ld (0x%lX)\n",
                  i, offsets[i], offsets[i] ));
    }
    if ( error )
      goto Bail;

    for ( i = 0; i < GLYPHPADOPTIONS; i++ )
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_LONG( bitmapSizes[i] );
      else
        (void)FT_READ_LONG_LE( bitmapSizes[i] );
      if ( error )
        goto Bail;

      sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];

      FT_TRACE4(( "  padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
    }

    FT_TRACE4(( "  %d bitmaps, padding index %ld\n",
                nbitmaps,
                PCF_GLYPH_PAD_INDEX( format ) ));
    FT_TRACE4(( "  bitmap size = %d\n", sizebitmaps ));

    FT_UNUSED( sizebitmaps );       /* only used for debugging */

    for ( i = 0; i < nbitmaps; i++ )
    {
      /* rough estimate */
      if ( ( offsets[i] < 0 )              ||
           ( (FT_ULong)offsets[i] > size ) )
      {
        FT_ERROR(( "pcf_get_bitmaps:"));
        FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i ));
      }
      else
        face->metrics[i].bits = stream->pos + offsets[i];
    }

    face->bitmapsFormat = format;

  Bail:
    FT_FREE( offsets );
    return error;
  }
Ejemplo n.º 7
0
  static FT_Error
  pcf_get_metrics( FT_Stream  stream,
                   PCF_Face   face )
  {
    FT_Error    error    = PCF_Err_Ok;
    FT_Memory   memory   = FT_FACE(face)->memory;
    FT_ULong    format, size;
    PCF_Metric  metrics  = 0;
    FT_ULong    nmetrics, i;


    error = pcf_seek_to_table_type( stream,
                                    face->toc.tables,
                                    face->toc.count,
                                    PCF_METRICS,
                                    &format,
                                    &size );
    if ( error )
      return error;

    if ( FT_READ_ULONG_LE( format ) )
      goto Bail;

    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )     &&
         !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
      return PCF_Err_Invalid_File_Format;

    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_ULONG( nmetrics );
      else
        (void)FT_READ_ULONG_LE( nmetrics );
    }
    else
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_USHORT( nmetrics );
      else
        (void)FT_READ_USHORT_LE( nmetrics );
    }
    if ( error )
      return PCF_Err_Invalid_File_Format;

    face->nmetrics = nmetrics;

    FT_TRACE4(( "pcf_get_metrics:\n" ));

    FT_TRACE4(( "  number of metrics: %d\n", nmetrics ));

    /* rough estimate */
    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
    {
      if ( nmetrics > size / PCF_METRIC_SIZE )
        return PCF_Err_Invalid_Table;
    }
    else
    {
      if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
        return PCF_Err_Invalid_Table;
    }

    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
      return PCF_Err_Out_Of_Memory;

    metrics = face->metrics;
    for ( i = 0; i < nmetrics; i++ )
    {
      error = pcf_get_metric( stream, format, metrics + i );

      metrics[i].bits = 0;

      FT_TRACE5(( "  idx %d: width=%d, "
                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
                  i,
                  ( metrics + i )->characterWidth,
                  ( metrics + i )->leftSideBearing,
                  ( metrics + i )->rightSideBearing,
                  ( metrics + i )->ascent,
                  ( metrics + i )->descent,
                  ( metrics + i )->attributes ));

      if ( error )
        break;
    }

    if ( error )
      FT_FREE( face->metrics );

  Bail:
    return error;
  }
Ejemplo n.º 8
0
  static FT_Error
  pcf_get_encodings( FT_Stream  stream,
                     PCF_Face   face )
  {
    FT_Error      error;
    FT_Memory     memory = FT_FACE( face )->memory;
    FT_ULong      format, size;
    int           firstCol, lastCol;
    int           firstRow, lastRow;
    int           nencoding, encodingOffset;
    int           i, j, k;
    PCF_Encoding  encoding = NULL;


    error = pcf_seek_to_table_type( stream,
                                    face->toc.tables,
                                    face->toc.count,
                                    PCF_BDF_ENCODINGS,
                                    &format,
                                    &size );
    if ( error )
      return error;

    error = FT_Stream_EnterFrame( stream, 14 );
    if ( error )
      return error;

    format = FT_GET_ULONG_LE();

    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
    {
      firstCol          = FT_GET_SHORT();
      lastCol           = FT_GET_SHORT();
      firstRow          = FT_GET_SHORT();
      lastRow           = FT_GET_SHORT();
      face->defaultChar = FT_GET_SHORT();
    }
    else
    {
      firstCol          = FT_GET_SHORT_LE();
      lastCol           = FT_GET_SHORT_LE();
      firstRow          = FT_GET_SHORT_LE();
      lastRow           = FT_GET_SHORT_LE();
      face->defaultChar = FT_GET_SHORT_LE();
    }

    FT_Stream_ExitFrame( stream );

    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
      return FT_THROW( Invalid_File_Format );

    /* sanity checks */
    if ( firstCol < 0       ||
         firstCol > lastCol ||
         lastCol  > 0xFF    ||
         firstRow < 0       ||
         firstRow > lastRow ||
         lastRow  > 0xFF    )
      return FT_THROW( Invalid_Table );

    FT_TRACE4(( "pdf_get_encodings:\n" ));

    FT_TRACE4(( "  firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
                firstCol, lastCol, firstRow, lastRow ));

    nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );

    if ( FT_NEW_ARRAY( encoding, nencoding ) )
      return FT_THROW( Out_Of_Memory );

    error = FT_Stream_EnterFrame( stream, 2 * nencoding );
    if ( error )
      goto Bail;

    k = 0;
    for ( i = firstRow; i <= lastRow; i++ )
    {
      for ( j = firstCol; j <= lastCol; j++ )
      {
        if ( PCF_BYTE_ORDER( format ) == MSBFirst )
          encodingOffset = FT_GET_SHORT();
        else
          encodingOffset = FT_GET_SHORT_LE();

        if ( encodingOffset != -1 )
        {
          encoding[k].enc   = i * 256 + j;
          encoding[k].glyph = (FT_Short)encodingOffset;

          FT_TRACE5(( "  code %d (0x%04X): idx %d\n",
                      encoding[k].enc, encoding[k].enc, encoding[k].glyph ));

          k++;
        }
      }
    }
    FT_Stream_ExitFrame( stream );

    if ( FT_RENEW_ARRAY( encoding, nencoding, k ) )
      goto Bail;

    face->nencodings = k;
    face->encodings  = encoding;

    return error;

  Bail:
    FT_FREE( encoding );
    return error;
  }
Ejemplo n.º 9
0
  static FT_Error
  pcf_get_metrics( FT_Stream  stream,
                   PCF_Face   face )
  {
    FT_Error    error;
    FT_Memory   memory  = FT_FACE( face )->memory;
    FT_ULong    format, size;
    PCF_Metric  metrics = 0;
    FT_ULong    nmetrics, i;


    error = pcf_seek_to_table_type( stream,
                                    face->toc.tables,
                                    face->toc.count,
                                    PCF_METRICS,
                                    &format,
                                    &size );
    if ( error )
      return error;

    if ( FT_READ_ULONG_LE( format ) )
      goto Bail;

    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )     &&
         !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
      return FT_THROW( Invalid_File_Format );

    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_ULONG( nmetrics );
      else
        (void)FT_READ_ULONG_LE( nmetrics );
    }
    else
    {
      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
        (void)FT_READ_USHORT( nmetrics );
      else
        (void)FT_READ_USHORT_LE( nmetrics );
    }
    if ( error )
      return FT_THROW( Invalid_File_Format );

    face->nmetrics = nmetrics;

    if ( !nmetrics )
      return FT_THROW( Invalid_Table );

    FT_TRACE4(( "pcf_get_metrics:\n" ));

    FT_TRACE4(( "  number of metrics: %d\n", nmetrics ));

    /* rough estimate */
    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
    {
      if ( nmetrics > size / PCF_METRIC_SIZE )
        return FT_THROW( Invalid_Table );
    }
    else
    {
      if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
        return FT_THROW( Invalid_Table );
    }

    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
      return FT_THROW( Out_Of_Memory );

    metrics = face->metrics;
    for ( i = 0; i < nmetrics; i++, metrics++ )
    {
      error = pcf_get_metric( stream, format, metrics );

      metrics->bits = 0;

      FT_TRACE5(( "  idx %d: width=%d, "
                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
                  i,
                  metrics->characterWidth,
                  metrics->leftSideBearing,
                  metrics->rightSideBearing,
                  metrics->ascent,
                  metrics->descent,
                  metrics->attributes ));

      if ( error )
        break;

      /* sanity checks -- those values are used in `PCF_Glyph_Load' to     */
      /* compute a glyph's bitmap dimensions, thus setting them to zero in */
      /* case of an error disables this particular glyph only              */
      if ( metrics->rightSideBearing < metrics->leftSideBearing ||
           metrics->ascent + metrics->descent < 0               )
      {
        metrics->characterWidth   = 0;
        metrics->leftSideBearing  = 0;
        metrics->rightSideBearing = 0;
        metrics->ascent           = 0;
        metrics->descent          = 0;

        FT_TRACE0(( "pcf_get_metrics:"
                    " invalid metrics for glyph %d\n", i ));
      }
    }

    if ( error )
      FT_FREE( face->metrics );

  Bail:
    return error;
  }
Ejemplo n.º 10
0
  cff_get_advances( FT_Face    face,
                    FT_UInt    start,
                    FT_UInt    count,
                    FT_Int32   flags,
                    FT_Fixed*  advances )
  {
    FT_UInt       nn;
    FT_Error      error = FT_Err_Ok;
    FT_GlyphSlot  slot  = face->glyph;


    if ( FT_IS_SFNT( face ) )
    {
      /* OpenType 1.7 mandates that the data from `hmtx' table be used; */
      /* it is no longer necessary that those values are identical to   */
      /* the values in the `CFF' table                                  */

      TT_Face   ttface = (TT_Face)face;
      FT_Short  dummy;


      if ( flags & FT_LOAD_VERTICAL_LAYOUT )
      {
        /* check whether we have data from the `vmtx' table at all; */
        /* otherwise we extract the info from the CFF glyphstrings  */
        /* (instead of synthesizing a global value using the `OS/2' */
        /* table)                                                   */
        if ( !ttface->vertical_info )
          goto Missing_Table;

        for ( nn = 0; nn < count; nn++ )
        {
          FT_UShort  ah;


          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
                                                       1,
                                                       start + nn,
                                                       &dummy,
                                                       &ah );

          FT_TRACE5(( "  idx %d: advance height %d font units\n",
                      start + nn, ah ));
          advances[nn] = ah;
        }
      }
      else
      {
        /* check whether we have data from the `hmtx' table at all */
        if ( !ttface->horizontal.number_Of_HMetrics )
          goto Missing_Table;

        for ( nn = 0; nn < count; nn++ )
        {
          FT_UShort  aw;


          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
                                                       0,
                                                       start + nn,
                                                       &dummy,
                                                       &aw );

          FT_TRACE5(( "  idx %d: advance width %d font units\n",
                      start + nn, aw ));
          advances[nn] = aw;
        }
      }

      return error;
    }

  Missing_Table:
    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;

    for ( nn = 0; nn < count; nn++ )
    {
      error = cff_glyph_load( slot, face->size, start + nn, flags );
      if ( error )
        break;

      advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
                     ? slot->linearVertAdvance
                     : slot->linearHoriAdvance;
    }

    return error;
  }