| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "core/paint/SVGInlineTextBoxPainter.h" | |
| 6 | |
| 7 #include "core/dom/Document.h" | |
| 8 #include "core/dom/Range.h" | |
| 9 #include "core/editing/DOMSelection.h" | |
| 10 #include "core/frame/LocalDOMWindow.h" | |
| 11 #include "core/layout/LayoutTestHelper.h" | |
| 12 #include "core/layout/line/InlineTextBox.h" | |
| 13 #include "core/layout/svg/LayoutSVGInlineText.h" | |
| 14 #include "core/layout/svg/LayoutSVGText.h" | |
| 15 #include "core/paint/PaintLayer.h" | |
| 16 #include "platform/graphics/GraphicsLayer.h" | |
| 17 #include "platform/graphics/paint/DisplayItemList.h" | |
| 18 #include "platform/graphics/paint/DrawingDisplayItem.h" | |
| 19 #include "platform/graphics/paint/PaintController.h" | |
| 20 #include "testing/gtest/include/gtest/gtest.h" | |
| 21 | |
| 22 namespace blink { | |
| 23 namespace { | |
| 24 | |
| 25 class SVGInlineTextBoxPainterTest : public RenderingTest { | |
| 26 public: | |
| 27 const DrawingDisplayItem* getDrawingForSVGTextById(const char* elementName) | |
| 28 { | |
| 29 // Look up the inline text box that serves as the display item client fo
r the painted text. | |
| 30 LayoutSVGText* targetSVGText = toLayoutSVGText( | |
| 31 document().getElementById(AtomicString(elementName))->layoutObject()
); | |
| 32 LayoutSVGInlineText* targetInlineText = targetSVGText->descendantTextNod
es()[0]; | |
| 33 const DisplayItemClient* targetClient = static_cast<const DisplayItemCli
ent*>(targetInlineText->firstTextBox()); | |
| 34 | |
| 35 // Find the appropriate drawing in the display item list. | |
| 36 const DisplayItemList& displayItemList = rootPaintController().getDispla
yItemList(); | |
| 37 for (size_t i = 0; i < displayItemList.size(); i++) { | |
| 38 if (displayItemList[i].client() == *targetClient) | |
| 39 return static_cast<const DrawingDisplayItem*>(&displayItemList[i
]); | |
| 40 } | |
| 41 | |
| 42 return nullptr; | |
| 43 } | |
| 44 | |
| 45 void selectAllText() | |
| 46 { | |
| 47 Range* range = document().createRange(); | |
| 48 range->selectNode(document().documentElement()); | |
| 49 LocalDOMWindow* window = document().domWindow(); | |
| 50 DOMSelection* selection = window->getSelection(); | |
| 51 selection->removeAllRanges(); | |
| 52 selection->addRange(range); | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 PaintController& rootPaintController() | |
| 57 { | |
| 58 return document().view()->layoutView()->layer()->graphicsLayerBacking()-
>getPaintController(); | |
| 59 } | |
| 60 | |
| 61 void SetUp() override | |
| 62 { | |
| 63 RenderingTest::SetUp(); | |
| 64 enableCompositing(); | |
| 65 } | |
| 66 }; | |
| 67 | |
| 68 static void assertTextDrawingEquals(const DrawingDisplayItem* drawingDisplayItem
, const char* str) | |
| 69 { | |
| 70 ASSERT_EQ(str, static_cast<const InlineTextBox*>(&drawingDisplayItem->client
())->text()); | |
| 71 } | |
| 72 | |
| 73 const static int kAllowedPixelDelta = 4; | |
| 74 | |
| 75 static void assertCullRectEquals(const DrawingDisplayItem* drawingDisplayItem, c
onst IntRect& expectedRect) | |
| 76 { | |
| 77 // Text metrics can vary slightly across platforms, so we allow for a small
pixel difference. | |
| 78 IntRect outerRect(expectedRect); | |
| 79 int delta = kAllowedPixelDelta / 2; | |
| 80 outerRect.expand(delta, delta); | |
| 81 IntRect innerRect(expectedRect); | |
| 82 // Rect contains is inclusive of edge, so shrink by one extra pixel. | |
| 83 innerRect.contract(delta + 1, delta + 1); | |
| 84 | |
| 85 IntRect actualRect(IntRect(drawingDisplayItem->picture()->cullRect())); | |
| 86 ASSERT_TRUE(outerRect.contains(actualRect) && !innerRect.contains(actualRect
)) | |
| 87 << "Cull rect not approximately equal [expected=(" | |
| 88 << expectedRect.x() << "," << expectedRect.y() << " " << expectedRect.wi
dth() << "x" << expectedRect.height() << "), actual=(" | |
| 89 << actualRect.x() << "," << actualRect.y() << " " << actualRect.width()
<< "x" << actualRect.height() << ")]."; | |
| 90 } | |
| 91 | |
| 92 TEST_F(SVGInlineTextBoxPainterTest, TextCullRect_DefaultWritingMode) | |
| 93 { | |
| 94 setBodyInnerHTML( | |
| 95 "<svg width='400px' height='400px' font-family='Arial' font-size='30'>" | |
| 96 "<text id='target' x='50' y='30'>x</text>" | |
| 97 "</svg>"); | |
| 98 document().view()->updateAllLifecyclePhases(); | |
| 99 | |
| 100 const DrawingDisplayItem* drawingDisplayItem = getDrawingForSVGTextById("tar
get"); | |
| 101 assertTextDrawingEquals(drawingDisplayItem, "x"); | |
| 102 assertCullRectEquals(drawingDisplayItem, IntRect(50, 3, 15, 33)); | |
| 103 | |
| 104 selectAllText(); | |
| 105 document().view()->updateAllLifecyclePhases(); | |
| 106 | |
| 107 drawingDisplayItem = getDrawingForSVGTextById("target"); | |
| 108 assertTextDrawingEquals(drawingDisplayItem, "x"); | |
| 109 assertCullRectEquals(drawingDisplayItem, IntRect(50, 3, 15, 33)); | |
| 110 } | |
| 111 | |
| 112 TEST_F(SVGInlineTextBoxPainterTest, TextCullRect_WritingModeTopToBottom) | |
| 113 { | |
| 114 setBodyInnerHTML( | |
| 115 "<svg width='400px' height='400px' font-family='Arial' font-size='30'>" | |
| 116 "<text id='target' x='50' y='30' writing-mode='tb'>x</text>" | |
| 117 "</svg>"); | |
| 118 document().view()->updateAllLifecyclePhases(); | |
| 119 | |
| 120 const DrawingDisplayItem* drawingDisplayItem = getDrawingForSVGTextById("tar
get"); | |
| 121 assertTextDrawingEquals(drawingDisplayItem, "x"); | |
| 122 assertCullRectEquals(drawingDisplayItem, IntRect(33, 30, 34, 15)); | |
| 123 | |
| 124 selectAllText(); | |
| 125 document().view()->updateAllLifecyclePhases(); | |
| 126 | |
| 127 // The selection rect is one pixel taller due to sub-pixel difference | |
| 128 // between the text bounds and selection bounds in combination with use of | |
| 129 // enclosingIntRect() in SVGInlineTextBox::localSelectionRect(). | |
| 130 drawingDisplayItem = getDrawingForSVGTextById("target"); | |
| 131 assertTextDrawingEquals(drawingDisplayItem, "x"); | |
| 132 assertCullRectEquals(drawingDisplayItem, IntRect(33, 30, 34, 16)); | |
| 133 } | |
| 134 | |
| 135 } // namespace | |
| 136 } // namespace blink | |
| OLD | NEW |