Bug 460926 A11y hierachy is broken on Ubuntu 8.10 (GNOME 2.24), r=Evan.Yan sr=roc
[wine-gecko.git] / gfx / thebes / public / gfxContext.h
blob8362505a9d33d89e9f77a795a22541002b89bb53
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Oracle Corporation code.
17 * The Initial Developer of the Original Code is Oracle Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Stuart Parmenter <pavlov@pavlov.net>
23 * Vladimir Vukicevic <vladimir@pobox.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef GFX_CONTEXT_H
40 #define GFX_CONTEXT_H
42 #include "gfxTypes.h"
44 #include "gfxASurface.h"
45 #include "gfxColor.h"
46 #include "gfxPoint.h"
47 #include "gfxRect.h"
48 #include "gfxMatrix.h"
49 #include "gfxPattern.h"
50 #include "gfxPath.h"
52 typedef struct _cairo cairo_t;
54 /**
55 * This is the main class for doing actual drawing. It is initialized using
56 * a surface and can be drawn on. It manages various state information like
57 * a current transformation matrix (CTM), a current path, current color,
58 * etc.
60 * All drawing happens by creating a path and then stroking or filling it.
61 * The functions like Rectangle and Arc do not do any drawing themselves.
62 * When a path is drawn (stroked or filled), it is filled/stroked with a
63 * pattern set by SetPattern, SetColor or SetSource.
65 * Note that the gfxContext takes coordinates in device pixels,
66 * as opposed to app units.
68 class THEBES_API gfxContext {
69 THEBES_INLINE_DECL_REFCOUNTING(gfxContext)
71 public:
72 /**
73 * Initialize this context from a surface.
75 gfxContext(gfxASurface *surface);
76 ~gfxContext();
78 /**
79 * Return the surface that this gfxContext was created with
81 gfxASurface *OriginalSurface();
83 /**
84 * Return the current transparency group target, if any, along
85 * with its device offsets from the top. If no group is
86 * active, returns the surface the gfxContext was created with,
87 * and 0,0 in dx,dy.
89 already_AddRefed<gfxASurface> CurrentSurface(gfxFloat *dx, gfxFloat *dy);
90 already_AddRefed<gfxASurface> CurrentSurface() {
91 return CurrentSurface(NULL, NULL);
94 /**
95 * Return the raw cairo_t object.
96 * XXX this should go away at some point.
98 cairo_t *GetCairo() { return mCairo; }
101 * Returns true if the cairo context is in an error state.
103 PRBool HasError();
106 ** State
108 // XXX document exactly what bits are saved
109 void Save();
110 void Restore();
113 ** Paths & Drawing
117 * Stroke the current path using the current settings (such as line
118 * width and color).
119 * A path is set up using functions such as Line, Rectangle and Arc.
121 * Does not consume the current path.
123 void Stroke();
125 * Fill the current path according to the current settings.
127 * Does not consume the current path.
129 void Fill();
132 * Forgets the current path.
134 void NewPath();
137 * Closes the path, i.e. connects the last drawn point to the first one.
139 * Filling a path will implicitly close it.
141 void ClosePath();
144 * Copies the current path and returns the copy.
146 already_AddRefed<gfxPath> CopyPath() const;
149 * Appends the given path to the current path.
151 void AppendPath(gfxPath* path);
154 * Moves the pen to a new point without drawing a line.
156 void MoveTo(const gfxPoint& pt);
159 * Creates a new subpath starting at the current point.
160 * Equivalent to MoveTo(CurrentPoint()).
162 void NewSubPath();
165 * Returns the current point in the current path.
167 gfxPoint CurrentPoint() const;
170 * Draws a line from the current point to pt.
172 * @see MoveTo
174 void LineTo(const gfxPoint& pt);
177 * Draws a cubic Bézier curve with control points pt1, pt2 and pt3.
179 void CurveTo(const gfxPoint& pt1, const gfxPoint& pt2, const gfxPoint& pt3);
182 * Draws a quadratic Bézier curve with control points pt1, pt2 and pt3.
184 void QuadraticCurveTo(const gfxPoint& pt1, const gfxPoint& pt2);
187 * Draws a clockwise arc (i.e. a circle segment).
188 * @param center The center of the circle
189 * @param radius The radius of the circle
190 * @param angle1 Starting angle for the segment
191 * @param angle2 Ending angle
193 void Arc(const gfxPoint& center, gfxFloat radius,
194 gfxFloat angle1, gfxFloat angle2);
197 * Draws a counter-clockwise arc (i.e. a circle segment).
198 * @param center The center of the circle
199 * @param radius The radius of the circle
200 * @param angle1 Starting angle for the segment
201 * @param angle2 Ending angle
204 void NegativeArc(const gfxPoint& center, gfxFloat radius,
205 gfxFloat angle1, gfxFloat angle2);
207 // path helpers
209 * Draws a line from start to end.
211 void Line(const gfxPoint& start, const gfxPoint& end); // XXX snapToPixels option?
214 * Draws the rectangle given by rect.
215 * @param snapToPixels ?
217 void Rectangle(const gfxRect& rect, PRBool snapToPixels = PR_FALSE);
220 * Draw an ellipse at the center corner with the given dimensions.
221 * It extends dimensions.width / 2.0 in the horizontal direction
222 * from the center, and dimensions.height / 2.0 in the vertical
223 * direction.
225 void Ellipse(const gfxPoint& center, const gfxSize& dimensions);
228 * Draw a polygon from the given points
230 void Polygon(const gfxPoint *points, PRUint32 numPoints);
233 * Draw a rounded rectangle, with the given outer rect and
234 * corners. The corners specify the radii of the two axes of an
235 * ellipse (the horizontal and vertical directions given by the
236 * width and height, respectively). By default the ellipse is
237 * drawn in a clockwise direction; if draw_clockwise is PR_FALSE,
238 * then it's drawn counterclockwise.
240 void RoundedRectangle(const gfxRect& rect,
241 const gfxCornerSizes& corners,
242 PRBool draw_clockwise = PR_TRUE);
245 ** Transformation Matrix manipulation
249 * Adds a translation to the current matrix. This translation takes place
250 * before the previously set transformations.
252 void Translate(const gfxPoint& pt);
255 * Adds a scale to the current matrix. This scaling takes place before the
256 * previously set transformations.
258 void Scale(gfxFloat x, gfxFloat y);
261 * Adds a rotation around the origin to the current matrix. This rotation
262 * takes place before the previously set transformations.
264 * @param angle The angle in radians.
266 void Rotate(gfxFloat angle);
269 * Post-multiplies 'other' onto the current CTM, i.e. this
270 * matrix's transformation will take place before the previously set
271 * transformations.
273 void Multiply(const gfxMatrix& other);
276 * Replaces the current transformation matrix with matrix.
278 void SetMatrix(const gfxMatrix& matrix);
281 * Sets the transformation matrix to the identity matrix.
283 void IdentityMatrix();
286 * Returns the current transformation matrix.
288 gfxMatrix CurrentMatrix() const;
291 * Converts a point from device to user coordinates using the inverse
292 * transformation matrix.
294 gfxPoint DeviceToUser(const gfxPoint& point) const;
297 * Converts a size from device to user coordinates. This does not apply
298 * translation components of the matrix.
300 gfxSize DeviceToUser(const gfxSize& size) const;
303 * Converts a rectangle from device to user coordinates; this has the
304 * same effect as using DeviceToUser on both the rectangle's point and
305 * size.
307 gfxRect DeviceToUser(const gfxRect& rect) const;
310 * Converts a point from user to device coordinates using the inverse
311 * transformation matrix.
313 gfxPoint UserToDevice(const gfxPoint& point) const;
316 * Converts a size from user to device coordinates. This does not apply
317 * translation components of the matrix.
319 gfxSize UserToDevice(const gfxSize& size) const;
322 * Converts a rectangle from user to device coordinates; this has the
323 * same effect as using UserToDevice on both the rectangle's point and
324 * size.
326 gfxRect UserToDevice(const gfxRect& rect) const;
329 * Takes the given rect and tries to align it to device pixels. If
330 * this succeeds, the method will return PR_TRUE, and the rect will
331 * be in device coordinates (already transformed by the CTM). If it
332 * fails, the method will return PR_FALSE, and the rect will not be
333 * changed.
335 * If ignoreScale is PR_TRUE, then snapping will take place even if
336 * the CTM has a scale applied. Snapping never takes place if
337 * there is a rotation in the CTM.
339 PRBool UserToDevicePixelSnapped(gfxRect& rect, PRBool ignoreScale = PR_FALSE) const;
342 * Takes the given point and tries to align it to device pixels. If
343 * this succeeds, the method will return PR_TRUE, and the point will
344 * be in device coordinates (already transformed by the CTM). If it
345 * fails, the method will return PR_FALSE, and the point will not be
346 * changed.
348 * If ignoreScale is PR_TRUE, then snapping will take place even if
349 * the CTM has a scale applied. Snapping never takes place if
350 * there is a rotation in the CTM.
352 PRBool UserToDevicePixelSnapped(gfxPoint& pt, PRBool ignoreScale = PR_FALSE) const;
355 * Attempts to pixel snap the rectangle, add it to the current
356 * path, and to set pattern as the current painting source. This
357 * should be used for drawing filled pixel-snapped rectangles (like
358 * images), because the CTM at the time of the SetPattern call needs
359 * to have a snapped translation, or you get smeared images.
361 void PixelSnappedRectangleAndSetPattern(const gfxRect& rect, gfxPattern *pattern);
364 ** Painting sources
368 * Set a solid color to use for drawing. This color is in the device color space
369 * and is not transformed.
371 void SetDeviceColor(const gfxRGBA& c);
374 * Gets the current color. It's returned in the device color space.
375 * returns PR_FALSE if there is something other than a color
376 * set as the current source (pattern, surface, etc)
378 PRBool GetDeviceColor(gfxRGBA& c);
381 * Set a solid color in the sRGB color space to use for drawing.
382 * If CMS is not enabled, the color is treated as a device-space color
383 * and this call is identical to SetDeviceColor().
385 void SetColor(const gfxRGBA& c);
388 * Uses a surface for drawing. This is a shorthand for creating a
389 * pattern and setting it.
391 * @param offset from the source surface, to use only part of it.
392 * May need to make it negative.
394 void SetSource(gfxASurface *surface, const gfxPoint& offset = gfxPoint(0.0, 0.0));
397 * Uses a pattern for drawing.
399 void SetPattern(gfxPattern *pattern);
402 * Get the source pattern (solid color, normal pattern, surface, etc)
404 already_AddRefed<gfxPattern> GetPattern();
407 ** Painting
410 * Paints the current source surface/pattern everywhere in the current
411 * clip region.
413 void Paint(gfxFloat alpha = 1.0);
416 ** Painting with a Mask
419 * Like Paint, except that it only draws the source where pattern is
420 * non-transparent.
422 void Mask(gfxPattern *pattern);
425 * Shorthand for creating a pattern and calling the pattern-taking
426 * variant of Mask.
428 void Mask(gfxASurface *surface, const gfxPoint& offset = gfxPoint(0.0, 0.0));
431 ** Shortcuts
435 * Creates a new path with a rectangle from 0,0 to size.w,size.h
436 * and calls cairo_fill.
438 void DrawSurface(gfxASurface *surface, const gfxSize& size);
441 ** Line Properties
444 typedef enum {
445 gfxLineSolid,
446 gfxLineDashed,
447 gfxLineDotted
448 } gfxLineType;
450 void SetDash(gfxLineType ltype);
451 void SetDash(gfxFloat *dashes, int ndash, gfxFloat offset);
452 //void getDash() const;
455 * Sets the line width that's used for line drawing.
457 void SetLineWidth(gfxFloat width);
460 * Returns the currently set line width.
462 * @see SetLineWidth
464 gfxFloat CurrentLineWidth() const;
466 enum GraphicsLineCap {
467 LINE_CAP_BUTT,
468 LINE_CAP_ROUND,
469 LINE_CAP_SQUARE
472 * Sets the line caps, i.e. how line endings are drawn.
474 void SetLineCap(GraphicsLineCap cap);
475 GraphicsLineCap CurrentLineCap() const;
477 enum GraphicsLineJoin {
478 LINE_JOIN_MITER,
479 LINE_JOIN_ROUND,
480 LINE_JOIN_BEVEL
483 * Sets the line join, i.e. how the connection between two lines is
484 * drawn.
486 void SetLineJoin(GraphicsLineJoin join);
487 GraphicsLineJoin CurrentLineJoin() const;
489 void SetMiterLimit(gfxFloat limit);
490 gfxFloat CurrentMiterLimit() const;
493 ** Fill Properties
496 enum FillRule {
497 FILL_RULE_WINDING,
498 FILL_RULE_EVEN_ODD
500 void SetFillRule(FillRule rule);
501 FillRule CurrentFillRule() const;
504 ** Operators and Rendering control
507 // define enum for operators (clear, src, dst, etc)
508 enum GraphicsOperator {
509 OPERATOR_CLEAR,
510 OPERATOR_SOURCE,
512 OPERATOR_OVER,
513 OPERATOR_IN,
514 OPERATOR_OUT,
515 OPERATOR_ATOP,
517 OPERATOR_DEST,
518 OPERATOR_DEST_OVER,
519 OPERATOR_DEST_IN,
520 OPERATOR_DEST_OUT,
521 OPERATOR_DEST_ATOP,
523 OPERATOR_XOR,
524 OPERATOR_ADD,
525 OPERATOR_SATURATE
528 * Sets the operator used for all further drawing. The operator affects
529 * how drawing something will modify the destination. For example, the
530 * OVER operator will do alpha blending of source and destination, while
531 * SOURCE will replace the destination with the source.
533 * Note that if the flag FLAG_SIMPLIFY_OPERATORS is set on this
534 * gfxContext, the actual operator set might change for optimization
535 * purposes. Check the comments below around that flag.
537 void SetOperator(GraphicsOperator op);
538 GraphicsOperator CurrentOperator() const;
541 * MODE_ALIASED means that only pixels whose centers are in the drawn area
542 * should be modified, and they should be modified to take the value drawn
543 * at the pixel center.
545 enum AntialiasMode {
546 MODE_ALIASED,
547 MODE_COVERAGE
549 void SetAntialiasMode(AntialiasMode mode);
550 AntialiasMode CurrentAntialiasMode() const;
553 ** Clipping
557 * Clips all further drawing to the current path.
558 * This does not consume the current path.
560 void Clip();
563 * Undoes any clipping. Further drawings will only be restricted by the
564 * surface dimensions.
566 void ResetClip();
569 * Helper functions that will create a rect path and call Clip().
570 * Any current path will be destroyed by these functions!
572 void Clip(const gfxRect& rect); // will clip to a rect
575 * This will ensure that the surface actually has its clip set.
576 * Useful if you are doing native drawing.
578 void UpdateSurfaceClip();
581 * This will return the current bounds of the clip region.
583 gfxRect GetClipExtents();
586 * Groups
588 void PushGroup(gfxASurface::gfxContentType content = gfxASurface::CONTENT_COLOR);
589 already_AddRefed<gfxPattern> PopGroup();
590 void PopGroupToSource();
593 ** Hit Testing - check if given point is in the current path
595 PRBool PointInFill(const gfxPoint& pt);
596 PRBool PointInStroke(const gfxPoint& pt);
599 ** Extents - returns user space extent of current path
601 gfxRect GetUserPathExtent();
602 gfxRect GetUserFillExtent();
603 gfxRect GetUserStrokeExtent();
606 ** Obtaining a "flattened" path - path converted to all line segments
608 already_AddRefed<gfxFlattenedPath> GetFlattenedPath();
611 ** Flags
614 enum {
615 /* If this flag is set, operators other than CLEAR, SOURCE, or
616 * OVER will be converted to OVER before being sent to cairo.
618 * This is most useful with a printing surface, where
619 * operators such as ADD are used to avoid seams for on-screen
620 * display, but where such errors aren't noticable in print.
621 * This approach is currently used in border rendering.
623 * However, when printing complex renderings such as SVG,
624 * care should be taken to clear this flag.
626 FLAG_SIMPLIFY_OPERATORS = (1 << 0),
628 * When this flag is set, snapping to device pixels is disabled.
629 * It simply never does anything.
631 FLAG_DISABLE_SNAPPING = (1 << 1),
633 * When this flag is set, rendering through this context
634 * is destined to be (eventually) drawn on the screen. It can be
635 * useful to know this, for example so that windowed plugins are
636 * not unnecessarily rendered (since they will already appear
637 * on the screen, thanks to their windows).
639 FLAG_DESTINED_FOR_SCREEN = (1 << 2)
642 void SetFlag(PRInt32 aFlag) { mFlags |= aFlag; }
643 void ClearFlag(PRInt32 aFlag) { mFlags &= ~aFlag; }
644 PRInt32 GetFlags() const { return mFlags; }
646 private:
647 cairo_t *mCairo;
648 nsRefPtr<gfxASurface> mSurface;
649 PRInt32 mFlags;
654 * Sentry helper class for functions with multiple return points that need to
655 * call Save() on a gfxContext and have Restore() called automatically on the
656 * gfxContext before they return.
658 class THEBES_API gfxContextAutoSaveRestore
660 public:
661 gfxContextAutoSaveRestore() : mContext(nsnull) {}
663 gfxContextAutoSaveRestore(gfxContext *aContext) : mContext(aContext) {
664 mContext->Save();
667 ~gfxContextAutoSaveRestore() {
668 if (mContext) {
669 mContext->Restore();
673 void SetContext(gfxContext *aContext) {
674 NS_ASSERTION(!mContext, "Not going to call Restore() on some context!!!");
675 mContext = aContext;
676 mContext->Save();
679 private:
680 gfxContext *mContext;
684 * Sentry helper class for functions with multiple return points that need to
685 * back up the current path of a context and have it automatically restored
686 * before they return. This class assumes that the transformation matrix will
687 * be the same when Save and Restore are called. The calling function must
688 * ensure that this is the case or the path will be copied incorrectly.
690 class THEBES_API gfxContextPathAutoSaveRestore
692 public:
693 gfxContextPathAutoSaveRestore() : mContext(nsnull) {}
695 gfxContextPathAutoSaveRestore(gfxContext *aContext, PRBool aSave = PR_TRUE) : mContext(aContext)
697 if (aSave)
698 Save();
701 ~gfxContextPathAutoSaveRestore()
703 Restore();
706 void SetContext(gfxContext *aContext, PRBool aSave = PR_TRUE)
708 mContext = aContext;
709 if (aSave)
710 Save();
714 * If a path is already saved, does nothing. Else copies the current path
715 * so that it may be restored.
717 void Save()
719 if (!mPath && mContext) {
720 mPath = mContext->CopyPath();
725 * If no path is saved, does nothing. Else replaces the context's path with
726 * a copy of the saved one, and clears the saved path.
728 void Restore()
730 if (mPath) {
731 mContext->NewPath();
732 mContext->AppendPath(mPath);
733 mPath = nsnull;
737 private:
738 gfxContext *mContext;
740 nsRefPtr<gfxPath> mPath;
744 * Sentry helper class for functions with multiple return points that need to
745 * back up the current matrix of a context and have it automatically restored
746 * before they return.
748 class THEBES_API gfxContextMatrixAutoSaveRestore
750 public:
751 gfxContextMatrixAutoSaveRestore(gfxContext *aContext) :
752 mContext(aContext), mMatrix(aContext->CurrentMatrix())
756 ~gfxContextMatrixAutoSaveRestore()
758 mContext->SetMatrix(mMatrix);
761 const gfxMatrix& Matrix()
763 return mMatrix;
766 private:
767 gfxContext *mContext;
768 gfxMatrix mMatrix;
771 #endif /* GFX_CONTEXT_H */