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;
      int           size_set = 0;


      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) == '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' )
            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;

      root->num_glyphs = face->nmetrics;

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

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

        size_set = 1;
      }
      else
      {
        prop = pcf_find_property( face, "POINT_SIZE" );
        if ( prop != NULL )
        {
          PCF_Property  xres, yres, avgw;


          xres = pcf_find_property( face, "RESOLUTION_X" );
          yres = pcf_find_property( face, "RESOLUTION_Y" );
          avgw = pcf_find_property( face, "AVERAGE_WIDTH" );

          if ( ( yres != NULL ) && ( xres != NULL ) )
          {
            root->available_sizes->height =
              (FT_Short)( prop->value.integer *
                          yres->value.integer / 720 );

              root->available_sizes->width =
                (FT_Short)( prop->value.integer *
                            xres->value.integer / 720 );

            size_set = 1;
          }
        }
      }

      if (size_set == 0 )
      {
        root->available_sizes->width  = 12;
        root->available_sizes->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;
  }
Exemple #2
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;
  }
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;
}