| OLD | NEW |
| 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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 if (x1 > x2) | 340 if (x1 > x2) |
| 341 std::swap(x1, x2); | 341 std::swap(x1, x2); |
| 342 | 342 |
| 343 if (x2 > x1) | 343 if (x2 > x1) |
| 344 result.append(ExclusionInterval(x1, x2)); | 344 result.append(ExclusionInterval(x1, x2)); |
| 345 } | 345 } |
| 346 | 346 |
| 347 sortExclusionIntervals(result); | 347 sortExclusionIntervals(result); |
| 348 } | 348 } |
| 349 | 349 |
| 350 void ExclusionPolygon::getExcludedIntervals(float logicalTop, float logicalHeigh
t, SegmentList& result) const | 350 void ExclusionPolygon::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit lo
gicalHeight, SegmentList& result) const |
| 351 { | 351 { |
| 352 const FloatPolygon& polygon = shapeMarginBounds(); | 352 const FloatPolygon& polygon = shapeMarginBounds(); |
| 353 if (polygon.isEmpty()) | 353 if (polygon.isEmpty()) |
| 354 return; | 354 return; |
| 355 | 355 |
| 356 float y1 = logicalTop; | 356 float y1 = logicalTop; |
| 357 float y2 = y1 + logicalHeight; | 357 float y2 = logicalTop + logicalHeight; |
| 358 | 358 |
| 359 Vector<ExclusionInterval> y1XIntervals, y2XIntervals; | 359 Vector<ExclusionInterval> y1XIntervals, y2XIntervals; |
| 360 computeXIntersections(polygon, y1, true, y1XIntervals); | 360 computeXIntersections(polygon, y1, true, y1XIntervals); |
| 361 computeXIntersections(polygon, y2, false, y2XIntervals); | 361 computeXIntersections(polygon, y2, false, y2XIntervals); |
| 362 | 362 |
| 363 Vector<ExclusionInterval> mergedIntervals; | 363 Vector<ExclusionInterval> mergedIntervals; |
| 364 mergeExclusionIntervals(y1XIntervals, y2XIntervals, mergedIntervals); | 364 mergeExclusionIntervals(y1XIntervals, y2XIntervals, mergedIntervals); |
| 365 | 365 |
| 366 Vector<ExclusionInterval> edgeIntervals; | 366 Vector<ExclusionInterval> edgeIntervals; |
| 367 computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals); | 367 computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals); |
| 368 | 368 |
| 369 Vector<ExclusionInterval> excludedIntervals; | 369 Vector<ExclusionInterval> excludedIntervals; |
| 370 mergeExclusionIntervals(mergedIntervals, edgeIntervals, excludedIntervals); | 370 mergeExclusionIntervals(mergedIntervals, edgeIntervals, excludedIntervals); |
| 371 | 371 |
| 372 for (unsigned i = 0; i < excludedIntervals.size(); ++i) { | 372 for (unsigned i = 0; i < excludedIntervals.size(); ++i) { |
| 373 ExclusionInterval interval = excludedIntervals[i]; | 373 ExclusionInterval interval = excludedIntervals[i]; |
| 374 result.append(LineSegment(interval.x1, interval.x2)); | 374 result.append(LineSegment(interval.x1, interval.x2)); |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 void ExclusionPolygon::getIncludedIntervals(float logicalTop, float logicalHeigh
t, SegmentList& result) const | 378 void ExclusionPolygon::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit lo
gicalHeight, SegmentList& result) const |
| 379 { | 379 { |
| 380 const FloatPolygon& polygon = shapePaddingBounds(); | 380 const FloatPolygon& polygon = shapePaddingBounds(); |
| 381 if (polygon.isEmpty()) | 381 if (polygon.isEmpty()) |
| 382 return; | 382 return; |
| 383 | 383 |
| 384 float y1 = logicalTop; | 384 float y1 = logicalTop; |
| 385 float y2 = y1 + logicalHeight; | 385 float y2 = logicalTop + logicalHeight; |
| 386 | 386 |
| 387 Vector<ExclusionInterval> y1XIntervals, y2XIntervals; | 387 Vector<ExclusionInterval> y1XIntervals, y2XIntervals; |
| 388 computeXIntersections(polygon, y1, true, y1XIntervals); | 388 computeXIntersections(polygon, y1, true, y1XIntervals); |
| 389 computeXIntersections(polygon, y2, false, y2XIntervals); | 389 computeXIntersections(polygon, y2, false, y2XIntervals); |
| 390 | 390 |
| 391 Vector<ExclusionInterval> commonIntervals; | 391 Vector<ExclusionInterval> commonIntervals; |
| 392 intersectExclusionIntervals(y1XIntervals, y2XIntervals, commonIntervals); | 392 intersectExclusionIntervals(y1XIntervals, y2XIntervals, commonIntervals); |
| 393 | 393 |
| 394 Vector<ExclusionInterval> edgeIntervals; | 394 Vector<ExclusionInterval> edgeIntervals; |
| 395 computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals); | 395 computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 420 | 420 |
| 421 static inline bool aboveOrToTheLeft(const FloatRect& r1, const FloatRect& r2) | 421 static inline bool aboveOrToTheLeft(const FloatRect& r1, const FloatRect& r2) |
| 422 { | 422 { |
| 423 if (r1.y() < r2.y()) | 423 if (r1.y() < r2.y()) |
| 424 return true; | 424 return true; |
| 425 if (r1.y() == r2.y()) | 425 if (r1.y() == r2.y()) |
| 426 return r1.x() < r2.x(); | 426 return r1.x() < r2.x(); |
| 427 return false; | 427 return false; |
| 428 } | 428 } |
| 429 | 429 |
| 430 bool ExclusionPolygon::firstIncludedIntervalLogicalTop(float minLogicalIntervalT
op, const FloatSize& minLogicalIntervalSize, float& result) const | 430 bool ExclusionPolygon::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalInte
rvalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const |
| 431 { | 431 { |
| 432 float minIntervalTop = minLogicalIntervalTop; |
| 433 float minIntervalHeight = minLogicalIntervalSize.height(); |
| 434 float minIntervalWidth = minLogicalIntervalSize.width(); |
| 435 |
| 432 const FloatPolygon& polygon = shapePaddingBounds(); | 436 const FloatPolygon& polygon = shapePaddingBounds(); |
| 433 const FloatRect boundingBox = polygon.boundingBox(); | 437 const FloatRect boundingBox = polygon.boundingBox(); |
| 434 if (minLogicalIntervalSize.width() > boundingBox.width()) | 438 if (minIntervalWidth > boundingBox.width()) |
| 435 return false; | 439 return false; |
| 436 | 440 |
| 437 float minY = std::max(boundingBox.y(), minLogicalIntervalTop); | 441 float minY = std::max(boundingBox.y(), minIntervalTop); |
| 438 float maxY = minY + minLogicalIntervalSize.height(); | 442 float maxY = minY + minIntervalHeight; |
| 439 | 443 |
| 440 if (maxY > boundingBox.maxY()) | 444 if (maxY > boundingBox.maxY()) |
| 441 return false; | 445 return false; |
| 442 | 446 |
| 443 Vector<const FloatPolygonEdge*> edges; | 447 Vector<const FloatPolygonEdge*> edges; |
| 444 polygon.overlappingEdges(minLogicalIntervalTop, boundingBox.maxY(), edges); | 448 polygon.overlappingEdges(minIntervalTop, boundingBox.maxY(), edges); |
| 445 | 449 |
| 446 float dx = minLogicalIntervalSize.width() / 2; | 450 float dx = minIntervalWidth / 2; |
| 447 float dy = minLogicalIntervalSize.height() / 2; | 451 float dy = minIntervalHeight / 2; |
| 448 Vector<OffsetPolygonEdge> offsetEdges; | 452 Vector<OffsetPolygonEdge> offsetEdges; |
| 449 | 453 |
| 450 for (unsigned i = 0; i < edges.size(); ++i) { | 454 for (unsigned i = 0; i < edges.size(); ++i) { |
| 451 const FloatPolygonEdge& edge = *(edges[i]); | 455 const FloatPolygonEdge& edge = *(edges[i]); |
| 452 const FloatPoint& vertex0 = edge.previousEdge().vertex1(); | 456 const FloatPoint& vertex0 = edge.previousEdge().vertex1(); |
| 453 const FloatPoint& vertex1 = edge.vertex1(); | 457 const FloatPoint& vertex1 = edge.vertex1(); |
| 454 const FloatPoint& vertex2 = edge.vertex2(); | 458 const FloatPoint& vertex2 = edge.vertex2(); |
| 455 Vector<OffsetPolygonEdge> offsetEdgeBuffer; | 459 Vector<OffsetPolygonEdge> offsetEdgeBuffer; |
| 456 | 460 |
| 457 if (vertex2.y() > vertex1.y() ? vertex2.x() >= vertex1.x() : vertex1.x()
>= vertex2.x()) { | 461 if (vertex2.y() > vertex1.y() ? vertex2.x() >= vertex1.x() : vertex1.x()
>= vertex2.x()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 471 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx
, dy), FloatSize(dx, dy))); | 475 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx
, dy), FloatSize(dx, dy))); |
| 472 else if (vertex2.y() >= vertex1.y() && vertex0.y() >= vertex1.y()) | 476 else if (vertex2.y() >= vertex1.y() && vertex0.y() >= vertex1.y()) |
| 473 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx
, -dy), FloatSize(dx, -dy))); | 477 offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx
, -dy), FloatSize(dx, -dy))); |
| 474 } | 478 } |
| 475 | 479 |
| 476 for (unsigned j = 0; j < offsetEdgeBuffer.size(); ++j) | 480 for (unsigned j = 0; j < offsetEdgeBuffer.size(); ++j) |
| 477 if (offsetEdgeBuffer[j].maxY() >= minY) | 481 if (offsetEdgeBuffer[j].maxY() >= minY) |
| 478 offsetEdges.append(offsetEdgeBuffer[j]); | 482 offsetEdges.append(offsetEdgeBuffer[j]); |
| 479 } | 483 } |
| 480 | 484 |
| 481 offsetEdges.append(OffsetPolygonEdge(polygon, minLogicalIntervalTop, FloatSi
ze(0, dy))); | 485 offsetEdges.append(OffsetPolygonEdge(polygon, minIntervalTop, FloatSize(0, d
y))); |
| 482 | 486 |
| 483 FloatPoint offsetEdgesIntersection; | 487 FloatPoint offsetEdgesIntersection; |
| 484 FloatRect firstFitRect; | 488 FloatRect firstFitRect; |
| 485 bool firstFitFound = false; | 489 bool firstFitFound = false; |
| 486 | 490 |
| 487 for (unsigned i = 0; i < offsetEdges.size() - 1; ++i) { | 491 for (unsigned i = 0; i < offsetEdges.size() - 1; ++i) { |
| 488 for (unsigned j = i + 1; j < offsetEdges.size(); ++j) { | 492 for (unsigned j = i + 1; j < offsetEdges.size(); ++j) { |
| 489 if (offsetEdges[i].intersection(offsetEdges[j], offsetEdgesIntersect
ion)) { | 493 if (offsetEdges[i].intersection(offsetEdges[j], offsetEdgesIntersect
ion)) { |
| 490 FloatPoint potentialFirstFitLocation(offsetEdgesIntersection.x()
- dx, offsetEdgesIntersection.y() - dy); | 494 FloatPoint potentialFirstFitLocation(offsetEdgesIntersection.x()
- dx, offsetEdgesIntersection.y() - dy); |
| 491 FloatRect potentialFirstFitRect(potentialFirstFitLocation, minLo
gicalIntervalSize); | 495 FloatRect potentialFirstFitRect(potentialFirstFitLocation, minLo
gicalIntervalSize); |
| 492 if ((offsetEdges[i].basis() == OffsetPolygonEdge::LineTop | 496 if ((offsetEdges[i].basis() == OffsetPolygonEdge::LineTop |
| 493 || offsetEdges[j].basis() == OffsetPolygonEdge::LineTop | 497 || offsetEdges[j].basis() == OffsetPolygonEdge::LineTop |
| 494 || potentialFirstFitLocation.y() >= minLogicalIntervalTop) | 498 || potentialFirstFitLocation.y() >= minIntervalTop) |
| 495 && (!firstFitFound || aboveOrToTheLeft(potentialFirstFitRect
, firstFitRect)) | 499 && (!firstFitFound || aboveOrToTheLeft(potentialFirstFitRect
, firstFitRect)) |
| 496 && polygon.contains(offsetEdgesIntersection) | 500 && polygon.contains(offsetEdgesIntersection) |
| 497 && firstFitRectInPolygon(polygon, potentialFirstFitRect, off
setEdges[i].edgeIndex(), offsetEdges[j].edgeIndex())) { | 501 && firstFitRectInPolygon(polygon, potentialFirstFitRect, off
setEdges[i].edgeIndex(), offsetEdges[j].edgeIndex())) { |
| 498 firstFitFound = true; | 502 firstFitFound = true; |
| 499 firstFitRect = potentialFirstFitRect; | 503 firstFitRect = potentialFirstFitRect; |
| 500 } | 504 } |
| 501 } | 505 } |
| 502 } | 506 } |
| 503 } | 507 } |
| 504 | 508 |
| 505 if (firstFitFound) | 509 if (firstFitFound) |
| 506 result = firstFitRect.y(); | 510 result = LayoutUnit::fromFloatCeil(firstFitRect.y()); |
| 507 return firstFitFound; | 511 return firstFitFound; |
| 508 } | 512 } |
| 509 | 513 |
| 510 } // namespace WebCore | 514 } // namespace WebCore |
| OLD | NEW |