Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gpdf/ChangeLog,v
retrieving revision 1.393
retrieving revision 1.395
diff -u -r1.393 -r1.395
--- ChangeLog	19 Jul 2004 16:01:01 -0000	1.393
+++ ChangeLog	24 Jul 2004 19:42:06 -0000	1.395
@@ -1,6 +1,13 @@
+2004-07-24  Martin Kretzschmar  <m_kretzschmar@gmx.net>
+
+	* xpdf/GPOutputDev.cc (getFontFaceEmbedded): rewrite, this time
+	respect encoding information/CID-to-GID stuff etc. Fixes Bug #148362.
+	(lookupGlyph): update for changes in getFontFaceEmbedded
+	(drawString): ditto.
+
 2004-07-20  Martin Kretzschmar  <m_kretzschmar@gmx.net>
 
 	* xpdf/gpdf-view.cc (gpdf_view_zoom): add the hack Federico did
 	for page changes for zooming as well. Still flashes when zooming,
 	but only in the background color, better than flashing with the
 	old content IMHO.
Index: xpdf/GPOutputDev.cc
===================================================================
RCS file: /cvs/gnome/gpdf/xpdf/GPOutputDev.cc,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- xpdf/GPOutputDev.cc	23 May 2004 20:56:48 -0000	1.30
+++ xpdf/GPOutputDev.cc	24 Jul 2004 19:42:06 -0000	1.31
@@ -30,6 +30,7 @@
 #include "GfxFont.h"
 #include "GPOutputDev.h"
 #include "FoFiTrueType.h"
+#include "FoFiType1C.h"
 
 #ifdef HAVE_FONT_EMBEDDING
 #  include "gpdf-g-switch.h"
@@ -208,78 +209,160 @@
     return gff;
   }
 
