This patch makes drawHighlightForText a completely cross-platform method
[WebKit-https.git] / WebCore / platform / GraphicsContext.cpp
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "GraphicsContext.h"
28
29 #include "DeprecatedString.h"
30 #include "Font.h"
31
32 using namespace std;
33
34 namespace WebCore {
35
36 struct GraphicsContextState {
37     GraphicsContextState() : fillColor(Color::black), paintingDisabled(false) { }
38     Font font;
39     Pen pen;
40     Color fillColor;
41     bool paintingDisabled;
42 };
43         
44 class GraphicsContextPrivate {
45 public:
46     GraphicsContextPrivate();
47     
48     GraphicsContextState state;
49     Vector<GraphicsContextState> stack;
50     Vector<IntRect> m_focusRingRects;
51     int m_focusRingWidth;
52     int m_focusRingOffset;
53     bool m_usesInactiveTextBackgroundColor;
54     bool m_updatingControlTints;
55 };
56
57 GraphicsContextPrivate::GraphicsContextPrivate()
58     : m_focusRingWidth(0)
59     , m_focusRingOffset(0)
60     , m_usesInactiveTextBackgroundColor(false)
61     , m_updatingControlTints(false)
62 {
63 }
64
65 GraphicsContextPrivate* GraphicsContext::createGraphicsContextPrivate()
66 {
67     return new GraphicsContextPrivate;
68 }
69
70 void GraphicsContext::destroyGraphicsContextPrivate(GraphicsContextPrivate* deleteMe)
71 {
72     delete deleteMe;
73 }
74
75 void GraphicsContext::save()
76 {
77     if (paintingDisabled())
78         return;
79
80     m_common->stack.append(m_common->state);
81     
82     savePlatformState();
83 }
84
85 void GraphicsContext::restore()
86 {
87     if (paintingDisabled())
88         return;
89
90     if (m_common->stack.isEmpty()) {
91         LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty");
92         return;
93     }
94     m_common->state = m_common->stack.last();
95     m_common->stack.removeLast();
96     
97     restorePlatformState();
98 }
99
100 const Font& GraphicsContext::font() const
101 {
102     return m_common->state.font;
103 }
104
105 void GraphicsContext::setFont(const Font& aFont)
106 {
107     m_common->state.font = aFont;
108 }
109
110 const Pen& GraphicsContext::pen() const
111 {
112     return m_common->state.pen;
113 }
114
115 void GraphicsContext::setPen(const Pen& pen)
116 {
117     m_common->state.pen = pen;
118 }
119
120 void GraphicsContext::setPen(Pen::PenStyle style)
121 {
122     m_common->state.pen.setStyle(style);
123     m_common->state.pen.setColor(Color::black);
124     m_common->state.pen.setWidth(0);
125 }
126
127 void GraphicsContext::setPen(RGBA32 rgb)
128 {
129     m_common->state.pen.setStyle(Pen::SolidLine);
130     m_common->state.pen.setColor(rgb);
131     m_common->state.pen.setWidth(0);
132 }
133
134 void GraphicsContext::setFillColor(const Color& color)
135 {
136     m_common->state.fillColor = color;
137 }
138
139 Color GraphicsContext::fillColor() const
140 {
141     return m_common->state.fillColor;
142 }
143
144 void GraphicsContext::setUsesInactiveTextBackgroundColor(bool u)
145 {
146     m_common->m_usesInactiveTextBackgroundColor = u;
147 }
148
149 bool GraphicsContext::usesInactiveTextBackgroundColor() const
150 {
151     return m_common->m_usesInactiveTextBackgroundColor;
152 }
153
154 bool GraphicsContext::updatingControlTints() const
155 {
156     return m_common->m_updatingControlTints;
157 }
158
159 void GraphicsContext::setUpdatingControlTints(bool b)
160 {
161     setPaintingDisabled(b);
162     m_common->m_updatingControlTints = b;
163 }
164
165 void GraphicsContext::setPaintingDisabled(bool f)
166 {
167     m_common->state.paintingDisabled = f;
168 }
169
170 bool GraphicsContext::paintingDisabled() const
171 {
172     return m_common->state.paintingDisabled;
173 }
174
175 void GraphicsContext::drawImage(Image* image, const IntPoint& p, CompositeOperator op)
176 {        
177     drawImage(image, p, IntRect(0, 0, -1, -1), op);
178 }
179
180 void GraphicsContext::drawImage(Image* image, const IntRect& r, CompositeOperator op)
181 {
182     drawImage(image, r, IntRect(0, 0, -1, -1), op);
183 }
184
185 void GraphicsContext::drawImage(Image* image, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op)
186 {
187     drawImage(image, IntRect(dest, srcRect.size()), srcRect, op);
188 }
189
190 void GraphicsContext::drawImage(Image* image, const IntRect& dest, const IntRect& srcRect, CompositeOperator op)
191 {
192     drawImage(image, FloatRect(dest), srcRect, op);
193 }
194
195 void GraphicsContext::drawText(const TextRun& run, const IntPoint& point, int tabWidth, int xpos, int toAdd,
196                                TextDirection d, bool visuallyOrdered)
197 {
198     if (paintingDisabled())
199         return;
200     
201     font().drawText(this, run, point, tabWidth, xpos, toAdd, d, visuallyOrdered);
202 }
203
204 void GraphicsContext::drawHighlightForText(const TextRun& run, const IntPoint& point, int h, int tabWidth, int xpos, int toAdd,
205                                            TextDirection d, bool visuallyOrdered, const Color& backgroundColor)
206 {
207     if (paintingDisabled())
208         return;
209
210     fillRect(font().selectionRectForText(run, point, h, tabWidth, xpos, toAdd, d == RTL, visuallyOrdered), backgroundColor);
211 }
212
213 void GraphicsContext::drawLineForText(const IntPoint& point, int yOffset, int width)
214 {
215     if (paintingDisabled())
216         return;
217
218     return font().drawLineForText(this, point, yOffset, width);
219 }
220
221
222 void GraphicsContext::drawLineForMisspelling(const IntPoint& point, int width)
223 {
224     if (paintingDisabled())
225         return;
226
227     return font().drawLineForMisspelling(this, point, width);
228 }
229
230 int GraphicsContext::misspellingLineThickness()
231 {
232     return font().misspellingLineThickness(this);
233 }
234
235 void GraphicsContext::initFocusRing(int width, int offset)
236 {
237     if (paintingDisabled())
238         return;
239     clearFocusRing();
240     
241     m_common->m_focusRingWidth = width;
242     m_common->m_focusRingOffset = offset;
243 }
244
245 void GraphicsContext::clearFocusRing()
246 {
247     m_common->m_focusRingRects.clear();
248 }
249
250 void GraphicsContext::addFocusRingRect(const IntRect& rect)
251 {
252     if (paintingDisabled() || rect.isEmpty())
253         return;
254     m_common->m_focusRingRects.append(rect);
255 }
256
257 int GraphicsContext::focusRingWidth() const
258 {
259     return m_common->m_focusRingWidth;
260 }
261
262 int GraphicsContext::focusRingOffset() const
263 {
264     return m_common->m_focusRingOffset;
265 }
266
267 const Vector<IntRect>& GraphicsContext::focusRingRects() const
268 {
269     return m_common->m_focusRingRects;
270 }
271
272 void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
273 {
274     if (paintingDisabled())
275         return;
276
277     float tsw = src.width();
278     float tsh = src.height();
279     float tw = dest.width();
280     float th = dest.height();
281         
282     if (tsw == -1)
283         tsw = image->width();
284     if (tsh == -1)
285         tsh = image->height();
286
287     if (tw == -1)
288         tw = image->width();
289     if (th == -1)
290         th = image->height();
291
292     image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op);
293 }
294
295 void GraphicsContext::drawTiledImage(Image* image, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize)
296 {
297     if (paintingDisabled())
298         return;
299
300     image->drawTiled(this, rect, srcPoint, tileSize);
301 }
302
303 void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const IntRect& srcRect, Image::TileRule hRule, Image::TileRule vRule)
304 {
305     if (paintingDisabled())
306         return;
307
308     if (hRule == Image::StretchTile && vRule == Image::StretchTile)
309         // Just do a scale.
310         return drawImage(image, dest, srcRect);
311
312     image->drawTiled(this, dest, srcRect, hRule, vRule);
313 }
314
315 }