diff options
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/BakedOpDispatcher.cpp | 9 | ||||
-rw-r--r-- | libs/hwui/DisplayListCanvas.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/DisplayListCanvas.h | 4 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 10 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 18 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.h | 8 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 20 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 6 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 3 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.h | 37 | ||||
-rw-r--r-- | libs/hwui/font/Font.cpp | 28 | ||||
-rw-r--r-- | libs/hwui/font/Font.h | 10 | ||||
-rw-r--r-- | libs/hwui/font/FontUtil.h | 23 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 38 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.h | 4 | ||||
-rw-r--r-- | libs/hwui/tests/unit/TextDropShadowCacheTests.cpp | 28 |
17 files changed, 125 insertions, 140 deletions
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp index e3a5f3eeeac1..f83e1faf9c8a 100644 --- a/libs/hwui/BakedOpDispatcher.cpp +++ b/libs/hwui/BakedOpDispatcher.cpp @@ -201,8 +201,7 @@ static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRender renderer.caches().dropShadowCache.setFontRenderer(fontRenderer); ShadowTexture* texture = renderer.caches().dropShadowCache.get( - op.paint, (const char*) op.glyphs, - op.glyphCount, textShadow.radius, op.positions); + op.paint, op.glyphs, op.glyphCount, textShadow.radius, op.positions); // If the drop shadow exceeds the max texture size or couldn't be // allocated, skip drawing if (!texture) return; @@ -277,8 +276,7 @@ static void renderTextOp(BakedOpRenderer& renderer, const TextOp& op, const Bake bool forceFinish = (renderType == TextRenderType::Flush); bool mustDirtyRenderTarget = renderer.offscreenRenderTarget(); const Rect* localOpClip = pureTranslate ? &state.computedState.clipRect() : nullptr; - fontRenderer.renderPosText(op.paint, localOpClip, - (const char*) op.glyphs, op.glyphCount, x, y, + fontRenderer.renderPosText(op.paint, localOpClip, op.glyphs, op.glyphCount, x, y, op.positions, mustDirtyRenderTarget ? &layerBounds : nullptr, &functor, forceFinish); if (mustDirtyRenderTarget) { @@ -701,8 +699,7 @@ void BakedOpDispatcher::onTextOnPathOp(BakedOpRenderer& renderer, const TextOnPa bool mustDirtyRenderTarget = renderer.offscreenRenderTarget(); const Rect localSpaceClip = state.computedState.computeLocalSpaceClip(); - if (fontRenderer.renderTextOnPath(op.paint, &localSpaceClip, - reinterpret_cast<const char*>(op.glyphs), op.glyphCount, + if (fontRenderer.renderTextOnPath(op.paint, &localSpaceClip, op.glyphs, op.glyphCount, op.path, op.hOffset, op.vOffset, mustDirtyRenderTarget ? &layerBounds : nullptr, &functor)) { if (mustDirtyRenderTarget) { diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index 3db14b55cff6..00560d7df454 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -428,7 +428,7 @@ void DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count, if (!glyphs || count <= 0) return; int bytesCount = 2 * count; - DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount), + DrawOp* op = new (alloc()) DrawTextOnPathOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count, refPath(&path), hOffset, vOffset, refPaint(&paint)); addDrawOp(op); @@ -442,11 +442,10 @@ void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; int bytesCount = count * 2; - const char* text = refText((const char*) glyphs, bytesCount); positions = refBuffer<float>(positions, count * 2); Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); - DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, + DrawOp* op = new (alloc()) DrawTextOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count, x, y, positions, refPaint(&paint), totalAdvance, bounds); addDrawOp(op); drawTextDecorations(x, y, totalAdvance, paint); diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h index 06e72a06eaca..e5711e35a88b 100644 --- a/libs/hwui/DisplayListCanvas.h +++ b/libs/hwui/DisplayListCanvas.h @@ -256,10 +256,6 @@ private: return dstBuffer; } - inline char* refText(const char* text, size_t byteLength) { - return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength); - } - inline const SkPath* refPath(const SkPath* path) { if (!path) return nullptr; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 92217edc2f16..20501ba3c1d9 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1229,7 +1229,7 @@ public: class DrawSomeTextOp : public DrawOp { public: - DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint) + DrawSomeTextOp(const glyph_t* text, int bytesCount, int count, const SkPaint* paint) : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; virtual void output(int level, uint32_t logFlags) const override { @@ -1251,14 +1251,14 @@ public: } protected: - const char* mText; + const glyph_t* mText; int mBytesCount; int mCount; }; class DrawTextOnPathOp : public DrawSomeTextOp { public: - DrawTextOnPathOp(const char* text, int bytesCount, int count, + DrawTextOnPathOp(const glyph_t* text, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) : DrawSomeTextOp(text, bytesCount, count, paint), mPath(path), mHOffset(hOffset), mVOffset(vOffset) { @@ -1280,7 +1280,7 @@ private: class DrawTextOp : public DrawStrokableOp { public: - DrawTextOp(const char* text, int bytesCount, int count, float x, float y, + DrawTextOp(const glyph_t* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds) : DrawStrokableOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count), mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) { @@ -1341,7 +1341,7 @@ public: virtual const char* name() override { return "DrawText"; } private: - const char* mText; + const glyph_t* mText; int mBytesCount; int mCount; float mX; diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 68bae6dc47f6..1b618c6a71c6 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -557,7 +557,7 @@ void FontRenderer::setFont(const SkPaint* paint, const SkMatrix& matrix) { mCurrentFont = Font::create(this, paint, matrix); } -FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text, +FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const glyph_t *glyphs, int numGlyphs, float radius, const float* positions) { checkInit(); @@ -577,7 +577,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co mBounds = nullptr; Rect bounds; - mCurrentFont->measure(paint, text, numGlyphs, &bounds, positions); + mCurrentFont->measure(paint, glyphs, numGlyphs, &bounds, positions); uint32_t intRadius = Blur::convertRadiusToInt(radius); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * intRadius; @@ -609,7 +609,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co // text has non-whitespace, so draw and blur to create the shadow // NOTE: bounds.isEmpty() can't be used here, since vertical coordinates are inverted // TODO: don't draw pure whitespace in the first place, and avoid needing this check - mCurrentFont->render(paint, text, numGlyphs, penX, penY, + mCurrentFont->render(paint, glyphs, numGlyphs, penX, penY, Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, nullptr, positions); // Unbind any PBO we might have used @@ -643,17 +643,17 @@ void FontRenderer::finishRender() { issueDrawCommand(); } -void FontRenderer::precache(const SkPaint* paint, const char* text, int numGlyphs, +void FontRenderer::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkMatrix& matrix) { Font* font = Font::create(this, paint, matrix); - font->precache(paint, text, numGlyphs); + font->precache(paint, glyphs, numGlyphs); } void FontRenderer::endPrecaching() { checkTextureUpdate(); } -bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text, +bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs, int x, int y, const float* positions, Rect* bounds, TextDrawFunctor* functor, bool forceFinish) { if (!mCurrentFont) { @@ -662,7 +662,7 @@ bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const c } initRender(clip, bounds, functor); - mCurrentFont->render(paint, text, numGlyphs, x, y, positions); + mCurrentFont->render(paint, glyphs, numGlyphs, x, y, positions); if (forceFinish) { finishRender(); @@ -671,7 +671,7 @@ bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const c return mDrawn; } -bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text, +bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs, const SkPath* path, float hOffset, float vOffset, Rect* bounds, TextDrawFunctor* functor) { if (!mCurrentFont) { @@ -680,7 +680,7 @@ bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, cons } initRender(clip, bounds, functor); - mCurrentFont->render(paint, text, numGlyphs, path, hOffset, vOffset); + mCurrentFont->render(paint, glyphs, numGlyphs, path, hOffset, vOffset); finishRender(); return mDrawn; diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index 99944985cda8..e10a81b8ccd8 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -104,14 +104,14 @@ public: void setFont(const SkPaint* paint, const SkMatrix& matrix); - void precache(const SkPaint* paint, const char* text, int numGlyphs, const SkMatrix& matrix); + void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkMatrix& matrix); void endPrecaching(); - bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text, + bool renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs, int x, int y, const float* positions, Rect* outBounds, TextDrawFunctor* functor, bool forceFinish = true); - bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text, + bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs, const SkPath* path, float hOffset, float vOffset, Rect* outBounds, TextDrawFunctor* functor); @@ -125,7 +125,7 @@ public: // After renderDropShadow returns, the called owns the memory in DropShadow.image // and is responsible for releasing it when it's done with it - DropShadow renderDropShadow(const SkPaint* paint, const char *text, int numGlyphs, + DropShadow renderDropShadow(const SkPaint* paint, const glyph_t *glyphs, int numGlyphs, float radius, const float* positions); void setTextureFiltering(bool linearFiltering) { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 587be92b4cbc..b7a5923cdd65 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1949,7 +1949,7 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, } } -void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, +void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const glyph_t* glyphs, int count, const float* positions, FontRenderer& fontRenderer, int alpha, float x, float y) { mCaches.textureState().activateTexture(0); @@ -1963,7 +1963,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, // if shader-based correction is enabled mCaches.dropShadowCache.setFontRenderer(fontRenderer); ShadowTexture* texture = mCaches.dropShadowCache.get( - paint, text, count, textShadow.radius, positions); + paint, glyphs, count, textShadow.radius, positions); // If the drop shadow exceeds the max texture size or couldn't be // allocated, skip drawing if (!texture) return; @@ -2084,14 +2084,14 @@ void OpenGLRenderer::setProjectionPathMask(LinearAllocator& allocator, const SkP mState.setProjectionPathMask(allocator, path); } -void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, +void OpenGLRenderer::drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { if (drawOpMode == DrawOpMode::kImmediate) { // The checks for corner-case ignorable text and quick rejection is only done for immediate // drawing as ops from DeferredDisplayList are already filtered for these - if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) || + if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) || quickRejectSetupScissor(bounds)) { return; } @@ -2115,7 +2115,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float if (CC_UNLIKELY(PaintUtils::hasTextShadow(paint))) { fontRenderer.setFont(paint, SkMatrix::I()); - drawTextShadow(paint, text, count, positions, fontRenderer, + drawTextShadow(paint, glyphs, count, positions, fontRenderer, alpha, oldX, oldY); } @@ -2156,10 +2156,10 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) { SkPaint paintCopy(*paint); paintCopy.setTextAlign(SkPaint::kLeft_Align); - status = fontRenderer.renderPosText(&paintCopy, clip, text, count, x, y, + status = fontRenderer.renderPosText(&paintCopy, clip, glyphs, count, x, y, positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } else { - status = fontRenderer.renderPosText(paint, clip, text, count, x, y, + status = fontRenderer.renderPosText(paint, clip, glyphs, count, x, y, positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish); } @@ -2173,9 +2173,9 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float mDirty = true; } -void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, +void OpenGLRenderer::drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { - if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { + if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) { return; } @@ -2198,7 +2198,7 @@ void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, const Rect* clip = &writableSnapshot()->getLocalClip(); Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); - if (fontRenderer.renderTextOnPath(paint, clip, text, count, path, + if (fontRenderer.renderTextOnPath(paint, clip, glyphs, count, path, hOffset, vOffset, hasLayer() ? &bounds : nullptr, &functor)) { dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, *currentTransform()); mDirty = true; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 84bc9b059d33..dacd8ccaa6ea 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -191,9 +191,9 @@ public: void drawPath(const SkPath* path, const SkPaint* paint); void drawLines(const float* points, int count, const SkPaint* paint); void drawPoints(const float* points, int count, const SkPaint* paint); - void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path, + void drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count, const SkPath* path, float hOffset, float vOffset, const SkPaint* paint); - void drawText(const char* text, int bytesCount, int count, float x, float y, + void drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode = DrawOpMode::kImmediate); void drawRects(const float* rects, int count, const SkPaint* paint); @@ -647,7 +647,7 @@ private: * @param x The x coordinate where the shadow will be drawn * @param y The y coordinate where the shadow will be drawn */ - void drawTextShadow(const SkPaint* paint, const char* text, int count, + void drawTextShadow(const SkPaint* paint, const glyph_t* glyphs, int count, const float* positions, FontRenderer& fontRenderer, int alpha, float x, float y); diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 3e111516ac63..249b5b07fa11 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -31,9 +31,6 @@ namespace uirenderer { // Compile-time properties /////////////////////////////////////////////////////////////////////////////// -// If turned on, text is interpreted as glyphs instead of UTF-16 -#define RENDER_TEXT_AS_GLYPHS 1 - // Textures used by layers must have dimensions multiples of this number #define LAYER_SIZE 64 diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index fe4b3d7507b2..e1f0b2a20172 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -37,9 +37,9 @@ hash_t ShadowText::hash() const { hash = JenkinsHashMix(hash, flags); hash = JenkinsHashMix(hash, android::hash_type(italicStyle)); hash = JenkinsHashMix(hash, android::hash_type(scaleX)); - if (text) { + if (glyphs) { hash = JenkinsHashMixShorts( - hash, reinterpret_cast<const uint16_t*>(text), glyphCount); + hash, reinterpret_cast<const uint16_t*>(glyphs), glyphCount); } if (positions) { for (uint32_t i = 0; i < glyphCount * 2; i++) { @@ -71,11 +71,11 @@ int ShadowText::compare(const ShadowText& lhs, const ShadowText& rhs) { if (lhs.scaleX < rhs.scaleX) return -1; if (lhs.scaleX > rhs.scaleX) return +1; - if (lhs.text != rhs.text) { - if (!lhs.text) return -1; - if (!rhs.text) return +1; + if (lhs.glyphs != rhs.glyphs) { + if (!lhs.glyphs) return -1; + if (!rhs.glyphs) return +1; - deltaInt = memcmp(lhs.text, rhs.text, lhs.glyphCount * sizeof(glyph_t)); + deltaInt = memcmp(lhs.glyphs, rhs.glyphs, lhs.glyphCount * sizeof(glyph_t)); if (deltaInt != 0) return deltaInt; } @@ -145,7 +145,7 @@ void TextDropShadowCache::clear() { mCache.clear(); } -ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* glyphs, int numGlyphs, +ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, float radius, const float* positions) { ShadowText entry(paint, radius, numGlyphs, glyphs, positions); ShadowTexture* texture = mCache.get(entry); diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index cf647882e5a7..d536c40756ff 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -35,26 +35,21 @@ class FontRenderer; struct ShadowText { ShadowText(): glyphCount(0), radius(0.0f), textSize(0.0f), typeface(nullptr), - flags(0), italicStyle(0.0f), scaleX(0), text(nullptr), positions(nullptr) { + flags(0), italicStyle(0.0f), scaleX(0), glyphs(nullptr), positions(nullptr) { } // len is the number of bytes in text - ShadowText(const SkPaint* paint, float radius, uint32_t glyphCount, const char* srcText, - const float* positions): - glyphCount(glyphCount), radius(radius), positions(positions) { - // TODO: Propagate this through the API, we should not cast here - text = (const char16_t*) srcText; - - textSize = paint->getTextSize(); - typeface = paint->getTypeface(); - - flags = 0; - if (paint->isFakeBoldText()) { - flags |= Font::kFakeBold; - } - - italicStyle = paint->getTextSkewX(); - scaleX = paint->getTextScaleX(); + ShadowText(const SkPaint* paint, float radius, uint32_t glyphCount, const glyph_t* srcGlyphs, + const float* positions) + : glyphCount(glyphCount) + , radius(radius) + , textSize(paint->getTextSize()) + , typeface(paint->getTypeface()) + , flags(paint->isFakeBoldText() ? Font::kFakeBold : 0) + , italicStyle(paint->getTextSkewX()) + , scaleX(paint->getTextScaleX()) + , glyphs(srcGlyphs) + , positions(positions) { } ~ShadowText() { @@ -73,8 +68,8 @@ struct ShadowText { } void copyTextLocally() { - str.setTo((const char16_t*) text, glyphCount); - text = str.string(); + str.setTo(reinterpret_cast<const char16_t*>(glyphs), glyphCount); + glyphs = reinterpret_cast<const glyph_t*>(str.string()); if (positions != nullptr) { positionsCopy.clear(); positionsCopy.appendArray(positions, glyphCount * 2); @@ -89,7 +84,7 @@ struct ShadowText { uint32_t flags; float italicStyle; float scaleX; - const char16_t* text; + const glyph_t* glyphs; const float* positions; // Not directly used to compute the cache key @@ -135,7 +130,7 @@ public: */ void operator()(ShadowText& text, ShadowTexture*& texture) override; - ShadowTexture* get(const SkPaint* paint, const char* text, + ShadowTexture* get(const SkPaint* paint, const glyph_t* text, int numGlyphs, float radius, const float* positions); /** diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index dc82041e8f89..9a825fdec601 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -291,15 +291,15 @@ CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bo return cachedGlyph; } -void Font::render(const SkPaint* paint, const char *text, +void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y, const float* positions) { - render(paint, text, numGlyphs, x, y, FRAMEBUFFER, nullptr, + render(paint, glyphs, numGlyphs, x, y, FRAMEBUFFER, nullptr, 0, 0, nullptr, positions); } -void Font::render(const SkPaint* paint, const char *text, int numGlyphs, +void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkPath* path, float hOffset, float vOffset) { - if (numGlyphs == 0 || text == nullptr) { + if (numGlyphs == 0 || glyphs == nullptr) { return; } @@ -315,7 +315,7 @@ void Font::render(const SkPaint* paint, const char *text, int numGlyphs, float pathLength = SkScalarToFloat(measure.getLength()); if (paint->getTextAlign() != SkPaint::kLeft_Align) { - float textWidth = SkScalarToFloat(paint->measureText(text, numGlyphs * 2)); + float textWidth = SkScalarToFloat(paint->measureText(glyphs, numGlyphs * 2)); float pathOffset = pathLength; if (paint->getTextAlign() == SkPaint::kCenter_Align) { textWidth *= 0.5f; @@ -325,7 +325,7 @@ void Font::render(const SkPaint* paint, const char *text, int numGlyphs, } while (glyphsCount < numGlyphs && penX < pathLength) { - glyph_t glyph = GET_GLYPH(text); + glyph_t glyph = *(glyphs++); if (IS_END_OF_STRING(glyph)) { break; @@ -345,26 +345,26 @@ void Font::render(const SkPaint* paint, const char *text, int numGlyphs, } } -void Font::measure(const SkPaint* paint, const char* text, +void Font::measure(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, Rect *bounds, const float* positions) { if (bounds == nullptr) { ALOGE("No return rectangle provided to measure text"); return; } bounds->set(1e6, -1e6, -1e6, 1e6); - render(paint, text, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions); + render(paint, glyphs, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions); } -void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) { +void Font::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs) { ATRACE_NAME("Precache Glyphs"); - if (numGlyphs == 0 || text == nullptr) { + if (numGlyphs == 0 || glyphs == nullptr) { return; } int glyphsCount = 0; while (glyphsCount < numGlyphs) { - glyph_t glyph = GET_GLYPH(text); + glyph_t glyph = *(glyphs++); // Reached the end of the string if (IS_END_OF_STRING(glyph)) { @@ -376,10 +376,10 @@ void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) { } } -void Font::render(const SkPaint* paint, const char* text, +void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) { - if (numGlyphs == 0 || text == nullptr) { + if (numGlyphs == 0 || glyphs == nullptr) { return; } @@ -396,7 +396,7 @@ void Font::render(const SkPaint* paint, const char* text, int glyphsCount = 0; while (glyphsCount < numGlyphs) { - glyph_t glyph = GET_GLYPH(text); + glyph_t glyph = *(glyphs++); // Reached the end of the string if (IS_END_OF_STRING(glyph)) { diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h index 59518a1fb8ee..e8882d9f4bda 100644 --- a/libs/hwui/font/Font.h +++ b/libs/hwui/font/Font.h @@ -82,10 +82,10 @@ public: ~Font(); - void render(const SkPaint* paint, const char* text, + void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y, const float* positions); - void render(const SkPaint* paint, const char* text, + void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkPath* path, float hOffset, float vOffset); const Font::FontDescription& getDescription() const { @@ -111,13 +111,13 @@ private: MEASURE, }; - void precache(const SkPaint* paint, const char* text, int numGlyphs); + void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs); - void render(const SkPaint* paint, const char *text, + void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions); - void measure(const SkPaint* paint, const char* text, + void measure(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, Rect *bounds, const float* positions); void invalidateTextureCache(CacheTexture* cacheTexture = nullptr); diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h index 4e5debe33c4a..aa77d98c9343 100644 --- a/libs/hwui/font/FontUtil.h +++ b/libs/hwui/font/FontUtil.h @@ -40,26 +40,9 @@ #define CACHE_BLOCK_ROUNDING_SIZE 4 -#if RENDER_TEXT_AS_GLYPHS - typedef uint16_t glyph_t; - #define TO_GLYPH(g) g - #define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph) - #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text) - #define IS_END_OF_STRING(glyph) false - - static inline glyph_t nextGlyph(const uint16_t** srcPtr) { - const uint16_t* src = *srcPtr; - glyph_t g = *src++; - *srcPtr = src; - return g; - } -#else - typedef SkUnichar glyph_t; - #define TO_GLYPH(g) ((SkUnichar) g) - #define GET_METRICS(cache, glyph) cache->getUnicharMetrics(glyph) - #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text) - #define IS_END_OF_STRING(glyph) glyph < 0 -#endif +typedef uint16_t glyph_t; +#define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph) +#define IS_END_OF_STRING(glyph) false #define AUTO_KERN(prev, next) (((next) - (prev) + 32) >> 6 << 16) diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 5ed7aa464026..3440d03b4fc5 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -58,27 +58,22 @@ sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater( return layerUpdater; } -void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, - const SkPaint& paint, float x, float y) { - // drawing text requires GlyphID TextEncoding (which JNI layer would have done) - LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding, - "must use glyph encoding"); +void TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text, + std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions, + float* outTotalAdvance, Rect* outBounds) { + Rect bounds; + float totalAdvance = 0; SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry); SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I()); - - float totalAdvance = 0; - std::vector<glyph_t> glyphs; - std::vector<float> positions; - Rect bounds; while (*text != '\0') { SkUnichar unichar = SkUTF8_NextUnichar(&text); glyph_t glyph = autoCache.getCache()->unicharToGlyph(unichar); autoCache.getCache()->unicharToGlyph(unichar); // push glyph and its relative position - glyphs.push_back(glyph); - positions.push_back(totalAdvance); - positions.push_back(0); + outGlyphs->push_back(glyph); + outPositions->push_back(totalAdvance); + outPositions->push_back(0); // compute bounds SkGlyph skGlyph = autoCache.getCache()->getUnicharMetrics(unichar); @@ -91,6 +86,23 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, paint.getTextWidths(&glyph, sizeof(glyph), &skWidth, NULL); totalAdvance += skWidth; } + *outBounds = bounds; + *outTotalAdvance = totalAdvance; +} + +void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text, + const SkPaint& paint, float x, float y) { + // drawing text requires GlyphID TextEncoding (which JNI layer would have done) + LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding, + "must use glyph encoding"); + SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry); + SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I()); + + std::vector<glyph_t> glyphs; + std::vector<float> positions; + float totalAdvance; + Rect bounds; + layoutTextUnscaled(paint, text, &glyphs, &positions, &totalAdvance, &bounds); // apply alignment via x parameter (which JNI layer would have done) if (paint.getTextAlign() == SkPaint::kCenter_Align) { diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index ae0814241055..6f237059dd33 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -205,6 +205,10 @@ public: static SkColor interpolateColor(float fraction, SkColor start, SkColor end); + static void layoutTextUnscaled(const SkPaint& paint, const char* text, + std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions, + float* outTotalAdvance, Rect* outBounds); + static void drawTextToCanvas(TestCanvas* canvas, const char* text, const SkPaint& paint, float x, float y); diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp index c54f2c365ee2..0d26df203f02 100644 --- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp +++ b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp @@ -21,29 +21,31 @@ #include "utils/Blur.h" #include "tests/common/TestUtils.h" -#include <SkBlurDrawLooper.h> #include <SkPaint.h> using namespace android; using namespace android::uirenderer; RENDERTHREAD_TEST(TextDropShadowCache, addRemove) { + SkPaint paint; + paint.setTextSize(20); + GammaFontRenderer gammaFontRenderer; FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer(); - TextDropShadowCache cache(5000); + fontRenderer.setFont(&paint, SkMatrix::I()); + TextDropShadowCache cache(MB(5)); cache.setFontRenderer(fontRenderer); - SkPaint paint; - paint.setLooper(SkBlurDrawLooper::Create((SkColor)0xFFFFFFFF, - Blur::convertRadiusToSigma(10), 10, 10))->unref(); - std::string msg("This is a test"); - std::unique_ptr<float[]> positions(new float[msg.length()]); - for (size_t i = 0; i < msg.length(); i++) { - positions[i] = i * 10.0f; - } - fontRenderer.setFont(&paint, SkMatrix::I()); - ShadowTexture* texture = cache.get(&paint, msg.c_str(), msg.length(), - 10.0f, positions.get()); + std::vector<glyph_t> glyphs; + std::vector<float> positions; + float totalAdvance; + uirenderer::Rect bounds; + TestUtils::layoutTextUnscaled(paint, "This is a test", + &glyphs, &positions, &totalAdvance, &bounds); + EXPECT_TRUE(bounds.contains(5, -10, 100, 0)) << "Expect input to be nontrivially sized"; + + ShadowTexture* texture = cache.get(&paint, glyphs.data(), glyphs.size(), 10, positions.data()); + ASSERT_TRUE(texture); ASSERT_FALSE(texture->cleanup); ASSERT_EQ((uint32_t) texture->objectSize(), cache.getSize()); |