diff --git a/glib/demo/render.c b/glib/demo/render.c index 1fa4761..33ff18c 100644 --- a/glib/demo/render.c +++ b/glib/demo/render.c @@ -157,6 +157,12 @@ pgd_render_start (GtkButton *button, width, height); cr = cairo_create (demo->surface); + if (!demo->printing) { + const cairo_font_options_t *options = gdk_screen_get_font_options (gdk_screen_get_default()); + + cairo_set_font_options (cr, options); + } + cairo_save (cr); switch (demo->rotate) { case 90: diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc index 0a627aa..ef88208 100644 --- a/poppler/CairoFontEngine.cc +++ b/poppler/CairoFontEngine.cc @@ -81,7 +81,7 @@ CairoFont::~CairoFont() { } GBool -CairoFont::matches(Ref &other, GBool printingA) { +CairoFont::matches(Ref &other, GBool printingA, int loadFlagsA) { return (other.num == ref.num && other.gen == ref.gen); } @@ -168,6 +168,7 @@ _ft_new_face_uncached (FT_Library lib, const char *filename, char *font_data, int font_data_len, + int ft_load_flags, FT_Face *face_out, cairo_font_face_t **font_face_out) { @@ -182,9 +183,7 @@ _ft_new_face_uncached (FT_Library lib, return gFalse; } - font_face = cairo_ft_font_face_create_for_ft_face (face, - FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP); + font_face = cairo_ft_font_face_create_for_ft_face (face, ft_load_flags); if (cairo_font_face_set_user_data (font_face, &_ft_cairo_key, face, @@ -211,6 +210,7 @@ static struct _ft_face_data { FT_Library lib; FT_Face face; + int load_flags; cairo_font_face_t *font_face; } *_ft_open_faces; @@ -235,6 +235,8 @@ _ft_face_data_equal (struct _ft_face_data *a, struct _ft_face_data *b) return gFalse; if (a->hash != b->hash) return gFalse; + if (a->load_flags != b->load_flags) + return gFalse; return memcmp (a->bytes, b->bytes, a->size) == 0; } @@ -267,6 +269,7 @@ _ft_new_face (FT_Library lib, const char *filename, char *font_data, int font_data_len, + int ft_load_flags, FT_Face *face_out, cairo_font_face_t **font_face_out) { @@ -280,11 +283,11 @@ _ft_new_face (FT_Library lib, /* if we fail to mmap the file, just pass it to FreeType instead */ tmpl.fd = open (filename, O_RDONLY); if (tmpl.fd == -1) - return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out); + return _ft_new_face_uncached (lib, filename, font_data, font_data_len, ft_load_flags, face_out, font_face_out); if (fstat (tmpl.fd, &st) == -1) { close (tmpl.fd); - return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out); + return _ft_new_face_uncached (lib, filename, font_data, font_data_len, ft_load_flags, face_out, font_face_out); } tmpl.bytes = (unsigned char *) mmap (NULL, st.st_size, @@ -292,7 +295,7 @@ _ft_new_face (FT_Library lib, tmpl.fd, 0); if (tmpl.bytes == MAP_FAILED) { close (tmpl.fd); - return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out); + return _ft_new_face_uncached (lib, filename, font_data, font_data_len, ft_load_flags, face_out, font_face_out); } tmpl.size = st.st_size; } else { @@ -303,6 +306,7 @@ _ft_new_face (FT_Library lib, /* check to see if this is a duplicate of any of the currently open fonts */ tmpl.lib = lib; tmpl.hash = _djb_hash (tmpl.bytes, tmpl.size); + tmpl.load_flags = ft_load_flags; for (l = _ft_open_faces; l; l = l->next) { if (_ft_face_data_equal (l, &tmpl)) { @@ -345,9 +349,7 @@ _ft_new_face (FT_Library lib, _ft_open_faces->prev = l; _ft_open_faces = l; - l->font_face = cairo_ft_font_face_create_for_ft_face (tmpl.face, - FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP); + l->font_face = cairo_ft_font_face_create_for_ft_face (tmpl.face, tmpl.load_flags); if (cairo_font_face_set_user_data (l->font_face, &_ft_cairo_key, l, @@ -370,17 +372,38 @@ CairoFreeTypeFont::CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, Gushort *codeToGID, int codeToGIDLen, - GBool substitute) : CairoFont(ref, - cairo_font_face, - codeToGID, - codeToGIDLen, - substitute, - gTrue) { } + GBool substitute, + int loadFlagsA) : CairoFont(ref, + cairo_font_face, + codeToGID, + codeToGIDLen, + substitute, + gTrue) { loadFlags = loadFlagsA; } CairoFreeTypeFont::~CairoFreeTypeFont() { } +GBool +CairoFreeTypeFont::matches(Ref &other, GBool printingA, int loadFlagsA) { + return (other.num == ref.num && other.gen == ref.gen && loadFlags == loadFlagsA); +} + +int +CairoFreeTypeFont::getLoadFlags(cairo_font_options_t *fontOptions) { + int load_flags = FT_LOAD_DEFAULT; + cairo_antialias_t antialias = cairo_font_options_get_antialias (fontOptions); + cairo_hint_style_t hint_style = cairo_font_options_get_hint_style (fontOptions); + + if (antialias != CAIRO_ANTIALIAS_NONE) + load_flags |= FT_LOAD_NO_BITMAP; + + if (hint_style == CAIRO_HINT_STYLE_NONE || hint_style == CAIRO_HINT_STYLE_DEFAULT) + load_flags |= FT_LOAD_NO_HINTING; + + return load_flags; +} + CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, - FT_Library lib, GBool useCIDs) { + FT_Library lib, GBool useCIDs, int loadFlagsA) { Ref embRef; Object refObj, strObj; GooString *fileName; @@ -451,7 +474,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, case fontType1: case fontType1C: case fontType1COT: - if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) { + if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, loadFlagsA, &face, &font_face)) { error(-1, "could not create type1 face"); goto err2; } @@ -507,7 +530,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, codeToGIDLen = 256; } delete ff; - if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) { + if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, loadFlagsA, &face, &font_face)) { error(-1, "could not create truetype face\n"); goto err2; } @@ -532,7 +555,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, } } - if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) { + if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, loadFlagsA, &face, &font_face)) { gfree(codeToGID); codeToGID = NULL; error(-1, "could not create cid face\n"); @@ -549,7 +572,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, return new CairoFreeTypeFont(ref, font_face, codeToGID, codeToGIDLen, - substitute); + substitute, loadFlagsA); err2: /* hmm? */ @@ -723,7 +746,7 @@ CairoType3Font::CairoType3Font(Ref ref, CairoType3Font::~CairoType3Font() { } GBool -CairoType3Font::matches(Ref &other, GBool printingA) { +CairoType3Font::matches(Ref &other, GBool printingA, int loadFlagsA) { return (other.num == ref.num && other.gen == ref.gen && printing == printingA); } @@ -757,17 +780,22 @@ CairoFontEngine::~CairoFontEngine() { } CairoFont * -CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog, GBool printing) { +CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog, GBool printing, cairo_font_options_t *fontOptions) { int i, j; Ref ref; + int ft_load_flags = 0; CairoFont *font; GfxFontType fontType; - + ref = *gfxFont->getID(); + fontType = gfxFont->getType(); + if (fontType != fontType3) + ft_load_flags = CairoFreeTypeFont::getLoadFlags (fontOptions); + for (i = 0; i < cairoFontCacheSize; ++i) { font = fontCache[i]; - if (font && font->matches(ref, printing)) { + if (font && font->matches(ref, printing, ft_load_flags)) { for (j = i; j > 0; --j) { fontCache[j] = fontCache[j-1]; } @@ -775,12 +803,11 @@ CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog, GBool p return font; } } - - fontType = gfxFont->getType(); + if (fontType == fontType3) font = CairoType3Font::create (gfxFont, xref, catalog, this, printing); else - font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs); + font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs, ft_load_flags); //XXX: if font is null should we still insert it into the cache? if (fontCache[cairoFontCacheSize - 1]) { diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h index 9cb0ce7..f6430cb 100644 --- a/poppler/CairoFontEngine.h +++ b/poppler/CairoFontEngine.h @@ -50,7 +50,7 @@ public: GBool printing); virtual ~CairoFont(); - virtual GBool matches(Ref &other, GBool printing); + virtual GBool matches(Ref &other, GBool printing, int loadFlags); cairo_font_face_t *getFontFace(void); unsigned long getGlyph(CharCode code, Unicode *u, int uLen); double getSubstitutionCorrection(GfxFont *gfxFont); @@ -71,12 +71,22 @@ protected: class CairoFreeTypeFont : public CairoFont { public: - static CairoFreeTypeFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs); + CairoFreeTypeFont (Ref ref, + cairo_font_face_t *face, + Gushort *codeToGID, + int codeToGIDLen, + GBool substitute, + int loadFlags); + static CairoFreeTypeFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs, int loadFlags); + static int getLoadFlags(cairo_font_options_t *fontOptions); virtual ~CairoFreeTypeFont(); + virtual GBool matches(Ref &other, GBool printing, int loadFlags); + private: CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, Gushort *codeToGID, int codeToGIDLen, GBool substitute); + int loadFlags; }; //------------------------------------------------------------------------ @@ -88,7 +98,7 @@ public: GBool printing); virtual ~CairoType3Font(); - virtual GBool matches(Ref &other, GBool printing); + virtual GBool matches(Ref &other, GBool printing, int loadFlags); private: CairoType3Font(Ref ref, XRef *xref, Catalog *catalog, @@ -114,7 +124,7 @@ public: CairoFontEngine(FT_Library libA); ~CairoFontEngine(); - CairoFont *getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog, GBool printing); + CairoFont *getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog, GBool printing, cairo_font_options_t *fontOptions); private: CairoFont *fontCache[cairoFontCacheSize]; diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 01ff92c..7233d36 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -558,6 +558,7 @@ void CairoOutputDev::updateBlendMode(GfxState *state) { void CairoOutputDev::updateFont(GfxState *state) { cairo_font_face_t *font_face; + cairo_font_options_t *font_options, *cr_font_options; cairo_matrix_t matrix, invert_matrix; LOG(printf ("updateFont() font=%s\n", state->getFont()->getName()->getCString())); @@ -567,8 +568,17 @@ void CairoOutputDev::updateFont(GfxState *state) { //FIXME: use cairo font engine? if (text) text->updateFont(state); - - currentFont = fontEngine->getFont (state->getFont(), xref, catalog, printing); + + font_options = cairo_font_options_create (); + cr_font_options = cairo_font_options_create (); + + cairo_get_font_options (cairo, cr_font_options); + cairo_surface_get_font_options (cairo_get_target (cairo), font_options); + cairo_font_options_merge (font_options, cr_font_options); + cairo_font_options_destroy (cr_font_options); + + currentFont = fontEngine->getFont (state->getFont(), xref, catalog, printing, font_options); + cairo_font_options_destroy (font_options); if (!currentFont) return;