2011-01-30 Simon Fraser <simon.fraser@apple.com>
[WebKit-https.git] / Source / WebCore / platform / graphics / GraphicsContext.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3  * Copyright (C) 2008-2009 Torch Mobile, Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef GraphicsContext_h
28 #define GraphicsContext_h
29
30 #include "ColorSpace.h"
31 #include "DashArray.h"
32 #include "FloatRect.h"
33 #include "Gradient.h"
34 #include "Image.h"
35 #include "Path.h"
36 #include "Pattern.h"
37 #include <wtf/Noncopyable.h>
38 #include <wtf/PassOwnPtr.h>
39
40 #if PLATFORM(CG)
41 typedef struct CGContext PlatformGraphicsContext;
42 #elif PLATFORM(CAIRO)
43 namespace WebCore {
44 class ContextShadow;
45 }
46 typedef struct _cairo PlatformGraphicsContext;
47 #elif PLATFORM(OPENVG)
48 namespace WebCore {
49 class SurfaceOpenVG;
50 }
51 typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
52 #elif PLATFORM(QT)
53 #include <QPainter>
54 namespace WebCore {
55 class ContextShadow;
56 }
57 typedef QPainter PlatformGraphicsContext;
58 #elif PLATFORM(WX)
59 class wxGCDC;
60 class wxWindowDC;
61
62 // wxGraphicsContext allows us to support Path, etc.
63 // but on some platforms, e.g. Linux, it requires fairly
64 // new software.
65 #if USE(WXGC)
66 // On OS X, wxGCDC is just a typedef for wxDC, so use wxDC explicitly to make
67 // the linker happy.
68 #ifdef __APPLE__
69     class wxDC;
70     typedef wxDC PlatformGraphicsContext;
71 #else
72     typedef wxGCDC PlatformGraphicsContext;
73 #endif
74 #else
75     typedef wxWindowDC PlatformGraphicsContext;
76 #endif
77 #elif PLATFORM(SKIA)
78 namespace WebCore {
79 class PlatformContextSkia;
80 }
81 typedef WebCore::PlatformContextSkia PlatformGraphicsContext;
82 #elif PLATFORM(HAIKU)
83 class BView;
84 typedef BView PlatformGraphicsContext;
85 struct pattern;
86 #elif OS(WINCE)
87 typedef struct HDC__ PlatformGraphicsContext;
88 #else
89 typedef void PlatformGraphicsContext;
90 #endif
91
92 #if PLATFORM(WIN)
93 typedef struct HDC__* HDC;
94 #if !PLATFORM(CG)
95 // UInt8 is defined in CoreFoundation/CFBase.h
96 typedef unsigned char UInt8;
97 #endif
98 #endif
99
100 #if PLATFORM(QT) && defined(Q_WS_WIN)
101 #include <windows.h>
102 #endif
103
104 namespace WebCore {
105
106 #if OS(WINCE) && !PLATFORM(QT)
107     class SharedBitmap;
108     class SimpleFontData;
109     class GlyphBuffer;
110 #endif
111
112     const int cMisspellingLineThickness = 3;
113     const int cMisspellingLinePatternWidth = 4;
114     const int cMisspellingLinePatternGapWidth = 1;
115
116     class AffineTransform;
117     class DrawingBuffer;
118     class Font;
119     class Generator;
120     class GraphicsContextPlatformPrivate;
121     class ImageBuffer;
122     class IntRect;
123     class RoundedIntRect;
124     class KURL;
125     class SharedGraphicsContext3D;
126     class TextRun;
127
128     enum TextDrawingMode {
129         TextModeInvisible = 0,
130         TextModeFill      = 1 << 0,
131         TextModeStroke    = 1 << 1,
132         TextModeClip      = 1 << 2
133     };
134     typedef unsigned TextDrawingModeFlags;
135
136     enum StrokeStyle {
137         NoStroke,
138         SolidStroke,
139         DottedStroke,
140         DashedStroke
141     };
142
143     enum InterpolationQuality {
144         InterpolationDefault,
145         InterpolationNone,
146         InterpolationLow,
147         InterpolationMedium,
148         InterpolationHigh
149     };
150
151     struct GraphicsContextState {
152         GraphicsContextState()
153             : strokeThickness(0)
154             , shadowBlur(0)
155 #if PLATFORM(CAIRO)
156             , globalAlpha(1)
157 #endif
158             , textDrawingMode(TextModeFill)
159             , strokeColor(Color::black)
160             , fillColor(Color::black)
161             , strokeStyle(SolidStroke)
162             , fillRule(RULE_NONZERO)
163             , strokeColorSpace(ColorSpaceDeviceRGB)
164             , fillColorSpace(ColorSpaceDeviceRGB)
165             , shadowColorSpace(ColorSpaceDeviceRGB)
166             , compositeOperator(CompositeSourceOver)
167             , shouldAntialias(true)
168             , shouldSmoothFonts(true)
169             , paintingDisabled(false)
170             , shadowsIgnoreTransforms(false)
171         {
172         }
173
174         RefPtr<Gradient> strokeGradient;
175         RefPtr<Pattern> strokePattern;
176         
177         RefPtr<Gradient> fillGradient;
178         RefPtr<Pattern> fillPattern;
179
180         FloatSize shadowOffset;
181
182         float strokeThickness;
183         float shadowBlur;
184
185 #if PLATFORM(CAIRO)
186         float globalAlpha;
187 #endif
188         TextDrawingModeFlags textDrawingMode;
189
190         Color strokeColor;
191         Color fillColor;
192         Color shadowColor;
193
194         StrokeStyle strokeStyle;
195         WindRule fillRule;
196
197         ColorSpace strokeColorSpace;
198         ColorSpace fillColorSpace;
199         ColorSpace shadowColorSpace;
200
201         CompositeOperator compositeOperator;
202
203         bool shouldAntialias : 1;
204         bool shouldSmoothFonts : 1;
205         bool paintingDisabled : 1;
206         bool shadowsIgnoreTransforms : 1;
207     };
208
209     class GraphicsContext {
210         WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
211     public:
212         GraphicsContext(PlatformGraphicsContext*);
213         ~GraphicsContext();
214
215 #if !OS(WINCE) || PLATFORM(QT)
216         PlatformGraphicsContext* platformContext() const;
217 #endif
218
219         float strokeThickness() const;
220         void setStrokeThickness(float);
221         StrokeStyle strokeStyle() const;
222         void setStrokeStyle(StrokeStyle);
223         Color strokeColor() const;
224         ColorSpace strokeColorSpace() const;
225         void setStrokeColor(const Color&, ColorSpace);
226
227         void setStrokePattern(PassRefPtr<Pattern>);
228         Pattern* strokePattern() const;
229
230         void setStrokeGradient(PassRefPtr<Gradient>);
231         Gradient* strokeGradient() const;
232
233         WindRule fillRule() const;
234         void setFillRule(WindRule);
235         Color fillColor() const;
236         ColorSpace fillColorSpace() const;
237         void setFillColor(const Color&, ColorSpace);
238
239         void setFillPattern(PassRefPtr<Pattern>);
240         Pattern* fillPattern() const;
241
242         void setFillGradient(PassRefPtr<Gradient>);
243         Gradient* fillGradient() const;
244
245         void setShadowsIgnoreTransforms(bool);
246         bool shadowsIgnoreTransforms() const;
247
248         void setShouldAntialias(bool);
249         bool shouldAntialias() const;
250
251         void setShouldSmoothFonts(bool);
252         bool shouldSmoothFonts() const;
253
254         const GraphicsContextState& state() const;
255
256 #if PLATFORM(CG)
257         void applyStrokePattern();
258         void applyFillPattern();
259         void drawPath(const Path&);
260         
261         // Allow font smoothing (LCD antialiasing). Not part of the graphics state.
262         void setAllowsFontSmoothing(bool);
263 #endif
264
265         void save();
266         void restore();
267
268         // These draw methods will do both stroking and filling.
269         // FIXME: ...except drawRect(), which fills properly but always strokes
270         // using a 1-pixel stroke inset from the rect borders (of the correct
271         // stroke color).
272         void drawRect(const IntRect&);
273         void drawLine(const IntPoint&, const IntPoint&);
274         void drawEllipse(const IntRect&);
275         void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
276
277         void fillPath(const Path&);
278         void strokePath(const Path&);
279
280         // Arc drawing (used by border-radius in CSS) just supports stroking at the moment.
281         void strokeArc(const IntRect&, int startAngle, int angleSpan);
282
283         void fillRect(const FloatRect&);
284         void fillRect(const FloatRect&, const Color&, ColorSpace);
285         void fillRect(const FloatRect&, Generator&);
286         void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&, ColorSpace);
287         void fillRoundedRect(const RoundedIntRect&, const Color&, ColorSpace);
288
289         void clearRect(const FloatRect&);
290
291         void strokeRect(const FloatRect&, float lineWidth);
292
293         void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
294         void drawImage(Image*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
295         void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver);
296         void drawImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
297         void drawImage(Image*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
298                        CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
299         void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
300                        CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
301         void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect,
302                             Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
303                             CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
304
305         void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
306         void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
307         void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver);
308         void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
309         void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
310                              CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
311
312         void setImageInterpolationQuality(InterpolationQuality);
313         InterpolationQuality imageInterpolationQuality() const;
314
315         void clip(const FloatRect&);
316         void addRoundedRectClip(const RoundedIntRect&);
317         void addInnerRoundedRectClip(const IntRect&, int thickness);
318         void clipOut(const IntRect&);
319         void clipOutRoundedRect(const RoundedIntRect&);
320         void clipPath(const Path&, WindRule);
321         void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
322         void clipToImageBuffer(ImageBuffer*, const FloatRect&);
323         
324         IntRect clipBounds() const;
325
326         TextDrawingModeFlags textDrawingMode() const;
327         void setTextDrawingMode(TextDrawingModeFlags);
328
329         void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1);
330         void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1);
331         void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
332         void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
333
334         FloatRect roundToDevicePixels(const FloatRect&);
335
336         void drawLineForText(const IntPoint&, int width, bool printing);
337         enum TextCheckingLineStyle {
338             TextCheckingSpellingLineStyle,
339             TextCheckingGrammarLineStyle,
340             TextCheckingReplacementLineStyle
341         };
342         void drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle);
343
344         bool paintingDisabled() const;
345         void setPaintingDisabled(bool);
346
347         bool updatingControlTints() const;
348         void setUpdatingControlTints(bool);
349
350         void beginTransparencyLayer(float opacity);
351         void endTransparencyLayer();
352
353         bool hasShadow() const;
354         void setShadow(const FloatSize&, float blur, const Color&, ColorSpace);
355         bool getShadow(FloatSize&, float&, Color&, ColorSpace&) const;
356         void clearShadow();
357
358         void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
359         void drawFocusRing(const Path&, int width, int offset, const Color&);
360
361         void setLineCap(LineCap);
362         void setLineDash(const DashArray&, float dashOffset);
363         void setLineJoin(LineJoin);
364         void setMiterLimit(float);
365
366         void setAlpha(float);
367 #if PLATFORM(CAIRO)
368         float getAlpha();
369 #endif
370
371         void setCompositeOperation(CompositeOperator);
372         CompositeOperator compositeOperation() const;
373
374         void clip(const Path&);
375
376         // This clip function is used only by <canvas> code. It allows
377         // implementations to handle clipping on the canvas differently since
378         // the discipline is different.
379         void canvasClip(const Path&);
380         void clipOut(const Path&);
381
382         void scale(const FloatSize&);
383         void rotate(float angleInRadians);
384         void translate(const FloatSize& size) { translate(size.width(), size.height()); }
385         void translate(float x, float y);
386
387         void setURLForRect(const KURL&, const IntRect&);
388
389         void concatCTM(const AffineTransform&);
390         AffineTransform getCTM() const;
391
392 #if OS(WINCE) && !PLATFORM(QT)
393         void setBitmap(PassRefPtr<SharedBitmap>);
394         const AffineTransform& affineTransform() const;
395         AffineTransform& affineTransform();
396         void resetAffineTransform();
397         void fillRect(const FloatRect&, const Gradient*);
398         void drawText(const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point);
399         void drawFrameControl(const IntRect& rect, unsigned type, unsigned state);
400         void drawFocusRect(const IntRect& rect);
401         void paintTextField(const IntRect& rect, unsigned state);
402         void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp);
403         void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize);
404         void drawIcon(HICON icon, const IntRect& dstRect, UINT flags);
405         HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
406         void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true);    // The passed in HDC should be the one handed back by getWindowsContext.
407         void drawRoundCorner(bool newClip, RECT clipRect, RECT rectWin, HDC dc, int width, int height);
408 #elif PLATFORM(WIN)
409         GraphicsContext(HDC, bool hasAlpha = false); // FIXME: To be removed.
410         bool inTransparencyLayer() const;
411         HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
412         void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);    // The passed in HDC should be the one handed back by getWindowsContext.
413
414         // When set to true, child windows should be rendered into this context
415         // rather than allowing them just to render to the screen. Defaults to
416         // false.
417         // FIXME: This is a layering violation. GraphicsContext shouldn't know
418         // what a "window" is. It would be much more appropriate for this flag
419         // to be passed as a parameter alongside the GraphicsContext, but doing
420         // that would require lots of changes in cross-platform code that we
421         // aren't sure we want to make.
422         void setShouldIncludeChildWindows(bool);
423         bool shouldIncludeChildWindows() const;
424
425         class WindowsBitmap {
426             WTF_MAKE_NONCOPYABLE(WindowsBitmap);
427         public:
428             WindowsBitmap(HDC, IntSize);
429             ~WindowsBitmap();
430
431             HDC hdc() const { return m_hdc; }
432             UInt8* buffer() const { return m_bitmapBuffer; }
433             unsigned bufferLength() const { return m_bitmapBufferLength; }
434             IntSize size() const { return m_size; }
435             unsigned bytesPerRow() const { return m_bytesPerRow; }
436
437         private:
438             HDC m_hdc;
439             HBITMAP m_bitmap;
440             UInt8* m_bitmapBuffer;
441             unsigned m_bitmapBufferLength;
442             IntSize m_size;
443             unsigned m_bytesPerRow;
444         };
445
446         WindowsBitmap* createWindowsBitmap(IntSize);
447         // The bitmap should be non-premultiplied.
448         void drawWindowsBitmap(WindowsBitmap*, const IntPoint&);
449 #endif
450
451 #if (PLATFORM(QT) && defined(Q_WS_WIN)) || (PLATFORM(WX) && OS(WINDOWS))
452         HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
453         void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
454         bool shouldIncludeChildWindows() const { return false; }
455 #endif
456
457 #if PLATFORM(WX)
458         bool inTransparencyLayer() const { return false; }
459 #endif
460
461 #if PLATFORM(QT)
462         bool inTransparencyLayer() const;
463         void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask);
464         void takeOwnershipOfPlatformContext();
465 #endif
466
467 #if PLATFORM(QT) || PLATFORM(CAIRO)
468         ContextShadow* contextShadow();
469 #endif
470
471 #if PLATFORM(GTK)
472         void setGdkExposeEvent(GdkEventExpose*);
473         GdkWindow* gdkWindow() const;
474         GdkEventExpose* gdkExposeEvent() const;
475 #endif
476
477 #if PLATFORM(HAIKU)
478         pattern getHaikuStrokeStyle();
479 #endif
480
481         void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
482         void syncSoftwareCanvas();
483         void markDirtyRect(const IntRect&); // Hints that a portion of the backing store is dirty.
484
485     private:
486         void platformInit(PlatformGraphicsContext*);
487         void platformDestroy();
488
489 #if PLATFORM(WIN) && !OS(WINCE)
490         void platformInit(HDC, bool hasAlpha = false);
491 #endif
492
493         void savePlatformState();
494         void restorePlatformState();
495
496         void setPlatformTextDrawingMode(TextDrawingModeFlags);
497         void setPlatformFont(const Font& font);
498
499         void setPlatformStrokeColor(const Color&, ColorSpace);
500         void setPlatformStrokeStyle(StrokeStyle);
501         void setPlatformStrokeThickness(float);
502         void setPlatformStrokeGradient(Gradient*);
503         void setPlatformStrokePattern(Pattern*);
504
505         void setPlatformFillColor(const Color&, ColorSpace);
506         void setPlatformFillGradient(Gradient*);
507         void setPlatformFillPattern(Pattern*);
508
509         void setPlatformShouldAntialias(bool);
510         void setPlatformShouldSmoothFonts(bool);
511
512         void setPlatformShadow(const FloatSize&, float blur, const Color&, ColorSpace);
513         void clearPlatformShadow();
514
515         void setPlatformCompositeOperation(CompositeOperator);
516
517         static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
518
519         GraphicsContextPlatformPrivate* m_data;
520
521         GraphicsContextState m_state;
522         Vector<GraphicsContextState> m_stack;
523         bool m_updatingControlTints;
524     };
525
526 } // namespace WebCore
527
528 #endif // GraphicsContext_h
529