summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-01-08 17:38:15 -0800
committerRomain Guy <romainguy@google.com>2013-01-08 17:38:15 -0800
commit19d4f1806a953b87435a2bb6fd8e738424e94003 (patch)
treeab561da75ff49699432723e2904a89d5cda534e2 /libs
parent1a9853fef502ef4dac48476b8b588650ae5db4ce (diff)
parentc88c60bed1fdf5b84cc16905c8743453203c19a5 (diff)
downloadframeworks_base-19d4f1806a953b87435a2bb6fd8e738424e94003.zip
frameworks_base-19d4f1806a953b87435a2bb6fd8e738424e94003.tar.gz
frameworks_base-19d4f1806a953b87435a2bb6fd8e738424e94003.tar.bz2
resolved conflicts for merge of c88c60be to master-chromium
Change-Id: I3b4b42443312068e942aa779dfdc928afa7569fd
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DisplayListRenderer.cpp6
-rw-r--r--libs/hwui/FontRenderer.cpp78
-rw-r--r--libs/hwui/FontRenderer.h11
-rw-r--r--libs/hwui/LayerCache.cpp8
-rw-r--r--libs/hwui/LayerCache.h28
-rw-r--r--libs/hwui/OpenGLRenderer.cpp33
-rw-r--r--libs/hwui/PathCache.cpp3
-rw-r--r--libs/hwui/font/Font.cpp196
-rw-r--r--libs/hwui/font/Font.h78
-rw-r--r--libs/hwui/font/FontUtil.h4
10 files changed, 216 insertions, 229 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 747856c..06574cd 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -1775,7 +1775,7 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i
paint->setAntiAlias(true);
SkPaint* addedPaint = addPaint(paint);
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
- fontRenderer.precache(addedPaint, text, count);
+ fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
return DrawGlInfo::kStatusDone;
}
@@ -1789,7 +1789,7 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int
paint->setAntiAlias(true);
SkPaint* addedPaint = addPaint(paint);
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
- fontRenderer.precache(addedPaint, text, count);
+ fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
return DrawGlInfo::kStatusDone;
}
@@ -1823,7 +1823,7 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou
SkPaint* addedPaint = addPaint(paint);
if (!reject) {
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
- fontRenderer.precache(addedPaint, text, count);
+ fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
}
addFloat(length);
addSkip(location);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 2a09ced..61107c6 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -37,7 +37,9 @@ namespace uirenderer {
static bool sLogFontRendererCreate = true;
-FontRenderer::FontRenderer() {
+FontRenderer::FontRenderer() :
+ mActiveFonts(LruCache<Font::FontDescription, Font*>::kUnlimitedCapacity) {
+
if (sLogFontRendererCreate) {
INIT_LOGD("Creating FontRenderer");
}
@@ -108,10 +110,11 @@ FontRenderer::~FontRenderer() {
delete[] mTextMesh;
}
- Vector<Font*> fontsToDereference = mActiveFonts;
- for (uint32_t i = 0; i < fontsToDereference.size(); i++) {
- delete fontsToDereference[i];
+ LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+ while (it.next()) {
+ delete it.value();
}
+ mActiveFonts.clear();
}
void FontRenderer::flushAllAndInvalidate() {
@@ -119,8 +122,9 @@ void FontRenderer::flushAllAndInvalidate() {
issueDrawCommand();
}
- for (uint32_t i = 0; i < mActiveFonts.size(); i++) {
- mActiveFonts[i]->invalidateTextureCache();
+ LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+ while (it.next()) {
+ it.value()->invalidateTextureCache();
}
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
@@ -147,8 +151,9 @@ void FontRenderer::flushLargeCaches() {
CacheTexture* cacheTexture = mCacheTextures[i];
if (cacheTexture->getTexture()) {
cacheTexture->init();
- for (uint32_t j = 0; j < mActiveFonts.size(); j++) {
- mActiveFonts[j]->invalidateTextureCache(cacheTexture);
+ LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+ while (it.next()) {
+ it.value()->invalidateTextureCache(cacheTexture);
}
cacheTexture->releaseTexture();
}
@@ -481,22 +486,8 @@ void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
}
}
-void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) {
- int flags = 0;
- if (paint->isFakeBoldText()) {
- flags |= Font::kFakeBold;
- }
-
- const float skewX = paint->getTextSkewX();
- uint32_t italicStyle = *(uint32_t*) &skewX;
- const float scaleXFloat = paint->getTextScaleX();
- uint32_t scaleX = *(uint32_t*) &scaleXFloat;
- SkPaint::Style style = paint->getStyle();
- const float strokeWidthFloat = paint->getStrokeWidth();
- uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
- mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle,
- scaleX, style, strokeWidth);
-
+void FontRenderer::setFont(SkPaint* paint, const mat4& matrix) {
+ mCurrentFont = Font::create(this, paint, matrix);
}
FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
@@ -562,39 +553,11 @@ void FontRenderer::finishRender() {
}
}
-void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs) {
- int flags = 0;
- if (paint->isFakeBoldText()) {
- flags |= Font::kFakeBold;
- }
- const float skewX = paint->getTextSkewX();
- uint32_t italicStyle = *(uint32_t*) &skewX;
- const float scaleXFloat = paint->getTextScaleX();
- uint32_t scaleX = *(uint32_t*) &scaleXFloat;
- SkPaint::Style style = paint->getStyle();
- const float strokeWidthFloat = paint->getStrokeWidth();
- uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
- float fontSize = paint->getTextSize();
- Font* font = Font::create(this, SkTypeface::UniqueID(paint->getTypeface()),
- fontSize, flags, italicStyle, scaleX, style, strokeWidth);
-
+void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix) {
+ Font* font = Font::create(this, paint, matrix);
font->precache(paint, text, numGlyphs);
}
-bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
- uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, Rect* bounds) {
- if (!mCurrentFont) {
- ALOGE("No font set");
- return false;
- }
-
- initRender(clip, bounds);
- mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y);
- finishRender();
-
- return mDrawn;
-}
-
bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
const float* positions, Rect* bounds) {
@@ -626,12 +589,7 @@ bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char
}
void FontRenderer::removeFont(const Font* font) {
- for (uint32_t ct = 0; ct < mActiveFonts.size(); ct++) {
- if (mActiveFonts[ct] == font) {
- mActiveFonts.removeAt(ct);
- break;
- }
- }
+ mActiveFonts.remove(font->getDescription());
if (mCurrentFont == font) {
mCurrentFont = NULL;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 09a3c25..3964bca 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_HWUI_FONT_RENDERER_H
#define ANDROID_HWUI_FONT_RENDERER_H
+#include <utils/LruCache.h>
#include <utils/Vector.h>
#include <SkPaint.h>
@@ -27,6 +28,7 @@
#include "font/CacheTexture.h"
#include "font/CachedGlyphInfo.h"
#include "font/Font.h"
+#include "Matrix.h"
#include "Properties.h"
namespace android {
@@ -47,14 +49,11 @@ public:
mGammaTable = gammaTable;
}
- void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
+ void setFont(SkPaint* paint, const mat4& matrix);
- void precache(SkPaint* paint, const char* text, int numGlyphs);
+ void precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
// bounds is an out parameter
- bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
- uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
- // bounds is an out parameter
bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
// bounds is an out parameter
@@ -153,7 +152,7 @@ private:
Vector<CacheTexture*> mCacheTextures;
Font* mCurrentFont;
- Vector<Font*> mActiveFonts;
+ LruCache<Font::FontDescription, Font*> mActiveFonts;
CacheTexture* mCurrentCacheTexture;
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index ce74cee..cfc5b04 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -67,6 +67,14 @@ void LayerCache::setMaxSize(uint32_t maxSize) {
// Caching
///////////////////////////////////////////////////////////////////////////////
+int LayerCache::LayerEntry::compare(const LayerCache::LayerEntry& lhs,
+ const LayerCache::LayerEntry& rhs) {
+ int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
+ if (deltaInt != 0) return deltaInt;
+
+ return int(lhs.mHeight) - int(rhs.mHeight);
+}
+
void LayerCache::deleteLayer(Layer* layer) {
if (layer) {
LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index fd698e2..fc2cd91 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -102,9 +102,6 @@ public:
*/
void dump();
-private:
- void deleteLayer(Layer* layer);
-
struct LayerEntry {
LayerEntry():
mLayer(NULL), mWidth(0), mHeight(0) {
@@ -119,15 +116,14 @@ private:
mLayer(layer), mWidth(layer->getWidth()), mHeight(layer->getHeight()) {
}
- bool operator<(const LayerEntry& rhs) const {
- if (mWidth == rhs.mWidth) {
- return mHeight < rhs.mHeight;
- }
- return mWidth < rhs.mWidth;
+ static int compare(const LayerEntry& lhs, const LayerEntry& rhs);
+
+ bool operator==(const LayerEntry& other) const {
+ return compare(*this, other) == 0;
}
- bool operator==(const LayerEntry& rhs) const {
- return mWidth == rhs.mWidth && mHeight == rhs.mHeight;
+ bool operator!=(const LayerEntry& other) const {
+ return compare(*this, other) != 0;
}
Layer* mLayer;
@@ -135,12 +131,24 @@ private:
uint32_t mHeight;
}; // struct LayerEntry
+private:
+ void deleteLayer(Layer* layer);
+
SortedList<LayerEntry> mCache;
uint32_t mSize;
uint32_t mMaxSize;
}; // class LayerCache
+inline int strictly_order_type(const LayerCache::LayerEntry& lhs,
+ const LayerCache::LayerEntry& rhs) {
+ return LayerCache::LayerEntry::compare(lhs, rhs) < 0;
+}
+
+inline int compare_type(const LayerCache::LayerEntry& lhs, const LayerCache::LayerEntry& rhs) {
+ return LayerCache::LayerEntry::compare(lhs, rhs);
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 8756805..8cda729 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1716,7 +1716,6 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
return DrawGlInfo::kStatusDone;
}
- // TODO: We should compute the bounding box when recording the display list
float left = FLT_MAX;
float top = FLT_MAX;
float right = FLT_MIN;
@@ -1754,7 +1753,6 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1);
TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2);
- // TODO: This could be optimized to avoid unnecessary ops
left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx])));
top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy])));
right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx])));
@@ -2453,7 +2451,8 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto
}
// TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
- if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || p->getStrokeCap() != SkPaint::kButt_Cap || useCenter) {
+ if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 ||
+ p->getStrokeCap() != SkPaint::kButt_Cap || useCenter) {
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
startAngle, sweepAngle, useCenter, p);
@@ -2577,16 +2576,15 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
}
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
- paint->getTextSize());
+ fontRenderer.setFont(paint, *mSnapshot->transform);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
if (CC_UNLIKELY(mHasShadow)) {
- drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode,
- 0.0f, 0.0f);
+ drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
+ alpha, mode, 0.0f, 0.0f);
}
// Pick the appropriate texture filtering
@@ -2655,6 +2653,14 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
return DrawGlInfo::kStatusDone;
}
+#if DEBUG_GLYPHS
+ ALOGD("OpenGLRenderer drawText() with FontID=%d",
+ SkTypeface::UniqueID(paint->getTypeface()));
+#endif
+
+ FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+ fontRenderer.setFont(paint, *mSnapshot->transform);
+
const float oldX = x;
const float oldY = y;
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
@@ -2663,15 +2669,6 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
}
-#if DEBUG_GLYPHS
- ALOGD("OpenGLRenderer drawText() with FontID=%d",
- SkTypeface::UniqueID(paint->getTypeface()));
-#endif
-
- FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
- paint->getTextSize());
-
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
@@ -2744,8 +2741,7 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co
}
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
- paint->getTextSize());
+ fontRenderer.setFont(paint, *mSnapshot->transform);
int alpha;
SkXfermode::Mode mode;
@@ -2789,7 +2785,6 @@ status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
mCaches.activeTexture(0);
- // TODO: Perform early clip test before we rasterize the path
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 03ddf59..4f682ed 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -93,9 +93,6 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
PathCacheEntry entry(path, paint);
PathTexture* texture = mCache.get(entry);
- float left, top, offset;
- uint32_t width, height;
-
if (!texture) {
texture = addTexture(entry, path, paint);
} else if (path->getGenerationID() != texture->generation) {
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 9068b8a..34afe97 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -18,7 +18,8 @@
#include <cutils/compiler.h>
-#include <SkGlyph.h>
+#include <utils/JenkinsHash.h>
+
#include <SkUtils.h>
#include "Debug.h"
@@ -34,14 +35,22 @@ namespace uirenderer {
// Font
///////////////////////////////////////////////////////////////////////////////
-Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX,
- SkPaint::Style style, uint32_t strokeWidth) :
- mState(state), mFontId(fontId), mFontSize(fontSize),
- mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX),
- mStyle(style), mStrokeWidth(mStrokeWidth) {
+Font::Font(FontRenderer* state, const Font::FontDescription& desc) :
+ mState(state), mDescription(desc) {
}
+Font::FontDescription::FontDescription(const SkPaint* paint, const mat4& matrix) {
+ mFontId = SkTypeface::UniqueID(paint->getTypeface());
+ mFontSize = paint->getTextSize();
+ mFlags = 0;
+ if (paint->isFakeBoldText()) {
+ mFlags |= Font::kFakeBold;
+ }
+ mItalicStyle = paint->getTextSkewX();
+ mScaleX = paint->getTextScaleX();
+ mStyle = paint->getStyle();
+ mStrokeWidth = paint->getStrokeWidth();
+}
Font::~Font() {
mState->removeFont(this);
@@ -51,6 +60,43 @@ Font::~Font() {
}
}
+hash_t Font::FontDescription::hash() const {
+ uint32_t hash = JenkinsHashMix(0, mFontId);
+ hash = JenkinsHashMix(hash, android::hash_type(mFontSize));
+ hash = JenkinsHashMix(hash, android::hash_type(mFlags));
+ hash = JenkinsHashMix(hash, android::hash_type(mItalicStyle));
+ hash = JenkinsHashMix(hash, android::hash_type(mScaleX));
+ hash = JenkinsHashMix(hash, android::hash_type(mStyle));
+ hash = JenkinsHashMix(hash, android::hash_type(mStrokeWidth));
+ return JenkinsHashWhiten(hash);
+}
+
+int Font::FontDescription::compare(const Font::FontDescription& lhs,
+ const Font::FontDescription& rhs) {
+ int deltaInt = int(lhs.mFontId) - int(rhs.mFontId);
+ if (deltaInt != 0) return deltaInt;
+
+ if (lhs.mFontSize < rhs.mFontSize) return -1;
+ if (lhs.mFontSize > rhs.mFontSize) return +1;
+
+ if (lhs.mItalicStyle < rhs.mItalicStyle) return -1;
+ if (lhs.mItalicStyle > rhs.mItalicStyle) return +1;
+
+ deltaInt = int(lhs.mFlags) - int(rhs.mFlags);
+ if (deltaInt != 0) return deltaInt;
+
+ if (lhs.mScaleX < rhs.mScaleX) return -1;
+ if (lhs.mScaleX > rhs.mScaleX) return +1;
+
+ deltaInt = int(lhs.mStyle) - int(rhs.mStyle);
+ if (deltaInt != 0) return deltaInt;
+
+ if (lhs.mStrokeWidth < rhs.mStrokeWidth) return -1;
+ if (lhs.mStrokeWidth > rhs.mStrokeWidth) return +1;
+
+ return 0;
+}
+
void Font::invalidateTextureCache(CacheTexture* cacheTexture) {
for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueAt(i);
@@ -84,17 +130,17 @@ void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
- int nPenX = x + glyph->mBitmapLeft;
- int nPenY = y + glyph->mBitmapTop + glyph->mBitmapHeight;
+ float nPenX = x + glyph->mBitmapLeft;
+ float nPenY = y + (glyph->mBitmapTop + glyph->mBitmapHeight);
+
+ float width = (float) glyph->mBitmapWidth;
+ float height = (float) glyph->mBitmapHeight;
float u1 = glyph->mBitmapMinU;
float u2 = glyph->mBitmapMaxU;
float v1 = glyph->mBitmapMinV;
float v2 = glyph->mBitmapMaxV;
- int width = (int) glyph->mBitmapWidth;
- int height = (int) glyph->mBitmapHeight;
-
mState->appendMeshQuad(nPenX, nPenY, u1, v2,
nPenX + width, nPenY, u2, v2,
nPenX + width, nPenY - height, u2, v1,
@@ -137,7 +183,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float
vOffset += glyph->mBitmapTop + height;
SkPoint destination[4];
- measure.getPosTan(x + hOffset + glyph->mBitmapLeft + halfWidth, position, tangent);
+ measure.getPosTan(x + hOffset + glyph->mBitmapLeft + halfWidth, position, tangent);
// Move along the tangent and offset by the normal
destination[0].set(-tangent->fX * halfWidth - tangent->fY * vOffset,
@@ -177,24 +223,13 @@ CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool pre
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
- const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit);
+ const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, NULL);
updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
}
return cachedGlyph;
}
-void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
- int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
- if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) {
- render(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap,
- bitmapW, bitmapH, NULL, NULL);
- } else {
- render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
- 0, 0, NULL, NULL);
- }
-}
-
void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
int numGlyphs, int x, int y, const float* positions) {
render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
@@ -299,71 +334,40 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len
text += start;
int glyphsCount = 0;
- if (CC_LIKELY(positions == NULL)) {
- SkFixed prevRsbDelta = 0;
-
- float penX = x + 0.5f;
- int penY = y;
-
- while (glyphsCount < numGlyphs) {
- glyph_t glyph = GET_GLYPH(text);
-
- // Reached the end of the string
- if (IS_END_OF_STRING(glyph)) {
- break;
- }
-
- CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
- penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
- prevRsbDelta = cachedGlyph->mRsbDelta;
+ const SkPaint::Align align = paint->getTextAlign();
- // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
- if (cachedGlyph->mIsValid) {
- (*this.*render)(cachedGlyph, (int) floorf(penX), penY,
- bitmap, bitmapW, bitmapH, bounds, positions);
- }
-
- penX += SkFixedToFloat(cachedGlyph->mAdvanceX);
+ while (glyphsCount < numGlyphs) {
+ glyph_t glyph = GET_GLYPH(text);
- glyphsCount++;
+ // Reached the end of the string
+ if (IS_END_OF_STRING(glyph)) {
+ break;
}
- } else {
- const SkPaint::Align align = paint->getTextAlign();
- // This is for renderPosText()
- while (glyphsCount < numGlyphs) {
- glyph_t glyph = GET_GLYPH(text);
-
- // Reached the end of the string
- if (IS_END_OF_STRING(glyph)) {
- break;
- }
+ CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
- CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
-
- // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
- if (cachedGlyph->mIsValid) {
- int penX = x + positions[(glyphsCount << 1)];
- int penY = y + positions[(glyphsCount << 1) + 1];
-
- switch (align) {
- case SkPaint::kRight_Align:
- penX -= SkFixedToFloat(cachedGlyph->mAdvanceX);
- penY -= SkFixedToFloat(cachedGlyph->mAdvanceY);
- break;
- case SkPaint::kCenter_Align:
- penX -= SkFixedToFloat(cachedGlyph->mAdvanceX >> 1);
- penY -= SkFixedToFloat(cachedGlyph->mAdvanceY >> 1);
- default:
- break;
- }
-
- (*this.*render)(cachedGlyph, penX, penY,
- bitmap, bitmapW, bitmapH, bounds, positions);
+ // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
+ if (cachedGlyph->mIsValid) {
+ int penX = x + positions[(glyphsCount << 1)];
+ int penY = y + positions[(glyphsCount << 1) + 1];
+
+ switch (align) {
+ case SkPaint::kRight_Align:
+ penX -= SkFixedToFloat(cachedGlyph->mAdvanceX);
+ penY -= SkFixedToFloat(cachedGlyph->mAdvanceY);
+ break;
+ case SkPaint::kCenter_Align:
+ penX -= SkFixedToFloat(cachedGlyph->mAdvanceX >> 1);
+ penY -= SkFixedToFloat(cachedGlyph->mAdvanceY >> 1);
+ default:
+ break;
}
- glyphsCount++;
+ (*this.*render)(cachedGlyph, penX, penY,
+ bitmap, bitmapW, bitmapH, bounds, positions);
}
+
+ glyphsCount++;
}
}
@@ -380,7 +384,7 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
uint32_t startY = 0;
// Get the bitmap for the glyph
- paint->findImage(skiaGlyph);
+ paint->findImage(skiaGlyph, NULL);
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
if (!glyph->mIsValid) {
@@ -410,7 +414,7 @@ CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
mCachedGlyphs.add(glyph, newGlyph);
- const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph);
+ const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph, NULL);
newGlyph->mGlyphIndex = skiaGlyph.fID;
newGlyph->mIsValid = false;
@@ -419,24 +423,16 @@ CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching
return newGlyph;
}
-Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX,
- SkPaint::Style style, uint32_t strokeWidth) {
- Vector<Font*> &activeFonts = state->mActiveFonts;
-
- for (uint32_t i = 0; i < activeFonts.size(); i++) {
- Font* font = activeFonts[i];
- if (font->mFontId == fontId && font->mFontSize == fontSize &&
- font->mFlags == flags && font->mItalicStyle == italicStyle &&
- font->mScaleX == scaleX && font->mStyle == style &&
- (style == SkPaint::kFill_Style || font->mStrokeWidth == strokeWidth)) {
- return font;
- }
+Font* Font::create(FontRenderer* state, const SkPaint* paint, const mat4& matrix) {
+ FontDescription description(paint, matrix);
+ Font* font = state->mActiveFonts.get(description);
+
+ if (font) {
+ return font;
}
- Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle,
- scaleX, style, strokeWidth);
- activeFonts.push(newFont);
+ Font* newFont = new Font(state, description);
+ state->mActiveFonts.put(description, newFont);
return newFont;
}
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 7cab31e..6ddf162 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -25,6 +25,7 @@
#include "CachedGlyphInfo.h"
#include "../Rect.h"
+#include "../Matrix.h"
namespace android {
namespace uirenderer {
@@ -45,31 +46,52 @@ public:
kFakeBold = 1
};
- ~Font();
+ struct FontDescription {
+ FontDescription(const SkPaint* paint, const mat4& matrix);
- /**
- * Renders the specified string of text.
- * If bitmap is specified, it will be used as the render target
- */
- void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
- int numGlyphs, int x, int y, uint8_t *bitmap = NULL,
- uint32_t bitmapW = 0, uint32_t bitmapH = 0);
+ static int compare(const FontDescription& lhs, const FontDescription& rhs);
- void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+ hash_t hash() const;
+
+ bool operator==(const FontDescription& other) const {
+ return compare(*this, other) == 0;
+ }
+
+ bool operator!=(const FontDescription& other) const {
+ return compare(*this, other) != 0;
+ }
+
+ SkFontID mFontId;
+ float mFontSize;
+ int mFlags;
+ float mItalicStyle;
+ float mScaleX;
+ uint8_t mStyle;
+ float mStrokeWidth;
+ };
+
+ ~Font();
+
+ void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
int numGlyphs, int x, int y, const float* positions);
- void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+ void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
int numGlyphs, SkPath* path, float hOffset, float vOffset);
+ const Font::FontDescription& getDescription() const {
+ return mDescription;
+ }
+
/**
* Creates a new font associated with the specified font state.
*/
- static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX, SkPaint::Style style,
- uint32_t strokeWidth);
+ static Font* create(FontRenderer* state, const SkPaint* paint, const mat4& matrix);
private:
friend class FontRenderer;
+
+ Font(FontRenderer* state, const Font::FontDescription& desc);
+
typedef void (Font::*RenderGlyph)(CachedGlyphInfo*, int, int, uint8_t*,
uint32_t, uint32_t, Rect*, const float*);
@@ -88,12 +110,6 @@ private:
void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
int numGlyphs, Rect *bounds, const float* positions);
- Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
- uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth);
-
- // Cache of glyphs
- DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
-
void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
@@ -115,15 +131,25 @@ private:
CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching = false);
FontRenderer* mState;
- uint32_t mFontId;
- float mFontSize;
- int mFlags;
- uint32_t mItalicStyle;
- uint32_t mScaleX;
- SkPaint::Style mStyle;
- uint32_t mStrokeWidth;
+ FontDescription mDescription;
+
+ // Cache of glyphs
+ DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
};
+inline int strictly_order_type(const Font::FontDescription& lhs,
+ const Font::FontDescription& rhs) {
+ return Font::FontDescription::compare(lhs, rhs) < 0;
+}
+
+inline int compare_type(const Font::FontDescription& lhs, const Font::FontDescription& rhs) {
+ return Font::FontDescription::compare(lhs, rhs);
+}
+
+inline hash_t hash_type(const Font::FontDescription& entry) {
+ return entry.hash();
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index 12247ba..4f9c46b 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -37,7 +37,7 @@
#if RENDER_TEXT_AS_GLYPHS
typedef uint16_t glyph_t;
#define TO_GLYPH(g) g
- #define GET_METRICS(paint, glyph) paint->getGlyphMetrics(glyph)
+ #define GET_METRICS(paint, glyph, matrix) paint->getGlyphMetrics(glyph, matrix)
#define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
#define IS_END_OF_STRING(glyph) false
@@ -50,7 +50,7 @@
#else
typedef SkUnichar glyph_t;
#define TO_GLYPH(g) ((SkUnichar) g)
- #define GET_METRICS(paint, glyph) paint->getUnicharMetrics(glyph)
+ #define GET_METRICS(paint, glyph, matrix) paint->getUnicharMetrics(glyph, matrix)
#define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
#define IS_END_OF_STRING(glyph) glyph < 0
#endif