-#ifdef PDF_DEBUG
-  switch (font->getType()) {
-  case fontType1: g_message("fontType1"); break;
-  case fontType1C: g_message("fontType1C"); break;
-  case fontTrueType: g_message("fontTrueType"); break;
-  case fontCIDType2: g_message("fontCIDType2"); break;
-  case fontCIDType0: g_message("fontCIDType0"); break;
-  case fontCIDType0C: g_message("fontCIDType0C"); break;
-  case fontType3: g_message("fontType3"); break;
-  case fontUnknownType: g_message("fontUnknownType"); break;
-  }
-#endif /* PDF_DEBUG */
+  // Extract the embedded font file
+  Ref embRef;
+  Object refObj, strObj;
+  
+  font->getEmbeddedFontID(&embRef);
+
+  refObj.initRef(embRef.num, embRef.gen);
+  refObj.fetch(xref, &strObj);
+  refObj.free();
+
+  guchar *contents;
+  gsize length;
+
+  strObj.streamReset();
+  if (!getStreamContents(strObj.getStream(), &contents, &length))
+    g_assert_not_reached(); /* FIXME */
+  strObj.free();
 
   switch (font->getType()) {
-  case fontTrueType:
   case fontType1:
   case fontType1C: {
-    Ref embRef;
-    Object refObj, strObj;
-
-    font->getEmbeddedFontID(&embRef);
-
-    refObj.initRef(embRef.num, embRef.gen);
-    refObj.fetch(xref, &strObj);
-    refObj.free();
-
-    guchar *contents;
-    gsize length;
-
-    strObj.streamReset();
-    if (!getStreamContents(strObj.getStream(), &contents, &length))
-      g_assert_not_reached(); /* FIXME */
-    strObj.free();
-
-    if (font->getType() == fontTrueType ||
-	font->getType() == fontCIDType2) {
-      /* FIXME THIS NEEDS ERROR CHECKING */
-      gint fd;
-      gchar *temp_name;
-
-      fd = g_file_open_tmp ("gpdf-ttf-XXXXXX", &temp_name, NULL);
-      FILE *f = fdopen (fd, "wb");
-
-      FoFiTrueType *ff = FoFiTrueType::make((char *)contents, length);
-      ff->writeTTF(&fileWrite, f);
-      delete ff;
-      g_free(contents);
-
-      fclose(f);
-
-      g_file_get_contents(temp_name, (gchar **)&contents, &length, NULL);
-
-      unlink(temp_name);
-      g_free(temp_name);
-    }
-
-    DBG (g_message("Adding font face for %s", font_name));
+    gchar **encoding;
+    gushort *code_to_gid;
+    const char *name;
+
+    gff = gpdf_font_face_download((const guchar *)font_name,
+				  (const guchar *)"",
+				  GNOME_FONT_REGULAR, FALSE,
+				  contents, length);
+
+    encoding = ((Gfx8BitFont *)font)->getEncoding();
+    code_to_gid = g_new0(gushort, 256);
+
+    GFF_LOADED(gff);
+
+    for (int i = 0; i < 256; ++i)
+      if ((name = encoding[i]) != NULL)
+	code_to_gid[i] = (gushort)FT_Get_Name_Index(gff->ft_face,
+						    (FT_String *)name);
+
+    g_object_set_data((GObject *)gff, "code-to-gid-len",
+		      GINT_TO_POINTER(256));
+    g_object_set_data_full((GObject *)gff, "code-to-gid", code_to_gid,
+			   (GDestroyNotify)g_free);
+    break;
+  }
+  case fontTrueType: {
+    FoFiTrueType *ff;
+    gint fd;
+    gchar *temp_name;
+    FILE *f;
+    gushort *code_to_gid;
+
+    ff = FoFiTrueType::make((char *)contents, length); // FIXME error handling
+
+    code_to_gid = ((Gfx8BitFont *)font)->getCodeToGIDMap(ff); // this is g(oo)malloc'd
+
+    fd = g_file_open_tmp("gpdf-ttf-XXXXXX", &temp_name, NULL);
+    f = fdopen(fd, "wb");
+    ff->writeTTF(&fileWrite, f);
+    delete ff;
+    g_free(contents);
+    fclose(f);
+
+    g_file_get_contents(temp_name, (gchar **)&contents, &length, NULL);
+    unlink(temp_name);
+    g_free(temp_name);
+
+    gff = gpdf_font_face_download((const guchar *)font_name,
+				  (const guchar *)"",
+				  GNOME_FONT_REGULAR, FALSE,
+				  contents, length);
+
+    g_object_set_data((GObject *)gff, "code-to-gid-len",
+		      GINT_TO_POINTER(256));
+    g_object_set_data_full((GObject *)gff, "code-to-gid", code_to_gid,
+			   (GDestroyNotify)gfree);
+    break;
+  }
+  case fontCIDType0: {
+    gff = gpdf_font_face_download((const guchar *)font_name,
+				  (const guchar *)"",
+				  GNOME_FONT_REGULAR, FALSE,
+				  contents, length);
+    g_object_set_data((GObject *)gff, "code-to-gid-len",
+		      GINT_TO_POINTER(0));
+    break;
+  }
+  case fontCIDType0C: {
+    FoFiType1C *ff;
+    gint n_cids;
+    gushort *code_to_gid;
     
-    gff = gpdf_font_face_download ((const guchar *)font_name,
-				    (const guchar *)"",
-				    GNOME_FONT_REGULAR, FALSE,
-				    contents, length);
-
-    g_hash_table_insert(embeddedFonts, g_strdup(font_name), gff);
-
-    g_object_ref (G_OBJECT(gff));
-    return gff;
+    ff = FoFiType1C::make((char *)contents, length);
+    code_to_gid = ff->getCIDToGIDMap(&n_cids); // this is g(oo)malloc'd
+    delete ff;
+
+    gff = gpdf_font_face_download((const guchar *)font_name,
+				  (const guchar *)"",
+				  GNOME_FONT_REGULAR, FALSE,
+				  contents, length);
+
+    g_object_set_data((GObject *)gff, "code-to-gid-len",
+		      GINT_TO_POINTER(n_cids));
+    g_object_set_data_full((GObject *)gff, "code-to-gid", code_to_gid,
+			   (GDestroyNotify)gfree);
+    break;
+  }
+  case fontCIDType2: {
+    FoFiTrueType *ff;
+    gint fd;
+    gchar *temp_name;
+    FILE *f;
+    gint n_cids;    
+    gushort *code_to_gid;
+
+    ff = FoFiTrueType::make((char *)contents, length); // FIXME error handling
+
+    fd = g_file_open_tmp("gpdf-ttf-XXXXXX", &temp_name, NULL);
+    f = fdopen(fd, "wb");
+    ff->writeTTF(&fileWrite, f);
+    delete ff;
+    g_free(contents);
+    fclose(f);
+
+    g_file_get_contents(temp_name, (gchar **)&contents, &length, NULL);
+    unlink(temp_name);
+    g_free(temp_name);
+
+    gff = gpdf_font_face_download((const guchar *)font_name,
+				  (const guchar *)"",
+				  GNOME_FONT_REGULAR, FALSE,
+				  contents, length);
+
+    n_cids = ((GfxCIDFont *)font)->getCIDToGIDLen();
+    code_to_gid = (gushort *)g_memdup(((GfxCIDFont *)font)->getCIDToGID(),
+				      n_cids * sizeof(gushort));
+
+    g_object_set_data((GObject *)gff, "code-to-gid-len",
+		      GINT_TO_POINTER(n_cids));
+    g_object_set_data_full((GObject *)gff, "code-to-gid", code_to_gid,
+			   (GDestroyNotify)g_free);
+    break;
   }
   default:
-    /* FIXME */
     return getFontFaceFallback(font);
   }
