[PATCH 1/2] cairo: only use show_text_glyphs if the surface supports it and the font has toUnicode

Adrian Johnson ajohnson at redneon.com
Mon Aug 22 04:56:24 PDT 2011


When generating pdf output, fonts that do not have toUnicode cause an
excessive number of empty text ActualText entries to be written due to
glyphs that do not have have a mapping.
---
 poppler/CairoOutputDev.cc |   12 ++++++++----
 poppler/CairoOutputDev.h  |    1 +
 poppler/GfxFont.h         |    3 +++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 08c28ec..e894b4e 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -138,6 +138,7 @@ CairoOutputDev::CairoOutputDev() {
   currentFont = NULL;
   prescaleImages = gTrue;
   printing = gTrue;
+  use_show_text_glyphs = gFalse;
   inType3Char = gFalse;
   t3_glyph_has_bbox = gFalse;
 
@@ -578,6 +579,9 @@ void CairoOutputDev::updateFont(GfxState *state) {
 
   font_face = currentFont->getFontFace();
   cairo_set_font_face (cairo, font_face);
+
+  use_show_text_glyphs = state->getFont()->hasToUnicodeCMap() &&
+    cairo_surface_has_show_text_glyphs (cairo_get_target (cairo));
  
   double fontSize = state->getFontSize();
   double *m = state->getTextMat();
@@ -1001,7 +1005,7 @@ void CairoOutputDev::beginString(GfxState *state, GooString *s)
 
   glyphs = (cairo_glyph_t *) gmallocn (len, sizeof (cairo_glyph_t));
   glyphCount = 0;
-  if (printing) {
+  if (use_show_text_glyphs) {
     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.
@@ -1020,7 +1024,7 @@ void CairoOutputDev::drawChar(GfxState *state, double x, double y,
     glyphs[glyphCount].x = x - originX;
     glyphs[glyphCount].y = y - originY;
     glyphCount++;
-    if (printing) {
+    if (use_show_text_glyphs) {
       if (utf8Max - utf8Count < uLen*6) {
         // utf8 encoded characters can be up to 6 bytes
 	if (utf8Max > uLen*6)
@@ -1070,7 +1074,7 @@ void CairoOutputDev::endString(GfxState *state)
   if (!(render & 1) && !haveCSPattern) {
     LOG (printf ("fill string\n"));
     cairo_set_source (cairo, fill_pattern);
-    if (printing)
+    if (use_show_text_glyphs)
       cairo_show_text_glyphs (cairo, utf8, utf8Count, glyphs, glyphCount, clusters, clusterCount, (cairo_text_cluster_flags_t)0);
     else
         cairo_show_glyphs (cairo, glyphs, glyphCount);
@@ -1118,7 +1122,7 @@ void CairoOutputDev::endString(GfxState *state)
 
   gfree (glyphs);
   glyphs = NULL;
-  if (printing) {
+  if (use_show_text_glyphs) {
     gfree (clusters);
     clusters = NULL;
     gfree (utf8);
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 67f7810..386e844 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -301,6 +301,7 @@ protected:
   cairo_matrix_t orig_matrix;
   GBool needFontUpdate;                // set when the font needs to be updated
   GBool printing;
+  GBool use_show_text_glyphs;
   cairo_surface_t *surface;
   cairo_glyph_t *glyphs;
   int glyphCount;
diff --git a/poppler/GfxFont.h b/poppler/GfxFont.h
index 09af062..9550398 100644
--- a/poppler/GfxFont.h
+++ b/poppler/GfxFont.h
@@ -221,6 +221,9 @@ public:
 			  Unicode **u, int *uLen,
 			  double *dx, double *dy, double *ox, double *oy) = 0;
 
+  // Does this font have a toUnicode map?
+  GBool hasToUnicodeCMap() { return hasToUnicode; }
+
   /* XXX: dfp shouldn't be public, however the font finding code is currently in
    * GlobalParams. Instead it should be inside the GfxFont class. However,
    * getDisplayFont currently uses FCcfg so moving it is not as simple. */
-- 
1.7.4.1


--------------070204050201080606010207
Content-Type: text/x-patch;
 name="0002-update-SEE-ALSO-section-of-man-pages.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment;
 filename="0002-update-SEE-ALSO-section-of-man-pages.patch"



More information about the poppler mailing list