15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2006, 2007 Apple Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Nokia.  All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatRect.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/FloatConversion.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/LayoutRect.h"
33521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "third_party/skia/include/core/SkRect.h"
34521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/MathExtras.h"
35521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
36521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <algorithm>
37521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <math.h>
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect::FloatRect(const IntRect& r) : m_location(r.location()), m_size(r.size())
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect::FloatRect(const LayoutRect& r) : m_location(r.location()), m_size(r.size())
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
49521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)FloatRect::FloatRect(const SkRect& r) : m_location(r.fLeft, r.fTop), m_size(r.width(), r.height())
50521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
51521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
52521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect FloatRect::narrowPrecision(double x, double y, double width, double height)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return FloatRect(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), narrowPrecisionToFloat(width), narrowPrecisionToFloat(height));
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FloatRect::isExpressibleAsIntRect() const
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isWithinIntRange(x()) && isWithinIntRange(y())
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && isWithinIntRange(width()) && isWithinIntRange(height())
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && isWithinIntRange(maxX()) && isWithinIntRange(maxY());
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FloatRect::intersects(const FloatRect& other) const
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Checking emptiness handles negative widths as well as zero.
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !isEmpty() && !other.isEmpty()
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && x() < other.maxX() && other.x() < maxX()
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && y() < other.maxY() && other.y() < maxY();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FloatRect::contains(const FloatRect& other) const
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return x() <= other.x() && maxX() >= other.maxX()
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && y() <= other.y() && maxY() >= other.maxY();
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FloatRect::contains(const FloatPoint& point, ContainsMode containsMode) const
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (containsMode == InsideOrOnStroke)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return contains(point.x(), point.y());
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return x() < point.x() && maxX() > point.x() && y() < point.y() && maxY() > point.y();
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::intersect(const FloatRect& other)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float left = std::max(x(), other.x());
891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float top = std::max(y(), other.y());
901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float right = std::min(maxX(), other.maxX());
911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float bottom = std::min(maxY(), other.maxY());
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Return a clean empty rectangle for non-intersecting cases.
941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (left >= right || top >= bottom) {
951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        left = 0;
961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        top = 0;
971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        right = 0;
981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        bottom = 0;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    setLocationAndSizeFromEdges(left, top, right, bottom);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::unite(const FloatRect& other)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle empty special cases first.
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (other.isEmpty())
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isEmpty()) {
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *this = other;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uniteEvenIfEmpty(other);
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::uniteEvenIfEmpty(const FloatRect& other)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float minX = std::min(x(), other.x());
1201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float minY = std::min(y(), other.y());
1211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float maxX = std::max(this->maxX(), other.maxX());
1221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float maxY = std::max(this->maxY(), other.maxY());
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocationAndSizeFromEdges(minX, minY, maxX, maxY);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::uniteIfNonZero(const FloatRect& other)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle empty special cases first.
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (other.isZero())
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isZero()) {
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *this = other;
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uniteEvenIfEmpty(other);
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::extend(const FloatPoint& p)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float minX = std::min(x(), p.x());
1431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float minY = std::min(y(), p.y());
1441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float maxX = std::max(this->maxX(), p.x());
1451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float maxY = std::max(this->maxY(), p.y());
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocationAndSizeFromEdges(minX, minY, maxX, maxY);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::scale(float sx, float sy)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_location.setX(x() * sx);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_location.setY(y() * sy);
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_size.setWidth(width() * sx);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_size.setHeight(height() * sy);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect unionRect(const Vector<FloatRect>& rects)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    FloatRect result;
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t count = rects.size();
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < count; ++i)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.unite(rects[i]);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1)
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float left = std::min(p0.x(), p1.x());
1721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float top = std::min(p0.y(), p1.y());
1731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float right = std::max(p0.x(), p1.x());
1741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    float bottom = std::max(p0.y(), p1.y());
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocationAndSizeFromEdges(left, top, right, bottom);
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Helpers for 3- and 4-way max and min.
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename T>
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)T min3(const T& v1, const T& v2, const T& v3)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return std::min(std::min(v1, v2), v3);
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename T>
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)T max3(const T& v1, const T& v2, const T& v3)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return std::max(std::max(v1, v2), v3);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename T>
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)T min4(const T& v1, const T& v2, const T& v3, const T& v4)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return std::min(std::min(v1, v2), std::min(v3, v4));
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename T>
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)T max4(const T& v1, const T& v2, const T& v3, const T& v4)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return std::max(std::max(v1, v2), std::max(v3, v4));
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // anonymous namespace
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float left = min3(p0.x(), p1.x(), p2.x());
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float top = min3(p0.y(), p1.y(), p2.y());
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float right = max3(p0.x(), p1.x(), p2.x());
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float bottom = max3(p0.y(), p1.y(), p2.y());
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocationAndSizeFromEdges(left, top, right, bottom);
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float left = min4(p0.x(), p1.x(), p2.x(), p3.x());
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float top = min4(p0.y(), p1.y(), p2.y(), p3.y());
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float right = max4(p0.x(), p1.x(), p2.x(), p3.x());
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float bottom = max4(p0.y(), p1.y(), p2.y(), p3.y());
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setLocationAndSizeFromEdges(left, top, right, bottom);
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
228521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)FloatRect::operator SkRect() const
229521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
230521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    SkRect rect = { x(), y(), maxX(), maxY() };
231521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return rect;
232521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
233521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect enclosingIntRect(const FloatRect& rect)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntPoint location = flooredIntPoint(rect.minXMinYCorner());
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntPoint maxPoint = ceiledIntPoint(rect.maxXMaxYCorner());
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(location, maxPoint - location);
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect enclosedIntRect(const FloatRect& rect)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntPoint location = ceiledIntPoint(rect.minXMinYCorner());
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntPoint maxPoint = flooredIntPoint(rect.maxXMaxYCorner());
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntSize size = maxPoint - location;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size.clampNegativeToZero();
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(location, size);
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect roundedIntRect(const FloatRect& rect)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(roundedIntPoint(rect.location()), roundedIntSize(rect.size()));
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FloatRect mapRect(const FloatRect& r, const FloatRect& srcRect, const FloatRect& destRect)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!srcRect.width() || !srcRect.height())
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FloatRect();
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float widthScale = destRect.width() / srcRect.width();
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    float heightScale = destRect.height() / srcRect.height();
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return FloatRect(destRect.x() + (r.x() - srcRect.x()) * widthScale,
2651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        destRect.y() + (r.y() - srcRect.y()) * heightScale,
2661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        r.width() * widthScale, r.height() * heightScale);
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
270