[poppler] [PATCH] cairo: drawChar->drawString
Jeff Muizelaar
jrmuizel at nit.ca
Fri Mar 4 10:59:43 PST 2005
2005-03-02 Jeff Muizelaar <jrmuizel at nit.ca>
* poppler/CairoOutputDev.cc (CairoOutputDev::drawString):
Implement drawString instead of drawChar. This change should
make clipping to a text path work and has a performance
improvement. Currently the code is a little ugly because we
can't concat matrices to cairo without losing our current font.
* poppler/CairoOutputDev.h (CairoOutputDev::useDrawChar):
Tell Gfx.cc that it should use drawString instead of drawChar.
diff -urp 01-cleanup/poppler/CairoOutputDev.cc 02-drawString/poppler/CairoOutputDev.cc
--- 01-cleanup/poppler/CairoOutputDev.cc 2005-03-02 12:22:08.000000000 -0500
+++ 02-drawString/poppler/CairoOutputDev.cc 2005-03-02 12:30:42.000000000 -0500
@@ -321,62 +321,112 @@ void CairoOutputDev::eoClip(GfxState *st
LOG (printf ("clip-eo\n"));
}
-void CairoOutputDev::drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, Unicode *u, int uLen) {
- cairo_glyph_t glyph;
- double x1, y1;
+void CairoOutputDev::drawString(GfxState *state, GooString *s)
+{
+ GfxFont *font;
+ int wMode;
int render;
-
- LOG (printf ("drawChar %d '%c'\n", code, code));
+ // the number of bytes in the string and not the number of glyphs?
+ int len = s->getLength();
+ // need at most len glyphs
+ cairo_glyph_t glyphs[len];
+ char *p = s->getCString();
+ int count = 0;
+ double curX, curY;
+ double riseX, riseY;
+
+ font = state->getFont();
+ wMode = font->getWMode();
+
if (needFontUpdate) {
updateFont(state);
}
if (!currentFont) {
return;
}
-
+
// check for invisible text -- this is used by Acrobat Capture
render = state->getRender();
if (render == 3) {
return;
}
- x -= originX;
- y -= originY;
- state->transform(x, y, &x1, &y1);
-
- glyph.index = currentFont->getGlyph (code, u, uLen);
- glyph.x = x1;
- glyph.y = y1;
-
+ // ignore empty strings
+ if (len == 0)
+ return;
+
+ state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
+ curX = state->getCurX();
+ curY = state->getCurY();
+ while (len > 0) {
+ double x, y;
+ double x1, y1;
+ double dx, dy, tdx, tdy;
+ double originX, originY, tOriginX, tOriginY;
+ int n, uLen;
+ CharCode code;
+ Unicode u[8];
+ n = font->getNextChar(p, len, &code,
+ u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+ &dx, &dy, &originX, &originY);
+ if (wMode) {
+ dx *= state->getFontSize();
+ dy = dy * state->getFontSize() + state->getCharSpace();
+ if (n == 1 && *p == ' ') {
+ dy += state->getWordSpace();
+ }
+ } else {
+ dx = dx * state->getFontSize() + state->getCharSpace();
+ if (n == 1 && *p == ' ') {
+ dx += state->getWordSpace();
+ }
+ dx *= state->getHorizScaling();
+ dy *= state->getFontSize();
+ }
+ originX *= state->getFontSize();
+ originY *= state->getFontSize();
+ state->textTransformDelta(dx, dy, &tdx, &tdy);
+ state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
+ x = curX + riseX;
+ y = curY + riseY;
+ x -= tOriginX;
+ y -= tOriginY;
+ state->transform(x, y, &x1, &y1);
+
+ glyphs[count].index = currentFont->getGlyph (code, u, uLen);
+ glyphs[count].x = x1;
+ glyphs[count].y = y1;
+ curX += tdx;
+ curY += tdy;
+ p += n;
+ len -= n;
+ count++;
+ }
// fill
if (!(render & 1)) {
- LOG (printf ("fill glyph\n"));
+ LOG (printf ("fill string\n"));
cairo_set_rgb_color (cairo,
fill_color.r, fill_color.g, fill_color.b);
- cairo_show_glyphs (cairo, &glyph, 1);
+ cairo_show_glyphs (cairo, glyphs, count);
}
-
+
// stroke
if ((render & 3) == 1 || (render & 3) == 2) {
- LOG (printf ("stroke glyph\n"));
+ LOG (printf ("stroke string\n"));
cairo_set_rgb_color (cairo,
stroke_color.r, stroke_color.g, stroke_color.b);
- cairo_glyph_path (cairo, &glyph, 1);
+ cairo_glyph_path (cairo, glyphs, count);
cairo_stroke (cairo);
}
-
// clip
if (render & 4) {
- printf ("TODO: clip to glyph\n");
- /* TODO: This reqires us to concatenat all clip paths
- until endTextObject */
+ LOG (printf ("clip string\n"));
+ cairo_glyph_path (cairo, glyphs, count);
+ cairo_clip (cairo);
}
-
+
}
GBool CairoOutputDev::beginType3Char(GfxState *state, double x, double y,
diff -urp 01-cleanup/poppler/CairoOutputDev.h 02-drawString/poppler/CairoOutputDev.h
--- 01-cleanup/poppler/CairoOutputDev.h 2005-03-02 12:27:40.000000000 -0500
+++ 02-drawString/poppler/CairoOutputDev.h 2005-03-02 12:30:32.000000000 -0500
@@ -48,7 +48,7 @@ public:
virtual GBool upsideDown() { return gTrue; }
// Does this device use drawChar() or drawString()?
- virtual GBool useDrawChar() { return gTrue; }
+ virtual GBool useDrawChar() { return gFalse; }
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
@@ -95,10 +95,7 @@ public:
virtual void eoClip(GfxState *state);
//----- text drawing
- virtual void drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, Unicode *u, int uLen);
+ virtual void drawString(GfxState *state, GooString *s);
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen);
More information about the poppler
mailing list