gfx/thebes/gfxContext.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef GFX_CONTEXT_H
     7 #define GFX_CONTEXT_H
     9 #include "gfxTypes.h"
    11 #include "gfxASurface.h"
    12 #include "gfxPoint.h"
    13 #include "gfxRect.h"
    14 #include "gfxMatrix.h"
    15 #include "gfxPattern.h"
    16 #include "gfxPath.h"
    17 #include "nsTArray.h"
    18 #include "nsAutoPtr.h"
    20 #include "mozilla/gfx/2D.h"
    22 typedef struct _cairo cairo_t;
    23 struct GlyphBufferAzure;
    24 template <typename T> class FallibleTArray;
    26 /**
    27  * This is the main class for doing actual drawing. It is initialized using
    28  * a surface and can be drawn on. It manages various state information like
    29  * a current transformation matrix (CTM), a current path, current color,
    30  * etc.
    31  *
    32  * All drawing happens by creating a path and then stroking or filling it.
    33  * The functions like Rectangle and Arc do not do any drawing themselves.
    34  * When a path is drawn (stroked or filled), it is filled/stroked with a
    35  * pattern set by SetPattern, SetColor or SetSource.
    36  *
    37  * Note that the gfxContext takes coordinates in device pixels,
    38  * as opposed to app units.
    39  */
    40 class gfxContext {
    41     NS_INLINE_DECL_REFCOUNTING(gfxContext)
    43 public:
    44     /**
    45      * Initialize this context from a surface.
    46      */
    47     gfxContext(gfxASurface *surface);
    49     /**
    50      * Initialize this context from a DrawTarget.
    51      * Strips any transform from aTarget.
    52      * aTarget will be flushed in the gfxContext's destructor.
    53      */
    54     gfxContext(mozilla::gfx::DrawTarget *aTarget,
    55                const mozilla::gfx::Point& aDeviceOffset = mozilla::gfx::Point());
    57     ~gfxContext();
    59     /**
    60      * Create a new gfxContext wrapping aTarget and preserving aTarget's
    61      * transform. Note that the transform is moved from aTarget to the resulting
    62      * gfxContext, aTarget will no longer have its transform.
    63      */
    64     static already_AddRefed<gfxContext> ContextForDrawTarget(mozilla::gfx::DrawTarget* aTarget);
    66     /**
    67      * Return the surface that this gfxContext was created with
    68      */
    69     gfxASurface *OriginalSurface();
    71     /**
    72      * Return the current transparency group target, if any, along
    73      * with its device offsets from the top.  If no group is
    74      * active, returns the surface the gfxContext was created with,
    75      * and 0,0 in dx,dy.
    76      */
    77     already_AddRefed<gfxASurface> CurrentSurface(gfxFloat *dx, gfxFloat *dy);
    78     already_AddRefed<gfxASurface> CurrentSurface() {
    79         return CurrentSurface(nullptr, nullptr);
    80     }
    82     /**
    83      * Return the raw cairo_t object.
    84      * XXX this should go away at some point.
    85      */
    86     cairo_t *GetCairo();
    88     mozilla::gfx::DrawTarget *GetDrawTarget() { return mDT; }
    90     /**
    91      * Returns true if the cairo context is in an error state.
    92      */
    93     bool HasError();
    95     /**
    96      ** State
    97      **/
    98     // XXX document exactly what bits are saved
    99     void Save();
   100     void Restore();
   102     /**
   103      ** Paths & Drawing
   104      **/
   106     /**
   107      * Stroke the current path using the current settings (such as line
   108      * width and color).
   109      * A path is set up using functions such as Line, Rectangle and Arc.
   110      *
   111      * Does not consume the current path.
   112      */
   113     void Stroke();
   114     /**
   115      * Fill the current path according to the current settings.
   116      *
   117      * Does not consume the current path.
   118      */
   119     void Fill();
   121     /**
   122      * Fill the current path according to the current settings and
   123      * with |aOpacity|.
   124      *
   125      * Does not consume the current path.
   126      */
   127     void FillWithOpacity(gfxFloat aOpacity);
   129     /**
   130      * Forgets the current path.
   131      */
   132     void NewPath();
   134     /**
   135      * Closes the path, i.e. connects the last drawn point to the first one.
   136      *
   137      * Filling a path will implicitly close it.
   138      */
   139     void ClosePath();
   141     /**
   142      * Copies the current path and returns the copy.
   143      */
   144     already_AddRefed<gfxPath> CopyPath();
   146     /**
   147      * Appends the given path to the current path.
   148      */
   149     void SetPath(gfxPath* path);
   151     /**
   152      * Moves the pen to a new point without drawing a line.
   153      */
   154     void MoveTo(const gfxPoint& pt);
   156     /**
   157      * Creates a new subpath starting at the current point.
   158      * Equivalent to MoveTo(CurrentPoint()).
   159      */
   160     void NewSubPath();
   162     /**
   163      * Returns the current point in the current path.
   164      */
   165     gfxPoint CurrentPoint();
   167     /**
   168      * Draws a line from the current point to pt.
   169      *
   170      * @see MoveTo
   171      */
   172     void LineTo(const gfxPoint& pt);
   174     /**
   175      * Draws a cubic Bézier curve with control points pt1, pt2 and pt3.
   176      */
   177     void CurveTo(const gfxPoint& pt1, const gfxPoint& pt2, const gfxPoint& pt3);
   179     /**
   180      * Draws a quadratic Bézier curve with control points pt1, pt2 and pt3.
   181      */
   182     void QuadraticCurveTo(const gfxPoint& pt1, const gfxPoint& pt2);
   184     /**
   185      * Draws a clockwise arc (i.e. a circle segment).
   186      * @param center The center of the circle
   187      * @param radius The radius of the circle
   188      * @param angle1 Starting angle for the segment
   189      * @param angle2 Ending angle
   190      */
   191     void Arc(const gfxPoint& center, gfxFloat radius,
   192              gfxFloat angle1, gfxFloat angle2);
   194     /**
   195      * Draws a counter-clockwise arc (i.e. a circle segment).
   196      * @param center The center of the circle
   197      * @param radius The radius of the circle
   198      * @param angle1 Starting angle for the segment
   199      * @param angle2 Ending angle
   200      */
   202     void NegativeArc(const gfxPoint& center, gfxFloat radius,
   203                      gfxFloat angle1, gfxFloat angle2);
   205     // path helpers
   206     /**
   207      * Draws a line from start to end.
   208      */
   209     void Line(const gfxPoint& start, const gfxPoint& end); // XXX snapToPixels option?
   211     /**
   212      * Draws the rectangle given by rect.
   213      * @param snapToPixels ?
   214      */
   215     void Rectangle(const gfxRect& rect, bool snapToPixels = false);
   216     void SnappedRectangle(const gfxRect& rect) { return Rectangle(rect, true); }
   218     /**
   219      * Draw an ellipse at the center corner with the given dimensions.
   220      * It extends dimensions.width / 2.0 in the horizontal direction
   221      * from the center, and dimensions.height / 2.0 in the vertical
   222      * direction.
   223      */
   224     void Ellipse(const gfxPoint& center, const gfxSize& dimensions);
   226     /**
   227      * Draw a polygon from the given points
   228      */
   229     void Polygon(const gfxPoint *points, uint32_t numPoints);
   231     /*
   232      * Draw a rounded rectangle, with the given outer rect and
   233      * corners.  The corners specify the radii of the two axes of an
   234      * ellipse (the horizontal and vertical directions given by the
   235      * width and height, respectively).  By default the ellipse is
   236      * drawn in a clockwise direction; if draw_clockwise is false,
   237      * then it's drawn counterclockwise.
   238      */
   239     void RoundedRectangle(const gfxRect& rect,
   240                           const gfxCornerSizes& corners,
   241                           bool draw_clockwise = true);
   243     /**
   244      ** Transformation Matrix manipulation
   245      **/
   247     /**
   248      * Adds a translation to the current matrix. This translation takes place
   249      * before the previously set transformations.
   250      */
   251     void Translate(const gfxPoint& pt);
   253     /**
   254      * Adds a scale to the current matrix. This scaling takes place before the
   255      * previously set transformations.
   256      */
   257     void Scale(gfxFloat x, gfxFloat y);
   259     /**
   260      * Adds a rotation around the origin to the current matrix. This rotation
   261      * takes place before the previously set transformations.
   262      *
   263      * @param angle The angle in radians.
   264      */
   265     void Rotate(gfxFloat angle);
   267     /**
   268      * Post-multiplies 'other' onto the current CTM, i.e. this
   269      * matrix's transformation will take place before the previously set
   270      * transformations.
   271      */
   272     void Multiply(const gfxMatrix& other);
   273     /**
   274      * As "Multiply", but also nudges any entries in the resulting matrix that
   275      * are close to an integer to that integer, to correct for
   276      * compounded rounding errors.
   277      */
   278     void MultiplyAndNudgeToIntegers(const gfxMatrix& other);
   280     /**
   281      * Replaces the current transformation matrix with matrix.
   282      */
   283     void SetMatrix(const gfxMatrix& matrix);
   285     /**
   286      * Sets the transformation matrix to the identity matrix.
   287      */
   288     void IdentityMatrix();
   290     /**
   291      * Returns the current transformation matrix.
   292      */
   293     gfxMatrix CurrentMatrix() const;
   295     /**
   296      * Snap components of the current matrix that are close to integers
   297      * to integers. In particular, components that are integral when
   298      * converted to single precision are set to those integers.
   299      */
   300     void NudgeCurrentMatrixToIntegers();
   302     /**
   303      * Converts a point from device to user coordinates using the inverse
   304      * transformation matrix.
   305      */
   306     gfxPoint DeviceToUser(const gfxPoint& point) const;
   308     /**
   309      * Converts a size from device to user coordinates. This does not apply
   310      * translation components of the matrix.
   311      */
   312     gfxSize DeviceToUser(const gfxSize& size) const;
   314     /**
   315      * Converts a rectangle from device to user coordinates; this has the
   316      * same effect as using DeviceToUser on both the rectangle's point and
   317      * size.
   318      */
   319     gfxRect DeviceToUser(const gfxRect& rect) const;
   321     /**
   322      * Converts a point from user to device coordinates using the transformation
   323      * matrix.
   324      */
   325     gfxPoint UserToDevice(const gfxPoint& point) const;
   327     /**
   328      * Converts a size from user to device coordinates. This does not apply
   329      * translation components of the matrix.
   330      */
   331     gfxSize UserToDevice(const gfxSize& size) const;
   333     /**
   334      * Converts a rectangle from user to device coordinates.  The
   335      * resulting rectangle is the minimum device-space rectangle that
   336      * encloses the user-space rectangle given.
   337      */
   338     gfxRect UserToDevice(const gfxRect& rect) const;
   340     /**
   341      * Takes the given rect and tries to align it to device pixels.  If
   342      * this succeeds, the method will return true, and the rect will
   343      * be in device coordinates (already transformed by the CTM).  If it 
   344      * fails, the method will return false, and the rect will not be
   345      * changed.
   346      *
   347      * If ignoreScale is true, then snapping will take place even if
   348      * the CTM has a scale applied.  Snapping never takes place if
   349      * there is a rotation in the CTM.
   350      */
   351     bool UserToDevicePixelSnapped(gfxRect& rect, bool ignoreScale = false) const;
   353     /**
   354      * Takes the given point and tries to align it to device pixels.  If
   355      * this succeeds, the method will return true, and the point will
   356      * be in device coordinates (already transformed by the CTM).  If it 
   357      * fails, the method will return false, and the point will not be
   358      * changed.
   359      *
   360      * If ignoreScale is true, then snapping will take place even if
   361      * the CTM has a scale applied.  Snapping never takes place if
   362      * there is a rotation in the CTM.
   363      */
   364     bool UserToDevicePixelSnapped(gfxPoint& pt, bool ignoreScale = false) const;
   366     /**
   367      * Attempts to pixel snap the rectangle, add it to the current
   368      * path, and to set pattern as the current painting source.  This
   369      * should be used for drawing filled pixel-snapped rectangles (like
   370      * images), because the CTM at the time of the SetPattern call needs
   371      * to have a snapped translation, or you get smeared images.
   372      */
   373     void PixelSnappedRectangleAndSetPattern(const gfxRect& rect, gfxPattern *pattern);
   375     /**
   376      ** Painting sources
   377      **/
   379     /**
   380      * Set a solid color to use for drawing.  This color is in the device color space
   381      * and is not transformed.
   382      */
   383     void SetDeviceColor(const gfxRGBA& c);
   385     /**
   386      * Gets the current color.  It's returned in the device color space.
   387      * returns false if there is something other than a color
   388      *         set as the current source (pattern, surface, etc)
   389      */
   390     bool GetDeviceColor(gfxRGBA& c);
   392     /**
   393      * Set a solid color in the sRGB color space to use for drawing.
   394      * If CMS is not enabled, the color is treated as a device-space color
   395      * and this call is identical to SetDeviceColor().
   396      */
   397     void SetColor(const gfxRGBA& c);
   399     /**
   400      * Uses a surface for drawing. This is a shorthand for creating a
   401      * pattern and setting it.
   402      *
   403      * @param offset from the source surface, to use only part of it.
   404      *        May need to make it negative.
   405      */
   406     void SetSource(gfxASurface *surface, const gfxPoint& offset = gfxPoint(0.0, 0.0));
   408     /**
   409      * Uses a pattern for drawing.
   410      */
   411     void SetPattern(gfxPattern *pattern);
   413     /**
   414      * Get the source pattern (solid color, normal pattern, surface, etc)
   415      */
   416     already_AddRefed<gfxPattern> GetPattern();
   418     /**
   419      ** Painting
   420      **/
   421     /**
   422      * Paints the current source surface/pattern everywhere in the current
   423      * clip region.
   424      */
   425     void Paint(gfxFloat alpha = 1.0);
   427     /**
   428      ** Painting with a Mask
   429      **/
   430     /**
   431      * Like Paint, except that it only draws the source where pattern is
   432      * non-transparent.
   433      */
   434     void Mask(gfxPattern *pattern);
   436     /**
   437      * Shorthand for creating a pattern and calling the pattern-taking
   438      * variant of Mask.
   439      */
   440     void Mask(gfxASurface *surface, const gfxPoint& offset = gfxPoint(0.0, 0.0));
   442     void Mask(mozilla::gfx::SourceSurface *surface, const mozilla::gfx::Point& offset = mozilla::gfx::Point());
   444     /**
   445      ** Shortcuts
   446      **/
   448     /**
   449      * Creates a new path with a rectangle from 0,0 to size.w,size.h
   450      * and calls cairo_fill.
   451      */
   452     void DrawSurface(gfxASurface *surface, const gfxSize& size);
   454     /**
   455      ** Line Properties
   456      **/
   458     typedef enum {
   459         gfxLineSolid,
   460         gfxLineDashed,
   461         gfxLineDotted
   462     } gfxLineType;
   464     void SetDash(gfxLineType ltype);
   465     void SetDash(gfxFloat *dashes, int ndash, gfxFloat offset);
   466     // Return true if dashing is set, false if it's not enabled or the
   467     // context is in an error state.  |offset| can be nullptr to mean
   468     // "don't care".
   469     bool CurrentDash(FallibleTArray<gfxFloat>& dashes, gfxFloat* offset) const;
   470     // Returns 0.0 if dashing isn't enabled.
   471     gfxFloat CurrentDashOffset() const;
   473     /**
   474      * Sets the line width that's used for line drawing.
   475      */
   476     void SetLineWidth(gfxFloat width);
   478     /**
   479      * Returns the currently set line width.
   480      *
   481      * @see SetLineWidth
   482      */
   483     gfxFloat CurrentLineWidth() const;
   485     enum GraphicsLineCap {
   486         LINE_CAP_BUTT,
   487         LINE_CAP_ROUND,
   488         LINE_CAP_SQUARE
   489     };
   490     /**
   491      * Sets the line caps, i.e. how line endings are drawn.
   492      */
   493     void SetLineCap(GraphicsLineCap cap);
   494     GraphicsLineCap CurrentLineCap() const;
   496     enum GraphicsLineJoin {
   497         LINE_JOIN_MITER,
   498         LINE_JOIN_ROUND,
   499         LINE_JOIN_BEVEL
   500     };
   501     /**
   502      * Sets the line join, i.e. how the connection between two lines is
   503      * drawn.
   504      */
   505     void SetLineJoin(GraphicsLineJoin join);
   506     GraphicsLineJoin CurrentLineJoin() const;
   508     void SetMiterLimit(gfxFloat limit);
   509     gfxFloat CurrentMiterLimit() const;
   511     /**
   512      ** Fill Properties
   513      **/
   515     enum FillRule {
   516         FILL_RULE_WINDING,
   517         FILL_RULE_EVEN_ODD
   518     };
   519     void SetFillRule(FillRule rule);
   520     FillRule CurrentFillRule() const;
   522     /**
   523      ** Operators and Rendering control
   524      **/
   526     // define enum for operators (clear, src, dst, etc)
   527     enum GraphicsOperator {
   528         OPERATOR_CLEAR,
   529         OPERATOR_SOURCE,
   531         OPERATOR_OVER,
   532         OPERATOR_IN,
   533         OPERATOR_OUT,
   534         OPERATOR_ATOP,
   536         OPERATOR_DEST,
   537         OPERATOR_DEST_OVER,
   538         OPERATOR_DEST_IN,
   539         OPERATOR_DEST_OUT,
   540         OPERATOR_DEST_ATOP,
   542         OPERATOR_XOR,
   543         OPERATOR_ADD,
   544         OPERATOR_SATURATE,
   546         OPERATOR_MULTIPLY,
   547         OPERATOR_SCREEN,
   548         OPERATOR_OVERLAY,
   549         OPERATOR_DARKEN,
   550         OPERATOR_LIGHTEN,
   551         OPERATOR_COLOR_DODGE,
   552         OPERATOR_COLOR_BURN,
   553         OPERATOR_HARD_LIGHT,
   554         OPERATOR_SOFT_LIGHT,
   555         OPERATOR_DIFFERENCE,
   556         OPERATOR_EXCLUSION,
   557         OPERATOR_HUE,
   558         OPERATOR_SATURATION,
   559         OPERATOR_COLOR,
   560         OPERATOR_LUMINOSITY
   561     };
   562     /**
   563      * Sets the operator used for all further drawing. The operator affects
   564      * how drawing something will modify the destination. For example, the
   565      * OVER operator will do alpha blending of source and destination, while
   566      * SOURCE will replace the destination with the source.
   567      *
   568      * Note that if the flag FLAG_SIMPLIFY_OPERATORS is set on this
   569      * gfxContext, the actual operator set might change for optimization
   570      * purposes.  Check the comments below around that flag.
   571      */
   572     void SetOperator(GraphicsOperator op);
   573     GraphicsOperator CurrentOperator() const;
   575     /**
   576      * MODE_ALIASED means that only pixels whose centers are in the drawn area
   577      * should be modified, and they should be modified to take the value drawn
   578      * at the pixel center.
   579      */
   580     enum AntialiasMode {
   581         MODE_ALIASED,
   582         MODE_COVERAGE
   583     };
   584     void SetAntialiasMode(AntialiasMode mode);
   585     AntialiasMode CurrentAntialiasMode() const;
   587     /**
   588      ** Clipping
   589      **/
   591     /**
   592      * Clips all further drawing to the current path.
   593      * This does not consume the current path.
   594      */
   595     void Clip();
   597     /**
   598      * Undoes any clipping. Further drawings will only be restricted by the
   599      * surface dimensions.
   600      */
   601     void ResetClip();
   603     /**
   604      * Helper functions that will create a rect path and call Clip().
   605      * Any current path will be destroyed by these functions!
   606      */
   607     void Clip(const gfxRect& rect); // will clip to a rect
   609     /**
   610      * This will ensure that the surface actually has its clip set.
   611      * Useful if you are doing native drawing.
   612      */
   613     void UpdateSurfaceClip();
   615     /**
   616      * This will return the current bounds of the clip region in user
   617      * space.
   618      */
   619     gfxRect GetClipExtents();
   621     /**
   622      * Returns true if the given rectangle is fully contained in the current clip. 
   623      * This is conservative; it may return false even when the given rectangle is 
   624      * fully contained by the current clip.
   625      */
   626     bool ClipContainsRect(const gfxRect& aRect);
   628     /**
   629      * Groups
   630      */
   631     void PushGroup(gfxContentType content = gfxContentType::COLOR);
   632     /**
   633      * Like PushGroup, but if the current surface is gfxContentType::COLOR and
   634      * content is gfxContentType::COLOR_ALPHA, makes the pushed surface gfxContentType::COLOR
   635      * instead and copies the contents of the current surface to the pushed
   636      * surface. This is good for pushing opacity groups, since blending the
   637      * group back to the current surface with some alpha applied will give
   638      * the correct results and using an opaque pushed surface gives better
   639      * quality and performance.
   640      * This API really only makes sense if you do a PopGroupToSource and
   641      * immediate Paint with OPERATOR_OVER.
   642      */
   643     void PushGroupAndCopyBackground(gfxContentType content = gfxContentType::COLOR);
   644     already_AddRefed<gfxPattern> PopGroup();
   645     void PopGroupToSource();
   647     /**
   648      ** Hit Testing - check if given point is in the current path
   649      **/
   650     bool PointInFill(const gfxPoint& pt);
   651     bool PointInStroke(const gfxPoint& pt);
   653     /**
   654      ** Extents - returns user space extent of current path
   655      **/
   656     gfxRect GetUserPathExtent();
   657     gfxRect GetUserFillExtent();
   658     gfxRect GetUserStrokeExtent();
   660     mozilla::gfx::Point GetDeviceOffset() const;
   662     /**
   663      ** Flags
   664      **/
   666     enum {
   667         /* If this flag is set, operators other than CLEAR, SOURCE, or
   668          * OVER will be converted to OVER before being sent to cairo.
   669          *
   670          * This is most useful with a printing surface, where
   671          * operators such as ADD are used to avoid seams for on-screen
   672          * display, but where such errors aren't noticeable in print.
   673          * This approach is currently used in border rendering.
   674          *
   675          * However, when printing complex renderings such as SVG,
   676          * care should be taken to clear this flag.
   677          */
   678         FLAG_SIMPLIFY_OPERATORS = (1 << 0),
   679         /**
   680          * When this flag is set, snapping to device pixels is disabled.
   681          * It simply never does anything.
   682          */
   683         FLAG_DISABLE_SNAPPING = (1 << 1),
   684         /**
   685          * Disable copying of backgrounds in PushGroupAndCopyBackground.
   686          */
   687         FLAG_DISABLE_COPY_BACKGROUND = (1 << 2)
   688     };
   690     void SetFlag(int32_t aFlag) { mFlags |= aFlag; }
   691     void ClearFlag(int32_t aFlag) { mFlags &= ~aFlag; }
   692     int32_t GetFlags() const { return mFlags; }
   694     bool IsCairo() const { return !mDT; }
   696     // Work out whether cairo will snap inter-glyph spacing to pixels.
   697     void GetRoundOffsetsToPixels(bool *aRoundX, bool *aRoundY);
   699 #ifdef MOZ_DUMP_PAINTING
   700     /**
   701      * Debug functions to encode the current surface as a PNG and export it.
   702      */
   704     /**
   705      * Writes a binary PNG file.
   706      */
   707     void WriteAsPNG(const char* aFile);
   709     /**
   710      * Write as a PNG encoded Data URL to stdout.
   711      */
   712     void DumpAsDataURL();
   714     /**
   715      * Copy a PNG encoded Data URL to the clipboard.
   716      */
   717     void CopyAsDataURL();
   718 #endif
   720     static mozilla::gfx::UserDataKey sDontUseAsSourceKey;
   722 private:
   723   friend class GeneralPattern;
   724   friend struct GlyphBufferAzure;
   726   typedef mozilla::gfx::Matrix Matrix;
   727   typedef mozilla::gfx::DrawTarget DrawTarget;
   728   typedef mozilla::gfx::Color Color;
   729   typedef mozilla::gfx::StrokeOptions StrokeOptions;
   730   typedef mozilla::gfx::Float Float;
   731   typedef mozilla::gfx::Rect Rect;
   732   typedef mozilla::gfx::CompositionOp CompositionOp;
   733   typedef mozilla::gfx::Path Path;
   734   typedef mozilla::gfx::PathBuilder PathBuilder;
   735   typedef mozilla::gfx::SourceSurface SourceSurface;
   737   struct AzureState {
   738     AzureState()
   739       : op(mozilla::gfx::CompositionOp::OP_OVER)
   740       , opIsClear(false)
   741       , color(0, 0, 0, 1.0f)
   742       , clipWasReset(false)
   743       , fillRule(mozilla::gfx::FillRule::FILL_WINDING)
   744       , aaMode(mozilla::gfx::AntialiasMode::SUBPIXEL)
   745       , patternTransformChanged(false)
   746     {}
   748     mozilla::gfx::CompositionOp op;
   749     bool opIsClear;
   750     Color color;
   751     nsRefPtr<gfxPattern> pattern;
   752     nsRefPtr<gfxASurface> sourceSurfCairo;
   753     mozilla::RefPtr<SourceSurface> sourceSurface;
   754     mozilla::gfx::Point sourceSurfaceDeviceOffset;
   755     Matrix surfTransform;
   756     Matrix transform;
   757     struct PushedClip {
   758       mozilla::RefPtr<Path> path;
   759       Rect rect;
   760       Matrix transform;
   761     };
   762     nsTArray<PushedClip> pushedClips;
   763     nsTArray<Float> dashPattern;
   764     bool clipWasReset;
   765     mozilla::gfx::FillRule fillRule;
   766     StrokeOptions strokeOptions;
   767     mozilla::RefPtr<DrawTarget> drawTarget;
   768     mozilla::RefPtr<DrawTarget> parentTarget;
   769     mozilla::gfx::AntialiasMode aaMode;
   770     bool patternTransformChanged;
   771     Matrix patternTransform;
   772     // This is used solely for using minimal intermediate surface size.
   773     mozilla::gfx::Point deviceOffset;
   774   };
   776   // This ensures mPath contains a valid path (in user space!)
   777   void EnsurePath();
   778   // This ensures mPathBuilder contains a valid PathBuilder (in user space!)
   779   void EnsurePathBuilder();
   780   void FillAzure(mozilla::gfx::Float aOpacity);
   781   void PushClipsToDT(mozilla::gfx::DrawTarget *aDT);
   782   CompositionOp GetOp();
   783   void ChangeTransform(const mozilla::gfx::Matrix &aNewMatrix, bool aUpdatePatternTransform = true);
   784   Rect GetAzureDeviceSpaceClipBounds();
   785   Matrix GetDeviceTransform() const;
   786   Matrix GetDTTransform() const;
   787   void PushNewDT(gfxContentType content);
   789   bool mPathIsRect;
   790   bool mTransformChanged;
   791   Matrix mPathTransform;
   792   Rect mRect;
   793   mozilla::RefPtr<PathBuilder> mPathBuilder;
   794   mozilla::RefPtr<Path> mPath;
   795   Matrix mTransform;
   796   nsTArray<AzureState> mStateStack;
   798   AzureState &CurrentState() { return mStateStack[mStateStack.Length() - 1]; }
   799   const AzureState &CurrentState() const { return mStateStack[mStateStack.Length() - 1]; }
   801   cairo_t *mCairo;
   802   cairo_t *mRefCairo;
   803   nsRefPtr<gfxASurface> mSurface;
   804   int32_t mFlags;
   806   mozilla::RefPtr<DrawTarget> mDT;
   807   mozilla::RefPtr<DrawTarget> mOriginalDT;
   808 };
   810 /**
   811  * Sentry helper class for functions with multiple return points that need to
   812  * call Save() on a gfxContext and have Restore() called automatically on the
   813  * gfxContext before they return.
   814  */
   815 class gfxContextAutoSaveRestore
   816 {
   817 public:
   818   gfxContextAutoSaveRestore() : mContext(nullptr) {}
   820   gfxContextAutoSaveRestore(gfxContext *aContext) : mContext(aContext) {
   821     mContext->Save();
   822   }
   824   ~gfxContextAutoSaveRestore() {
   825     if (mContext) {
   826       mContext->Restore();
   827     }
   828   }
   830   void SetContext(gfxContext *aContext) {
   831     NS_ASSERTION(!mContext, "Not going to call Restore() on some context!!!");
   832     mContext = aContext;
   833     mContext->Save();    
   834   }
   836   void Reset(gfxContext *aContext) {
   837     // Do the equivalent of destroying and re-creating this object.
   838     NS_PRECONDITION(aContext, "must provide a context");
   839     if (mContext) {
   840       mContext->Restore();
   841     }
   842     mContext = aContext;
   843     mContext->Save();
   844   }
   846 private:
   847   gfxContext *mContext;
   848 };
   850 /**
   851  * Sentry helper class for functions with multiple return points that need to
   852  * back up the current path of a context and have it automatically restored
   853  * before they return. This class assumes that the transformation matrix will
   854  * be the same when Save and Restore are called. The calling function must
   855  * ensure that this is the case or the path will be copied incorrectly.
   856  */
   857 class gfxContextPathAutoSaveRestore
   858 {
   859 public:
   860     gfxContextPathAutoSaveRestore() : mContext(nullptr) {}
   862     gfxContextPathAutoSaveRestore(gfxContext *aContext, bool aSave = true) : mContext(aContext)
   863     {
   864         if (aSave)
   865             Save();       
   866     }
   868     ~gfxContextPathAutoSaveRestore()
   869     {
   870         Restore();
   871     }
   873     void SetContext(gfxContext *aContext, bool aSave = true)
   874     {
   875         mContext = aContext;
   876         if (aSave)
   877             Save();
   878     }
   880     /**
   881      * If a path is already saved, does nothing. Else copies the current path
   882      * so that it may be restored.
   883      */
   884     void Save()
   885     {
   886         if (!mPath && mContext) {
   887             mPath = mContext->CopyPath();
   888         }
   889     }
   891     /**
   892      * If no path is saved, does nothing. Else replaces the context's path with
   893      * a copy of the saved one, and clears the saved path.
   894      */
   895     void Restore()
   896     {
   897         if (mPath) {
   898             mContext->SetPath(mPath);
   899             mPath = nullptr;
   900         }
   901     }
   903 private:
   904     gfxContext *mContext;
   906     nsRefPtr<gfxPath> mPath;
   907 };
   909 /**
   910  * Sentry helper class for functions with multiple return points that need to
   911  * back up the current matrix of a context and have it automatically restored
   912  * before they return.
   913  */
   914 class gfxContextMatrixAutoSaveRestore
   915 {
   916 public:
   917     gfxContextMatrixAutoSaveRestore() :
   918         mContext(nullptr)
   919     {
   920     }
   922     gfxContextMatrixAutoSaveRestore(gfxContext *aContext) :
   923         mContext(aContext), mMatrix(aContext->CurrentMatrix())
   924     {
   925     }
   927     ~gfxContextMatrixAutoSaveRestore()
   928     {
   929         if (mContext) {
   930             mContext->SetMatrix(mMatrix);
   931         }
   932     }
   934     void SetContext(gfxContext *aContext)
   935     {
   936         NS_ASSERTION(!mContext, "Not going to restore the matrix on some context!");
   937         mContext = aContext;
   938         mMatrix = aContext->CurrentMatrix();
   939     }
   941     void Restore()
   942     {
   943         if (mContext) {
   944             mContext->SetMatrix(mMatrix);
   945         }
   946     }
   948     const gfxMatrix& Matrix()
   949     {
   950         MOZ_ASSERT(mContext, "mMatrix doesn't contain a useful matrix");
   951         return mMatrix;
   952     }
   954 private:
   955     gfxContext *mContext;
   956     gfxMatrix   mMatrix;
   957 };
   960 class gfxContextAutoDisableSubpixelAntialiasing {
   961 public:
   962     gfxContextAutoDisableSubpixelAntialiasing(gfxContext *aContext, bool aDisable)
   963     {
   964         if (aDisable) {
   965             if (aContext->IsCairo()) {
   966                 mSurface = aContext->CurrentSurface();
   967                 if (!mSurface) {
   968                   return;
   969                 }
   970                 mSubpixelAntialiasingEnabled = mSurface->GetSubpixelAntialiasingEnabled();
   971                 mSurface->SetSubpixelAntialiasingEnabled(false);
   972             } else {
   973                 mDT = aContext->GetDrawTarget();
   975                 mSubpixelAntialiasingEnabled = mDT->GetPermitSubpixelAA();
   976                 mDT->SetPermitSubpixelAA(false);
   977             }
   978         }
   979     }
   980     ~gfxContextAutoDisableSubpixelAntialiasing()
   981     {
   982         if (mSurface) {
   983             mSurface->SetSubpixelAntialiasingEnabled(mSubpixelAntialiasingEnabled);
   984         } else if (mDT) {
   985             mDT->SetPermitSubpixelAA(mSubpixelAntialiasingEnabled);
   986         }
   987     }
   989 private:
   990     nsRefPtr<gfxASurface> mSurface;
   991     mozilla::RefPtr<mozilla::gfx::DrawTarget> mDT;
   992     bool mSubpixelAntialiasingEnabled;
   993 };
   995 #endif /* GFX_CONTEXT_H */

mercurial