diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index 0c5a616387..5655b02d44 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -438,6 +438,7 @@ class HasGlyphsConsumer { : fHasArray(hasArray) { } + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) @@ -481,6 +482,7 @@ class EdgesConsumer { , fSize(size) { } + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) @@ -549,6 +551,7 @@ public: { } + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) @@ -619,6 +622,7 @@ public: { } + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) @@ -676,6 +680,7 @@ class BoundingBoxConsumer { { } + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) {} @@ -802,6 +807,7 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[], class StringWidthConsumer { public: StringWidthConsumer() : width(0.0) {} + bool NeedsVector() { return false; } void Start() {} void Finish(double x, double y) { width = x; } void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) {} diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp index f1f9cd8972..829214f099 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp @@ -144,6 +144,11 @@ public: { } + bool NeedsVector() + { + return !fTransform.IsTranslationOnly(); + } + void Start() { fRenderer.fRasterizer.reset(); diff --git a/src/servers/app/drawing/Painter/Transformable.cpp b/src/servers/app/drawing/Painter/Transformable.cpp index ee801900f2..07769d963a 100644 --- a/src/servers/app/drawing/Painter/Transformable.cpp +++ b/src/servers/app/drawing/Painter/Transformable.cpp @@ -268,6 +268,17 @@ Transformable::TransformBounds(const BRect& bounds) const return bounds; } + +bool +Transformable::IsTranslationOnly() const +{ + double matrix[6]; + store_to(matrix); + return matrix[0] == 1.0 && matrix[1] == 0.0 + && matrix[2] == 0.0 && matrix[3] == 1.0; +} + + // TranslateBy void Transformable::TranslateBy(BPoint offset) diff --git a/src/servers/app/drawing/Painter/Transformable.h b/src/servers/app/drawing/Painter/Transformable.h index 7cf3d4999d..98540207be 100644 --- a/src/servers/app/drawing/Painter/Transformable.h +++ b/src/servers/app/drawing/Painter/Transformable.h @@ -53,6 +53,8 @@ class Transformable : public BArchivable, // returns the *bounding box* of that BRect TransformBounds(const BRect& bounds) const; + bool IsTranslationOnly() const; + // some convenience functions virtual void TranslateBy(BPoint offset); virtual void RotateBy(BPoint origin, double radians); diff --git a/src/servers/app/font/FontCache.cpp b/src/servers/app/font/FontCache.cpp index 52baa53899..da7298ae03 100644 --- a/src/servers/app/font/FontCache.cpp +++ b/src/servers/app/font/FontCache.cpp @@ -50,11 +50,12 @@ FontCache::Default() // FontCacheEntryFor FontCacheEntry* -FontCache::FontCacheEntryFor(const ServerFont& font) +FontCache::FontCacheEntryFor(const ServerFont& font, bool forceVector) { static const size_t signatureSize = 512; char signature[signatureSize]; - FontCacheEntry::GenerateSignature(signature, signatureSize, font); + FontCacheEntry::GenerateSignature(signature, signatureSize, font, + forceVector); AutoReadLocker readLocker(this); @@ -85,7 +86,7 @@ FontCache::FontCacheEntryFor(const ServerFont& font) // remove old entries, keep entries below certain count _ConstrainEntryCount(); entry = new (nothrow) FontCacheEntry(); - if (!entry || !entry->Init(font) + if (!entry || !entry->Init(font, forceVector) || fFontCacheEntries.Put(signature, entry) < B_OK) { fprintf(stderr, "FontCache::FontCacheEntryFor() - " "out of memory or no font file\n"); diff --git a/src/servers/app/font/FontCache.h b/src/servers/app/font/FontCache.h index 45ad1f42f9..aaa0058697 100644 --- a/src/servers/app/font/FontCache.h +++ b/src/servers/app/font/FontCache.h @@ -24,7 +24,8 @@ class FontCache : public MultiLocker { // global instance static FontCache* Default(); - FontCacheEntry* FontCacheEntryFor(const ServerFont& font); + FontCacheEntry* FontCacheEntryFor(const ServerFont& font, + bool forceVector); void Recycle(FontCacheEntry* entry); private: diff --git a/src/servers/app/font/FontCacheEntry.cpp b/src/servers/app/font/FontCacheEntry.cpp index 306f99de67..8c8ac0232a 100644 --- a/src/servers/app/font/FontCacheEntry.cpp +++ b/src/servers/app/font/FontCacheEntry.cpp @@ -146,12 +146,12 @@ FontCacheEntry::~FontCacheEntry() bool -FontCacheEntry::Init(const ServerFont& font) +FontCacheEntry::Init(const ServerFont& font, bool forceVector) { if (fGlyphCache == NULL) return false; - glyph_rendering renderingType = _RenderTypeFor(font); + glyph_rendering renderingType = _RenderTypeFor(font, forceVector); // TODO: encoding from font FT_Encoding charMap = FT_ENCODING_NONE; @@ -362,9 +362,9 @@ FontCacheEntry::GetKerning(uint32 glyphCode1, uint32 glyphCode2, /*static*/ void FontCacheEntry::GenerateSignature(char* signature, size_t signatureSize, - const ServerFont& font) + const ServerFont& font, bool forceVector) { - glyph_rendering renderingType = _RenderTypeFor(font); + glyph_rendering renderingType = _RenderTypeFor(font, forceVector); // TODO: read more of these from the font FT_Encoding charMap = FT_ENCODING_NONE; @@ -393,12 +393,12 @@ FontCacheEntry::UpdateUsage() /*static*/ glyph_rendering -FontCacheEntry::_RenderTypeFor(const ServerFont& font) +FontCacheEntry::_RenderTypeFor(const ServerFont& font, bool forceVector) { glyph_rendering renderingType = gSubpixelAntialiasing ? glyph_ren_subpix : glyph_ren_native_gray8; - if (font.Rotation() != 0.0 || font.Shear() != 90.0 + if (forceVector || font.Rotation() != 0.0 || font.Shear() != 90.0 || font.FalseBoldWidth() != 0.0 || (font.Flags() & B_DISABLE_ANTIALIASING) != 0 || font.Size() > 30 diff --git a/src/servers/app/font/FontCacheEntry.h b/src/servers/app/font/FontCacheEntry.h index 5e939f64a7..138d930c80 100644 --- a/src/servers/app/font/FontCacheEntry.h +++ b/src/servers/app/font/FontCacheEntry.h @@ -99,7 +99,7 @@ class FontCacheEntry : public MultiLocker, public BReferenceable { FontCacheEntry(); virtual ~FontCacheEntry(); - bool Init(const ServerFont& font); + bool Init(const ServerFont& font, bool forceVector); bool HasGlyphs(const char* utf8String, ssize_t glyphCount) const; @@ -120,7 +120,7 @@ class FontCacheEntry : public MultiLocker, public BReferenceable { static void GenerateSignature(char* signature, size_t signatureSize, - const ServerFont& font); + const ServerFont& font, bool forceVector); // private to FontCache class: void UpdateUsage(); @@ -133,7 +133,8 @@ class FontCacheEntry : public MultiLocker, public BReferenceable { FontCacheEntry(const FontCacheEntry&); const FontCacheEntry& operator=(const FontCacheEntry&); - static glyph_rendering _RenderTypeFor(const ServerFont& font); + static glyph_rendering _RenderTypeFor(const ServerFont& font, + bool forceVector); class GlyphCachePool; diff --git a/src/servers/app/font/GlyphLayoutEngine.h b/src/servers/app/font/GlyphLayoutEngine.h index 63ec4d0891..2039cd7aa4 100644 --- a/src/servers/app/font/GlyphLayoutEngine.h +++ b/src/servers/app/font/GlyphLayoutEngine.h @@ -80,6 +80,7 @@ public: static bool IsWhiteSpace(uint32 glyphCode); static FontCacheEntry* FontCacheEntryFor(const ServerFont& font, + bool forceVector, const FontCacheEntry* disallowedEntry, const char* utf8String, int32 length, FontCacheReference& cacheReference, @@ -100,7 +101,7 @@ private: static bool _WriteLockAndAcquireFallbackEntry( FontCacheReference& cacheReference, FontCacheEntry* entry, - const ServerFont& font, + const ServerFont& font, bool needsVector, const char* utf8String, int32 length, FontCacheReference& fallbackCacheReference, FontCacheEntry*& fallbackEntry); @@ -131,14 +132,14 @@ GlyphLayoutEngine::IsWhiteSpace(uint32 charCode) inline FontCacheEntry* -GlyphLayoutEngine::FontCacheEntryFor(const ServerFont& font, +GlyphLayoutEngine::FontCacheEntryFor(const ServerFont& font, bool forceVector, const FontCacheEntry* disallowedEntry, const char* utf8String, int32 length, FontCacheReference& cacheReference, bool needsWriteLock) { ASSERT(cacheReference.Entry() == NULL); FontCache* cache = FontCache::Default(); - FontCacheEntry* entry = cache->FontCacheEntryFor(font); + FontCacheEntry* entry = cache->FontCacheEntryFor(font, forceVector); if (entry == NULL) return NULL; @@ -192,8 +193,8 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, } if (entry == NULL) { - entry = FontCacheEntryFor(font, NULL, utf8String, length, - cacheReference, false); + entry = FontCacheEntryFor(font, consumer.NeedsVector(), NULL, + utf8String, length, cacheReference, false); if (entry == NULL) return false; @@ -211,7 +212,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, double advanceX = 0.0; double advanceY = 0.0; -// uint32 lastCharCode = 0; +// uint32 lastCharCode = 0; // Needed for kerning, see below uint32 charCode; int32 index = 0; bool writeLocked = false; @@ -244,8 +245,8 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, // we only have to do this switch once for the whole string. if (!writeLocked) { writeLocked = _WriteLockAndAcquireFallbackEntry(cacheReference, - entry, font, utf8String, length, fallbackCacheReference, - fallbackEntry); + entry, font, consumer.NeedsVector(), utf8String, length, + fallbackCacheReference, fallbackEntry); } if (writeLocked) @@ -293,8 +294,9 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, inline bool GlyphLayoutEngine::_WriteLockAndAcquireFallbackEntry( FontCacheReference& cacheReference, FontCacheEntry* entry, - const ServerFont& font, const char* utf8String, int32 length, - FontCacheReference& fallbackCacheReference, FontCacheEntry*& fallbackEntry) + const ServerFont& font, bool forceVector, const char* utf8String, + int32 length, FontCacheReference& fallbackCacheReference, + FontCacheEntry*& fallbackEntry) { // We need the fallback font, since potentially, we have to obtain missing // glyphs from it. We need to obtain the fallback font while we have not @@ -320,7 +322,7 @@ GlyphLayoutEngine::_WriteLockAndAcquireFallbackEntry( // to the other, but create new glyphs which are stored in // "entry" in any case, which requires the write cache for // sure (used FontEngine of fallbackEntry). - fallbackEntry = FontCacheEntryFor(fallbackFont, entry, + fallbackEntry = FontCacheEntryFor(fallbackFont, forceVector, entry, utf8String, length, fallbackCacheReference, true); // NOTE: We don't care if fallbackEntry is NULL, fetching // alternate glyphs will simply not work.