LCOV - app.info - gfx/thebes/gfxPattern.cpp

LCOV - code coverage report
| Current view: | directory - gfx/thebes - gfxPattern.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 180 | 10 | 5.6 %
| Date: | 2012-06-02 | Functions: | 22 | 4 | 18.2 %

           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
           4                 :  *
           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/
           9                 :  *
          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.
          14                 :  *
          15                 :  * The Original Code is Mozilla Corporation code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2007
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Stuart Parmenter <stuart@mozilla.com>
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #include "gfxTypes.h"
          39                 : #include "gfxPattern.h"
          40                 : #include "gfxASurface.h"
          41                 : #include "gfxPlatform.h"
          42                 :
          43                 : #include "cairo.h"
          44                 :
          45                 : #include <vector>
          46                 :
          47                 : using namespace mozilla::gfx;
          48                 :
          49               0 : gfxPattern::gfxPattern(cairo_pattern_t *aPattern)
          50               0 :   : mGfxPattern(NULL)
          51                 : {
          52               0 :     mPattern = cairo_pattern_reference(aPattern);
          53               0 : }
          54                 :
          55               0 : gfxPattern::gfxPattern(const gfxRGBA& aColor)
          56               0 :   : mGfxPattern(NULL)
          57                 : {
          58               0 :     mPattern = cairo_pattern_create_rgba(aColor.r, aColor.g, aColor.b, aColor.a);
          59               0 : }
          60                 :
          61                 : // from another surface
          62              19 : gfxPattern::gfxPattern(gfxASurface *surface)
          63              19 :   : mGfxPattern(NULL)
          64                 : {
          65              19 :     mPattern = cairo_pattern_create_for_surface(surface->CairoSurface());
          66              19 : }
          67                 :
          68                 : // linear
          69               0 : gfxPattern::gfxPattern(gfxFloat x0, gfxFloat y0, gfxFloat x1, gfxFloat y1)
          70               0 :   : mGfxPattern(NULL)
          71                 : {
          72               0 :     mPattern = cairo_pattern_create_linear(x0, y0, x1, y1);
          73               0 : }
          74                 :
          75                 : // radial
          76               0 : gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
          77                 :                        gfxFloat cx1, gfxFloat cy1, gfxFloat radius1)
          78               0 :   : mGfxPattern(NULL)
          79                 : {
          80                 :     mPattern = cairo_pattern_create_radial(cx0, cy0, radius0,
          81               0 :                                            cx1, cy1, radius1);
          82               0 : }
          83                 :
          84                 : // Azure
          85               0 : gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aTransform)
          86                 :   : mPattern(NULL)
          87                 :   , mGfxPattern(NULL)
          88                 :   , mSourceSurface(aSurface)
          89               0 :   , mTransform(aTransform)
          90                 : {
          91               0 : }
          92                 :
          93              57 : gfxPattern::~gfxPattern()
          94                 : {
          95              19 :     cairo_pattern_destroy(mPattern);
          96                 :
          97              19 :     if (mGfxPattern) {
          98               0 :       mGfxPattern->~Pattern();
          99                 :     }
         100              76 : }
         101                 :
         102                 : cairo_pattern_t *
         103              19 : gfxPattern::CairoPattern()
         104                 : {
         105              19 :     return mPattern;
         106                 : }
         107                 :
         108                 : void
         109               0 : gfxPattern::AddColorStop(gfxFloat offset, const gfxRGBA& c)
         110                 : {
         111               0 :   if (mPattern) {
         112               0 :     mStops = NULL;
         113               0 :     if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
         114               0 :         gfxRGBA cms;
         115               0 :         gfxPlatform::TransformPixel(c, cms, gfxPlatform::GetCMSRGBTransform());
         116                 :
         117                 :         // Use the original alpha to avoid unnecessary float->byte->float
         118                 :         // conversion errors
         119                 :         cairo_pattern_add_color_stop_rgba(mPattern, offset,
         120               0 :                                           cms.r, cms.g, cms.b, c.a);
         121                 :     }
         122                 :     else
         123               0 :         cairo_pattern_add_color_stop_rgba(mPattern, offset, c.r, c.g, c.b, c.a);
         124                 :   }
         125               0 : }
         126                 :
         127                 : void
         128               0 : gfxPattern::SetMatrix(const gfxMatrix& matrix)
         129                 : {
         130               0 :   if (mPattern) {
         131               0 :     cairo_matrix_t mat = *reinterpret_cast<const cairo_matrix_t*>(&matrix);
         132               0 :     cairo_pattern_set_matrix(mPattern, &mat);
         133                 :   } else {
         134               0 :     mTransform = ToMatrix(matrix);
         135                 :   }
         136               0 : }
         137                 :
         138                 : gfxMatrix
         139               0 : gfxPattern::GetMatrix() const
         140                 : {
         141               0 :   if (mPattern) {
         142                 :     cairo_matrix_t mat;
         143               0 :     cairo_pattern_get_matrix(mPattern, &mat);
         144               0 :     return gfxMatrix(*reinterpret_cast<gfxMatrix*>(&mat));
         145                 :   } else {
         146               0 :     return ThebesMatrix(mTransform);
         147                 :   }
         148                 : }
         149                 :
         150                 : Pattern*
         151               0 : gfxPattern::GetPattern(mozilla::gfx::DrawTarget *aTarget)
         152                 : {
         153               0 :   if (!mPattern) {
         154               0 :     mGfxPattern = new (mSurfacePattern.addr())
         155               0 :       SurfacePattern(mSourceSurface, EXTEND_CLAMP, mTransform);
         156               0 :     return mGfxPattern;
         157                 :   }
         158                 :
         159               0 :   GraphicsExtend extend = (GraphicsExtend)cairo_pattern_get_extend(mPattern);
         160                 :
         161               0 :   switch (cairo_pattern_get_type(mPattern)) {
         162                 :   case CAIRO_PATTERN_TYPE_SURFACE:
         163                 :     {
         164               0 :       GraphicsFilter filter = (GraphicsFilter)cairo_pattern_get_filter(mPattern);
         165                 :       cairo_matrix_t mat;
         166               0 :       cairo_pattern_get_matrix(mPattern, &mat);
         167               0 :       gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));
         168                 :
         169               0 :       cairo_surface_t *surf = NULL;
         170               0 :       cairo_pattern_get_surface(mPattern, &surf);
         171                 :
         172               0 :       if (!mSourceSurface) {
         173               0 :         nsRefPtr<gfxASurface> gfxSurf = gfxASurface::Wrap(surf);
         174                 :         mSourceSurface =
         175               0 :           gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxSurf);
         176                 :       }
         177                 :
         178               0 :       if (mSourceSurface) {
         179               0 :         Matrix newMat = ToMatrix(matrix);
         180               0 :         newMat.Invert();
         181                 :         double x, y;
         182               0 :         cairo_surface_get_device_offset(surf, &x, &y);
         183               0 :         newMat.Translate(-x, -y);
         184               0 :         mGfxPattern = new (mSurfacePattern.addr())
         185               0 :           SurfacePattern(mSourceSurface, ToExtendMode(extend), newMat, ToFilter(filter));
         186               0 :         return mGfxPattern;
         187                 :       }
         188               0 :       break;
         189                 :     }
         190                 :   case CAIRO_PATTERN_TYPE_LINEAR:
         191                 :     {
         192                 :       double x1, y1, x2, y2;
         193               0 :       cairo_pattern_get_linear_points(mPattern, &x1, &y1, &x2, &y2);
         194               0 :       if (!mStops) {
         195               0 :         int count = 0;
         196               0 :         cairo_pattern_get_color_stop_count(mPattern, &count);
         197                 :
         198               0 :         std::vector<GradientStop> stops;
         199                 :
         200               0 :         for (int i = 0; i < count; i++) {
         201               0 :           GradientStop stop;
         202                 :           double r, g, b, a, offset;
         203               0 :           cairo_pattern_get_color_stop_rgba(mPattern, i, &offset, &r, &g, &b, &a);
         204                 :
         205               0 :           stop.offset = offset;
         206               0 :           stop.color = Color(Float(r), Float(g), Float(b), Float(a));
         207               0 :           stops.push_back(stop);
         208                 :         }
         209                 :
         210               0 :         mStops = aTarget->CreateGradientStops(&stops.front(), count, ToExtendMode(extend));
         211                 :       }
         212                 :
         213               0 :       if (mStops) {
         214                 :         cairo_matrix_t mat;
         215               0 :         cairo_pattern_get_matrix(mPattern, &mat);
         216               0 :         gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));
         217                 :
         218               0 :         Matrix newMat = ToMatrix(matrix);
         219               0 :         newMat.Invert();
         220                 :
         221               0 :         mGfxPattern = new (mLinearGradientPattern.addr())
         222               0 :           LinearGradientPattern(Point(x1, y1), Point(x2, y2), mStops, newMat);
         223                 :
         224               0 :         return mGfxPattern;
         225                 :       }
         226               0 :       break;
         227                 :     }
         228                 :   case CAIRO_PATTERN_TYPE_RADIAL:
         229                 :     {
         230               0 :       if (!mStops) {
         231               0 :         int count = 0;
         232               0 :         cairo_pattern_get_color_stop_count(mPattern, &count);
         233                 :
         234               0 :         std::vector<GradientStop> stops;
         235                 :
         236               0 :         for (int i = 0; i < count; i++) {
         237               0 :           GradientStop stop;
         238                 :           double r, g, b, a, offset;
         239               0 :           cairo_pattern_get_color_stop_rgba(mPattern, i, &offset, &r, &g, &b, &a);
         240                 :
         241               0 :           stop.offset = offset;
         242               0 :           stop.color = Color(Float(r), Float(g), Float(b), Float(a));
         243               0 :           stops.push_back(stop);
         244                 :         }
         245                 :
         246               0 :         mStops = aTarget->CreateGradientStops(&stops.front(), count, ToExtendMode(extend));
         247                 :       }
         248                 :
         249               0 :       if (mStops) {
         250                 :         cairo_matrix_t mat;
         251               0 :         cairo_pattern_get_matrix(mPattern, &mat);
         252               0 :         gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));
         253                 :
         254               0 :         Matrix newMat = ToMatrix(matrix);
         255               0 :         newMat.Invert();
         256                 :
         257                 :         double x1, y1, x2, y2, r1, r2;
         258               0 :         cairo_pattern_get_radial_circles(mPattern, &x1, &y1, &r1, &x2, &y2, &r2);
         259               0 :         mGfxPattern = new (mRadialGradientPattern.addr())
         260               0 :           RadialGradientPattern(Point(x1, y1), Point(x2, y2), r1, r2, mStops, newMat);
         261                 :
         262               0 :         return mGfxPattern;
         263                 :       }
         264               0 :       break;
         265                 :     }
         266                 :   default:
         267                 :     /* Reassure the compiler we are handling all the enum values.  */
         268               0 :     break;
         269                 :   }
         270                 :
         271               0 :   new (mColorPattern.addr()) ColorPattern(Color(0, 0, 0, 0));
         272               0 :   return mColorPattern.addr();
         273                 : }
         274                 :
         275                 : void
         276               0 : gfxPattern::SetExtend(GraphicsExtend extend)
         277                 : {
         278               0 :   if (mPattern) {
         279               0 :     mStops = NULL;
         280               0 :     if (extend == EXTEND_PAD_EDGE) {
         281               0 :         if (cairo_pattern_get_type(mPattern) == CAIRO_PATTERN_TYPE_SURFACE) {
         282               0 :             cairo_surface_t *surf = NULL;
         283                 :
         284               0 :             cairo_pattern_get_surface (mPattern, &surf);
         285               0 :             if (surf) {
         286               0 :                 switch (cairo_surface_get_type(surf)) {
         287                 :                     case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
         288                 :                     case CAIRO_SURFACE_TYPE_QUARTZ:
         289               0 :                         extend = EXTEND_NONE;
         290               0 :                         break;
         291                 :
         292                 :                     case CAIRO_SURFACE_TYPE_WIN32:
         293                 :                     case CAIRO_SURFACE_TYPE_XLIB:
         294                 :                     default:
         295               0 :                         extend = EXTEND_PAD;
         296               0 :                         break;
         297                 :                 }
         298                 :             }
         299                 :         }
         300                 :
         301                 :         // if something went wrong, or not a surface pattern, use PAD
         302               0 :         if (extend == EXTEND_PAD_EDGE)
         303               0 :             extend = EXTEND_PAD;
         304                 :     }
         305                 :
         306               0 :     cairo_pattern_set_extend(mPattern, (cairo_extend_t)extend);
         307                 :   } else {
         308                 :     // This is always a surface pattern and will default to EXTEND_PAD
         309                 :     // for EXTEND_PAD_EDGE.
         310               0 :     mExtend = ToExtendMode(extend);
         311                 :   }
         312               0 : }
         313                 :
         314                 : bool
         315               0 : gfxPattern::IsOpaque()
         316                 : {
         317               0 :   if (mPattern) {
         318               0 :     switch (cairo_pattern_get_type(mPattern)) {
         319                 :     case CAIRO_PATTERN_TYPE_SURFACE:
         320                 :       {
         321               0 :         cairo_surface_t *surf = NULL;
         322               0 :         cairo_pattern_get_surface(mPattern, &surf);
         323                 :
         324               0 :         if (cairo_surface_get_content(surf) == CAIRO_CONTENT_COLOR) {
         325               0 :           return true;
         326                 :         }
         327                 :       }
         328                 :     default:
         329               0 :       return false;
         330                 :     }
         331                 :   }
         332                 :
         333               0 :   if (mSourceSurface->GetFormat() == FORMAT_B8G8R8X8) {
         334               0 :     return true;
         335                 :   }
         336               0 :   return false;
         337                 : }
         338                 :
         339                 : gfxPattern::GraphicsExtend
         340               0 : gfxPattern::Extend() const
         341                 : {
         342               0 :   if (mPattern) {
         343               0 :     return (GraphicsExtend)cairo_pattern_get_extend(mPattern);
         344                 :   } else {
         345               0 :     return ThebesExtend(mExtend);
         346                 :   }
         347                 : }
         348                 :
         349                 : void
         350               0 : gfxPattern::SetFilter(GraphicsFilter filter)
         351                 : {
         352               0 :   if (mPattern) {
         353               0 :     cairo_pattern_set_filter(mPattern, (cairo_filter_t)filter);
         354                 :   } else {
         355               0 :     mFilter = ToFilter(filter);
         356                 :   }
         357               0 : }
         358                 :
         359                 : gfxPattern::GraphicsFilter
         360               0 : gfxPattern::Filter() const
         361                 : {
         362               0 :   if (mPattern) {
         363               0 :     return (GraphicsFilter)cairo_pattern_get_filter(mPattern);
         364                 :   } else {
         365               0 :     return ThebesFilter(mFilter);
         366                 :   }
         367                 : }
         368                 :
         369                 : bool
         370               0 : gfxPattern::GetSolidColor(gfxRGBA& aColor)
         371                 : {
         372                 :     return cairo_pattern_get_rgba(mPattern,
         373                 :                                   &aColor.r,
         374                 :                                   &aColor.g,
         375                 :                                   &aColor.b,
         376               0 :                                   &aColor.a) == CAIRO_STATUS_SUCCESS;
         377                 : }
         378                 :
         379                 : already_AddRefed<gfxASurface>
         380               0 : gfxPattern::GetSurface()
         381                 : {
         382               0 :   if (mPattern) {
         383               0 :     cairo_surface_t *surf = nsnull;
         384                 :
         385               0 :     if (cairo_pattern_get_surface (mPattern, &surf) != CAIRO_STATUS_SUCCESS)
         386               0 :         return nsnull;
         387                 :
         388               0 :     return gfxASurface::Wrap(surf);
         389                 :   } else {
         390                 :     // We should never be trying to get the surface off an Azure gfx Pattern.
         391               0 :     NS_ERROR("Attempt to get surface off an Azure gfxPattern!");
         392               0 :     return NULL;
         393                 :   }
         394                 : }
         395                 :
         396                 : gfxPattern::GraphicsPatternType
         397               0 : gfxPattern::GetType() const
         398                 : {
         399               0 :   if (mPattern) {
         400               0 :     return (GraphicsPatternType) cairo_pattern_get_type(mPattern);
         401                 :   } else {
         402                 :     // We should never be trying to get the type off an Azure gfx Pattern.
         403               0 :     MOZ_ASSERT(0);
         404               0 :     return PATTERN_SURFACE;
         405                 :   }
         406                 : }
         407                 :
         408                 : int
         409               0 : gfxPattern::CairoStatus()
         410                 : {
         411               0 :   if (mPattern) {
         412               0 :     return cairo_pattern_status(mPattern);
         413                 :   } else {
         414                 :     // An Azure pattern as this point is never in error status.
         415               0 :     return CAIRO_STATUS_SUCCESS;
         416                 :   }
         417                 : }

Generated by: LCOV version 1.7