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 |