• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "config.h"
29 #include "GraphicsContext.h"
30 
31 #include "AffineTransform.h"
32 #include "Color.h"
33 #include "Font.h"
34 #include "FontData.h"
35 #include "NotImplemented.h"
36 #include "Path.h"
37 #include <wtf/text/CString.h>
38 #include <GraphicsDefs.h>
39 #include <Region.h>
40 #include <View.h>
41 #include <Window.h>
42 #include <stdio.h>
43 
44 
45 namespace WebCore {
46 
47 class GraphicsContextPlatformPrivate {
48 public:
49     GraphicsContextPlatformPrivate(BView* view);
50     ~GraphicsContextPlatformPrivate();
51 
52     BView* m_view;
53 };
54 
GraphicsContextPlatformPrivate(BView * view)55 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(BView* view)
56     : m_view(view)
57 {
58 }
59 
~GraphicsContextPlatformPrivate()60 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
61 {
62 }
63 
platformInit(PlatformGraphicsContext * context)64 void GraphicsContext::platformInit(PlatformGraphicsContext* context)
65 {
66     m_data = new GraphicsContextPlatformPrivate(context);
67     setPaintingDisabled(!context);
68 }
69 
platformDestroy()70 void GraphicsContext::platformDestroy()
71 {
72     delete m_data;
73 }
74 
platformContext() const75 PlatformGraphicsContext* GraphicsContext::platformContext() const
76 {
77     return m_data->m_view;
78 }
79 
savePlatformState()80 void GraphicsContext::savePlatformState()
81 {
82     m_data->m_view->PushState();
83 }
84 
restorePlatformState()85 void GraphicsContext::restorePlatformState()
86 {
87     m_data->m_view->PopState();
88 }
89 
90 // Draws a filled rectangle with a stroked border.
drawRect(const IntRect & rect)91 void GraphicsContext::drawRect(const IntRect& rect)
92 {
93     if (paintingDisabled())
94         return;
95 
96     m_data->m_view->FillRect(rect);
97     if (strokeStyle() != NoStroke)
98         m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
99 }
100 
101 // This is only used to draw borders.
drawLine(const IntPoint & point1,const IntPoint & point2)102 void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
103 {
104     if (paintingDisabled())
105         return;
106 
107     if (strokeStyle() == NoStroke)
108         return;
109 
110     m_data->m_view->StrokeLine(point1, point2, getHaikuStrokeStyle());
111 }
112 
113 // This method is only used to draw the little circles used in lists.
drawEllipse(const IntRect & rect)114 void GraphicsContext::drawEllipse(const IntRect& rect)
115 {
116     if (paintingDisabled())
117         return;
118 
119     m_data->m_view->FillEllipse(rect);
120     if (strokeStyle() != NoStroke)
121         m_data->m_view->StrokeEllipse(rect, getHaikuStrokeStyle());
122 }
123 
strokeArc(const IntRect & rect,int startAngle,int angleSpan)124 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
125 {
126     if (paintingDisabled())
127         return;
128 
129     m_data->m_view->StrokeArc(rect, startAngle, angleSpan, getHaikuStrokeStyle());
130 }
131 
strokePath(const Path &)132 void GraphicsContext::strokePath(const Path&)
133 {
134     notImplemented();
135 }
136 
drawConvexPolygon(size_t pointsLength,const FloatPoint * points,bool shouldAntialias)137 void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* points, bool shouldAntialias)
138 {
139     if (paintingDisabled())
140         return;
141 
142     BPoint bPoints[pointsLength];
143     for (size_t i = 0; i < pointsLength; i++)
144         bPoints[i] = points[i];
145 
146     m_data->m_view->FillPolygon(bPoints, pointsLength);
147     if (strokeStyle() != NoStroke)
148         // Stroke with low color
149         m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle());
150 }
151 
clipConvexPolygon(size_t numPoints,const FloatPoint * points,bool antialiased)152 void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased)
153 {
154     if (paintingDisabled())
155         return;
156 
157     if (numPoints <= 1)
158         return;
159 
160     // FIXME: IMPLEMENT!!
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     rgb_color oldColor = m_data->m_view->HighColor();
169     m_data->m_view->SetHighColor(color);
170     m_data->m_view->FillRect(rect);
171     m_data->m_view->SetHighColor(oldColor);
172 }
173 
fillRect(const FloatRect & rect)174 void GraphicsContext::fillRect(const FloatRect& rect)
175 {
176     if (paintingDisabled())
177         return;
178 }
179 
fillRoundedRect(const IntRect & rect,const IntSize & topLeft,const IntSize & topRight,const IntSize & bottomLeft,const IntSize & bottomRight,const Color & color,ColorSpace colorSpace)180 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
181 {
182     if (paintingDisabled() || !color.alpha())
183         return;
184 
185     notImplemented();
186     // FIXME: A simple implementation could just use FillRoundRect if all
187     // the sizes are the same, or even if they are not. Otherwise several
188     // FillRect and FillArc calls are needed.
189 }
190 
fillPath(const Path &)191 void GraphicsContext::fillPath(const Path&)
192 {
193     notImplemented();
194 }
195 
clip(const FloatRect & rect)196 void GraphicsContext::clip(const FloatRect& rect)
197 {
198     if (paintingDisabled())
199         return;
200 
201     BRegion region(rect);
202     m_data->m_view->ConstrainClippingRegion(&region);
203 }
204 
drawFocusRing(const Path & path,int width,int offset,const Color & color)205 void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color)
206 {
207     // FIXME: implement
208 }
209 
drawFocusRing(const Vector<IntRect> & rects,int,int,const Color & color)210 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
211 {
212     if (paintingDisabled())
213         return;
214 
215     unsigned rectCount = rects.size();
216 
217     // FIXME: maybe we should implement this with BShape?
218 
219     if (rects.size() > 1) {
220         BRegion    region;
221         for (int i = 0; i < rectCount; ++i)
222             region.Include(BRect(rects[i]));
223 
224         m_data->m_view->SetHighColor(color);
225         m_data->m_view->StrokeRect(region.Frame(), B_MIXED_COLORS);
226     }
227 }
228 
drawLineForText(const IntPoint & origin,int width,bool printing)229 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
230 {
231     if (paintingDisabled())
232         return;
233 
234     IntPoint endPoint = origin + IntSize(width, 0);
235     drawLine(origin, endPoint);
236 }
237 
drawLineForTextChecking(const IntPoint &,int width,TextCheckingLineStyle)238 void GraphicsContext::drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle)
239 {
240     if (paintingDisabled())
241         return;
242 
243     notImplemented();
244 }
245 
roundToDevicePixels(const FloatRect & rect)246 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
247 {
248     notImplemented();
249     return rect;
250 }
251 
beginTransparencyLayer(float opacity)252 void GraphicsContext::beginTransparencyLayer(float opacity)
253 {
254     if (paintingDisabled())
255         return;
256 
257     notImplemented();
258 }
259 
endTransparencyLayer()260 void GraphicsContext::endTransparencyLayer()
261 {
262     if (paintingDisabled())
263         return;
264 
265     notImplemented();
266 }
267 
clearRect(const FloatRect & rect)268 void GraphicsContext::clearRect(const FloatRect& rect)
269 {
270     if (paintingDisabled())
271         return;
272 
273     notImplemented();
274 }
275 
strokeRect(const FloatRect & rect,float width)276 void GraphicsContext::strokeRect(const FloatRect& rect, float width)
277 {
278     if (paintingDisabled())
279         return;
280 
281     float oldSize = m_data->m_view->PenSize();
282     m_data->m_view->SetPenSize(width);
283     m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
284     m_data->m_view->SetPenSize(oldSize);
285 }
286 
setLineCap(LineCap lineCap)287 void GraphicsContext::setLineCap(LineCap lineCap)
288 {
289     if (paintingDisabled())
290         return;
291 
292     cap_mode mode = B_BUTT_CAP;
293     switch (lineCap) {
294     case RoundCap:
295         mode = B_ROUND_CAP;
296         break;
297     case SquareCap:
298         mode = B_SQUARE_CAP;
299         break;
300     case ButtCap:
301     default:
302         break;
303     }
304 
305     m_data->m_view->SetLineMode(mode, m_data->m_view->LineJoinMode(), m_data->m_view->LineMiterLimit());
306 }
307 
setLineJoin(LineJoin lineJoin)308 void GraphicsContext::setLineJoin(LineJoin lineJoin)
309 {
310     if (paintingDisabled())
311         return;
312 
313     join_mode mode = B_MITER_JOIN;
314     switch (lineJoin) {
315     case RoundJoin:
316         mode = B_ROUND_JOIN;
317         break;
318     case BevelJoin:
319         mode = B_BEVEL_JOIN;
320         break;
321     case MiterJoin:
322     default:
323         break;
324     }
325 
326     m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), mode, m_data->m_view->LineMiterLimit());
327 }
328 
setMiterLimit(float limit)329 void GraphicsContext::setMiterLimit(float limit)
330 {
331     if (paintingDisabled())
332         return;
333 
334     m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), m_data->m_view->LineJoinMode(), limit);
335 }
336 
setAlpha(float opacity)337 void GraphicsContext::setAlpha(float opacity)
338 {
339     if (paintingDisabled())
340         return;
341 
342     notImplemented();
343 }
344 
setPlatformCompositeOperation(CompositeOperator op)345 void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
346 {
347     if (paintingDisabled())
348         return;
349 
350     drawing_mode mode = B_OP_COPY;
351     switch (op) {
352     case CompositeClear:
353     case CompositeCopy:
354         // Use the default above
355         break;
356     case CompositeSourceOver:
357         mode = B_OP_OVER;
358         break;
359     default:
360         printf("GraphicsContext::setPlatformCompositeOperation: Unsupported composite operation %s\n",
361                 compositeOperatorName(op).utf8().data());
362     }
363     m_data->m_view->SetDrawingMode(mode);
364 }
365 
clip(const Path & path)366 void GraphicsContext::clip(const Path& path)
367 {
368     if (paintingDisabled())
369         return;
370 
371     m_data->m_view->ConstrainClippingRegion(path.platformPath());
372 }
373 
canvasClip(const Path & path)374 void GraphicsContext::canvasClip(const Path& path)
375 {
376     clip(path);
377 }
378 
clipOut(const Path & path)379 void GraphicsContext::clipOut(const Path& path)
380 {
381     if (paintingDisabled())
382         return;
383 
384     notImplemented();
385 }
386 
clipToImageBuffer(const FloatRect &,const ImageBuffer *)387 void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
388 {
389     notImplemented();
390 }
391 
getCTM() const392 AffineTransform GraphicsContext::getCTM() const
393 {
394     notImplemented();
395     return AffineTransform();
396 }
397 
translate(float x,float y)398 void GraphicsContext::translate(float x, float y)
399 {
400     if (paintingDisabled())
401         return;
402 
403     notImplemented();
404 }
405 
rotate(float radians)406 void GraphicsContext::rotate(float radians)
407 {
408     if (paintingDisabled())
409         return;
410 
411     notImplemented();
412 }
413 
scale(const FloatSize & size)414 void GraphicsContext::scale(const FloatSize& size)
415 {
416     if (paintingDisabled())
417         return;
418 
419     notImplemented();
420 }
421 
clipOut(const IntRect & rect)422 void GraphicsContext::clipOut(const IntRect& rect)
423 {
424     if (paintingDisabled())
425         return;
426 
427     notImplemented();
428 }
429 
addInnerRoundedRectClip(const IntRect & rect,int thickness)430 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
431 {
432     if (paintingDisabled())
433         return;
434 
435     notImplemented();
436 }
437 
concatCTM(const AffineTransform & transform)438 void GraphicsContext::concatCTM(const AffineTransform& transform)
439 {
440     if (paintingDisabled())
441         return;
442 
443     notImplemented();
444 }
445 
setCTM(const AffineTransform & transform)446 void GraphicsContext::setCTM(const AffineTransform& transform)
447 {
448     if (paintingDisabled())
449         return;
450 
451     notImplemented();
452 }
453 
setPlatformShouldAntialias(bool enable)454 void GraphicsContext::setPlatformShouldAntialias(bool enable)
455 {
456     if (paintingDisabled())
457         return;
458 
459     notImplemented();
460 }
461 
setImageInterpolationQuality(InterpolationQuality)462 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
463 {
464 }
465 
imageInterpolationQuality() const466 InterpolationQuality GraphicsContext::imageInterpolationQuality() const
467 {
468     notImplemented();
469     return InterpolationDefault;
470 }
471 
setURLForRect(const KURL & link,const IntRect & destRect)472 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
473 {
474     notImplemented();
475 }
476 
setPlatformFont(const Font & font)477 void GraphicsContext::setPlatformFont(const Font& font)
478 {
479     m_data->m_view->SetFont(font.primaryFont()->platformData().font());
480 }
481 
setPlatformStrokeColor(const Color & color,ColorSpace colorSpace)482 void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
483 {
484     if (paintingDisabled())
485         return;
486 
487     m_data->m_view->SetHighColor(color);
488 }
489 
getHaikuStrokeStyle()490 pattern GraphicsContext::getHaikuStrokeStyle()
491 {
492     switch (strokeStyle()) {
493     case SolidStroke:
494         return B_SOLID_HIGH;
495         break;
496     case DottedStroke:
497         return B_MIXED_COLORS;
498         break;
499     case DashedStroke:
500         // FIXME: use a better dashed stroke!
501         notImplemented();
502         return B_MIXED_COLORS;
503         break;
504     default:
505         return B_SOLID_LOW;
506         break;
507     }
508 }
509 
setPlatformStrokeStyle(StrokeStyle strokeStyle)510 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
511 {
512     // FIXME: see getHaikuStrokeStyle.
513     notImplemented();
514 }
515 
setPlatformStrokeThickness(float thickness)516 void GraphicsContext::setPlatformStrokeThickness(float thickness)
517 {
518     if (paintingDisabled())
519         return;
520 
521     m_data->m_view->SetPenSize(thickness);
522 }
523 
setPlatformFillColor(const Color & color,ColorSpace colorSpace)524 void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
525 {
526     if (paintingDisabled())
527         return;
528 
529     m_data->m_view->SetHighColor(color);
530 }
531 
clearPlatformShadow()532 void GraphicsContext::clearPlatformShadow()
533 {
534     notImplemented();
535 }
536 
setPlatformShadow(FloatSize const &,float,Color const &,ColorSpace)537 void GraphicsContext::setPlatformShadow(FloatSize const&, float, Color const&, ColorSpace)
538 {
539     notImplemented();
540 }
541 
542 } // namespace WebCore
543 
544