app_server: Prepare to be able to force vector glyphs...
...in everything text rendering related.
This commit is contained in:
@@ -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) {}
|
||||
|
||||
@@ -144,6 +144,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool NeedsVector()
|
||||
{
|
||||
return !fTransform.IsTranslationOnly();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
fRenderer.fRasterizer.reset();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user