-
Notifications
You must be signed in to change notification settings - Fork 35
Open
Description
Hi.
There are two issues in cache realization in FTSimpleLayout:
- store pointers to original string, but need to cached string - original can out of scope;
- no cache invalidating after change layout parameters.
My patch to fix this:
From f33041e830d791cfaee2ef5847584429965efea8 Mon Sep 17 00:00:00 2001
From: Oleg aka Blake-R <blake-r@mail.ru>
Date: Thu, 25 Aug 2011 09:09:13 +0400
Subject: [PATCH] Fix cache store and it's invalidation on change layout
parameters.
---
ftgles/src/FTLayout/FTSimpleLayout.cpp | 60 ++++++++++++++++++++---------
ftgles/src/FTLayout/FTSimpleLayoutImpl.h | 6 ++-
2 files changed, 45 insertions(+), 21 deletions(-)
diff --git a/ftgles/src/FTLayout/FTSimpleLayout.cpp b/ftgles/src/FTLayout/FTSimpleLayout.cpp
index ff2ec11..050d231 100755
--- a/ftgles/src/FTLayout/FTSimpleLayout.cpp
+++ b/ftgles/src/FTLayout/FTSimpleLayout.cpp
@@ -81,6 +81,7 @@ void FTSimpleLayout::Render(const wchar_t* string, const int len, FTPoint pos,
void FTSimpleLayout::SetFont(FTFont *fontInit)
{
dynamic_cast<FTSimpleLayoutImpl*>(impl)->currentFont = fontInit;
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate();
}
@@ -93,6 +94,7 @@ FTFont *FTSimpleLayout::GetFont()
void FTSimpleLayout::SetLineLength(const float LineLength)
{
dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineLength = LineLength;
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate();
}
@@ -105,6 +107,7 @@ float FTSimpleLayout::GetLineLength() const
void FTSimpleLayout::SetAlignment(const FTGL::TextAlignment Alignment)
{
dynamic_cast<FTSimpleLayoutImpl*>(impl)->alignment = Alignment;
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate();
}
@@ -117,6 +120,7 @@ FTGL::TextAlignment FTSimpleLayout::GetAlignment() const
void FTSimpleLayout::SetLineSpacing(const float LineSpacing)
{
dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineSpacing = LineSpacing;
+ dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate();
}
@@ -137,6 +141,21 @@ FTSimpleLayoutImpl::FTSimpleLayoutImpl()
lineLength = 100.0f;
alignment = FTGL::ALIGN_LEFT;
lineSpacing = 1.0f;
+ stringCache = NULL;
+ stringCacheCount = 0;
+}
+
+
+FTSimpleLayoutImpl::~FTSimpleLayoutImpl()
+{
+ free(stringCache);
+ stringCache = NULL;
+ stringCacheCount = 0;
+}
+
+
+inline void FTSimpleLayoutImpl::invalidate()
+{
stringCacheCount = 0;
}
@@ -209,6 +228,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
{
FTUnicodeStringItr<T> breakItr(buf); // points to the last break character
FTUnicodeStringItr<T> lineStart(buf); // points to the line start
+ unsigned int new_stringCacheCount = 0; // length of buffer
float nextStart = 0.0; // total width of the current line
float breakWidth = 0.0; // width of the line up to the last word break
float currentWidth = 0.0; // width of all characters on the current line
@@ -228,31 +248,33 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
{
bounds->Invalidate();
}
-
+
+ {
+ FTUnicodeStringItr<T> itr(buf);
+ for (; *itr; ++itr) {}
+ new_stringCacheCount = itr.getBufferFromHere() - buf + sizeof(T)/*terminator*/;
+ }
+
// Check if the incoming string is different to the previously
// cached string.
- unsigned int i = 0;
- for (FTUnicodeStringItr<T> itr(buf); *itr; itr++)
- {
- if (i >= stringCacheCount ||
- stringCache[i++] != (unsigned int)*itr)
- {
- refresh = true;
- break;
- }
+ if (stringCache && stringCacheCount == new_stringCacheCount) refresh = !!memcmp(stringCache, buf, stringCacheCount);
+ else {
+ refresh = true;
+ stringCacheCount = new_stringCacheCount;
+ if (!stringCache) stringCache = (unsigned char *)malloc(stringCacheCount);
+ else stringCache = (unsigned char *)realloc(stringCache, stringCacheCount);
+ if (!stringCache) throw std::bad_alloc();
}
-
+
if (refresh)
{
- stringCacheCount = 0;
+ memcpy(stringCache, buf, stringCacheCount);
layoutGlyphCache.clear();
// Scan the input for all characters that need output
FTUnicodeStringItr<T> prevItr(buf);
for (FTUnicodeStringItr<T> itr(buf); *itr; prevItr = itr++, charCount++)
- {
- stringCache[stringCacheCount++] = (unsigned int)*itr;
-
+ {
// Find the width of the current glyph
glyphBounds = currentFont->BBox(itr.getBufferFromHere(), 1);
glyphWidth = glyphBounds.Upper().Xf() - glyphBounds.Lower().Xf();
@@ -296,7 +318,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
}
layoutGlyphCacheItem_t cacheItem;
- cacheItem.buf = (T*)lineStart.getBufferFromHere();
+ cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf);
cacheItem.charCount = breakCharCount;
cacheItem.position = FTPoint(position.X(), position.Y(), position.Z());
cacheItem.remainingWidth = remainingWidth;
@@ -331,7 +353,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
wordLength += advance;
}
}
-
+
float remainingWidth = lineLength - currentWidth;
// Render any remaining text on the last line
// Disable justification for the last row
@@ -339,7 +361,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
{
alignment = FTGL::ALIGN_LEFT;
layoutGlyphCacheItem_t cacheItem;
- cacheItem.buf = (T *)lineStart.getBufferFromHere();
+ cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf);
cacheItem.charCount = -1;
cacheItem.position = FTPoint(position.X(), position.Y(), position.Z());
cacheItem.penDiff = FTPoint(0,0,0);
@@ -350,7 +372,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len,
else
{
layoutGlyphCacheItem_t cacheItem;
- cacheItem.buf = (T *)lineStart.getBufferFromHere();
+ cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf);
cacheItem.charCount = -1;
cacheItem.position = FTPoint(position.X(), position.Y(), position.Z());
cacheItem.penDiff = FTPoint(0,0,0);
diff --git a/ftgles/src/FTLayout/FTSimpleLayoutImpl.h b/ftgles/src/FTLayout/FTSimpleLayoutImpl.h
index 63b56cc..dd84234 100755
--- a/ftgles/src/FTLayout/FTSimpleLayoutImpl.h
+++ b/ftgles/src/FTLayout/FTSimpleLayoutImpl.h
@@ -50,7 +50,7 @@ class FTSimpleLayoutImpl : public FTLayoutImpl
protected:
FTSimpleLayoutImpl();
- virtual ~FTSimpleLayoutImpl() {};
+ virtual ~FTSimpleLayoutImpl();
virtual FTBBox BBox(const char* string, const int len,
FTPoint position);
@@ -211,10 +211,12 @@ private:
*/
std::list<layoutGlyphCacheItem_t> layoutGlyphCache;
- unsigned int stringCache[4096];
+ unsigned char * stringCache;
unsigned int stringCacheCount;
+
+ void invalidate();
/* Internal generic BBox() implementation */
template <typename T>
--
1.7.6.1Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels