diff --git a/glib/demo/render.c b/glib/demo/render.c index 354b862..bed4749 100644 --- a/glib/demo/render.c +++ b/glib/demo/render.c @@ -116,6 +116,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 c4493e8..bcf091c 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); } @@ -167,6 +167,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) { @@ -181,9 +182,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, @@ -210,6 +209,7 @@ static struct _ft_face_data { FT_Library lib; FT_Face face; + int load_flags; cairo_font_face_t *font_face; } *_ft_open_faces; @@ -234,6 +234,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; } @@ -266,6 +268,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) { @@ -279,11 +282,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, @@ -291,7 +294,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 { @@ -302,6 +305,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)) { @@ -344,9 +348,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, @@ -369,17 +371,38 @@ CairoFreeTypeFont::CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, int *codeToGID, Guint 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) { Object refObj, strObj; GooString *fileName; char *fileNameC; @@ -439,7 +462,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(errSyntaxError, -1, "could not create type1 face"); goto err2; } @@ -495,7 +518,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(errSyntaxError, -1, "could not create truetype face\n"); goto err2; } @@ -520,7 +543,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(errSyntaxError, -1, "could not create cid face\n"); @@ -538,7 +561,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, return new CairoFreeTypeFont(ref, font_face, codeToGID, codeToGIDLen, - substitute); + substitute, loadFlagsA); err2: /* hmm? */ @@ -733,7 +756,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); } @@ -767,17 +790,22 @@ CairoFontEngine::~CairoFontEngine() { } CairoFont * -CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing) { +CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, 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]; } @@ -786,11 +814,10 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing) { } } - fontType = gfxFont->getType(); if (fontType == fontType3) font = CairoType3Font::create (gfxFont, doc, this, printing); else - font = CairoFreeTypeFont::create (gfxFont, doc->getXRef(), lib, useCIDs); + font = CairoFreeTypeFont::create (gfxFont, doc->getXRef(), 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 6335348..98826d6 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,17 @@ protected: class CairoFreeTypeFont : public CairoFont { public: - static CairoFreeTypeFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs); + 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, - int *codeToGID, Guint codeToGIDLen, GBool substitute); + int *codeToGID, Guint codeToGIDLen, GBool substitute, + int loadFlags); + int loadFlags; }; //------------------------------------------------------------------------ @@ -88,7 +93,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, PDFDoc *doc, @@ -113,7 +118,7 @@ public: CairoFontEngine(FT_Library libA); ~CairoFontEngine(); - CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing); + CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, cairo_font_options_t *fontOptions); private: CairoFont *fontCache[cairoFontCacheSize]; diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 34d5a70..4ab85b3 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -592,6 +592,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())); @@ -602,7 +603,16 @@ void CairoOutputDev::updateFont(GfxState *state) { if (text) text->updateFont(state); - currentFont = fontEngine->getFont (state->getFont(), doc, 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(), doc, printing, font_options); + cairo_font_options_destroy (font_options); if (!currentFont) return;