2 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008-2009 Torch Mobile, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 #ifndef GraphicsContext_h
28 #define GraphicsContext_h
30 #include "ColorSpace.h"
31 #include "DashArray.h"
32 #include "FloatRect.h"
36 #include "ImageOrientation.h"
39 #include <wtf/Noncopyable.h>
40 #include <wtf/PassOwnPtr.h>
43 typedef struct CGContext PlatformGraphicsContext;
46 class PlatformContextCairo;
48 typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
49 #elif PLATFORM(OPENVG)
53 typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
59 typedef QPainter PlatformGraphicsContext;
64 // wxGraphicsContext allows us to support Path, etc.
65 // but on some platforms, e.g. Linux, it requires fairly
68 // On OS X, wxGCDC is just a typedef for wxDC, so use wxDC explicitly to make
72 typedef wxDC PlatformGraphicsContext;
74 typedef wxGCDC PlatformGraphicsContext;
77 typedef wxWindowDC PlatformGraphicsContext;
81 class PlatformContextSkia;
82 typedef PlatformContextSkia GraphicsContextPlatformPrivate;
84 typedef WebCore::PlatformContextSkia PlatformGraphicsContext;
86 typedef struct HDC__ PlatformGraphicsContext;
88 typedef void PlatformGraphicsContext;
92 #include "DIBPixelData.h"
93 typedef struct HDC__* HDC;
95 // UInt8 is defined in CoreFoundation/CFBase.h
96 typedef unsigned char UInt8;
100 #if PLATFORM(QT) && OS(WINDOWS)
106 #if OS(WINCE) && !PLATFORM(QT)
108 class SimpleFontData;
112 const int cMisspellingLineThickness = 3;
113 const int cMisspellingLinePatternWidth = 4;
114 const int cMisspellingLinePatternGapWidth = 1;
116 class AffineTransform;
120 class GraphicsContextPlatformPrivate;
126 class GraphicsContext3D;
128 class TransformationMatrix;
130 enum TextDrawingMode {
131 TextModeInvisible = 0,
132 TextModeFill = 1 << 0,
133 TextModeStroke = 1 << 1,
134 TextModeClip = 1 << 2
136 typedef unsigned TextDrawingModeFlags;
145 enum InterpolationQuality {
146 InterpolationDefault,
153 struct GraphicsContextState {
154 GraphicsContextState()
156 #if ENABLE(TIZEN_CANVAS_2D_LINE_JOIN)
157 , lineJoin(MiterJoin)
160 , textDrawingMode(TextModeFill)
161 , strokeColor(Color::black)
162 , fillColor(Color::black)
163 , strokeStyle(SolidStroke)
164 , fillRule(RULE_NONZERO)
165 , strokeColorSpace(ColorSpaceDeviceRGB)
166 , fillColorSpace(ColorSpaceDeviceRGB)
167 , shadowColorSpace(ColorSpaceDeviceRGB)
168 , compositeOperator(CompositeSourceOver)
169 , shouldAntialias(true)
170 , shouldSmoothFonts(true)
171 , paintingDisabled(false)
172 , shadowsIgnoreTransforms(false)
174 // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
175 // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
176 , shadowsUseLegacyRadius(false)
181 RefPtr<Gradient> strokeGradient;
182 RefPtr<Pattern> strokePattern;
184 RefPtr<Gradient> fillGradient;
185 RefPtr<Pattern> fillPattern;
187 FloatSize shadowOffset;
189 float strokeThickness;
190 #if ENABLE(TIZEN_CANVAS_2D_LINE_JOIN)
195 TextDrawingModeFlags textDrawingMode;
201 StrokeStyle strokeStyle;
204 ColorSpace strokeColorSpace;
205 ColorSpace fillColorSpace;
206 ColorSpace shadowColorSpace;
208 CompositeOperator compositeOperator;
210 bool shouldAntialias : 1;
211 bool shouldSmoothFonts : 1;
212 bool paintingDisabled : 1;
213 bool shadowsIgnoreTransforms : 1;
215 bool shadowsUseLegacyRadius : 1;
219 class GraphicsContext {
220 WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
222 GraphicsContext(PlatformGraphicsContext*);
225 #if !OS(WINCE) || PLATFORM(QT)
226 PlatformGraphicsContext* platformContext() const;
229 float strokeThickness() const;
230 void setStrokeThickness(float);
231 #if ENABLE(TIZEN_CANVAS_2D_LINE_JOIN)
232 void setPlatformLineJoin(LineJoin);
234 StrokeStyle strokeStyle() const;
235 void setStrokeStyle(StrokeStyle);
236 Color strokeColor() const;
237 ColorSpace strokeColorSpace() const;
238 void setStrokeColor(const Color&, ColorSpace);
240 void setStrokePattern(PassRefPtr<Pattern>);
241 Pattern* strokePattern() const;
243 void setStrokeGradient(PassRefPtr<Gradient>);
244 Gradient* strokeGradient() const;
246 WindRule fillRule() const;
247 void setFillRule(WindRule);
248 Color fillColor() const;
249 ColorSpace fillColorSpace() const;
250 void setFillColor(const Color&, ColorSpace);
252 void setFillPattern(PassRefPtr<Pattern>);
253 Pattern* fillPattern() const;
255 void setFillGradient(PassRefPtr<Gradient>);
256 Gradient* fillGradient() const;
258 void setShadowsIgnoreTransforms(bool);
259 bool shadowsIgnoreTransforms() const;
261 void setShouldAntialias(bool);
262 bool shouldAntialias() const;
264 void setShouldSmoothFonts(bool);
265 bool shouldSmoothFonts() const;
267 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING) || ENABLE(TIZEN_CANVAS_SURFACE_LOCKING)
268 void setState(const GraphicsContextState&);
270 const GraphicsContextState& state() const;
273 void applyStrokePattern();
274 void applyFillPattern();
275 void drawPath(const Path&);
277 void drawNativeImage(NativeImagePtr, const FloatSize& selfSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, ImageOrientation = DefaultImageOrientation);
279 // Allow font smoothing (LCD antialiasing). Not part of the graphics state.
280 void setAllowsFontSmoothing(bool);
282 void setIsCALayerContext(bool);
283 bool isCALayerContext() const;
285 void setIsAcceleratedContext(bool);
287 bool isAcceleratedContext() const;
292 // These draw methods will do both stroking and filling.
293 // FIXME: ...except drawRect(), which fills properly but always strokes
294 // using a 1-pixel stroke inset from the rect borders (of the correct
296 void drawRect(const IntRect&);
297 void drawLine(const IntPoint&, const IntPoint&);
298 void drawEllipse(const IntRect&);
299 void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
301 void fillPath(const Path&);
302 void strokePath(const Path&);
304 void fillEllipse(const FloatRect&);
305 void strokeEllipse(const FloatRect&);
307 // Arc drawing (used by border-radius in CSS) just supports stroking at the moment.
308 void strokeArc(const IntRect&, int startAngle, int angleSpan);
310 void fillRect(const FloatRect&);
311 void fillRect(const FloatRect&, const Color&, ColorSpace);
312 void fillRect(const FloatRect&, Generator&);
313 void fillRect(const FloatRect&, const Color&, ColorSpace, CompositeOperator);
314 void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&, ColorSpace);
315 void fillRoundedRect(const RoundedRect&, const Color&, ColorSpace);
316 void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&, ColorSpace);
318 void clearRect(const FloatRect&);
320 void strokeRect(const FloatRect&, float lineWidth);
322 void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
323 void drawImage(Image*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
324 void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
325 void drawImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
326 void drawImage(Image*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
327 CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
328 void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
329 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
330 void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect,
331 const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
332 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
334 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
335 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
336 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver);
337 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
338 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
339 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
341 void setImageInterpolationQuality(InterpolationQuality);
342 InterpolationQuality imageInterpolationQuality() const;
344 void clip(const IntRect&);
345 void clip(const FloatRect&);
346 void addRoundedRectClip(const RoundedRect&);
347 void addInnerRoundedRectClip(const IntRect&, int thickness);
348 void clipOut(const IntRect&);
349 void clipOutRoundedRect(const RoundedRect&);
350 void clipPath(const Path&, WindRule);
351 void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
352 void clipToImageBuffer(ImageBuffer*, const FloatRect&);
354 IntRect clipBounds() const;
356 TextDrawingModeFlags textDrawingMode() const;
357 void setTextDrawingMode(TextDrawingModeFlags);
359 void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
360 void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
361 void drawBidiText(const Font&, const TextRun&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
362 void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
366 RoundOriginAndDimensions
368 FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
370 void drawLineForText(const FloatPoint&, float width, bool printing);
371 enum DocumentMarkerLineStyle {
372 DocumentMarkerSpellingLineStyle,
373 DocumentMarkerGrammarLineStyle,
374 DocumentMarkerAutocorrectionReplacementLineStyle,
375 DocumentMarkerDictationAlternativesLineStyle
377 void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
379 bool paintingDisabled() const;
380 void setPaintingDisabled(bool);
382 bool updatingControlTints() const;
383 void setUpdatingControlTints(bool);
385 void beginTransparencyLayer(float opacity);
386 void endTransparencyLayer();
387 bool isInTransparencyLayer() const;
389 bool hasShadow() const;
390 void setShadow(const FloatSize&, float blur, const Color&, ColorSpace);
391 // Legacy shadow blur radius is used for canvas, and -webkit-box-shadow.
392 // It has different treatment of radii > 8px.
393 void setLegacyShadow(const FloatSize&, float blur, const Color&, ColorSpace);
395 bool getShadow(FloatSize&, float&, Color&, ColorSpace&) const;
398 void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
399 void drawFocusRing(const Path&, int width, int offset, const Color&);
401 void setLineCap(LineCap);
402 void setLineDash(const DashArray&, float dashOffset);
403 void setLineJoin(LineJoin);
404 void setMiterLimit(float);
406 void setAlpha(float);
408 void setCompositeOperation(CompositeOperator);
409 CompositeOperator compositeOperation() const;
411 void clip(const Path&);
413 // This clip function is used only by <canvas> code. It allows
414 // implementations to handle clipping on the canvas differently since
415 // the discipline is different.
416 void canvasClip(const Path&);
417 void clipOut(const Path&);
419 void scale(const FloatSize&);
420 void rotate(float angleInRadians);
421 void translate(const FloatSize& size) { translate(size.width(), size.height()); }
422 void translate(float x, float y);
424 void setURLForRect(const KURL&, const IntRect&);
426 void concatCTM(const AffineTransform&);
427 void setCTM(const AffineTransform&);
429 enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
430 AffineTransform getCTM(IncludeDeviceScale includeScale = PossiblyIncludeDeviceScale) const;
432 #if ENABLE(3D_RENDERING) && USE(TEXTURE_MAPPER)
433 // This is needed when using accelerated-compositing in software mode, like in TextureMapper.
434 void concat3DTransform(const TransformationMatrix&);
435 void set3DTransform(const TransformationMatrix&);
436 TransformationMatrix get3DTransform() const;
438 // Create an image buffer compatible with this context, with suitable resolution
439 // for drawing into the buffer and then into this context.
440 PassOwnPtr<ImageBuffer> createCompatibleBuffer(const IntSize&) const;
441 bool isCompatibleWithBuffer(ImageBuffer*) const;
443 // This function applies the device scale factor to the context, making the context capable of
444 // acting as a base-level context for a HiDPI environment.
445 void applyDeviceScaleFactor(float);
446 void platformApplyDeviceScaleFactor(float);
449 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
450 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in HDC should be the one handed back by getWindowsContext.
453 void setBitmap(PassRefPtr<SharedBitmap>);
454 const AffineTransform& affineTransform() const;
455 AffineTransform& affineTransform();
456 void resetAffineTransform();
457 void fillRect(const FloatRect&, const Gradient*);
458 void drawText(const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point);
459 void drawFrameControl(const IntRect& rect, unsigned type, unsigned state);
460 void drawFocusRect(const IntRect& rect);
461 void paintTextField(const IntRect& rect, unsigned state);
462 void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp);
463 void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize);
464 void drawIcon(HICON icon, const IntRect& dstRect, UINT flags);
465 void drawRoundCorner(bool newClip, RECT clipRect, RECT rectWin, HDC dc, int width, int height);
467 GraphicsContext(HDC, bool hasAlpha = false); // FIXME: To be removed.
469 // When set to true, child windows should be rendered into this context
470 // rather than allowing them just to render to the screen. Defaults to
472 // FIXME: This is a layering violation. GraphicsContext shouldn't know
473 // what a "window" is. It would be much more appropriate for this flag
474 // to be passed as a parameter alongside the GraphicsContext, but doing
475 // that would require lots of changes in cross-platform code that we
476 // aren't sure we want to make.
477 void setShouldIncludeChildWindows(bool);
478 bool shouldIncludeChildWindows() const;
480 class WindowsBitmap {
481 WTF_MAKE_NONCOPYABLE(WindowsBitmap);
483 WindowsBitmap(HDC, const IntSize&);
486 HDC hdc() const { return m_hdc; }
487 UInt8* buffer() const { return m_pixelData.buffer(); }
488 unsigned bufferLength() const { return m_pixelData.bufferLength(); }
489 const IntSize& size() const { return m_pixelData.size(); }
490 unsigned bytesPerRow() const { return m_pixelData.bytesPerRow(); }
491 unsigned short bitsPerPixel() const { return m_pixelData.bitsPerPixel(); }
492 const DIBPixelData& windowsDIB() const { return m_pixelData; }
497 DIBPixelData m_pixelData;
500 PassOwnPtr<WindowsBitmap> createWindowsBitmap(const IntSize&);
501 // The bitmap should be non-premultiplied.
502 void drawWindowsBitmap(WindowsBitmap*, const IntPoint&);
504 #else // PLATFORM(WIN)
505 bool shouldIncludeChildWindows() const { return false; }
506 #endif // PLATFORM(WIN)
507 #endif // OS(WINDOWS)
510 // This is needed because of a bug whereby getting an HDC from a GDI+ context
511 // loses the scale operations applied to the context.
512 FloatSize currentScale();
516 void pushTransparencyLayerInternal(const QRect&, qreal, QImage&);
517 void takeOwnershipOfPlatformContext();
521 ShadowBlur* shadowBlur();
525 GraphicsContext(cairo_t*);
529 void setGdkExposeEvent(GdkEventExpose*);
530 GdkWindow* gdkWindow() const;
531 GdkEventExpose* gdkExposeEvent() const;
534 static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
536 #if USE(CAIRO) && ENABLE(TIZEN_GRAPHICSCONTEXT_COLLECT_REGION)
537 void setCollectClipRegion(bool); //Enable or disable collect clip region operation for TransparencyLayer
538 void collectClipRegion(const IntRect& clipRect);
542 void platformInit(PlatformGraphicsContext*);
543 void platformDestroy();
545 #if PLATFORM(WIN) && !OS(WINCE)
546 void platformInit(HDC, bool hasAlpha = false);
549 void savePlatformState();
550 void restorePlatformState();
552 void setPlatformTextDrawingMode(TextDrawingModeFlags);
553 void setPlatformFont(const Font& font);
555 void setPlatformStrokeColor(const Color&, ColorSpace);
556 void setPlatformStrokeStyle(StrokeStyle);
557 void setPlatformStrokeThickness(float);
559 void setPlatformFillColor(const Color&, ColorSpace);
561 void setPlatformShouldAntialias(bool);
562 void setPlatformShouldSmoothFonts(bool);
564 void setPlatformShadow(const FloatSize&, float blur, const Color&, ColorSpace);
565 void clearPlatformShadow();
567 void setPlatformCompositeOperation(CompositeOperator);
569 void beginPlatformTransparencyLayer(float opacity);
570 void endPlatformTransparencyLayer();
571 static bool supportsTransparencyLayers();
573 void fillEllipseAsPath(const FloatRect&);
574 void strokeEllipseAsPath(const FloatRect&);
576 void platformFillEllipse(const FloatRect&);
577 void platformStrokeEllipse(const FloatRect&);
579 GraphicsContextPlatformPrivate* m_data;
581 GraphicsContextState m_state;
582 Vector<GraphicsContextState> m_stack;
583 bool m_updatingControlTints;
584 unsigned m_transparencyCount;
587 class GraphicsContextStateSaver {
589 GraphicsContextStateSaver(GraphicsContext& context, bool saveAndRestore = true)
591 , m_saveAndRestore(saveAndRestore)
593 if (m_saveAndRestore)
597 ~GraphicsContextStateSaver()
599 if (m_saveAndRestore)
605 ASSERT(!m_saveAndRestore);
607 m_saveAndRestore = true;
612 ASSERT(m_saveAndRestore);
614 m_saveAndRestore = false;
617 GraphicsContext* context() const { return &m_context; }
620 GraphicsContext& m_context;
621 bool m_saveAndRestore;
624 } // namespace WebCore
626 #endif // GraphicsContext_h