Fix the issue that Web Audio test case fails on PR3.
[framework/web/webkit-efl.git] / Source / WebCore / rendering / RenderDetailsMarker.cpp
1 /*
2  * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "RenderDetailsMarker.h"
23
24 #if ENABLE(DETAILS_ELEMENT) || ENABLE(CALENDAR_PICKER)
25 #include "Element.h"
26 #include "GraphicsContext.h"
27 #include "HTMLNames.h"
28 #include "PaintInfo.h"
29
30 namespace WebCore {
31
32 using namespace HTMLNames;
33
34 RenderDetailsMarker::RenderDetailsMarker(Node* node)
35     : RenderBlock(node)
36 {
37 }
38
39 static Path createPath(const FloatPoint* path)
40 {
41     Path result;
42     result.moveTo(FloatPoint(path[0].x(), path[0].y()));
43     for (int i = 1; i < 4; ++i)
44         result.addLineTo(FloatPoint(path[i].x(), path[i].y()));
45     return result;
46 }
47
48 static Path createDownArrowPath()
49 {
50     FloatPoint points[4] = { FloatPoint(0.0f, 0.07f), FloatPoint(0.5f, 0.93f), FloatPoint(1.0f, 0.07f), FloatPoint(0.0f, 0.07f) };
51     return createPath(points);
52 }
53
54 static Path createUpArrowPath()
55 {
56     FloatPoint points[4] = { FloatPoint(0.0f, 0.93f), FloatPoint(0.5f, 0.07f), FloatPoint(1.0f, 0.93f), FloatPoint(0.0f, 0.93f) };
57     return createPath(points);
58 }
59
60 static Path createLeftArrowPath()
61 {
62     FloatPoint points[4] = { FloatPoint(1.0f, 0.0f), FloatPoint(0.14f, 0.5f), FloatPoint(1.0f, 1.0f), FloatPoint(1.0f, 0.0f) };
63     return createPath(points);
64 }
65
66 static Path createRightArrowPath()
67 {
68     FloatPoint points[4] = { FloatPoint(0.0f, 0.0f), FloatPoint(0.86f, 0.5f), FloatPoint(0.0f, 1.0f), FloatPoint(0.0f, 0.0f) };
69     return createPath(points);
70 }
71
72 RenderDetailsMarker::Orientation RenderDetailsMarker::orientation() const
73 {
74     switch (style()->writingMode()) {
75     case TopToBottomWritingMode:
76         if (style()->isLeftToRightDirection())
77             return isOpen() ? Down : Right;
78         return isOpen() ? Down : Left;
79     case RightToLeftWritingMode:
80         if (style()->isLeftToRightDirection())
81             return isOpen() ? Left : Down;
82         return isOpen() ? Left : Up;
83     case LeftToRightWritingMode:
84         if (style()->isLeftToRightDirection())
85             return isOpen() ? Right : Down;
86         return isOpen() ? Right : Up;
87     case BottomToTopWritingMode:
88         if (style()->isLeftToRightDirection())
89             return isOpen() ? Up : Right;
90         return isOpen() ? Up : Left;
91     }
92     return Right;
93 }
94
95 Path RenderDetailsMarker::getCanonicalPath() const
96 {
97     switch (orientation()) {
98     case Left: return createLeftArrowPath();
99     case Right: return createRightArrowPath();
100     case Up: return createUpArrowPath();
101     case Down: return createDownArrowPath();
102     }
103
104     return Path();
105 }
106
107 Path RenderDetailsMarker::getPath(const LayoutPoint& origin) const
108 {
109     Path result = getCanonicalPath();
110     result.transform(AffineTransform().scale(contentWidth(), contentHeight()));
111     result.translate(FloatSize(origin.x(), origin.y()));
112     return result;
113 }
114
115 void RenderDetailsMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
116 {
117     if (paintInfo.phase != PaintPhaseForeground || style()->visibility() != VISIBLE) {
118         RenderBlock::paint(paintInfo, paintOffset);
119         return;
120     }
121
122     LayoutPoint boxOrigin(paintOffset + location());
123     LayoutRect overflowRect(visualOverflowRect());
124     overflowRect.moveBy(boxOrigin);
125     overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
126
127     if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
128         return;
129
130     const Color color(style()->visitedDependentColor(CSSPropertyColor));
131     paintInfo.context->setStrokeColor(color, style()->colorSpace());
132     paintInfo.context->setStrokeStyle(SolidStroke);
133     paintInfo.context->setStrokeThickness(1.0f);
134     paintInfo.context->setFillColor(color, style()->colorSpace());
135
136     boxOrigin.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
137     paintInfo.context->fillPath(getPath(boxOrigin));
138 }
139
140 bool RenderDetailsMarker::isOpen() const
141 {
142     for (RenderObject* renderer = parent(); renderer; renderer = renderer->parent()) {
143         if (!renderer->node())
144             continue;
145         if (renderer->node()->hasTagName(detailsTag))
146             return !toElement(renderer->node())->getAttribute(openAttr).isNull();
147         if (renderer->node()->hasTagName(inputTag))
148             return true;
149     }
150
151     return false;
152 }
153
154 }
155
156 #endif