[poppler] poppler/poppler: CairoFontEngine.cc, 1.20,
1.21 CairoFontEngine.h, 1.7, 1.8 CairoOutputDev.cc, 1.35,
1.36 CairoOutputDev.h, 1.14, 1.15 Gfx.cc, 1.9,
1.10 TextOutputDev.cc, 1.18, 1.19
Kristian Høgsberg
krh at kemper.freedesktop.org
Fri May 19 12:22:01 PDT 2006
Update of /cvs/poppler/poppler/poppler
In directory kemper:/tmp/cvs-serv22952/poppler
Modified Files:
CairoFontEngine.cc CairoFontEngine.h CairoOutputDev.cc
CairoOutputDev.h Gfx.cc TextOutputDev.cc
Log Message:
2006-05-19 Kristian Høgsberg <krh at redhat.com>
Memory leak patch from Carlos Garcia Campos (#6947).
* glib/poppler-action.cc:
* glib/poppler-document.cc:
* glib/poppler-page.cc:
* poppler/CairoFontEngine.cc:
* poppler/CairoFontEngine.h:
* poppler/CairoOutputDev.cc:
* poppler/CairoOutputDev.h:
* poppler/Gfx.cc:
* poppler/TextOutputDev.cc: Fix various memory leaks.
Index: CairoFontEngine.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoFontEngine.cc,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- CairoFontEngine.cc 21 Dec 2005 17:30:33 -0000 1.20
+++ CairoFontEngine.cc 19 May 2006 19:21:59 -0000 1.21
@@ -9,6 +9,7 @@
#include <config.h>
+#include <math.h>
#include "config.h"
#include <string.h>
#include "CairoFontEngine.h"
@@ -18,6 +19,11 @@
#include <fofi/FoFiType1C.h>
#include "goo/gfile.h"
#include "Error.h"
+#include "Gfx.h"
+#include "Page.h"
+#include "Parser.h"
+#include "Lexer.h"
+#include "CairoOutputDev.h"
#ifdef USE_GCC_PRAGMAS
#pragma implementation
@@ -27,18 +33,261 @@
fwrite(data, 1, len, (FILE *)stream);
}
+static void
+init_cairo_matrix(cairo_matrix_t *matrix, double *d)
+{
+ matrix->xx = d[0];
+ matrix->yx = -d[2];
+ matrix->xy = d[1];
+ matrix->yy = -d[3];
+ matrix->x0 = d[2] + d[4];
+ matrix->y0 = d[3] + d[5];
+}
+
+static cairo_user_data_key_t cairo_font_face_key;
+
//------------------------------------------------------------------------
-// CairoFont
+// CairoType3Font
//------------------------------------------------------------------------
-static void cairo_font_face_destroy (void *data)
+class CairoType3Font : public CairoFont {
+public:
+ CairoType3Font(GfxFont *gfxFont, XRef *xref);
+
+private:
+
+ Gfx8BitFont *gfxFont;
+
+ /* Static functions for implementing the cairo user font interface. */
+ static void *scaled_font_create (cairo_scaled_font_t *scaled_font,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_font_extents_t *metrics);
+ static void scaled_font_destroy (void *closure);
+
+ static unsigned long ucs4_to_index(void *closure,
+ unsigned long ucs4);
+
+ static cairo_status_t get_glyph_metrics(void *closure,
+ unsigned long index,
+ cairo_font_options_t *font_options,
+ cairo_text_extents_t *metrics);
+
+ static cairo_status_t render_glyph(void *closure,
+ unsigned long index,
+ cairo_font_options_t *font_options,
+ cairo_t *cr);
+
+ static cairo_user_font_backend_t font_backend;
+};
+
+cairo_user_font_backend_t CairoType3Font::font_backend = {
+ CairoType3Font::scaled_font_create,
+ CairoType3Font::scaled_font_destroy,
+ CairoType3Font::ucs4_to_index,
+ CairoType3Font::get_glyph_metrics,
+ CairoType3Font::render_glyph
+};
+
+CairoType3Font::CairoType3Font(GfxFont *gfxFontA, XRef *xref)
+ : CairoFont(gfxFontA, xref)
{
- CairoFont *font = (CairoFont *) data;
+ this->gfxFont = (Gfx8BitFont *) gfxFontA;
+ cairo_font_face = cairo_user_font_face_create (&font_backend);
- delete font;
+ printf ("created type3 font\n");
}
-CairoFont::CairoFont(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs) {
+void *
+CairoType3Font::scaled_font_create (cairo_scaled_font_t *scaled_font,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_font_extents_t *metrics)
+{
+ return cairo_scaled_font_get_font_face (scaled_font);
+}
+
+void
+CairoType3Font::scaled_font_destroy (void *closure)
+{
+}
+
+unsigned long
+CairoType3Font::ucs4_to_index(void *closure,
+ unsigned long ucs4)
+{
+ return 0;
+}
+
+cairo_status_t
+CairoType3Font::get_glyph_metrics(void *closure,
+ unsigned long index,
+ cairo_font_options_t *font_options,
+ cairo_text_extents_t *metrics)
+{
+ CairoType3Font *font;
+ double *bbox;
+ Object charProc, obj;
+ Object argObjs[maxArgs];
+ Parser *parser;
+ char *name;
+ double args[maxArgs];
+ int i, numArgs;
+ cairo_matrix_t font_matrix;
+ cairo_font_face_t *face = (cairo_font_face_t *) closure;
+
+ font = (CairoType3Font *)
+ cairo_font_face_get_user_data (face, &cairo_font_face_key);
+
+ font->gfxFont->getCharProc(index, &charProc);
+ if (!charProc.isStream()) {
+ charProc.free();
+ return CAIRO_STATUS_SUCCESS;
+ }
+ parser = new Parser(font->xref, new Lexer(font->xref, &charProc));
+
+ numArgs = 0;
+ parser->getObj(&obj);
+ while (!obj.isEOF()) {
+
+ // got a command - execute it
+ if (obj.isCmd()) {
+
+ name = obj.getCmd();
+ if (strcmp(name, "d0") == 0) {
+ /* FIXME: Handle d0 glyphs. */
+ } else if (strcmp(name, "d1") == 0) {
+ if (numArgs < 6)
+ goto cont;
+ for (i = 0; i < 6; i++) {
+ if (!argObjs[numArgs - 6 + i].isNum())
+ goto cont;
+ args[i] = argObjs[numArgs - 6 + i].getNum();
+ }
+
+ /* Transform glyph coordinates to text coordinates, which is
+ * what cairo expects. */
+ init_cairo_matrix (&font_matrix, font->gfxFont->getFontMatrix());
+ cairo_matrix_transform_distance (&font_matrix, &args[0], &args[1]);
+ cairo_matrix_transform_distance (&font_matrix, &args[2], &args[3]);
+ cairo_matrix_transform_distance (&font_matrix, &args[4], &args[5]);
+
+ metrics->x_bearing = args[2];
+ metrics->y_bearing = args[5];
+ metrics->width = args[4] - args[2];
+ metrics->height = args[3] - args[5];
+ metrics->x_advance = args[0];
+ metrics->y_advance = args[1];
+
+ break;
+ }
+ cont:
+ obj.free();
+ for (i = 0; i < numArgs; ++i)
+ argObjs[i].free();
+ numArgs = 0;
+ } else if (numArgs < maxArgs) {
+ argObjs[numArgs++] = obj;
+ }
+
+ parser->getObj(&obj);
+ }
+ obj.free();
+ for (i = 0; i < numArgs; ++i)
+ argObjs[i].free();
+
+ delete parser;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+CairoType3Font::render_glyph(void *closure,
+ unsigned long index,
+ cairo_font_options_t *font_options,
+ cairo_t *cr)
+{
+ Dict *resources;
+ Gfx *gfx;
+ Object charProc;
+ CairoOutputDev *out;
+ CairoType3Font *font;
+ cairo_matrix_t font_matrix;
+ cairo_font_face_t *face = (cairo_font_face_t *) closure;
+
+ cairo_surface_t *target;
+ int width, height;
+
+ target = cairo_get_target (cr);
+ width = cairo_image_surface_get_width (target);
+ height = cairo_image_surface_get_height (target);
+ PDFRectangle box(0, 0, width, height);
+
+ font = (CairoType3Font *)
+ cairo_font_face_get_user_data (face, &cairo_font_face_key);
+
+ out = new CairoOutputDev();
+ out->setCairo(cr);
+ resources = font->gfxFont->getResources();
+
+ gfx = new Gfx(font->xref, out, resources, &box, NULL);
+
+ font->gfxFont->getCharProc(index, &charProc);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_move_to (cr, -10, 0);
+ cairo_line_to (cr, 10, 0);
+ cairo_move_to (cr, 0, -10);
+ cairo_line_to (cr, 0, 10);
+ cairo_move_to (cr, -10, -10);
+ cairo_line_to (cr, 10, 10);
+ cairo_move_to (cr, 10, -10);
+ cairo_line_to (cr, -10, 10);
+ cairo_set_line_width (cr, 5);
+ cairo_stroke (cr);
+
+ init_cairo_matrix(&font_matrix, font->gfxFont->getFontMatrix());
+ cairo_transform (cr, &font_matrix);
+
+ if (charProc.isStream()) {
+ gfx->display(&charProc, gFalse);
+ } else {
+ error(-1, "Missing or bad Type3 CharProc entry");
+ }
+
+ delete gfx;
+ delete out;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+//------------------------------------------------------------------------
+// CairoFTFont
+//------------------------------------------------------------------------
+
+class CairoFTFont : public CairoFont {
+public:
+ CairoFTFont(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs);
+ virtual ~CairoFTFont();
+
+ GBool matches(Ref &other);
+ cairo_font_face_t *getFontFace(void);
+ unsigned long getGlyph(CharCode code, Unicode *u, int uLen);
+
+private:
+ FT_Face face;
+};
+
+CairoFTFont::CairoFTFont(GfxFont *gfxFont, XRef *xref,
+ FT_Library lib, GBool useCIDs)
+ : CairoFont(gfxFont, xref)
+{
Ref embRef;
Object refObj, strObj;
GooString *tmpFileName, *fileName, *substName,*tmpFileName2;
@@ -52,14 +301,8 @@
FoFiType1C *ff1c;
CharCodeToUnicode *ctu;
Unicode uBuf[8];
- static cairo_user_data_key_t cairo_font_face_key;
dfp = NULL;
- codeToGID = NULL;
- codeToGIDLen = 0;
- cairo_font_face = NULL;
-
- ref = *gfxFont->getID();
fontType = gfxFont->getType();
tmpFileName = NULL;
@@ -219,7 +462,7 @@
goto err2;
}
break;
-
+
default:
printf ("font type not handled\n");
goto err2;
@@ -237,25 +480,63 @@
cairo_font_face = cairo_ft_font_face_create_for_ft_face (face,
FT_LOAD_NO_HINTING |
FT_LOAD_NO_BITMAP);
- if (cairo_font_face == NULL) {
- error(-1, "could not create cairo font\n");
- goto err2; /* this doesn't do anything, but it looks like we're
- * handling the error */
- }
-
- cairo_font_face_set_user_data (cairo_font_face,
- &cairo_font_face_key,
- this,
- cairo_font_face_destroy);
-
return;
err2:
/* hmm? */
printf ("some font thing failed\n");
}
-CairoFont::~CairoFont() {
+CairoFTFont::~CairoFTFont() {
FT_Done_Face (face);
+}
+
+//------------------------------------------------------------------------
+// CairoFont
+//------------------------------------------------------------------------
+
+void cairo_font_destroy (void *data)
+{
+ CairoFont *font = (CairoFont *) data;
+
+ font->unreference();
+}
+
+CairoFont *
+CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs)
+{
+ CairoFont *font;
+
+ switch (gfxFont->getType()) {
+ case fontType3:
+ font = new CairoType3Font(gfxFont, xref);
+ break;
+ default:
+ font = new CairoFTFont(gfxFont, xref, lib, useCIDs);
+ break;
+ }
+
+ if (font->cairo_font_face == NULL)
+ error(-1, "could not create cairo font\n");
+ else
+ cairo_font_face_set_user_data (font->cairo_font_face,
+ &cairo_font_face_key,
+ font->reference(),
+ cairo_font_destroy);
+
+ return font;
+}
+
+CairoFont::CairoFont(GfxFont *gfxFont, XRef *xrefA)
+{
+ codeToGID = NULL;
+ codeToGIDLen = 0;
+ ref = *gfxFont->getID();
+ xref = xrefA;
+ refcount = 1;
+}
+
+CairoFont::~CairoFont()
+{
gfree(codeToGID);
}
@@ -274,7 +555,7 @@
Unicode *u, int uLen) {
FT_UInt gid;
- if (codeToGID && code < codeToGIDLen) {
+ if (codeToGID && code < (unsigned) codeToGIDLen) {
gid = (FT_UInt)codeToGID[code];
} else {
gid = (FT_UInt)code;
@@ -282,6 +563,8 @@
return gid;
}
+
+
//------------------------------------------------------------------------
// CairoFontEngine
//------------------------------------------------------------------------
@@ -306,7 +589,7 @@
for (i = 0; i < cairoFontCacheSize; ++i) {
if (fontCache[i])
- delete fontCache[i];
+ fontCache[i]->unreference();
}
}
@@ -315,13 +598,6 @@
int i, j;
Ref ref;
CairoFont *font;
- GfxFontType fontType;
-
- fontType = gfxFont->getType();
- if (fontType == fontType3) {
- /* Need to figure this out later */
- // return NULL;
- }
ref = *gfxFont->getID();
@@ -336,9 +612,9 @@
}
}
- font = new CairoFont (gfxFont, xref, lib, useCIDs);
+ font = CairoFont::create (gfxFont, xref, lib, useCIDs);
if (fontCache[cairoFontCacheSize - 1]) {
- delete fontCache[cairoFontCacheSize - 1];
+ fontCache[cairoFontCacheSize - 1]->unreference();
}
for (j = cairoFontCacheSize - 1; j > 0; --j) {
fontCache[j] = fontCache[j-1];
@@ -346,4 +622,3 @@
fontCache[0] = font;
return font;
}
-
Index: CairoFontEngine.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoFontEngine.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- CairoFontEngine.h 20 Mar 2006 19:02:10 -0000 1.7
+++ CairoFontEngine.h 19 May 2006 19:21:59 -0000 1.8
@@ -18,19 +18,26 @@
class CairoFont {
public:
- CairoFont(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs);
- ~CairoFont();
+ static CairoFont *create(GfxFont *gfxFont, XRef *xref,
+ FT_Library lib, GBool useCIDs);
+
+ CairoFont *reference() { refcount++; return this; }
+ void unreference() { if (--refcount == 0) delete this; }
GBool matches(Ref &other);
cairo_font_face_t *getFontFace(void);
unsigned long getGlyph(CharCode code, Unicode *u, int uLen);
-private:
+
+protected:
+ CairoFont(GfxFont *gfxFont, XRef *xref);
+ virtual ~CairoFont();
+
Ref ref;
+ XRef *xref;
cairo_font_face_t *cairo_font_face;
- FT_Face face;
-
Gushort *codeToGID;
int codeToGIDLen;
+ int refcount;
};
//------------------------------------------------------------------------
Index: CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- CairoOutputDev.cc 27 Apr 2006 17:26:37 -0000 1.35
+++ CairoOutputDev.cc 19 May 2006 19:21:59 -0000 1.36
@@ -258,9 +258,6 @@
needFontUpdate = gFalse;
- if (state->getFont()->getType() == fontType3)
- return;
-
currentFont = fontEngine->getFont (state->getFont(), xref);
state->getFontTransMat(&m11, &m12, &m21, &m22);
@@ -448,7 +445,7 @@
}
void CairoOutputDev::type3D1(GfxState *state, double wx, double wy,
- double llx, double lly, double urx, double ury) {
+ double llx, double lly, double urx, double ury) {
}
void CairoOutputDev::endTextObject(GfxState *state) {
Index: CairoOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- CairoOutputDev.h 12 Apr 2006 06:52:07 -0000 1.14
+++ CairoOutputDev.h 19 May 2006 19:21:59 -0000 1.15
@@ -52,7 +52,7 @@
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
- virtual GBool interpretType3Chars() { return gTrue; }
+ virtual GBool interpretType3Chars() { return gFalse; }
//----- initialization and control
Index: Gfx.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Gfx.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Gfx.cc 2 May 2006 04:38:39 -0000 1.9
+++ Gfx.cc 19 May 2006 19:21:59 -0000 1.10
@@ -483,6 +483,7 @@
// initialize
out = outA;
state = new GfxState(72, 72, box, 0, gFalse);
+ out->updateAll(state);
fontChanged = gFalse;
clip = clipNone;
ignoreUndef = 0;
Index: TextOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.cc,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- TextOutputDev.cc 2 May 2006 04:38:39 -0000 1.18
+++ TextOutputDev.cc 19 May 2006 19:21:59 -0000 1.19
@@ -2375,6 +2375,8 @@
//----- column assignment
// sort blocks into xy order for column assignment
+ if (blocks)
+ gfree (blocks);
blocks = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *));
for (blk = blkList, i = 0; blk; blk = blk->next, ++i) {
blocks[i] = blk;
@@ -2512,6 +2514,11 @@
//~ this also needs to account for right-to-left column ordering
blkArray = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *));
memcpy(blkArray, blocks, nBlocks * sizeof(TextBlock *));
+ while (flows) {
+ flow = flows;
+ flows = flows->next;
+ delete flow;
+ }
flows = lastFlow = NULL;
firstBlkIdx = 0;
nBlocksLeft = nBlocks;
@@ -3375,6 +3382,8 @@
word->charcode[i], 1, NULL, 0);
out->endString(state);
+
+ delete string;
}
void TextWord::visitSelection(TextSelectionVisitor *visitor,
More information about the poppler
mailing list