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