From 2548c4c974ec0a0313391cfa33275e58dcac17be Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Tue, 6 Jul 2010 20:52:10 +0000 Subject: [PATCH] Minimal font overlay : * FontCacheEntry will not use the "empty" glyph from fonts anymore, so squares are not drawn anymore * GlyphLayoutEngine will try the VL Gothic font, if the requested font doesn't have any glyph fo the requested character. The caching for the fallback is suboptimal, and the font choice quite limited, but this allows at least japanese text to display properly on haiku out of the box. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37413 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/FontCacheEntry.cpp | 2 ++ src/servers/app/GlyphLayoutEngine.h | 51 ++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/servers/app/FontCacheEntry.cpp b/src/servers/app/FontCacheEntry.cpp index 49a4485343..76733636de 100644 --- a/src/servers/app/FontCacheEntry.cpp +++ b/src/servers/app/FontCacheEntry.cpp @@ -192,6 +192,8 @@ const GlyphCache* FontCacheEntry::Glyph(uint32 glyphCode) { uint32 glyphIndex = fEngine.GlyphIndexForGlyphCode(glyphCode); + if (glyphIndex==0) + return NULL; const GlyphCache* glyph = fGlyphCache->FindGlyph(glyphIndex); if (glyph) { return glyph; diff --git a/src/servers/app/GlyphLayoutEngine.h b/src/servers/app/GlyphLayoutEngine.h index 41cf9b2444..00e23b6e75 100644 --- a/src/servers/app/GlyphLayoutEngine.h +++ b/src/servers/app/GlyphLayoutEngine.h @@ -13,6 +13,7 @@ #include "FontCache.h" #include "FontCacheEntry.h" +#include "FontManager.h" #include "ServerFont.h" #include @@ -95,6 +96,7 @@ GlyphLayoutEngine::IsWhiteSpace(uint32 charCode) return false; } + // LayoutGlyphs template inline bool @@ -107,6 +109,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, // TODO: implement spacing modes FontCacheEntry* entry = NULL; + FontCacheEntry* fallbackEntry = NULL; bool needsWriteLock = false; if (cacheReference) { entry = cacheReference->Entry(); @@ -171,11 +174,51 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, const GlyphCache* glyph = entry->Glyph(charCode); if (glyph == NULL) { - fprintf(stderr, "failed to load glyph for 0x%04lx (%c)\n", charCode, - isprint(charCode) ? (char)charCode : '-'); + // Try to find a suitable glyph in another font + FontCache* cache = FontCache::Default(); + bool needsWriteLock = false; + ServerFont f(*(gFontManager->GetStyleByIndex("VL Gothic",0))); + // We always try to get the glyph from VL Gothic, so we can display + // japanese character. Other scripts (indian, ...) should be handled + // too, perhaps with a charcode > font mapping. + fallbackEntry = cache->FontCacheEntryFor(f); + if (!fallbackEntry || !fallbackEntry->ReadLock()) { + cache->Recycle(fallbackEntry); + continue; + } - consumer.ConsumeEmptyGlyph(index, charCode, x, y); - continue; + needsWriteLock = !fallbackEntry->HasGlyphs(utf8String, length); + + if (needsWriteLock) { + fallbackEntry->ReadUnlock(); + if (!fallbackEntry->WriteLock()) { + cache->Recycle(fallbackEntry); + continue; + } + } + + bool consumed = true; + glyph = fallbackEntry->Glyph(charCode); + if (glyph != NULL && !consumer.ConsumeGlyph(index, charCode, glyph, fallbackEntry, x, y)) { + advanceX = 0; + advanceY = 0; + consumed = false; + } + + if (needsWriteLock) + fallbackEntry->WriteUnlock(); + else + fallbackEntry->ReadUnlock(); + + FontCache::Default()->Recycle(fallbackEntry); + + if (glyph == NULL) { + consumer.ConsumeEmptyGlyph(index, charCode, x, y); + continue; + } + + if (!consumed) + break; } if (!consumer.ConsumeGlyph(index, charCode, glyph, entry, x, y)) {