Changeset 106547 in webkit
- Timestamp:
- Feb 2, 2012 5:53:57 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r106545 r106547 1 2012-02-02 Kenneth Rohde Christiansen <kenneth@webkit.org> 2 3 Make the tap highlighting work for all test cases 4 https://bugs.webkit.org/show_bug.cgi?id=77626 5 6 Reviewed by Simon Hausmann. 7 8 Clean up of the current code to make it more generic. Now uses 9 addFocusRingRects for finding the areas to highlight. 10 11 Tested by current manual tests. 12 13 * page/GestureTapHighlighter.cpp: 14 (WebCore::GestureTapHighlighter::pathForNodeHighlight): 15 1 16 2012-02-02 Mario Sanchez Prada <msanchez@igalia.com> 2 17 -
trunk/Source/WebCore/page/GestureTapHighlighter.cpp
r106357 r106547 82 82 } 83 83 84 Path pathForRenderBox(RenderBox* o) 85 { 86 ASSERT(o); 87 const int rounding = 4; 88 89 LayoutRect contentBox; 90 LayoutRect paddingBox; 91 LayoutRect borderBox; 92 93 contentBox = o->contentBoxRect(); 94 paddingBox = LayoutRect( 95 contentBox.x() - o->paddingLeft(), 96 contentBox.y() - o->paddingTop(), 97 contentBox.width() + o->paddingLeft() + o->paddingRight(), 98 contentBox.height() + o->paddingTop() + o->paddingBottom()); 99 borderBox = LayoutRect( 100 paddingBox.x() - o->borderLeft(), 101 paddingBox.y() - o->borderTop(), 102 paddingBox.width() + o->borderLeft() + o->borderRight(), 103 paddingBox.height() + o->borderTop() + o->borderBottom()); 104 105 FloatRect rect(borderBox); 106 rect.inflate(rounding); 107 108 rect.move(toLayoutSize(ownerFrameToMainFrameOffset(o))); 109 110 Path path; 111 FloatSize rounded(rounding * 1.8, rounding * 1.8); 112 path.addRoundedRect(rect, rounded); 113 114 return path; 115 } 116 117 void addRectWithRoundedCorners(Path& path, const LayoutRect& rect, bool topLeft, bool topRight, bool bottomLeft, bool bottomRight) 118 { 84 inline bool contains(const LayoutRect& rect, int x) 85 { 86 return !rect.isEmpty() && x >= rect.x() && x <= rect.maxX(); 87 } 88 89 inline bool strikes(const LayoutRect& a, const LayoutRect& b) 90 { 91 return !a.isEmpty() && !b.isEmpty() 92 && a.x() <= b.maxX() && b.x() <= a.maxX() 93 && a.y() <= b.maxY() && b.y() <= a.maxY(); 94 } 95 96 inline void shiftXEdgesToContainIfStrikes(LayoutRect& rect, const LayoutRect& other) 97 { 98 int leftSide = rect.x(); 99 int rightSide = rect.maxX(); 100 101 if (!other.isEmpty() && strikes(rect, other)) { 102 leftSide = std::min(leftSide, other.x()); 103 rightSide = std::max(rightSide, other.maxX()); 104 } 105 106 rect.setX(leftSide); 107 rect.setWidth(rightSide - leftSide); 108 } 109 110 inline void addHighlightRect(Path& path, const LayoutRect& rect, const LayoutRect& prev, const LayoutRect& next) 111 { 112 // The rounding check depends on the rects not intersecting eachother, 113 // or being contained for that matter. 114 ASSERT(!rect.intersects(prev)); 115 ASSERT(!rect.intersects(next)); 116 117 if (rect.isEmpty()) 118 return; 119 119 120 const int rounding = 4; 120 121 … … 127 128 128 129 path.addBeziersForRoundedRect(copy, 129 topLeft ? rounded : squared, topRight ? rounded : squared, 130 bottomLeft ? rounded : squared, bottomRight ? rounded : squared); 131 } 132 133 inline bool contains(LayoutRect rect, int x) 134 { 135 return !rect.isEmpty() && x >= rect.x() && x <= rect.maxX(); 136 } 137 138 Path pathForRenderInline(RenderInline* o) 130 contains(prev, rect.x()) ? squared : rounded, 131 contains(prev, rect.maxX()) ? squared : rounded, 132 contains(next, rect.x()) ? squared : rounded, 133 contains(next, rect.maxX()) ? squared : rounded); 134 } 135 136 Path pathForRenderer(RenderObject* o) 139 137 { 140 138 ASSERT(o); … … 142 140 143 141 Vector<LayoutRect> rects; 144 o->absoluteRects(rects, /* acc. offset */ ownerFrameToMainFrameOffset(o)); 145 146 LayoutRect first = rects.size() ? rects.first() : LayoutRect(); 147 LayoutRect last = rects.size() > 1 ? rects.last() : LayoutRect(); 148 LayoutRect middle; 142 o->addFocusRingRects(rects, /* acc. offset */ ownerFrameToMainFrameOffset(o)); 143 144 // The basic idea is to allow up to three different boxes in order to highlight 145 // text with line breaks more nicer than using a bounding box. 146 147 // Merge all center boxes (all but the first and the last). 148 LayoutRect mid; 149 149 for (int i = 1; i < rects.size() - 1; ++i) 150 middle.uniteIfNonZero(rects.at(i)); 151 152 if (!middle.isEmpty()) { 153 int leftSide = middle.x(); 154 int rightSide = middle.maxX(); 155 156 if (!first.isEmpty()) { 157 leftSide = std::min(leftSide, first.x()); 158 rightSide = std::max(rightSide, first.maxX()); 159 } 160 if (!last.isEmpty()) { 161 leftSide = std::min(leftSide, last.x()); 162 rightSide = std::max(rightSide, last.maxX()); 163 } 164 165 middle.setX(leftSide); 166 middle.setWidth(rightSide - leftSide); 167 } 168 169 if (!first.isEmpty()) { 170 bool roundBottomLeft = !contains(middle, first.x()) && !contains(last, first.x()); 171 bool roundBottomRight = !contains(middle, first.maxX()) && !contains(last, first.maxX()); 172 addRectWithRoundedCorners(path, first, /* roundTopLeft */ true, /* roundTopRight */ true, roundBottomLeft, roundBottomRight); 173 } 174 175 if (!middle.isEmpty()) { 176 bool roundTopLeft = !contains(first, middle.x()); 177 bool roundBottomRight = !contains(last, middle.maxX()); 178 addRectWithRoundedCorners(path, middle, roundTopLeft, /* roundTopRight */ false, /* roundBottomLeft */ false, roundBottomRight); 179 } 180 181 if (!last.isEmpty()) { 182 bool roundTopLeft = !contains(middle, last.x()) && !contains(first, last.x()); 183 bool roundTopRight = !contains(middle, last.maxX()) && !contains(first, last.maxX()); 184 addRectWithRoundedCorners(path, last, roundTopLeft, roundTopRight, /* roundBottomLeft */ true, /* roundBottomRight */ true); 150 mid.uniteIfNonZero(rects.at(i)); 151 152 Vector<LayoutRect> drawableRects; 153 154 if (!mid.isEmpty()) 155 drawableRects.append(mid); 156 157 // Add the first box, but merge it with the center boxes if it intersects. 158 if (rects.size() && !rects.first().isEmpty()) { 159 if (drawableRects.size() && drawableRects.last().intersects(rects.first())) 160 drawableRects.last().unite(rects.first()); 161 else 162 drawableRects.prepend(rects.first()); 163 } 164 165 // Add the last box, but merge it with the center boxes if it intersects. 166 if (rects.size() > 1 && !rects.last().isEmpty()) { 167 if (drawableRects.size() && drawableRects.last().intersects(rects.last())) 168 drawableRects.last().unite(rects.last()); 169 else 170 drawableRects.append(rects.last()); 171 } 172 173 // Adjust middle to boundaries of first and last. 174 if (drawableRects.size() == 3) { 175 LayoutRect& middle = drawableRects.at(1); 176 shiftXEdgesToContainIfStrikes(middle, drawableRects.at(0)); 177 shiftXEdgesToContainIfStrikes(middle, drawableRects.at(2)); 178 } 179 180 for (int i = 0; i < drawableRects.size(); ++i) { 181 LayoutRect prev = (i - 1) >= 0 ? drawableRects.at(i - 1) : LayoutRect(); 182 LayoutRect next = (i + 1) < drawableRects.size() ? drawableRects.at(i + 1) : LayoutRect(); 183 addHighlightRect(path, drawableRects.at(i), prev, next); 185 184 } 186 185 … … 200 199 return path; 201 200 202 if (renderer->isBox()) 203 path = pathForRenderBox(toRenderBox(renderer)); 204 else 205 path = pathForRenderInline(toRenderInline(renderer)); 206 201 path = pathForRenderer(renderer); 207 202 path.transform(localToAbsoluteTransform(renderer)); 203 208 204 return path; 209 205 }
Note: See TracChangeset
for help on using the changeset viewer.