Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: Source/core/rendering/shapes/PolygonShape.cpp

Issue 216793009: Remove shape-padding (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Remove m_padding Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/rendering/shapes/PolygonShape.h ('k') | Source/core/rendering/shapes/RasterShape.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above 8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following 9 * copyright notice, this list of conditions and the following
10 * disclaimer. 10 * disclaimer.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 VertexMaxY, 42 VertexMaxY,
43 VertexYBoth 43 VertexYBoth
44 }; 44 };
45 45
46 struct EdgeIntersection { 46 struct EdgeIntersection {
47 const FloatPolygonEdge* edge; 47 const FloatPolygonEdge* edge;
48 FloatPoint point; 48 FloatPoint point;
49 EdgeIntersectionType type; 49 EdgeIntersectionType type;
50 }; 50 };
51 51
52 static inline float leftSide(const FloatPoint& vertex1, const FloatPoint& vertex 2, const FloatPoint& point)
53 {
54 return ((point.x() - vertex1.x()) * (vertex2.y() - vertex1.y())) - ((vertex2 .x() - vertex1.x()) * (point.y() - vertex1.y()));
55 }
56
57 static inline bool isReflexVertex(const FloatPoint& prevVertex, const FloatPoint & vertex, const FloatPoint& nextVertex)
58 {
59 return leftSide(prevVertex, nextVertex, vertex) < 0;
60 }
61
62 static bool computeXIntersection(const FloatPolygonEdge* edgePointer, float y, E dgeIntersection& result) 52 static bool computeXIntersection(const FloatPolygonEdge* edgePointer, float y, E dgeIntersection& result)
63 { 53 {
64 const FloatPolygonEdge& edge = *edgePointer; 54 const FloatPolygonEdge& edge = *edgePointer;
65 55
66 if (edge.minY() > y || edge.maxY() < y) 56 if (edge.minY() > y || edge.maxY() < y)
67 return false; 57 return false;
68 58
69 const FloatPoint& vertex1 = edge.vertex1(); 59 const FloatPoint& vertex1 = edge.vertex1();
70 const FloatPoint& vertex2 = edge.vertex2(); 60 const FloatPoint& vertex2 = edge.vertex2();
71 float dy = vertex2.y() - vertex1.y(); 61 float dy = vertex2.y() - vertex1.y();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 119 }
130 vertices.append(endArcVertex); 120 vertices.append(endArcVertex);
131 } 121 }
132 122
133 static inline void snapVerticesToLayoutUnitGrid(Vector<FloatPoint>& vertices) 123 static inline void snapVerticesToLayoutUnitGrid(Vector<FloatPoint>& vertices)
134 { 124 {
135 for (unsigned i = 0; i < vertices.size(); ++i) 125 for (unsigned i = 0; i < vertices.size(); ++i)
136 vertices[i] = flooredLayoutPoint(vertices[i]); 126 vertices[i] = flooredLayoutPoint(vertices[i]);
137 } 127 }
138 128
139 static inline PassOwnPtr<FloatPolygon> computeShapePaddingBounds(const FloatPoly gon& polygon, float padding, WindRule fillRule)
140 {
141 OwnPtr<Vector<FloatPoint> > paddedVertices = adoptPtr(new Vector<FloatPoint> ());
142 FloatPoint intersection;
143
144 for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) {
145 const FloatPolygonEdge& thisEdge = polygon.edgeAt(i);
146 const FloatPolygonEdge& prevEdge = thisEdge.previousEdge();
147 OffsetPolygonEdge thisOffsetEdge(thisEdge, inwardEdgeNormal(thisEdge) * padding);
148 OffsetPolygonEdge prevOffsetEdge(prevEdge, inwardEdgeNormal(prevEdge) * padding);
149
150 if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
151 paddedVertices->append(intersection);
152 else if (isReflexVertex(prevEdge.vertex1(), thisEdge.vertex1(), thisEdge .vertex2()))
153 appendArc(*paddedVertices, thisEdge.vertex1(), padding, prevOffsetEd ge.vertex2(), thisOffsetEdge.vertex1(), true);
154 }
155
156 snapVerticesToLayoutUnitGrid(*paddedVertices);
157 return adoptPtr(new FloatPolygon(paddedVertices.release(), fillRule));
158 }
159
160 static inline PassOwnPtr<FloatPolygon> computeShapeMarginBounds(const FloatPolyg on& polygon, float margin, WindRule fillRule) 129 static inline PassOwnPtr<FloatPolygon> computeShapeMarginBounds(const FloatPolyg on& polygon, float margin, WindRule fillRule)
161 { 130 {
162 OwnPtr<Vector<FloatPoint> > marginVertices = adoptPtr(new Vector<FloatPoint> ()); 131 OwnPtr<Vector<FloatPoint> > marginVertices = adoptPtr(new Vector<FloatPoint> ());
163 FloatPoint intersection; 132 FloatPoint intersection;
164 133
165 for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) { 134 for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) {
166 const FloatPolygonEdge& thisEdge = polygon.edgeAt(i); 135 const FloatPolygonEdge& thisEdge = polygon.edgeAt(i);
167 const FloatPolygonEdge& prevEdge = thisEdge.previousEdge(); 136 const FloatPolygonEdge& prevEdge = thisEdge.previousEdge();
168 OffsetPolygonEdge thisOffsetEdge(thisEdge, outwardEdgeNormal(thisEdge) * margin); 137 OffsetPolygonEdge thisOffsetEdge(thisEdge, outwardEdgeNormal(thisEdge) * margin);
169 OffsetPolygonEdge prevOffsetEdge(prevEdge, outwardEdgeNormal(prevEdge) * margin); 138 OffsetPolygonEdge prevOffsetEdge(prevEdge, outwardEdgeNormal(prevEdge) * margin);
170 139
171 if (prevOffsetEdge.intersection(thisOffsetEdge, intersection)) 140 if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
172 marginVertices->append(intersection); 141 marginVertices->append(intersection);
173 else 142 else
174 appendArc(*marginVertices, thisEdge.vertex1(), margin, prevOffsetEdg e.vertex2(), thisOffsetEdge.vertex1(), false); 143 appendArc(*marginVertices, thisEdge.vertex1(), margin, prevOffsetEdg e.vertex2(), thisOffsetEdge.vertex1(), false);
175 } 144 }
176 145
177 snapVerticesToLayoutUnitGrid(*marginVertices); 146 snapVerticesToLayoutUnitGrid(*marginVertices);
178 return adoptPtr(new FloatPolygon(marginVertices.release(), fillRule)); 147 return adoptPtr(new FloatPolygon(marginVertices.release(), fillRule));
179 } 148 }
180 149
181 const FloatPolygon& PolygonShape::shapePaddingBounds() const
182 {
183 ASSERT(shapePadding() >= 0);
184 if (!shapePadding() || m_polygon.isEmpty())
185 return m_polygon;
186
187 if (!m_paddingBounds)
188 m_paddingBounds = computeShapePaddingBounds(m_polygon, shapePadding(), m _polygon.fillRule());
189
190 return *m_paddingBounds;
191 }
192
193 const FloatPolygon& PolygonShape::shapeMarginBounds() const 150 const FloatPolygon& PolygonShape::shapeMarginBounds() const
194 { 151 {
195 ASSERT(shapeMargin() >= 0); 152 ASSERT(shapeMargin() >= 0);
196 if (!shapeMargin() || m_polygon.isEmpty()) 153 if (!shapeMargin() || m_polygon.isEmpty())
197 return m_polygon; 154 return m_polygon;
198 155
199 if (!m_marginBounds) 156 if (!m_marginBounds)
200 m_marginBounds = computeShapeMarginBounds(m_polygon, shapeMargin(), m_po lygon.fillRule()); 157 m_marginBounds = computeShapeMarginBounds(m_polygon, shapeMargin(), m_po lygon.fillRule());
201 158
202 return *m_marginBounds; 159 return *m_marginBounds;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 340
384 FloatShapeIntervals excludedIntervals; 341 FloatShapeIntervals excludedIntervals;
385 FloatShapeInterval::uniteShapeIntervals(mergedIntervals, edgeIntervals, excl udedIntervals); 342 FloatShapeInterval::uniteShapeIntervals(mergedIntervals, edgeIntervals, excl udedIntervals);
386 343
387 for (unsigned i = 0; i < excludedIntervals.size(); ++i) { 344 for (unsigned i = 0; i < excludedIntervals.size(); ++i) {
388 const FloatShapeInterval& interval = excludedIntervals[i]; 345 const FloatShapeInterval& interval = excludedIntervals[i];
389 result.append(LineSegment(interval.x1(), interval.x2())); 346 result.append(LineSegment(interval.x1(), interval.x2()));
390 } 347 }
391 } 348 }
392 349
393 void PolygonShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logica lHeight, SegmentList& result) const
394 {
395 const FloatPolygon& polygon = shapePaddingBounds();
396 if (polygon.isEmpty())
397 return;
398
399 float y1 = logicalTop.toFloat();
400 float y2 = (logicalTop + logicalHeight).toFloat();
401
402 FloatShapeIntervals y1XIntervals, y2XIntervals;
403 computeXIntersections(polygon, y1, true, y1XIntervals);
404 computeXIntersections(polygon, y2, false, y2XIntervals);
405
406 FloatShapeIntervals commonIntervals;
407 FloatShapeInterval::intersectShapeIntervals(y1XIntervals, y2XIntervals, comm onIntervals);
408
409 FloatShapeIntervals edgeIntervals;
410 computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals);
411
412 FloatShapeIntervals includedIntervals;
413 FloatShapeInterval::subtractShapeIntervals(commonIntervals, edgeIntervals, i ncludedIntervals);
414
415 for (unsigned i = 0; i < includedIntervals.size(); ++i) {
416 const FloatShapeInterval& interval = includedIntervals[i];
417 result.append(LineSegment(interval.x1(), interval.x2()));
418 }
419 }
420
421 static inline bool firstFitRectInPolygon(const FloatPolygon& polygon, const Floa tRect& rect, unsigned offsetEdgeIndex1, unsigned offsetEdgeIndex2)
422 {
423 Vector<const FloatPolygonEdge*> edges;
424 if (!polygon.overlappingEdges(rect.y(), rect.maxY(), edges))
425 return true;
426
427 for (unsigned i = 0; i < edges.size(); ++i) {
428 const FloatPolygonEdge* edge = edges[i];
429 if (edge->edgeIndex() != offsetEdgeIndex1 && edge->edgeIndex() != offset EdgeIndex2 && edge->overlapsRect(rect))
430 return false;
431 }
432
433 return true;
434 }
435
436 static inline bool aboveOrToTheLeft(const FloatRect& r1, const FloatRect& r2)
437 {
438 if (r1.y() < r2.y())
439 return true;
440 if (r1.y() == r2.y())
441 return r1.x() < r2.x();
442 return false;
443 }
444
445 bool PolygonShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalInterval Top, const FloatSize& minLogicalIntervalSize, LayoutUnit& result) const
446 {
447 float minIntervalTop = minLogicalIntervalTop.toFloat();
448 float minIntervalHeight = minLogicalIntervalSize.height();
449 float minIntervalWidth = minLogicalIntervalSize.width();
450
451 const FloatPolygon& polygon = shapePaddingBounds();
452 const FloatRect boundingBox = polygon.boundingBox();
453 if (minIntervalWidth > boundingBox.width())
454 return false;
455
456 float minY = std::max(boundingBox.y(), minIntervalTop);
457 float maxY = minY + minIntervalHeight;
458
459 if (maxY > boundingBox.maxY())
460 return false;
461
462 Vector<const FloatPolygonEdge*> edges;
463 polygon.overlappingEdges(minIntervalTop, boundingBox.maxY(), edges);
464
465 float dx = minIntervalWidth / 2;
466 float dy = minIntervalHeight / 2;
467 Vector<OffsetPolygonEdge> offsetEdges;
468
469 for (unsigned i = 0; i < edges.size(); ++i) {
470 const FloatPolygonEdge& edge = *(edges[i]);
471 const FloatPoint& vertex0 = edge.previousEdge().vertex1();
472 const FloatPoint& vertex1 = edge.vertex1();
473 const FloatPoint& vertex2 = edge.vertex2();
474 Vector<OffsetPolygonEdge> offsetEdgeBuffer;
475
476 if (vertex2.y() > vertex1.y() ? vertex2.x() >= vertex1.x() : vertex1.x() >= vertex2.x()) {
477 offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(dx, -dy))) ;
478 offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(-dx, dy))) ;
479 } else {
480 offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(dx, dy)));
481 offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(-dx, -dy)) );
482 }
483
484 if (isReflexVertex(vertex0, vertex1, vertex2)) {
485 if (vertex2.x() <= vertex1.x() && vertex0.x() <= vertex1.x())
486 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(dx, -dy), FloatSize(dx, dy)));
487 else if (vertex2.x() >= vertex1.x() && vertex0.x() >= vertex1.x())
488 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx , -dy), FloatSize(-dx, dy)));
489 if (vertex2.y() <= vertex1.y() && vertex0.y() <= vertex1.y())
490 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx , dy), FloatSize(dx, dy)));
491 else if (vertex2.y() >= vertex1.y() && vertex0.y() >= vertex1.y())
492 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx , -dy), FloatSize(dx, -dy)));
493 }
494
495 for (unsigned j = 0; j < offsetEdgeBuffer.size(); ++j) {
496 if (offsetEdgeBuffer[j].maxY() >= minY)
497 offsetEdges.append(offsetEdgeBuffer[j]);
498 }
499 }
500
501 offsetEdges.append(OffsetPolygonEdge(polygon, minIntervalTop, FloatSize(0, d y)));
502
503 FloatPoint offsetEdgesIntersection;
504 FloatRect firstFitRect;
505 bool firstFitFound = false;
506
507 for (unsigned i = 0; i < offsetEdges.size() - 1; ++i) {
508 for (unsigned j = i + 1; j < offsetEdges.size(); ++j) {
509 if (offsetEdges[i].intersection(offsetEdges[j], offsetEdgesIntersect ion)) {
510 FloatPoint potentialFirstFitLocation(offsetEdgesIntersection.x() - dx, offsetEdgesIntersection.y() - dy);
511 FloatRect potentialFirstFitRect(potentialFirstFitLocation, minLo gicalIntervalSize);
512 if ((offsetEdges[i].basis() == OffsetPolygonEdge::LineTop
513 || offsetEdges[j].basis() == OffsetPolygonEdge::LineTop
514 || potentialFirstFitLocation.y() >= minIntervalTop)
515 && (!firstFitFound || aboveOrToTheLeft(potentialFirstFitRect , firstFitRect))
516 && polygon.contains(offsetEdgesIntersection)
517 && firstFitRectInPolygon(polygon, potentialFirstFitRect, off setEdges[i].edgeIndex(), offsetEdges[j].edgeIndex())) {
518 firstFitFound = true;
519 firstFitRect = potentialFirstFitRect;
520 }
521 }
522 }
523 }
524
525 if (firstFitFound)
526 result = LayoutUnit::fromFloatCeil(firstFitRect.y());
527 return firstFitFound;
528 }
529
530 } // namespace WebCore 350 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/shapes/PolygonShape.h ('k') | Source/core/rendering/shapes/RasterShape.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698