misc/libfreetype/src/pfr/pfrcmap.c
changeset 5172 88f2e05288ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libfreetype/src/pfr/pfrcmap.c	Mon Apr 25 01:46:54 2011 +0200
@@ -0,0 +1,166 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pfrcmap.c                                                              */
+/*                                                                         */
+/*    FreeType PFR cmap handling (body).                                   */
+/*                                                                         */
+/*  Copyright 2002, 2007, 2009 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 "pfrcmap.h"
+#include "pfrobjs.h"
+
+#include "pfrerror.h"
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  pfr_cmap_init( PFR_CMap  cmap )
+  {
+    FT_Error  error = PFR_Err_Ok;
+    PFR_Face  face  = (PFR_Face)FT_CMAP_FACE( cmap );
+
+
+    cmap->num_chars = face->phy_font.num_chars;
+    cmap->chars     = face->phy_font.chars;
+
+    /* just for safety, check that the character entries are correctly */
+    /* sorted in increasing character code order                       */
+    {
+      FT_UInt  n;
+
+
+      for ( n = 1; n < cmap->num_chars; n++ )
+      {
+        if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
+        {
+          error = PFR_Err_Invalid_Table;
+          goto Exit;
+        }
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( void )
+  pfr_cmap_done( PFR_CMap  cmap )
+  {
+    cmap->chars     = NULL;
+    cmap->num_chars = 0;
+  }
+
+
+  FT_CALLBACK_DEF( FT_UInt )
+  pfr_cmap_char_index( PFR_CMap   cmap,
+                       FT_UInt32  char_code )
+  {
+    FT_UInt   min = 0;
+    FT_UInt   max = cmap->num_chars;
+    FT_UInt   mid;
+    PFR_Char  gchar;
+
+
+    while ( min < max )
+    {
+      mid   = min + ( max - min ) / 2;
+      gchar = cmap->chars + mid;
+
+      if ( gchar->char_code == char_code )
+        return mid + 1;
+
+      if ( gchar->char_code < char_code )
+        min = mid + 1;
+      else
+        max = mid;
+    }
+    return 0;
+  }
+
+
+  FT_CALLBACK_DEF( FT_UInt32 )
+  pfr_cmap_char_next( PFR_CMap    cmap,
+                      FT_UInt32  *pchar_code )
+  {
+    FT_UInt    result    = 0;
+    FT_UInt32  char_code = *pchar_code + 1;
+
+
+  Restart:
+    {
+      FT_UInt   min = 0;
+      FT_UInt   max = cmap->num_chars;
+      FT_UInt   mid;
+      PFR_Char  gchar;
+
+
+      while ( min < max )
+      {
+        mid   = min + ( ( max - min ) >> 1 );
+        gchar = cmap->chars + mid;
+
+        if ( gchar->char_code == char_code )
+        {
+          result = mid;
+          if ( result != 0 )
+          {
+            result++;
+            goto Exit;
+          }
+
+          char_code++;
+          goto Restart;
+        }
+
+        if ( gchar->char_code < char_code )
+          min = mid+1;
+        else
+          max = mid;
+      }
+
+      /* we didn't find it, but we have a pair just above it */
+      char_code = 0;
+
+      if ( min < cmap->num_chars )
+      {
+        gchar  = cmap->chars + min;
+        result = min;
+        if ( result != 0 )
+        {
+          result++;
+          char_code = gchar->char_code;
+        }
+      }
+    }
+
+  Exit:
+    *pchar_code = char_code;
+    return result;
+  }
+
+
+  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
+  pfr_cmap_class_rec =
+  {
+    sizeof ( PFR_CMapRec ),
+
+    (FT_CMap_InitFunc)     pfr_cmap_init,
+    (FT_CMap_DoneFunc)     pfr_cmap_done,
+    (FT_CMap_CharIndexFunc)pfr_cmap_char_index,
+    (FT_CMap_CharNextFunc) pfr_cmap_char_next,
+
+    NULL, NULL, NULL, NULL, NULL
+  };
+
+
+/* END */