diff --git a/src/servers/app/font/FontCacheEntry.cpp b/src/servers/app/font/FontCacheEntry.cpp index 8c8ac0232a..39b64d295e 100644 --- a/src/servers/app/font/FontCacheEntry.cpp +++ b/src/servers/app/font/FontCacheEntry.cpp @@ -96,14 +96,16 @@ public: GlyphCache* CacheGlyph(uint32 glyphIndex, uint32 dataSize, glyph_data_type dataType, const agg::rect_i& bounds, - float advanceX, float advanceY, float insetLeft, float insetRight) + float advanceX, float advanceY, float preciseAdvanceX, + float preciseAdvanceY, float insetLeft, float insetRight) { GlyphCache* glyph = fGlyphTable.Lookup(glyphIndex); if (glyph != NULL) return NULL; glyph = new(std::nothrow) GlyphCache(glyphIndex, dataSize, dataType, - bounds, advanceX, advanceY, insetLeft, insetRight); + bounds, advanceX, advanceY, preciseAdvanceX, preciseAdvanceY, + insetLeft, insetRight); if (glyph == NULL || glyph->data == NULL) { delete glyph; return NULL; @@ -293,7 +295,7 @@ FontCacheEntry::CreateGlyph(uint32 glyphCode, FontCacheEntry* fallbackEntry) if (render_as_zero_width(glyphCode)) { // cache and return a zero width glyph return fGlyphCache->CacheGlyph(glyphCode, 0, glyph_data_invalid, - agg::rect_i(0, 0, -1, -1), 0, 0, 0, 0); + agg::rect_i(0, 0, -1, -1), 0, 0, 0, 0, 0, 0); } // reset to our engine @@ -310,6 +312,7 @@ FontCacheEntry::CreateGlyph(uint32 glyphCode, FontCacheEntry* fallbackEntry) glyph = fGlyphCache->CacheGlyph(glyphCode, engine->DataSize(), engine->DataType(), engine->Bounds(), engine->AdvanceX(), engine->AdvanceY(), + engine->PreciseAdvanceX(), engine->PreciseAdvanceY(), engine->InsetLeft(), engine->InsetRight()); if (glyph != NULL) @@ -326,7 +329,7 @@ FontCacheEntry::InitAdaptors(const GlyphCache* glyph, GlyphGray8Adapter& gray8Adapter, GlyphPathAdapter& pathAdapter, double scale) { - if (!glyph) + if (glyph == NULL) return; switch(glyph->data_type) { diff --git a/src/servers/app/font/FontCacheEntry.h b/src/servers/app/font/FontCacheEntry.h index 138d930c80..abe085adec 100644 --- a/src/servers/app/font/FontCacheEntry.h +++ b/src/servers/app/font/FontCacheEntry.h @@ -43,6 +43,7 @@ struct GlyphCache { GlyphCache(uint32 glyphIndex, uint32 dataSize, glyph_data_type dataType, const agg::rect_i& bounds, float advanceX, float advanceY, + float preciseAdvanceX, float preciseAdvanceY, float insetLeft, float insetRight) : glyph_index(glyphIndex), @@ -52,6 +53,8 @@ struct GlyphCache { bounds(bounds), advance_x(advanceX), advance_y(advanceY), + precise_advance_x(preciseAdvanceX), + precise_advance_y(preciseAdvanceY), inset_left(insetLeft), inset_right(insetRight), hash_link(NULL) @@ -70,6 +73,8 @@ struct GlyphCache { agg::rect_i bounds; float advance_x; float advance_y; + float precise_advance_x; + float precise_advance_y; float inset_left; float inset_right; diff --git a/src/servers/app/font/FontEngine.cpp b/src/servers/app/font/FontEngine.cpp index bb028951f7..c6e269d764 100644 --- a/src/servers/app/font/FontEngine.cpp +++ b/src/servers/app/font/FontEngine.cpp @@ -624,7 +624,22 @@ FontEngine::PrepareGlyph(uint32 glyphIndex) loadFlags |= fGlyphRendering == glyph_ren_subpix ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_NORMAL; - fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); + if (fHinting) { + // Load without hinting to get precise advance values + // for B_CHAR_SPACING + fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags + | FT_LOAD_NO_HINTING); + } else { + fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); + } + + fPreciseAdvanceX = int26p6_to_dbl(fFace->glyph->advance.x); + fPreciseAdvanceY = int26p6_to_dbl(fFace->glyph->advance.y); + + if (fHinting) { + // Need to load again with hinting. + fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); + } if (fLastError != 0) return false; diff --git a/src/servers/app/font/FontEngine.h b/src/servers/app/font/FontEngine.h index b401102b04..d599d07e8a 100644 --- a/src/servers/app/font/FontEngine.h +++ b/src/servers/app/font/FontEngine.h @@ -105,6 +105,10 @@ class FontEngine { { return fAdvanceX; } double AdvanceY() const { return fAdvanceY; } + double PreciseAdvanceX() const + { return fPreciseAdvanceX; } + double PreciseAdvanceY() const + { return fPreciseAdvanceY; } double InsetLeft() const { return fInsetLeft; } double InsetRight() const @@ -136,6 +140,8 @@ class FontEngine { agg::rect_i fBounds; double fAdvanceX; double fAdvanceY; + double fPreciseAdvanceX; + double fPreciseAdvanceY; double fInsetLeft; double fInsetRight; diff --git a/src/servers/app/font/GlyphLayoutEngine.h b/src/servers/app/font/GlyphLayoutEngine.h index 6ed1d3ae60..b1fc624f32 100644 --- a/src/servers/app/font/GlyphLayoutEngine.h +++ b/src/servers/app/font/GlyphLayoutEngine.h @@ -253,8 +253,13 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, advanceY = 0; } else { // get next increment for pen position - advanceX = glyph->advance_x; - advanceY = glyph->advance_y; + if (spacing == B_CHAR_SPACING) { + advanceX = glyph->precise_advance_x; + advanceY = glyph->precise_advance_y; + } else { + advanceX = glyph->advance_x; + advanceY = glyph->advance_y; + } // adjust for custom spacing if (delta != NULL) {