misc/libfreetype/src/pfr/pfrdrivr.c
changeset 5172 88f2e05288ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libfreetype/src/pfr/pfrdrivr.c	Mon Apr 25 01:46:54 2011 +0200
@@ -0,0 +1,214 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pfrdrivr.c                                                             */
+/*                                                                         */
+/*    FreeType PFR driver interface (body).                                */
+/*                                                                         */
+/*  Copyright 2002, 2003, 2004, 2006, 2008, 2010 by                        */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_SERVICE_PFR_H
+#include FT_SERVICE_XFREE86_NAME_H
+#include "pfrdrivr.h"
+#include "pfrobjs.h"
+
+#include "pfrerror.h"
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  pfr_get_kerning( FT_Face     pfrface,     /* PFR_Face */
+                   FT_UInt     left,
+                   FT_UInt     right,
+                   FT_Vector  *avector )
+  {
+    PFR_Face     face = (PFR_Face)pfrface;
+    PFR_PhyFont  phys = &face->phy_font;
+
+
+    pfr_face_get_kerning( pfrface, left, right, avector );
+
+    /* convert from metrics to outline units when necessary */
+    if ( phys->outline_resolution != phys->metrics_resolution )
+    {
+      if ( avector->x != 0 )
+        avector->x = FT_MulDiv( avector->x, phys->outline_resolution,
+                                            phys->metrics_resolution );
+
+      if ( avector->y != 0 )
+        avector->y = FT_MulDiv( avector->x, phys->outline_resolution,
+                                            phys->metrics_resolution );
+    }
+
+    return PFR_Err_Ok;
+  }
+
+
+ /*
+  *  PFR METRICS SERVICE
+  *
+  */
+
+  FT_CALLBACK_DEF( FT_Error )
+  pfr_get_advance( FT_Face   pfrface,       /* PFR_Face */
+                   FT_UInt   gindex,
+                   FT_Pos   *anadvance )
+  {
+    PFR_Face  face  = (PFR_Face)pfrface;
+    FT_Error  error = PFR_Err_Invalid_Argument;
+
+
+    *anadvance = 0;
+
+    if ( !gindex )
+      goto Exit;
+
+    gindex--;
+
+    if ( face )
+    {
+      PFR_PhyFont  phys = &face->phy_font;
+
+
+      if ( gindex < phys->num_chars )
+      {
+        *anadvance = phys->chars[gindex].advance;
+        error = PFR_Err_Ok;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  pfr_get_metrics( FT_Face    pfrface,      /* PFR_Face */
+                   FT_UInt   *anoutline_resolution,
+                   FT_UInt   *ametrics_resolution,
+                   FT_Fixed  *ametrics_x_scale,
+                   FT_Fixed  *ametrics_y_scale )
+  {
+    PFR_Face     face = (PFR_Face)pfrface;
+    PFR_PhyFont  phys = &face->phy_font;
+    FT_Fixed     x_scale, y_scale;
+    FT_Size      size = face->root.size;
+
+
+    if ( anoutline_resolution )
+      *anoutline_resolution = phys->outline_resolution;
+
+    if ( ametrics_resolution )
+      *ametrics_resolution = phys->metrics_resolution;
+
+    x_scale = 0x10000L;
+    y_scale = 0x10000L;
+
+    if ( size )
+    {
+      x_scale = FT_DivFix( size->metrics.x_ppem << 6,
+                           phys->metrics_resolution );
+
+      y_scale = FT_DivFix( size->metrics.y_ppem << 6,
+                           phys->metrics_resolution );
+    }
+
+    if ( ametrics_x_scale )
+      *ametrics_x_scale = x_scale;
+
+    if ( ametrics_y_scale )
+      *ametrics_y_scale = y_scale;
+
+    return PFR_Err_Ok;
+  }
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FT_Service_PfrMetricsRec  pfr_metrics_service_rec =
+  {
+    pfr_get_metrics,
+    pfr_face_get_kerning,
+    pfr_get_advance
+  };
+
+
+ /*
+  *  SERVICE LIST
+  *
+  */
+
+  static const FT_ServiceDescRec  pfr_services[] =
+  {
+    { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec },
+    { FT_SERVICE_ID_XF86_NAME,   FT_XF86_FORMAT_PFR },
+    { NULL, NULL }
+  };
+
+
+  FT_CALLBACK_DEF( FT_Module_Interface )
+  pfr_get_service( FT_Module         module,
+                   const FT_String*  service_id )
+  {
+    FT_UNUSED( module );
+
+    return ft_service_list_lookup( pfr_services, service_id );
+  }
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FT_Driver_ClassRec  pfr_driver_class =
+  {
+    {
+      FT_MODULE_FONT_DRIVER     |
+      FT_MODULE_DRIVER_SCALABLE,
+
+      sizeof( FT_DriverRec ),
+
+      "pfr",
+      0x10000L,
+      0x20000L,
+
+      NULL,
+
+      0,
+      0,
+      pfr_get_service
+    },
+
+    sizeof( PFR_FaceRec ),
+    sizeof( PFR_SizeRec ),
+    sizeof( PFR_SlotRec ),
+
+    pfr_face_init,
+    pfr_face_done,
+    0,                  /* FT_Size_InitFunc */
+    0,                  /* FT_Size_DoneFunc */
+    pfr_slot_init,
+    pfr_slot_done,
+
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+    ft_stub_set_char_sizes,
+    ft_stub_set_pixel_sizes,
+#endif
+    pfr_slot_load,
+
+    pfr_get_kerning,
+    0,                  /* FT_Face_AttachFunc      */
+    0,                   /* FT_Face_GetAdvancesFunc */
+    0,                  /* FT_Size_RequestFunc */
+    0,                  /* FT_Size_SelectFunc  */
+  };
+
+
+/* END */