[PATCH 8/9] cairo: use cairo_show_text_glyphs() when printing

Adrian Johnson ajohnson at redneon.com
Fri Aug 5 06:31:51 PDT 2011


This will allow cairo to setup the correct toUnicode or glyph names to
ensure text can be extracted.
---
 poppler/CairoOutputDev.cc |   43 ++++++++++++++++++++++++++++++++++++++++---
 poppler/CairoOutputDev.h  |    6 ++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 6e7fd53..75a9aea 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -60,6 +60,7 @@
 #include "CairoOutputDev.h"
 #include "CairoFontEngine.h"
 #include "CairoRescaleBox.h"
+#include "UTF8.h"
 //------------------------------------------------------------------------
 
 // #define LOG_CAIRO
@@ -149,6 +150,7 @@ CairoOutputDev::CairoOutputDev() {
 
   text = NULL;
   actualText = NULL;
+  has_showtextglyphs = gFalse;
 }
 
 CairoOutputDev::~CairoOutputDev() {
@@ -187,6 +189,7 @@ void CairoOutputDev::setCairo(cairo_t *cairo)
 	/* save the initial matrix so that we can use it for type3 fonts. */
 	//XXX: is this sufficient? could we miss changes to the matrix somehow?
 	cairo_get_matrix(cairo, &orig_matrix);
+	has_showtextglyphs = cairo_surface_has_show_text_glyphs (cairo_get_target (cairo));
   } else {
     this->cairo = NULL;
     this->cairo_shape = NULL;
@@ -994,6 +997,13 @@ void CairoOutputDev::beginString(GfxState *state, GooString *s)
 
   glyphs = (cairo_glyph_t *) gmallocn (len, sizeof (cairo_glyph_t));
   glyphCount = 0;
+  if (has_showtextglyphs) {
+    clusters = (cairo_text_cluster_t *) gmallocn (len, sizeof (cairo_text_cluster_t));
+    clusterCount = 0;
+    utf8Max = len*2; // start with twice the number of glyphs. we will realloc if we need more.
+    utf8 = (char *) gmalloc (utf8Max);
+    utf8Count = 0;
+  }
 }
 
 void CairoOutputDev::drawChar(GfxState *state, double x, double y,
@@ -1006,6 +1016,24 @@ void CairoOutputDev::drawChar(GfxState *state, double x, double y,
     glyphs[glyphCount].x = x - originX;
     glyphs[glyphCount].y = y - originY;
     glyphCount++;
+    if (has_showtextglyphs) {
+      if (utf8Max - utf8Count < uLen*6) {
+        // utf8 encoded characters can be up to 6 bytes
+	if (utf8Max > uLen*6)
+	  utf8Max *= 2;
+	else
+	  utf8Max += 2*uLen*6;
+	utf8 = (char *) grealloc (utf8, utf8Max);
+      }
+      clusters[clusterCount].num_bytes = 0;
+      for (int i = 0; i < uLen; i++) {
+	int size = mapUTF8 (u[i], utf8 + utf8Count, utf8Max - utf8Count);
+	utf8Count += size;
+	clusters[clusterCount].num_bytes += size;
+      }
+      clusters[clusterCount].num_glyphs = 1;
+      clusterCount++;
+    }
   }
 
   if (!text)
@@ -1034,15 +1062,18 @@ void CairoOutputDev::endString(GfxState *state)
     glyphs = NULL;
     return;
   }
-  
+
   if (!(render & 1) && !haveCSPattern) {
     LOG (printf ("fill string\n"));
     cairo_set_source (cairo, fill_pattern);
-    cairo_show_glyphs (cairo, glyphs, glyphCount);
+    if (has_showtextglyphs)
+      cairo_show_text_glyphs (cairo, utf8, utf8Count, glyphs, glyphCount, clusters, clusterCount, (cairo_text_cluster_flags_t)0);
+    else
+        cairo_show_glyphs (cairo, glyphs, glyphCount);
     if (cairo_shape)
       cairo_show_glyphs (cairo_shape, glyphs, glyphCount);
   }
-  
+
   // stroke
   if ((render & 3) == 1 || (render & 3) == 2) {
     LOG (printf ("stroke string\n"));
@@ -1083,6 +1114,12 @@ void CairoOutputDev::endString(GfxState *state)
 
   gfree (glyphs);
   glyphs = NULL;
+  if (has_showtextglyphs) {
+    gfree (clusters);
+    clusters = NULL;
+    gfree (utf8);
+    utf8 = NULL;
+  }
 }
 
 
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 730a23c..9b2fa0e 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -304,6 +304,12 @@ protected:
   cairo_surface_t *surface;
   cairo_glyph_t *glyphs;
   int glyphCount;
+  GBool has_showtextglyphs;
+  cairo_text_cluster_t *clusters;
+  int clusterCount;
+  char *utf8;
+  int utf8Count;
+  int utf8Max;
   cairo_path_t *textClipPath;
   GBool inType3Char;		// inside a Type 3 CharProc
   double t3_glyph_wx, t3_glyph_wy;
-- 
1.7.4.1


--------------070003040404090602010801--


More information about the poppler mailing list