GraphicsContextOpenVG.cpp revision 81bc750723a18f21cd17d1b173cd2a4dda9cea6e
1/*
2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
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#include "config.h"
21#include "GraphicsContext.h"
22
23#include "AffineTransform.h"
24#include "KURL.h"
25#include "NotImplemented.h"
26#include "PainterOpenVG.h"
27#include "SurfaceOpenVG.h"
28
29#include <wtf/Assertions.h>
30#include <wtf/MathExtras.h>
31#include <wtf/UnusedParam.h>
32#include <wtf/Vector.h>
33
34#if PLATFORM(EGL)
35#include "EGLDisplayOpenVG.h"
36#include "EGLUtils.h"
37#include <egl.h>
38#endif
39
40namespace WebCore {
41
42// typedef'ing doesn't work, let's inherit from PainterOpenVG instead
43class GraphicsContextPlatformPrivate : public PainterOpenVG {
44public:
45    GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
46        : PainterOpenVG(surface)
47    {
48    }
49};
50
51void GraphicsContext::platformInit(SurfaceOpenVG* surface)
52{
53    m_data = surface ? new GraphicsContextPlatformPrivate(surface) : 0;
54    setPaintingDisabled(!surface);
55}
56
57void GraphicsContext::platformDestroy()
58{
59    delete m_data;
60}
61
62PlatformGraphicsContext* GraphicsContext::platformContext() const
63{
64    if (paintingDisabled())
65        return 0;
66
67    return m_data->baseSurface();
68}
69
70AffineTransform GraphicsContext::getCTM() const
71{
72    if (paintingDisabled())
73        return AffineTransform();
74
75    return m_data->transformation();
76}
77
78void GraphicsContext::savePlatformState()
79{
80    if (paintingDisabled())
81        return;
82
83    m_data->save();
84}
85
86void GraphicsContext::restorePlatformState()
87{
88    if (paintingDisabled())
89        return;
90
91    m_data->restore();
92}
93
94void GraphicsContext::drawRect(const IntRect& rect)
95{
96    if (paintingDisabled())
97        return;
98
99    m_data->drawRect(rect);
100}
101
102void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
103{
104    if (paintingDisabled())
105        return;
106
107    m_data->drawLine(from, to);
108}
109
110/**
111 * Draw the largest ellipse that fits into the given rectangle.
112 */
113void GraphicsContext::drawEllipse(const IntRect& rect)
114{
115    if (paintingDisabled())
116        return;
117
118    m_data->drawEllipse(rect);
119}
120
121void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
122{
123    if (paintingDisabled())
124        return;
125
126    m_data->drawArc(rect, startAngle, angleSpan, VG_STROKE_PATH);
127}
128
129void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
130{
131    if (paintingDisabled())
132        return;
133
134    m_data->drawPolygon(numPoints, points);
135
136    UNUSED_PARAM(shouldAntialias); // FIXME
137}
138
139void GraphicsContext::fillPath(const Path& path)
140{
141    if (paintingDisabled())
142        return;
143
144    m_data->drawPath(path, VG_FILL_PATH, m_state.fillRule);
145}
146
147void GraphicsContext::strokePath(const Path& path)
148{
149    if (paintingDisabled())
150        return;
151
152    m_data->drawPath(path, VG_STROKE_PATH, m_state.fillRule);
153}
154
155void GraphicsContext::fillRect(const FloatRect& rect)
156{
157    if (paintingDisabled())
158        return;
159
160    m_data->drawRect(rect, VG_FILL_PATH);
161}
162
163void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
164{
165    if (paintingDisabled())
166        return;
167
168    Color oldColor = m_data->fillColor();
169    m_data->setFillColor(color);
170    m_data->drawRect(rect, VG_FILL_PATH);
171    m_data->setFillColor(oldColor);
172
173    UNUSED_PARAM(colorSpace); // FIXME
174}
175
176void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
177{
178    if (paintingDisabled())
179        return;
180
181    Color oldColor = m_data->fillColor();
182    m_data->setFillColor(color);
183    m_data->drawRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, VG_FILL_PATH);
184    m_data->setFillColor(oldColor);
185
186    UNUSED_PARAM(colorSpace); // FIXME
187}
188
189void GraphicsContext::clip(const FloatRect& rect)
190{
191    if (paintingDisabled())
192        return;
193
194    m_data->intersectClipRect(rect);
195}
196
197void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
198{
199    if (paintingDisabled())
200        return;
201
202    m_data->clipPath(path, PainterOpenVG::IntersectClip, clipRule);
203}
204
205void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
206{
207    if (paintingDisabled())
208        return;
209
210    if (rects.isEmpty())
211        return;
212
213    // FIXME: We just unite all focus ring rects into one for now.
214    // We should outline the edge of the full region.
215    offset += (width - 1) / 2;
216    IntRect finalFocusRect;
217
218    for (unsigned i = 0; i < rects.size(); i++) {
219        IntRect focusRect = rects[i];
220        focusRect.inflate(offset);
221        finalFocusRect.unite(focusRect);
222    }
223
224    StrokeStyle oldStyle = m_data->strokeStyle();
225    Color oldStrokeColor = m_data->strokeColor();
226    m_data->setStrokeStyle(DashedStroke);
227    m_data->setStrokeColor(color);
228    strokeRect(FloatRect(finalFocusRect), 1.f);
229    m_data->setStrokeStyle(oldStyle);
230    m_data->setStrokeColor(oldStrokeColor);
231}
232
233void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
234{
235    if (paintingDisabled())
236        return;
237
238    if (width <= 0)
239        return;
240
241    StrokeStyle oldStyle = m_data->strokeStyle();
242    m_data->setStrokeStyle(SolidStroke);
243    drawLine(origin, origin + IntSize(width, 0));
244    m_data->setStrokeStyle(oldStyle);
245
246    UNUSED_PARAM(printing);
247}
248
249void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
250{
251    if (paintingDisabled())
252        return;
253
254    notImplemented();
255    UNUSED_PARAM(origin);
256    UNUSED_PARAM(width);
257    UNUSED_PARAM(style);
258}
259
260FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
261{
262    if (paintingDisabled())
263        return FloatRect();
264
265    return FloatRect(enclosingIntRect(m_data->transformation().mapRect(rect)));
266}
267
268void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace colorSpace)
269{
270    if (paintingDisabled())
271        return;
272
273    notImplemented();
274    UNUSED_PARAM(size);
275    UNUSED_PARAM(blur);
276    UNUSED_PARAM(color);
277    UNUSED_PARAM(colorSpace);
278}
279
280void GraphicsContext::clearPlatformShadow()
281{
282    if (paintingDisabled())
283        return;
284
285    notImplemented();
286}
287
288void GraphicsContext::beginTransparencyLayer(float opacity)
289{
290    if (paintingDisabled())
291        return;
292
293    notImplemented();
294    UNUSED_PARAM(opacity);
295}
296
297void GraphicsContext::endTransparencyLayer()
298{
299    if (paintingDisabled())
300        return;
301
302    notImplemented();
303}
304
305void GraphicsContext::clearRect(const FloatRect& rect)
306{
307    if (paintingDisabled())
308        return;
309
310    CompositeOperator op = m_data->compositeOperation();
311    m_data->setCompositeOperation(CompositeClear);
312    m_data->drawRect(rect, VG_FILL_PATH);
313    m_data->setCompositeOperation(op);
314}
315
316void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
317{
318    if (paintingDisabled())
319        return;
320
321    float oldThickness = m_data->strokeThickness();
322    m_data->setStrokeThickness(lineWidth);
323    m_data->drawRect(rect, VG_STROKE_PATH);
324    m_data->setStrokeThickness(oldThickness);
325}
326
327void GraphicsContext::setLineCap(LineCap lc)
328{
329    if (paintingDisabled())
330        return;
331
332    m_data->setLineCap(lc);
333}
334
335void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
336{
337    if (paintingDisabled())
338        return;
339
340    m_data->setLineDash(dashes, dashOffset);
341}
342
343void GraphicsContext::setLineJoin(LineJoin lj)
344{
345    if (paintingDisabled())
346        return;
347
348    m_data->setLineJoin(lj);
349}
350
351void GraphicsContext::setMiterLimit(float limit)
352{
353    if (paintingDisabled())
354        return;
355
356    m_data->setMiterLimit(limit);
357}
358
359void GraphicsContext::setAlpha(float opacity)
360{
361    if (paintingDisabled())
362        return;
363
364    m_data->setOpacity(opacity);
365}
366
367void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
368{
369    if (paintingDisabled())
370        return;
371
372    m_data->setCompositeOperation(op);
373}
374
375void GraphicsContext::clip(const Path& path)
376{
377    if (paintingDisabled())
378        return;
379
380    m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule);
381}
382
383void GraphicsContext::canvasClip(const Path& path)
384{
385    clip(path);
386}
387
388void GraphicsContext::clipOut(const Path& path)
389{
390    if (paintingDisabled())
391        return;
392
393    m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule);
394}
395
396void GraphicsContext::scale(const FloatSize& scaleFactors)
397{
398    if (paintingDisabled())
399        return;
400
401    m_data->scale(scaleFactors);
402}
403
404void GraphicsContext::rotate(float radians)
405{
406    if (paintingDisabled())
407        return;
408
409    m_data->rotate(radians);
410}
411
412void GraphicsContext::translate(float dx, float dy)
413{
414    if (paintingDisabled())
415        return;
416
417    m_data->translate(dx, dy);
418}
419
420void GraphicsContext::clipOut(const IntRect& rect)
421{
422    if (paintingDisabled())
423        return;
424
425    Path path;
426    path.addRect(rect);
427    m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule);
428}
429
430void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
431{
432    if (paintingDisabled())
433        return;
434
435    notImplemented();
436    UNUSED_PARAM(rect);
437    UNUSED_PARAM(imageBuffer);
438}
439
440void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
441{
442    if (paintingDisabled())
443        return;
444
445    Path path;
446    path.addEllipse(rect);
447    path.addEllipse(FloatRect(rect.x() + thickness, rect.y() + thickness,
448        rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
449
450    m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule);
451}
452
453void GraphicsContext::concatCTM(const AffineTransform& transformation)
454{
455    if (paintingDisabled())
456        return;
457
458    m_data->concatTransformation(transformation);
459}
460
461void GraphicsContext::setCTM(const AffineTransform& transformation)
462{
463    if (paintingDisabled())
464        return;
465
466    m_data->setTransformation(transformation);
467}
468
469void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
470{
471    notImplemented();
472    UNUSED_PARAM(link);
473    UNUSED_PARAM(destRect);
474}
475
476void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
477{
478    if (paintingDisabled())
479        return;
480
481    m_data->setStrokeColor(color);
482
483    UNUSED_PARAM(colorSpace); // FIXME
484}
485
486void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
487{
488    if (paintingDisabled())
489        return;
490
491    m_data->setStrokeStyle(strokeStyle);
492}
493
494void GraphicsContext::setPlatformStrokeThickness(float thickness)
495{
496    if (paintingDisabled())
497        return;
498
499    m_data->setStrokeThickness(thickness);
500}
501
502void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
503{
504    if (paintingDisabled())
505        return;
506
507    m_data->setFillColor(color);
508
509    UNUSED_PARAM(colorSpace); // FIXME
510}
511
512void GraphicsContext::setPlatformShouldAntialias(bool enable)
513{
514    if (paintingDisabled())
515        return;
516
517    m_data->setAntialiasingEnabled(enable);
518}
519
520void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
521{
522    notImplemented();
523}
524
525InterpolationQuality GraphicsContext::imageInterpolationQuality() const
526{
527    notImplemented();
528    return InterpolationDefault;
529}
530
531}
532