OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 break; | 1987 break; |
1988 default: | 1988 default: |
1989 break; | 1989 break; |
1990 } | 1990 } |
1991 | 1991 |
1992 graphicsContext->setStrokeStyle(NoStroke); | 1992 graphicsContext->setStrokeStyle(NoStroke); |
1993 graphicsContext->setFillColor(color); | 1993 graphicsContext->setFillColor(color); |
1994 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); | 1994 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); |
1995 } | 1995 } |
1996 | 1996 |
1997 static void findInnerVertex(const FloatPoint& outerCorner, const FloatPoint& inn
erCorner, const FloatPoint& centerPoint, FloatPoint& result) | |
1998 { | |
1999 // If the line between outer and inner corner is towards the horizontal, int
ersect with a vertical line through the center, | |
2000 // otherwise with a horizontal line through the center. The points that form
this line are arbitrary (we use 0, 100). | |
2001 // Note that if findIntersection fails, it will leave result untouched. | |
2002 float diffInnerOuterX = fabs(innerCorner.x() - outerCorner.x()); | |
2003 float diffInnerOuterY = fabs(innerCorner.y() - outerCorner.y()); | |
2004 float diffCenterOuterX = fabs(centerPoint.x() - outerCorner.x()); | |
2005 float diffCenterOuterY = fabs(centerPoint.y() - outerCorner.y()); | |
2006 if (diffInnerOuterY * diffCenterOuterX < diffCenterOuterY * diffInnerOuterX) | |
2007 findIntersection(outerCorner, innerCorner, FloatPoint(centerPoint.x(), 0
), FloatPoint(centerPoint.x(), 100), result); | |
2008 else | |
2009 findIntersection(outerCorner, innerCorner, FloatPoint(0, centerPoint.y()
), FloatPoint(100, centerPoint.y()), result); | |
2010 } | |
2011 | |
2012 void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex
t, const RoundedRect& outerBorder, const RoundedRect& innerBorder, | 1997 void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex
t, const RoundedRect& outerBorder, const RoundedRect& innerBorder, |
2013 BoxSide side, bool firstEdgeMat
ches, bool secondEdgeMatches) | 1998 BoxSide side, bool firstEdgeMat
ches, bool secondEdgeMatches) |
2014 { | 1999 { |
2015 FloatPoint quad[4]; | 2000 FloatPoint quad[4]; |
2016 | 2001 |
2017 const LayoutRect& outerRect = outerBorder.rect(); | 2002 const LayoutRect& outerRect = outerBorder.rect(); |
2018 const LayoutRect& innerRect = innerBorder.rect(); | 2003 const LayoutRect& innerRect = innerBorder.rect(); |
2019 | 2004 |
2020 FloatPoint centerPoint(innerRect.location().x() + static_cast<float>(innerRe
ct.width()) / 2, innerRect.location().y() + static_cast<float>(innerRect.height(
)) / 2); | 2005 FloatPoint centerPoint(innerRect.location().x() + static_cast<float>(innerRe
ct.width()) / 2, innerRect.location().y() + static_cast<float>(innerRect.height(
)) / 2); |
2021 | 2006 |
(...skipping 11 matching lines...) Expand all Loading... |
2033 // 3 / \ 3 | 2018 // 3 / \ 3 |
2034 // 0----------------3 | 2019 // 0----------------3 |
2035 // | 2020 // |
2036 switch (side) { | 2021 switch (side) { |
2037 case BSTop: | 2022 case BSTop: |
2038 quad[0] = outerRect.minXMinYCorner(); | 2023 quad[0] = outerRect.minXMinYCorner(); |
2039 quad[1] = innerRect.minXMinYCorner(); | 2024 quad[1] = innerRect.minXMinYCorner(); |
2040 quad[2] = innerRect.maxXMinYCorner(); | 2025 quad[2] = innerRect.maxXMinYCorner(); |
2041 quad[3] = outerRect.maxXMinYCorner(); | 2026 quad[3] = outerRect.maxXMinYCorner(); |
2042 | 2027 |
2043 if (!innerBorder.radii().topLeft().isZero()) | 2028 if (!innerBorder.radii().topLeft().isZero()) { |
2044 findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner
(), centerPoint, quad[1]); | 2029 findIntersection(quad[0], quad[1], |
| 2030 FloatPoint( |
| 2031 quad[1].x() + innerBorder.radii().topLeft().width(), |
| 2032 quad[1].y()), |
| 2033 FloatPoint( |
| 2034 quad[1].x(), |
| 2035 quad[1].y() + innerBorder.radii().topLeft().height()), |
| 2036 quad[1]); |
| 2037 } |
2045 | 2038 |
2046 if (!innerBorder.radii().topRight().isZero()) | 2039 if (!innerBorder.radii().topRight().isZero()) { |
2047 findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner
(), centerPoint, quad[2]); | 2040 findIntersection(quad[3], quad[2], |
| 2041 FloatPoint( |
| 2042 quad[2].x() - innerBorder.radii().topRight().width(), |
| 2043 quad[2].y()), |
| 2044 FloatPoint( |
| 2045 quad[2].x(), |
| 2046 quad[2].y() + innerBorder.radii().topRight().height()), |
| 2047 quad[2]); |
| 2048 } |
2048 break; | 2049 break; |
2049 | 2050 |
2050 case BSLeft: | 2051 case BSLeft: |
2051 quad[0] = outerRect.minXMinYCorner(); | 2052 quad[0] = outerRect.minXMinYCorner(); |
2052 quad[1] = innerRect.minXMinYCorner(); | 2053 quad[1] = innerRect.minXMinYCorner(); |
2053 quad[2] = innerRect.minXMaxYCorner(); | 2054 quad[2] = innerRect.minXMaxYCorner(); |
2054 quad[3] = outerRect.minXMaxYCorner(); | 2055 quad[3] = outerRect.minXMaxYCorner(); |
2055 | 2056 |
2056 if (!innerBorder.radii().topLeft().isZero()) | 2057 if (!innerBorder.radii().topLeft().isZero()) { |
2057 findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner
(), centerPoint, quad[1]); | 2058 findIntersection(quad[0], quad[1], |
| 2059 FloatPoint( |
| 2060 quad[1].x() + innerBorder.radii().topLeft().width(), |
| 2061 quad[1].y()), |
| 2062 FloatPoint( |
| 2063 quad[1].x(), |
| 2064 quad[1].y() + innerBorder.radii().topLeft().height()), |
| 2065 quad[1]); |
| 2066 } |
2058 | 2067 |
2059 if (!innerBorder.radii().bottomLeft().isZero()) | 2068 if (!innerBorder.radii().bottomLeft().isZero()) { |
2060 findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner
(), centerPoint, quad[2]); | 2069 findIntersection(quad[3], quad[2], |
| 2070 FloatPoint( |
| 2071 quad[2].x() + innerBorder.radii().bottomLeft().width(), |
| 2072 quad[2].y()), |
| 2073 FloatPoint( |
| 2074 quad[2].x(), |
| 2075 quad[2].y() - innerBorder.radii().bottomLeft().height()), |
| 2076 quad[2]); |
| 2077 } |
2061 break; | 2078 break; |
2062 | 2079 |
2063 case BSBottom: | 2080 case BSBottom: |
2064 quad[0] = outerRect.minXMaxYCorner(); | 2081 quad[0] = outerRect.minXMaxYCorner(); |
2065 quad[1] = innerRect.minXMaxYCorner(); | 2082 quad[1] = innerRect.minXMaxYCorner(); |
2066 quad[2] = innerRect.maxXMaxYCorner(); | 2083 quad[2] = innerRect.maxXMaxYCorner(); |
2067 quad[3] = outerRect.maxXMaxYCorner(); | 2084 quad[3] = outerRect.maxXMaxYCorner(); |
2068 | 2085 |
2069 if (!innerBorder.radii().bottomLeft().isZero()) | 2086 if (!innerBorder.radii().bottomLeft().isZero()) { |
2070 findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner
(), centerPoint, quad[1]); | 2087 findIntersection(quad[0], quad[1], |
| 2088 FloatPoint( |
| 2089 quad[1].x() + innerBorder.radii().bottomLeft().width(), |
| 2090 quad[1].y()), |
| 2091 FloatPoint( |
| 2092 quad[1].x(), |
| 2093 quad[1].y() - innerBorder.radii().bottomLeft().height()), |
| 2094 quad[1]); |
| 2095 } |
2071 | 2096 |
2072 if (!innerBorder.radii().bottomRight().isZero()) | 2097 if (!innerBorder.radii().bottomRight().isZero()) { |
2073 findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner
(), centerPoint, quad[2]); | 2098 findIntersection(quad[3], quad[2], |
| 2099 FloatPoint( |
| 2100 quad[2].x() - innerBorder.radii().bottomRight().width(), |
| 2101 quad[2].y()), |
| 2102 FloatPoint( |
| 2103 quad[2].x(), |
| 2104 quad[2].y() - innerBorder.radii().bottomRight().height()), |
| 2105 quad[2]); |
| 2106 } |
2074 break; | 2107 break; |
2075 | 2108 |
2076 case BSRight: | 2109 case BSRight: |
2077 quad[0] = outerRect.maxXMinYCorner(); | 2110 quad[0] = outerRect.maxXMinYCorner(); |
2078 quad[1] = innerRect.maxXMinYCorner(); | 2111 quad[1] = innerRect.maxXMinYCorner(); |
2079 quad[2] = innerRect.maxXMaxYCorner(); | 2112 quad[2] = innerRect.maxXMaxYCorner(); |
2080 quad[3] = outerRect.maxXMaxYCorner(); | 2113 quad[3] = outerRect.maxXMaxYCorner(); |
2081 | 2114 |
2082 if (!innerBorder.radii().topRight().isZero()) | 2115 if (!innerBorder.radii().topRight().isZero()) { |
2083 findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner
(), centerPoint, quad[1]); | 2116 findIntersection(quad[0], quad[1], |
| 2117 FloatPoint( |
| 2118 quad[1].x() - innerBorder.radii().topRight().width(), |
| 2119 quad[1].y()), |
| 2120 FloatPoint( |
| 2121 quad[1].x(), |
| 2122 quad[1].y() + innerBorder.radii().topRight().height()), |
| 2123 quad[1]); |
| 2124 } |
2084 | 2125 |
2085 if (!innerBorder.radii().bottomRight().isZero()) | 2126 if (!innerBorder.radii().bottomRight().isZero()) { |
2086 findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner
(), centerPoint, quad[2]); | 2127 findIntersection(quad[3], quad[2], |
| 2128 FloatPoint( |
| 2129 quad[2].x() - innerBorder.radii().bottomRight().width(), |
| 2130 quad[2].y()), |
| 2131 FloatPoint( |
| 2132 quad[2].x(), |
| 2133 quad[2].y() - innerBorder.radii().bottomRight().height()), |
| 2134 quad[2]); |
| 2135 } |
2087 break; | 2136 break; |
2088 } | 2137 } |
2089 | 2138 |
2090 // If the border matches both of its adjacent sides, don't anti-alias the cl
ip, and | 2139 // If the border matches both of its adjacent sides, don't anti-alias the cl
ip, and |
2091 // if neither side matches, anti-alias the clip. | 2140 // if neither side matches, anti-alias the clip. |
2092 if (firstEdgeMatches == secondEdgeMatches) { | 2141 if (firstEdgeMatches == secondEdgeMatches) { |
2093 graphicsContext->clipConvexPolygon(4, quad, !firstEdgeMatches); | 2142 graphicsContext->clipConvexPolygon(4, quad, !firstEdgeMatches); |
2094 return; | 2143 return; |
2095 } | 2144 } |
2096 | 2145 |
2097 // Square off the end which shouldn't be affected by antialiasing, and clip. | 2146 // If antialiasing settings for the first edge and second edge is different, |
| 2147 // they have to be addressed separately. We do this by breaking the quad int
o |
| 2148 // two parallelograms, made by moving quad[1] and quad[2]. |
| 2149 float ax = quad[1].x() - quad[0].x(); |
| 2150 float ay = quad[1].y() - quad[0].y(); |
| 2151 float bx = quad[2].x() - quad[1].x(); |
| 2152 float by = quad[2].y() - quad[1].y(); |
| 2153 float cx = quad[3].x() - quad[2].x(); |
| 2154 float cy = quad[3].y() - quad[2].y(); |
| 2155 |
| 2156 const static float kEpsilon = 1e-2f; |
| 2157 float r1, r2; |
| 2158 if (fabsf(bx) < kEpsilon && fabsf(by) < kEpsilon) { |
| 2159 // The quad was actually a triangle. |
| 2160 r1 = r2 = 1.0f; |
| 2161 } else { |
| 2162 // Extend parallelogram a bit to hide calculation error |
| 2163 const static float kExtendFill = 1e-2f; |
| 2164 |
| 2165 r1 = (-ax * by + ay * bx) / (cx * by - cy * bx) + kExtendFill; |
| 2166 r2 = (-cx * by + cy * bx) / (ax * by - ay * bx) + kExtendFill; |
| 2167 } |
| 2168 |
2098 FloatPoint firstQuad[4]; | 2169 FloatPoint firstQuad[4]; |
2099 firstQuad[0] = quad[0]; | 2170 firstQuad[0] = quad[0]; |
2100 firstQuad[1] = quad[1]; | 2171 firstQuad[1] = quad[1]; |
2101 firstQuad[2] = side == BSTop || side == BSBottom ? FloatPoint(quad[3].x(), q
uad[2].y()) | 2172 firstQuad[2] = FloatPoint(quad[3].x() + r2 * ax, quad[3].y() + r2 * ay); |
2102 : FloatPoint(quad[2].x(), quad[3].y()); | |
2103 firstQuad[3] = quad[3]; | 2173 firstQuad[3] = quad[3]; |
2104 graphicsContext->clipConvexPolygon(4, firstQuad, !firstEdgeMatches); | 2174 graphicsContext->clipConvexPolygon(4, firstQuad, !firstEdgeMatches); |
2105 | 2175 |
2106 FloatPoint secondQuad[4]; | 2176 FloatPoint secondQuad[4]; |
2107 secondQuad[0] = quad[0]; | 2177 secondQuad[0] = quad[0]; |
2108 secondQuad[1] = side == BSTop || side == BSBottom ? FloatPoint(quad[0].x(),
quad[1].y()) | 2178 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); |
2109 : FloatPoint(quad[1].x(), quad[0].y()); | |
2110 secondQuad[2] = quad[2]; | 2179 secondQuad[2] = quad[2]; |
2111 secondQuad[3] = quad[3]; | 2180 secondQuad[3] = quad[3]; |
2112 // Antialiasing affects the second side. | |
2113 graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches); | 2181 graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches); |
2114 } | 2182 } |
2115 | 2183 |
2116 static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, c
onst BorderEdge edges[], BoxSide side) | 2184 static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, c
onst BorderEdge edges[], BoxSide side) |
2117 { | 2185 { |
2118 IntRect sideRect = outerBorder.rect(); | 2186 IntRect sideRect = outerBorder.rect(); |
2119 int width; | 2187 int width; |
2120 | 2188 |
2121 switch (side) { | 2189 switch (side) { |
2122 case BSTop: | 2190 case BSTop: |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2753 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
2686 for (RenderObject* child = startChild; child && child != endChild; ) { | 2754 for (RenderObject* child = startChild; child && child != endChild; ) { |
2687 // Save our next sibling as moveChildTo will clear it. | 2755 // Save our next sibling as moveChildTo will clear it. |
2688 RenderObject* nextSibling = child->nextSibling(); | 2756 RenderObject* nextSibling = child->nextSibling(); |
2689 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2757 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
2690 child = nextSibling; | 2758 child = nextSibling; |
2691 } | 2759 } |
2692 } | 2760 } |
2693 | 2761 |
2694 } // namespace WebCore | 2762 } // namespace WebCore |
OLD | NEW |