75dbadb2273945f892172293f516f9cf40fa5ac1
[WebKit-https.git] / Source / WebCore / platform / graphics / openvg / GraphicsContextOpenVG.cpp
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
40 namespace WebCore {
41
42 // typedef'ing doesn't work, let's inherit from PainterOpenVG instead
43 class GraphicsContextPlatformPrivate : public PainterOpenVG {
44 public:
45     GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
46         : PainterOpenVG(surface)
47     {
48     }
49 };
50
51 void GraphicsContext::platformInit(SurfaceOpenVG* surface)
52 {
53     m_data = surface ? new GraphicsContextPlatformPrivate(surface) : 0;
54     setPaintingDisabled(!surface);
55 }
56
57 void GraphicsContext::platformDestroy()
58 {
59     delete m_data;
60 }
61
62 PlatformGraphicsContext* GraphicsContext::platformContext() const
63 {
64     if (paintingDisabled())
65         return 0;
66
67     return m_data->baseSurface();
68 }
69
70 AffineTransform GraphicsContext::getCTM() const
71 {
72     if (paintingDisabled())
73         return AffineTransform();
74
75     return m_data->transformation();
76 }
77
78 void GraphicsContext::savePlatformState()
79 {
80     if (paintingDisabled())
81         return;
82
83     m_data->save();
84 }
85
86 void GraphicsContext::restorePlatformState()
87 {
88     if (paintingDisabled())
89         return;
90
91     m_data->restore();
92 }
93
94 void GraphicsContext::drawRect(const IntRect& rect)
95 {
96     if (paintingDisabled())
97         return;
98
99     m_data->drawRect(rect);
100 }
101
102 void 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  */
113 void GraphicsContext::drawEllipse(const IntRect& rect)
114 {
115     if (paintingDisabled())
116         return;
117
118     m_data->drawEllipse(rect);
119 }
120
121 void 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
129 void 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
139 void 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
147 void 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
155 void GraphicsContext::fillRect(const FloatRect& rect)
156 {
157     if (paintingDisabled())
158         return;
159
160     m_data->drawRect(rect, VG_FILL_PATH);
161 }
162
163 void 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
176 void 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
189 void GraphicsContext::clip(const FloatRect& rect)
190 {
191     if (paintingDisabled())
192         return;
193
194     m_data->intersectClipRect(rect);
195 }
196
197 void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
198 {
199     if (paintingDisabled())
200         return;
201
202     m_data->clipPath(path, PainterOpenVG::IntersectClip, clipRule);
203 }
204
205 void 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
233 void 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
249 void 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
260 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
261 {
262     if (paintingDisabled())
263         return FloatRect();
264
265     return FloatRect(enclosingIntRect(m_data->transformation().mapRect(rect)));
266 }
267
268 void 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
280 void GraphicsContext::clearPlatformShadow()
281 {
282     if (paintingDisabled())
283         return;
284
285     notImplemented();
286 }
287
288 void GraphicsContext::beginTransparencyLayer(float opacity)
289 {
290     if (paintingDisabled())
291         return;
292
293     notImplemented();
294     UNUSED_PARAM(opacity);
295 }
296
297 void GraphicsContext::endTransparencyLayer()
298 {
299     if (paintingDisabled())
300         return;
301
302     notImplemented();
303 }
304
305 void 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
316 void 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
327 void GraphicsContext::setLineCap(LineCap lc)
328 {
329     if (paintingDisabled())
330         return;
331
332     m_data->setLineCap(lc);
333 }
334
335 void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
336 {
337     if (paintingDisabled())
338         return;
339
340     m_data->setLineDash(dashes, dashOffset);
341 }
342
343 void GraphicsContext::setLineJoin(LineJoin lj)
344 {
345     if (paintingDisabled())
346         return;
347
348     m_data->setLineJoin(lj);
349 }
350
351 void GraphicsContext::setMiterLimit(float limit)
352 {
353     if (paintingDisabled())
354         return;
355
356     m_data->setMiterLimit(limit);
357 }
358
359 void GraphicsContext::setAlpha(float opacity)
360 {
361     if (paintingDisabled())
362         return;
363
364     m_data->setOpacity(opacity);
365 }
366
367 void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
368 {
369     if (paintingDisabled())
370         return;
371
372     m_data->setCompositeOperation(op);
373 }
374
375 void GraphicsContext::clip(const Path& path)
376 {
377     if (paintingDisabled())
378         return;
379
380     m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule);
381 }
382
383 void GraphicsContext::canvasClip(const Path& path)
384 {
385     clip(path);
386 }
387
388 void GraphicsContext::clipOut(const Path& path)
389 {
390     if (paintingDisabled())
391         return;
392
393     m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule);
394 }
395
396 void GraphicsContext::scale(const FloatSize& scaleFactors)
397 {
398     if (paintingDisabled())
399         return;
400
401     m_data->scale(scaleFactors);
402 }
403
404 void GraphicsContext::rotate(float radians)
405 {
406     if (paintingDisabled())
407         return;
408
409     m_data->rotate(radians);
410 }
411
412 void GraphicsContext::translate(float dx, float dy)
413 {
414     if (paintingDisabled())
415         return;
416
417     m_data->translate(dx, dy);
418 }
419
420 void 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
430 void 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
440 void 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
453 void GraphicsContext::concatCTM(const AffineTransform& transformation)
454 {
455     if (paintingDisabled())
456         return;
457
458     m_data->concatTransformation(transformation);
459 }
460
461 void GraphicsContext::setCTM(const AffineTransform& transformation)
462 {
463     if (paintingDisabled())
464         return;
465
466     m_data->setTransformation(transformation);
467 }
468
469 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
470 {
471     notImplemented();
472     UNUSED_PARAM(link);
473     UNUSED_PARAM(destRect);
474 }
475
476 void 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
486 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
487 {
488     if (paintingDisabled())
489         return;
490
491     m_data->setStrokeStyle(strokeStyle);
492 }
493
494 void GraphicsContext::setPlatformStrokeThickness(float thickness)
495 {
496     if (paintingDisabled())
497         return;
498
499     m_data->setStrokeThickness(thickness);
500 }
501
502 void 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
512 void GraphicsContext::setPlatformShouldAntialias(bool enable)
513 {
514     if (paintingDisabled())
515         return;
516
517     m_data->setAntialiasingEnabled(enable);
518 }
519
520 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
521 {
522     notImplemented();
523 }
524
525 InterpolationQuality GraphicsContext::imageInterpolationQuality() const
526 {
527     notImplemented();
528     return InterpolationDefault;
529 }
530
531 }