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 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1986 break; | 1986 break; |
1987 default: | 1987 default: |
1988 break; | 1988 break; |
1989 } | 1989 } |
1990 | 1990 |
1991 graphicsContext->setStrokeStyle(NoStroke); | 1991 graphicsContext->setStrokeStyle(NoStroke); |
1992 graphicsContext->setFillColor(color, style->colorSpace()); | 1992 graphicsContext->setFillColor(color, style->colorSpace()); |
1993 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); | 1993 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); |
1994 } | 1994 } |
1995 | 1995 |
1996 static void findInnerVertex(const FloatPoint& outerCorner, const FloatPoint& inn erCorner, const FloatPoint& centerPoint, FloatPoint& result) | |
1997 { | |
1998 // If the line between outer and inner corner is towards the horizontal, int ersect with a vertical line through the center, | |
1999 // otherwise with a horizontal line through the center. The points that form this line are arbitrary (we use 0, 100). | |
2000 // Note that if findIntersection fails, it will leave result untouched. | |
2001 float diffInnerOuterX = fabs(innerCorner.x() - outerCorner.x()); | |
2002 float diffInnerOuterY = fabs(innerCorner.y() - outerCorner.y()); | |
2003 float diffCenterOuterX = fabs(centerPoint.x() - outerCorner.x()); | |
2004 float diffCenterOuterY = fabs(centerPoint.y() - outerCorner.y()); | |
2005 if (diffInnerOuterY * diffCenterOuterX < diffCenterOuterY * diffInnerOuterX) | |
2006 findIntersection(outerCorner, innerCorner, FloatPoint(centerPoint.x(), 0 ), FloatPoint(centerPoint.x(), 100), result); | |
2007 else | |
2008 findIntersection(outerCorner, innerCorner, FloatPoint(0, centerPoint.y() ), FloatPoint(100, centerPoint.y()), result); | |
2009 } | |
2010 | |
2011 void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex t, const RoundedRect& outerBorder, const RoundedRect& innerBorder, | 1996 void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex t, const RoundedRect& outerBorder, const RoundedRect& innerBorder, |
2012 BoxSide side, bool firstEdgeMat ches, bool secondEdgeMatches) | 1997 BoxSide side, bool firstEdgeMat ches, bool secondEdgeMatches) |
2013 { | 1998 { |
2014 FloatPoint quad[4]; | 1999 FloatPoint quad[4]; |
2015 | 2000 |
2016 const LayoutRect& outerRect = outerBorder.rect(); | 2001 const LayoutRect& outerRect = outerBorder.rect(); |
2017 const LayoutRect& innerRect = innerBorder.rect(); | 2002 const LayoutRect& innerRect = innerBorder.rect(); |
2018 | 2003 |
2019 FloatPoint centerPoint(innerRect.location().x() + static_cast<float>(innerRe ct.width()) / 2, innerRect.location().y() + static_cast<float>(innerRect.height( )) / 2); | 2004 FloatPoint centerPoint(innerRect.location().x() + static_cast<float>(innerRe ct.width()) / 2, innerRect.location().y() + static_cast<float>(innerRect.height( )) / 2); |
2020 | 2005 |
(...skipping 12 matching lines...) Expand all Loading... | |
2033 // 0----------------3 | 2018 // 0----------------3 |
2034 // | 2019 // |
2035 switch (side) { | 2020 switch (side) { |
2036 case BSTop: | 2021 case BSTop: |
2037 quad[0] = outerRect.minXMinYCorner(); | 2022 quad[0] = outerRect.minXMinYCorner(); |
2038 quad[1] = innerRect.minXMinYCorner(); | 2023 quad[1] = innerRect.minXMinYCorner(); |
2039 quad[2] = innerRect.maxXMinYCorner(); | 2024 quad[2] = innerRect.maxXMinYCorner(); |
2040 quad[3] = outerRect.maxXMinYCorner(); | 2025 quad[3] = outerRect.maxXMinYCorner(); |
2041 | 2026 |
2042 if (!innerBorder.radii().topLeft().isZero()) | 2027 if (!innerBorder.radii().topLeft().isZero()) |
2043 findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner (), centerPoint, quad[1]); | 2028 findIntersection(quad[0], quad[1], |
2029 FloatPoint( | |
2030 quad[1].x() + innerBorder.radii().topLeft().width(), | |
2031 quad[1].y()), | |
2032 FloatPoint( | |
2033 quad[1].x(), | |
2034 quad[1].y() + innerBorder.radii().topLeft().height()), | |
2035 quad[1]); | |
2044 | 2036 |
2045 if (!innerBorder.radii().topRight().isZero()) | 2037 if (!innerBorder.radii().topRight().isZero()) |
2046 findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner (), centerPoint, quad[2]); | 2038 findIntersection(quad[3], quad[2], |
2039 FloatPoint( | |
2040 quad[2].x() - innerBorder.radii().topRight().width(), | |
2041 quad[2].y()), | |
2042 FloatPoint( | |
2043 quad[2].x(), | |
2044 quad[2].y() + innerBorder.radii().topRight().height()), | |
2045 quad[2]); | |
2047 break; | 2046 break; |
2048 | 2047 |
2049 case BSLeft: | 2048 case BSLeft: |
2050 quad[0] = outerRect.minXMinYCorner(); | 2049 quad[0] = outerRect.minXMinYCorner(); |
2051 quad[1] = innerRect.minXMinYCorner(); | 2050 quad[1] = innerRect.minXMinYCorner(); |
2052 quad[2] = innerRect.minXMaxYCorner(); | 2051 quad[2] = innerRect.minXMaxYCorner(); |
2053 quad[3] = outerRect.minXMaxYCorner(); | 2052 quad[3] = outerRect.minXMaxYCorner(); |
2054 | 2053 |
2055 if (!innerBorder.radii().topLeft().isZero()) | 2054 if (!innerBorder.radii().topLeft().isZero()) |
2056 findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner (), centerPoint, quad[1]); | 2055 findIntersection(quad[0], quad[1], |
2056 FloatPoint( | |
2057 quad[1].x() + innerBorder.radii().topLeft().width(), | |
2058 quad[1].y()), | |
2059 FloatPoint( | |
2060 quad[1].x(), | |
2061 quad[1].y() + innerBorder.radii().topLeft().height()), | |
2062 quad[1]); | |
2057 | 2063 |
2058 if (!innerBorder.radii().bottomLeft().isZero()) | 2064 if (!innerBorder.radii().bottomLeft().isZero()) |
2059 findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner (), centerPoint, quad[2]); | 2065 findIntersection(quad[3], quad[2], |
2066 FloatPoint( | |
2067 quad[2].x() + innerBorder.radii().bottomLeft().width(), | |
2068 quad[2].y()), | |
2069 FloatPoint( | |
2070 quad[2].x(), | |
2071 quad[2].y() - innerBorder.radii().bottomLeft().height()), | |
2072 quad[2]); | |
2060 break; | 2073 break; |
2061 | 2074 |
2062 case BSBottom: | 2075 case BSBottom: |
2063 quad[0] = outerRect.minXMaxYCorner(); | 2076 quad[0] = outerRect.minXMaxYCorner(); |
2064 quad[1] = innerRect.minXMaxYCorner(); | 2077 quad[1] = innerRect.minXMaxYCorner(); |
2065 quad[2] = innerRect.maxXMaxYCorner(); | 2078 quad[2] = innerRect.maxXMaxYCorner(); |
2066 quad[3] = outerRect.maxXMaxYCorner(); | 2079 quad[3] = outerRect.maxXMaxYCorner(); |
2067 | 2080 |
2068 if (!innerBorder.radii().bottomLeft().isZero()) | 2081 if (!innerBorder.radii().bottomLeft().isZero()) |
2069 findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner (), centerPoint, quad[1]); | 2082 findIntersection(quad[0], quad[1], |
2083 FloatPoint( | |
2084 quad[1].x() + innerBorder.radii().bottomLeft().width(), | |
2085 quad[1].y()), | |
2086 FloatPoint( | |
2087 quad[1].x(), | |
2088 quad[1].y() - innerBorder.radii().bottomLeft().height()), | |
2089 quad[1]); | |
2070 | 2090 |
2071 if (!innerBorder.radii().bottomRight().isZero()) | 2091 if (!innerBorder.radii().bottomRight().isZero()) |
2072 findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner (), centerPoint, quad[2]); | 2092 findIntersection(quad[3], quad[2], |
2093 FloatPoint( | |
2094 quad[2].x() - innerBorder.radii().bottomRight().width(), | |
2095 quad[2].y()), | |
2096 FloatPoint( | |
2097 quad[2].x(), | |
2098 quad[2].y() - innerBorder.radii().bottomRight().height()), | |
2099 quad[2]); | |
2073 break; | 2100 break; |
2074 | 2101 |
2075 case BSRight: | 2102 case BSRight: |
2076 quad[0] = outerRect.maxXMinYCorner(); | 2103 quad[0] = outerRect.maxXMinYCorner(); |
2077 quad[1] = innerRect.maxXMinYCorner(); | 2104 quad[1] = innerRect.maxXMinYCorner(); |
2078 quad[2] = innerRect.maxXMaxYCorner(); | 2105 quad[2] = innerRect.maxXMaxYCorner(); |
2079 quad[3] = outerRect.maxXMaxYCorner(); | 2106 quad[3] = outerRect.maxXMaxYCorner(); |
2080 | 2107 |
2081 if (!innerBorder.radii().topRight().isZero()) | 2108 if (!innerBorder.radii().topRight().isZero()) |
2082 findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner (), centerPoint, quad[1]); | 2109 findIntersection(quad[0], quad[1], |
2110 FloatPoint( | |
2111 quad[1].x() - innerBorder.radii().topRight().width(), | |
2112 quad[1].y()), | |
2113 FloatPoint( | |
2114 quad[1].x(), | |
2115 quad[1].y() + innerBorder.radii().topRight().height()), | |
2116 quad[1]); | |
2083 | 2117 |
2084 if (!innerBorder.radii().bottomRight().isZero()) | 2118 if (!innerBorder.radii().bottomRight().isZero()) |
2085 findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner (), centerPoint, quad[2]); | 2119 findIntersection(quad[3], quad[2], |
2120 FloatPoint( | |
2121 quad[2].x() - innerBorder.radii().bottomRight().width(), | |
2122 quad[2].y()), | |
2123 FloatPoint( | |
2124 quad[2].x(), | |
2125 quad[2].y() - innerBorder.radii().bottomRight().height()), | |
2126 quad[2]); | |
2086 break; | 2127 break; |
2087 } | 2128 } |
2088 | 2129 |
2089 // If the border matches both of its adjacent sides, don't anti-alias the cl ip, and | 2130 // If the border matches both of its adjacent sides, don't anti-alias the cl ip, and |
2090 // if neither side matches, anti-alias the clip. | 2131 // if neither side matches, anti-alias the clip. |
2091 if (firstEdgeMatches == secondEdgeMatches) { | 2132 if (firstEdgeMatches == secondEdgeMatches) { |
2092 graphicsContext->clipConvexPolygon(4, quad, !firstEdgeMatches); | 2133 graphicsContext->clipConvexPolygon(4, quad, !firstEdgeMatches); |
2093 return; | 2134 return; |
2094 } | 2135 } |
2095 | 2136 |
2096 // Square off the end which shouldn't be affected by antialiasing, and clip. | 2137 // If antialiasing settings for the first edge and second edge is different, |
2138 // they have to be addressed separately. We do this by breaking the quad int o | |
2139 // two parallelograms, made by moving quad[1] and quad[2]. | |
2140 float ax = quad[1].x() - quad[0].x(); | |
2141 float ay = quad[1].y() - quad[0].y(); | |
2142 float bx = quad[2].x() - quad[1].x(); | |
2143 float by = quad[2].y() - quad[1].y(); | |
2144 float cx = quad[3].x() - quad[2].x(); | |
2145 float cy = quad[3].y() - quad[2].y(); | |
2146 float dx = quad[0].x() - quad[3].x(); | |
2147 float dy = quad[0].y() - quad[3].y(); | |
2148 | |
2149 const static float kEpsilon = 1e-2f; | |
2150 float r1, r2; | |
2151 if (bx < kEpsilon && by < kEpsilon) { | |
kouhei (in TOK)
2013/05/30 15:24:55
I think this needs fabs, will post a fix later
| |
2152 // The quad was actually a triangle. | |
2153 r1 = r2 = 1.0f; | |
2154 } else { | |
2155 // Extend parallelogram a bit to hide calculation error | |
2156 const static float kExtendFill = 1e-2f; | |
2157 | |
2158 r1 = (-ax*by + ay*bx) / (cx*by - cy*bx) + kExtendFill; | |
2159 r2 = (-cx*by + cy*bx) / (ax*by - ay*bx) + kExtendFill; | |
2160 } | |
2161 | |
2097 FloatPoint firstQuad[4]; | 2162 FloatPoint firstQuad[4]; |
2098 firstQuad[0] = quad[0]; | 2163 firstQuad[0] = quad[0]; |
2099 firstQuad[1] = quad[1]; | 2164 firstQuad[1] = quad[1]; |
2100 firstQuad[2] = side == BSTop || side == BSBottom ? FloatPoint(quad[3].x(), q uad[2].y()) | 2165 firstQuad[2] = FloatPoint(quad[3].x() + r2*ax, quad[3].y() + r2*ay); |
2101 : FloatPoint(quad[2].x(), quad[3].y()); | |
2102 firstQuad[3] = quad[3]; | 2166 firstQuad[3] = quad[3]; |
2103 graphicsContext->clipConvexPolygon(4, firstQuad, !firstEdgeMatches); | 2167 graphicsContext->clipConvexPolygon(4, firstQuad, !firstEdgeMatches); |
2104 | 2168 |
2105 FloatPoint secondQuad[4]; | 2169 FloatPoint secondQuad[4]; |
2106 secondQuad[0] = quad[0]; | 2170 secondQuad[0] = quad[0]; |
2107 secondQuad[1] = side == BSTop || side == BSBottom ? FloatPoint(quad[0].x(), quad[1].y()) | 2171 secondQuad[1] = FloatPoint(quad[0].x() - r1*cx, quad[0].y() - r1*cy); |
2108 : FloatPoint(quad[1].x(), quad[0].y()); | |
2109 secondQuad[2] = quad[2]; | 2172 secondQuad[2] = quad[2]; |
2110 secondQuad[3] = quad[3]; | 2173 secondQuad[3] = quad[3]; |
2111 // Antialiasing affects the second side. | |
2112 graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches); | 2174 graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches); |
2113 } | 2175 } |
2114 | 2176 |
2115 static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, c onst BorderEdge edges[], BoxSide side) | 2177 static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, c onst BorderEdge edges[], BoxSide side) |
2116 { | 2178 { |
2117 IntRect sideRect = outerBorder.rect(); | 2179 IntRect sideRect = outerBorder.rect(); |
2118 int width; | 2180 int width; |
2119 | 2181 |
2120 switch (side) { | 2182 switch (side) { |
2121 case BSTop: | 2183 case BSTop: |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2665 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2727 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
2666 for (RenderObject* child = startChild; child && child != endChild; ) { | 2728 for (RenderObject* child = startChild; child && child != endChild; ) { |
2667 // Save our next sibling as moveChildTo will clear it. | 2729 // Save our next sibling as moveChildTo will clear it. |
2668 RenderObject* nextSibling = child->nextSibling(); | 2730 RenderObject* nextSibling = child->nextSibling(); |
2669 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2731 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
2670 child = nextSibling; | 2732 child = nextSibling; |
2671 } | 2733 } |
2672 } | 2734 } |
2673 | 2735 |
2674 } // namespace WebCore | 2736 } // namespace WebCore |
OLD | NEW |