OSDN Git Service

Account for text op stroke in bounds calculation
authorChris Craik <ccraik@google.com>
Thu, 17 Mar 2016 00:15:12 +0000 (17:15 -0700)
committerChris Craik <ccraik@google.com>
Thu, 17 Mar 2016 00:46:40 +0000 (17:46 -0700)
bug:27410033
Change-Id: Idf5bd5d2401f458d03af11617144cbe88adaf886

libs/hwui/FrameBuilder.cpp
libs/hwui/tests/unit/FrameBuilderTests.cpp

index fd5856a..50b21a4 100644 (file)
@@ -646,7 +646,9 @@ static batchid_t textBatchId(const SkPaint& paint) {
 }
 
 void FrameBuilder::deferTextOp(const TextOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
+    BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct(
+            mAllocator, *mCanvasState.writableSnapshot(), op,
+            BakedOpState::StrokeBehavior::StyleDefined);
     if (!bakedState) return; // quick rejected
 
     batchid_t batchId = textBatchId(*(op.paint));
index f147fd4..31555f2 100644 (file)
@@ -316,6 +316,61 @@ TEST(FrameBuilder, textStrikethrough) {
             << "Expect number of ops = 2 * loop count";
 }
 
+static auto styles = {
+        SkPaint::kFill_Style, SkPaint::kStroke_Style, SkPaint::kStrokeAndFill_Style };
+
+TEST(FrameBuilder, textStyle) {
+    class TextStyleTestRenderer : public TestRendererBase {
+    public:
+        void onMergedTextOps(const MergedBakedOpList& opList) override {
+            ASSERT_EQ(0, mIndex);
+            ASSERT_EQ(3u, opList.count);
+            mIndex += opList.count;
+
+            int index = 0;
+            for (auto style : styles) {
+                auto state = opList.states[index++];
+                ASSERT_EQ(style, state->op->paint->getStyle())
+                        << "Remainder of validation relies upon stable merged order";
+                ASSERT_EQ(0, state->computedState.clipSideFlags)
+                        << "Clipped bounds validation requires unclipped ops";
+            }
+
+            Rect fill = opList.states[0]->computedState.clippedBounds;
+            Rect stroke = opList.states[1]->computedState.clippedBounds;
+            EXPECT_EQ(stroke, opList.states[2]->computedState.clippedBounds)
+                    << "Stroke+Fill should be same as stroke";
+
+            EXPECT_TRUE(stroke.contains(fill));
+            EXPECT_FALSE(fill.contains(stroke));
+
+            Rect outsetFill(fill);
+            outsetFill.outset(10);
+            EXPECT_EQ(stroke, outsetFill);
+        }
+    };
+    auto node = TestUtils::createNode(0, 0, 400, 400,
+            [](RenderProperties& props, TestCanvas& canvas) {
+        SkPaint paint;
+        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        paint.setAntiAlias(true);
+        paint.setTextSize(50);
+        paint.setStrokeWidth(10);
+
+        // draw 3 copies of the same text overlapping, each with a different style.
+        // They'll get merged, but with
+        for (auto style : styles) {
+            paint.setStyle(style);
+            TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100);
+        }
+    });
+    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
+            TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr);
+    TextStyleTestRenderer renderer;
+    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(3, renderer.getIndex()) << "Expect 3 ops";
+}
+
 RENDERTHREAD_TEST(FrameBuilder, textureLayer) {
     class TextureLayerTestRenderer : public TestRendererBase {
     public: