OSDN Git Service

Fix TextDropShadowCacheTests and glyph_t everywhere
authorChris Craik <ccraik@google.com>
Sat, 6 Feb 2016 04:10:50 +0000 (20:10 -0800)
committerChris Craik <ccraik@google.com>
Mon, 8 Feb 2016 22:45:22 +0000 (22:45 +0000)
Change-Id: I943eae4e9408c77bdfba6304ba7ee3e862351a41

17 files changed:
libs/hwui/BakedOpDispatcher.cpp
libs/hwui/DisplayListCanvas.cpp
libs/hwui/DisplayListCanvas.h
libs/hwui/DisplayListOp.h
libs/hwui/FontRenderer.cpp
libs/hwui/FontRenderer.h
libs/hwui/OpenGLRenderer.cpp
libs/hwui/OpenGLRenderer.h
libs/hwui/Properties.h
libs/hwui/TextDropShadowCache.cpp
libs/hwui/TextDropShadowCache.h
libs/hwui/font/Font.cpp
libs/hwui/font/Font.h
libs/hwui/font/FontUtil.h
libs/hwui/tests/common/TestUtils.cpp
libs/hwui/tests/common/TestUtils.h
libs/hwui/tests/unit/TextDropShadowCacheTests.cpp

index e3a5f3e..f83e1fa 100644 (file)
@@ -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) {
index 3db14b5..00560d7 100644 (file)
@@ -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);
index 06e72a0..e5711e3 100644 (file)
@@ -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;
 
index 92217ed..20501ba 100644 (file)
@@ -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;
index 68bae6d..1b618c6 100644 (file)
@@ -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;
index 9994498..e10a81b 100644 (file)
@@ -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) {
index 587be92..b7a5923 100644 (file)
@@ -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;
index 84bc9b0..dacd8cc 100755 (executable)
@@ -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);
 
index 3e11151..249b5b0 100644 (file)
@@ -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
 
index fe4b3d7..e1f0b2a 100644 (file)
@@ -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);
index cf64788..d536c40 100644 (file)
@@ -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);
 
     /**
index dc82041..9a825fd 100644 (file)
@@ -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)) {
index 59518a1..e8882d9 100644 (file)
@@ -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);
index 4e5debe..aa77d98 100644 (file)
 
 #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)
 
index 5ed7aa4..3440d03 100644 (file)
@@ -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) {
index ae08142..6f23705 100644 (file)
@@ -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);
 
index c54f2c3..0d26df2 100644 (file)
 #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());