15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2006, 2009 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. 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) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef RoundedRect_h
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define RoundedRect_h
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatQuad.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)// This class is used to represent rectangles with rounded corners. It is only
36f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)// used for painting. It uses integer units because using layout units leads to
37f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)// blurry rounded corners.
381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT RoundedRect {
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    class PLATFORM_EXPORT Radii {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        Radii() { }
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Radii(const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            : m_topLeft(topLeft)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , m_topRight(topRight)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , m_bottomLeft(bottomLeft)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , m_bottomRight(bottomRight)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void setTopLeft(const IntSize& size) { m_topLeft = size; }
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void setTopRight(const IntSize& size) { m_topRight = size; }
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void setBottomLeft(const IntSize& size) { m_bottomLeft = size; }
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void setBottomRight(const IntSize& size) { m_bottomRight = size; }
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const IntSize& topLeft() const { return m_topLeft; }
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const IntSize& topRight() const { return m_topRight; }
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const IntSize& bottomLeft() const { return m_bottomLeft; }
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const IntSize& bottomRight() const { return m_bottomRight; }
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isZero() const;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void scale(float factor);
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void expand(int topWidth, int bottomWidth, int leftWidth, int rightWidth);
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void expand(int size) { expand(size, size, size, size); }
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void shrink(int topWidth, int bottomWidth, int leftWidth, int rightWidth) { expand(-topWidth, -bottomWidth, -leftWidth, -rightWidth); }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void shrink(int size) { shrink(size, size, size, size); }
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IntSize m_topLeft;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IntSize m_topRight;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IntSize m_bottomLeft;
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        IntSize m_bottomRight;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    explicit RoundedRect(const IntRect&, const Radii& = Radii());
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RoundedRect(int x, int y, int width, int height);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const IntRect& rect() const { return m_rect; }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Radii& radii() const { return m_radii; }
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isRounded() const { return !m_radii.isZero(); }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isEmpty() const { return m_rect.isEmpty(); }
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
873c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // Returns a quickly computed rect enclosed by the rounded rect.
883c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    IntRect radiusCenterRect() const;
893c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setRect(const IntRect& rect) { m_rect = rect; }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setRadii(const Radii& radii) { m_radii = radii; }
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void move(const IntSize& size) { m_rect.move(size); }
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void inflate(int size) { m_rect.inflate(size);  }
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void inflateWithRadii(int size);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void expandRadii(int size) { m_radii.expand(size); }
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void shrinkRadii(int size) { m_radii.shrink(size); }
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isRenderable() const;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void adjustRadii();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Tests whether the quad intersects any part of this rounded rectangle.
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // This only works for convex quads.
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool intersectsQuad(const FloatQuad&) const;
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntRect m_rect;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Radii m_radii;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(const RoundedRect::Radii& a, const RoundedRect::Radii& b)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return a.topLeft() == b.topLeft() && a.topRight() == b.topRight() && a.bottomLeft() == b.bottomLeft() && a.bottomRight() == b.bottomRight();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)inline bool operator!=(const RoundedRect::Radii& a, const RoundedRect::Radii& b)
12093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
12193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return !(a == b);
12293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
12393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(const RoundedRect& a, const RoundedRect& b)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return a.rect() == b.rect() && a.radii() == b.radii();
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // RoundedRect_h
133