[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