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:
GraphicsContextPlatformPrivate(SurfaceOpenVG * surface)45 GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
46 : PainterOpenVG(surface)
47 {
48 }
49 };
50
platformInit(SurfaceOpenVG * surface)51 void GraphicsContext::platformInit(SurfaceOpenVG* surface)
52 {
53 m_data = surface ? new GraphicsContextPlatformPrivate(surface) : 0;
54 setPaintingDisabled(!surface);
55 }
56
platformDestroy()57 void GraphicsContext::platformDestroy()
58 {
59 delete m_data;
60 }
61
platformContext() const62 PlatformGraphicsContext* GraphicsContext::platformContext() const
63 {
64 if (paintingDisabled())
65 return 0;
66
67 return m_data->baseSurface();
68 }
69
getCTM() const70 AffineTransform GraphicsContext::getCTM() const
71 {
72 if (paintingDisabled())
73 return AffineTransform();
74
75 return m_data->transformation();
76 }
77
savePlatformState()78 void GraphicsContext::savePlatformState()
79 {
80 if (paintingDisabled())
81 return;
82
83 m_data->save();
84 }
85
restorePlatformState()86 void GraphicsContext::restorePlatformState()
87 {
88 if (paintingDisabled())
89 return;
90
91 m_data->restore();
92 }
93
drawRect(const IntRect & rect)94 void GraphicsContext::drawRect(const IntRect& rect)
95 {
96 if (paintingDisabled())
97 return;
98
99 m_data->drawRect(rect);
100 }
101
drawLine(const IntPoint & from,const IntPoint & to)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 */
drawEllipse(const IntRect & rect)113 void GraphicsContext::drawEllipse(const IntRect& rect)
114 {
115 if (paintingDisabled())
116 return;
117
118 m_data->drawEllipse(rect);
119 }
120
strokeArc(const IntRect & rect,int startAngle,int angleSpan)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
drawConvexPolygon(size_t numPoints,const FloatPoint * points,bool shouldAntialias)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
fillPath(const Path & path)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
strokePath(const Path & path)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
fillRect(const FloatRect & rect)155 void GraphicsContext::fillRect(const FloatRect& rect)
156 {
157 if (paintingDisabled())
158 return;
159
160 m_data->drawRect(rect, VG_FILL_PATH);
161 }
162
fillRect(const FloatRect & rect,const Color & color,ColorSpace colorSpace)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
fillRoundedRect(const IntRect & rect,const IntSize & topLeft,const IntSize & topRight,const IntSize & bottomLeft,const IntSize & bottomRight,const Color & color,ColorSpace colorSpace)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
clip(const FloatRect & rect)189 void GraphicsContext::clip(const FloatRect& rect)
190 {
191 if (paintingDisabled())
192 return;
193
194 m_data->intersectClipRect(rect);
195 }
196
clipPath(const Path & path,WindRule clipRule)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
drawFocusRing(const Vector<IntRect> & rects,int width,int offset,const Color & color)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
drawLineForText(const IntPoint & origin,int width,bool printing)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
drawLineForTextChecking(const IntPoint & origin,int width,TextCheckingLineStyle style)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
roundToDevicePixels(const FloatRect & rect,RoundingMode)260 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
261 {
262 if (paintingDisabled())
263 return FloatRect();
264
265 return FloatRect(enclosingIntRect(m_data->transformation().mapRect(rect)));
266 }
267
setPlatformShadow(const FloatSize & size,float blur,const Color & color,ColorSpace colorSpace)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
clearPlatformShadow()280 void GraphicsContext::clearPlatformShadow()
281 {
282 if (paintingDisabled())
283 return;
284
285 notImplemented();
286 }
287
beginTransparencyLayer(float opacity)288 void GraphicsContext::beginTransparencyLayer(float opacity)
289 {
290 if (paintingDisabled())
291 return;
292
293 notImplemented();
294 UNUSED_PARAM(opacity);
295 }
296
endTransparencyLayer()297 void GraphicsContext::endTransparencyLayer()
298 {
299 if (paintingDisabled())
300 return;
301
302 notImplemented();
303 }
304
clearRect(const FloatRect & rect)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
strokeRect(const FloatRect & rect,float lineWidth)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
setLineCap(LineCap lc)327 void GraphicsContext::setLineCap(LineCap lc)
328 {
329 if (paintingDisabled())
330 return;
331
332 m_data->setLineCap(lc);
333 }
334
setLineDash(const DashArray & dashes,float dashOffset)335 void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
336 {
337 if (paintingDisabled())
338 return;
339
340 m_data->setLineDash(dashes, dashOffset);
341 }
342
setLineJoin(LineJoin lj)343 void GraphicsContext::setLineJoin(LineJoin lj)
344 {
345 if (paintingDisabled())
346 return;
347
348 m_data->setLineJoin(lj);
349 }
350
setMiterLimit(float limit)351 void GraphicsContext::setMiterLimit(float limit)
352 {
353 if (paintingDisabled())
354 return;
355
356 m_data->setMiterLimit(limit);
357 }
358
setAlpha(float opacity)359 void GraphicsContext::setAlpha(float opacity)
360 {
361 if (paintingDisabled())
362 return;
363
364 m_data->setOpacity(opacity);
365 }
366
setPlatformCompositeOperation(CompositeOperator op)367 void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
368 {
369 if (paintingDisabled())
370 return;
371
372 m_data->setCompositeOperation(op);
373 }
374
clip(const Path & path)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
canvasClip(const Path & path)383 void GraphicsContext::canvasClip(const Path& path)
384 {
385 clip(path);
386 }
387
clipOut(const Path & path)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
scale(const FloatSize & scaleFactors)396 void GraphicsContext::scale(const FloatSize& scaleFactors)
397 {
398 if (paintingDisabled())
399 return;
400
401 m_data->scale(scaleFactors);
402 }
403
rotate(float radians)404 void GraphicsContext::rotate(float radians)
405 {
406 if (paintingDisabled())
407 return;
408
409 m_data->rotate(radians);
410 }
411
translate(float dx,float dy)412 void GraphicsContext::translate(float dx, float dy)
413 {
414 if (paintingDisabled())
415 return;
416
417 m_data->translate(dx, dy);
418 }
419
clipOut(const IntRect & rect)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
clipToImageBuffer(const FloatRect & rect,const ImageBuffer * imageBuffer)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
addInnerRoundedRectClip(const IntRect & rect,int thickness)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
concatCTM(const AffineTransform & transformation)453 void GraphicsContext::concatCTM(const AffineTransform& transformation)
454 {
455 if (paintingDisabled())
456 return;
457
458 m_data->concatTransformation(transformation);
459 }
460
setCTM(const AffineTransform & transformation)461 void GraphicsContext::setCTM(const AffineTransform& transformation)
462 {
463 if (paintingDisabled())
464 return;
465
466 m_data->setTransformation(transformation);
467 }
468
setURLForRect(const KURL & link,const IntRect & destRect)469 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
470 {
471 notImplemented();
472 UNUSED_PARAM(link);
473 UNUSED_PARAM(destRect);
474 }
475
setPlatformStrokeColor(const Color & color,ColorSpace colorSpace)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
setPlatformStrokeStyle(StrokeStyle strokeStyle)486 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
487 {
488 if (paintingDisabled())
489 return;
490
491 m_data->setStrokeStyle(strokeStyle);
492 }
493
setPlatformStrokeThickness(float thickness)494 void GraphicsContext::setPlatformStrokeThickness(float thickness)
495 {
496 if (paintingDisabled())
497 return;
498
499 m_data->setStrokeThickness(thickness);
500 }
501
setPlatformFillColor(const Color & color,ColorSpace colorSpace)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
setPlatformShouldAntialias(bool enable)512 void GraphicsContext::setPlatformShouldAntialias(bool enable)
513 {
514 if (paintingDisabled())
515 return;
516
517 m_data->setAntialiasingEnabled(enable);
518 }
519
setImageInterpolationQuality(InterpolationQuality)520 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
521 {
522 notImplemented();
523 }
524
imageInterpolationQuality() const525 InterpolationQuality GraphicsContext::imageInterpolationQuality() const
526 {
527 notImplemented();
528 return InterpolationDefault;
529 }
530
531 }
532