+
+  DBG (g_message("Adding font face for %s", font_name));
+  
+  g_hash_table_insert(embeddedFonts, g_strdup(font_name), gff);
+    
+  g_object_ref (G_OBJECT(gff));
+  return gff;
 #else
   return NULL;
 #endif /* HAVE_FONT_EMBEDDING */
@@ -538,12 +621,6 @@
   gnome_font = gnome_font_face_get_font_default(font_face,
 						state->getFontSize());
   gnome_font_face_unref(font_face);
-
-//   DBG (g_message("updateFont: pdf: %s, gp: %s",
-// 	    state->getFont()->getName()
-// 	    ? state->getFont()->getName()->getCString()
-// 	    : "none",
-// 	    gnome_font_get_name(gnome_font)));
 }
 
 void GPOutputDev::updateTextPos(GfxState *state)
@@ -648,10 +725,20 @@
 	  ((gint)(CLAMP (alpha, 0.0, 1.0) * 255.999)));
 }
 
-static gint lookupGlyph(GnomeFont *font, CharCode c, Unicode u)
+static gint lookupGlyph(GnomeFont *font, CharCode c)
 {
-  /* FIXME */
-  return gnome_font_lookup_default(font, u > 0 ? u : c);
+  gint code_to_gid_len;
+  const gushort *code_to_gid;
+
+  code_to_gid = (const gushort *)g_object_get_data((GObject *)font->face,
+						   "code-to-gid");
+  code_to_gid_len = GPOINTER_TO_INT(g_object_get_data((GObject *)font->face,
+						      "code-to-gid-len"));
+
+  if (code_to_gid && (gint)c < code_to_gid_len)
+    return code_to_gid[c];
+  else
+    return c;
 }
 
 // text drawing
@@ -711,8 +798,13 @@
     DBG (if (uLen > 1)
       g_warning("drawString: uLen > 1; p: %x", (gint)*p));
 
-    gnome_glyphlist_glyph(ggl,
-			  lookupGlyph(gnome_font, code, uLen > 0 ? u[0] : 0));
+    Ref embRef;
+    if (font->getEmbeddedFontID(&embRef)) // FIXME HACK
+      gnome_glyphlist_glyph(ggl, lookupGlyph(gnome_font, code));
+    else
+      gnome_glyphlist_glyph(
+	ggl, gnome_font_lookup_default(gnome_font, uLen > 0 ? u[0] : code));
+
     gnome_glyphlist_rmoveto(ggl, dx, dy);
 
     text_pos_x += dx;
