LCOV - code coverage report
Current view: directory - gfx/2d - DrawTargetSkia.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 376 0 0.0 %
Date: 2012-06-02 Functions: 47 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       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) 2011
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *     Matt Woodrow <mwoodrow@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 "DrawTargetSkia.h"
      39                 : #include "SourceSurfaceSkia.h"
      40                 : #include "ScaledFontBase.h"
      41                 : #include "skia/SkDevice.h"
      42                 : #include "skia/SkTypeface.h"
      43                 : #include "skia/SkGradientShader.h"
      44                 : #include "skia/SkBlurDrawLooper.h"
      45                 : #include "skia/SkBlurMaskFilter.h"
      46                 : #include "skia/SkColorFilter.h"
      47                 : #include "skia/SkLayerRasterizer.h"
      48                 : #include "skia/SkLayerDrawLooper.h"
      49                 : #include "skia/SkDashPathEffect.h"
      50                 : #include "Logging.h"
      51                 : #include "HelpersSkia.h"
      52                 : #include "Tools.h"
      53                 : #include <algorithm>
      54                 : 
      55                 : #ifdef ANDROID
      56                 : # define USE_SOFT_CLIPPING false
      57                 : #else
      58                 : # define USE_SOFT_CLIPPING true
      59                 : #endif
      60                 : 
      61                 : namespace mozilla {
      62                 : namespace gfx {
      63                 : 
      64               0 : SkColor ColorToSkColor(const Color &color, Float aAlpha)
      65                 : {
      66                 :   //XXX: do a better job converting to int
      67               0 :   return SkColorSetARGB(color.a*aAlpha*255.0, color.r*255.0, color.g*255.0, color.b*255.0);
      68                 : }
      69                 : 
      70                 : class GradientStopsSkia : public GradientStops
      71               0 : {
      72                 : public:
      73               0 :   GradientStopsSkia(const std::vector<GradientStop>& aStops, uint32_t aNumStops, ExtendMode aExtendMode)
      74                 :     : mCount(aNumStops)
      75               0 :     , mExtendMode(aExtendMode)
      76                 :   {
      77               0 :     if (mCount == 0) {
      78               0 :       return;
      79                 :     }
      80                 : 
      81                 :     // Skia gradients always require a stop at 0.0 and 1.0, insert these if
      82                 :     // we don't have them.
      83               0 :     uint32_t shift = 0;
      84               0 :     if (aStops[0].offset != 0) {
      85               0 :       mCount++;
      86               0 :       shift = 1;
      87                 :     }
      88               0 :     if (aStops[aNumStops-1].offset != 1) {
      89               0 :       mCount++;
      90                 :     }
      91               0 :     mColors.resize(mCount);
      92               0 :     mPositions.resize(mCount);
      93               0 :     if (aStops[0].offset != 0) {
      94               0 :       mColors[0] = ColorToSkColor(aStops[0].color, 1.0);
      95               0 :       mPositions[0] = 0;
      96                 :     }
      97               0 :     for (uint32_t i = 0; i < aNumStops; i++) {
      98               0 :       mColors[i + shift] = ColorToSkColor(aStops[i].color, 1.0);
      99               0 :       mPositions[i + shift] = SkFloatToScalar(aStops[i].offset);
     100                 :     }
     101               0 :     if (aStops[aNumStops-1].offset != 1) {
     102               0 :       mColors[mCount-1] = ColorToSkColor(aStops[aNumStops-1].color, 1.0);
     103               0 :       mPositions[mCount-1] = SK_Scalar1;
     104                 :     }
     105                 :   }
     106                 : 
     107               0 :   BackendType GetBackendType() const { return BACKEND_SKIA; }
     108                 : 
     109                 :   std::vector<SkColor> mColors;
     110                 :   std::vector<SkScalar> mPositions;
     111                 :   int mCount;
     112                 :   ExtendMode mExtendMode;
     113                 : };
     114                 : 
     115                 : SkXfermode::Mode
     116               0 : GfxOpToSkiaOp(CompositionOp op)
     117                 : {
     118               0 :   switch (op)
     119                 :   {
     120                 :     case OP_OVER:
     121               0 :       return SkXfermode::kSrcOver_Mode;
     122                 :     case OP_ADD:
     123               0 :       return SkXfermode::kPlus_Mode;
     124                 :     case OP_ATOP:
     125               0 :       return SkXfermode::kSrcATop_Mode;
     126                 :     case OP_OUT:
     127               0 :       return SkXfermode::kSrcOut_Mode;
     128                 :     case OP_IN:
     129               0 :       return SkXfermode::kSrcIn_Mode;
     130                 :     case OP_SOURCE:
     131               0 :       return SkXfermode::kSrc_Mode;
     132                 :     case OP_DEST_IN:
     133               0 :       return SkXfermode::kDstIn_Mode;
     134                 :     case OP_DEST_OUT:
     135               0 :       return SkXfermode::kDstOut_Mode;
     136                 :     case OP_DEST_OVER:
     137               0 :       return SkXfermode::kDstOver_Mode;
     138                 :     case OP_DEST_ATOP:
     139               0 :       return SkXfermode::kDstATop_Mode;
     140                 :     case OP_XOR:
     141               0 :       return SkXfermode::kXor_Mode;
     142                 :     case OP_COUNT:
     143               0 :       return SkXfermode::kSrcOver_Mode;
     144                 :   }
     145               0 :   return SkXfermode::kSrcOver_Mode;
     146                 : }
     147                 : 
     148                 : 
     149                 : SkRect
     150               0 : RectToSkRect(const Rect& aRect)
     151                 : {
     152                 :   return SkRect::MakeXYWH(SkFloatToScalar(aRect.x), SkFloatToScalar(aRect.y), 
     153               0 :                           SkFloatToScalar(aRect.width), SkFloatToScalar(aRect.height));
     154                 : }
     155                 : 
     156                 : SkRect
     157               0 : IntRectToSkRect(const IntRect& aRect)
     158                 : {
     159                 :   return SkRect::MakeXYWH(SkIntToScalar(aRect.x), SkIntToScalar(aRect.y), 
     160               0 :                           SkIntToScalar(aRect.width), SkIntToScalar(aRect.height));
     161                 : }
     162                 : 
     163                 : SkIRect
     164               0 : RectToSkIRect(const Rect& aRect)
     165                 : {
     166               0 :   return SkIRect::MakeXYWH(aRect.x, aRect.y, aRect.width, aRect.height);
     167                 : }
     168                 : 
     169                 : SkIRect
     170               0 : IntRectToSkIRect(const IntRect& aRect)
     171                 : {
     172               0 :   return SkIRect::MakeXYWH(aRect.x, aRect.y, aRect.width, aRect.height);
     173                 : }
     174                 : 
     175                 : 
     176               0 : DrawTargetSkia::DrawTargetSkia()
     177                 : {
     178               0 : }
     179                 : 
     180               0 : DrawTargetSkia::~DrawTargetSkia()
     181                 : {
     182               0 :   if (mSnapshots.size()) {
     183               0 :     for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
     184               0 :          iter != mSnapshots.end(); iter++) {
     185               0 :       (*iter)->DrawTargetDestroyed();
     186                 :     }
     187                 :     // All snapshots will now have copied data.
     188               0 :     mSnapshots.clear();
     189                 :   }
     190               0 : }
     191                 : 
     192                 : TemporaryRef<SourceSurface>
     193               0 : DrawTargetSkia::Snapshot()
     194                 : {
     195               0 :   RefPtr<SourceSurfaceSkia> source = new SourceSurfaceSkia();
     196               0 :   if (!source->InitWithBitmap(mBitmap, mFormat, this)) {
     197               0 :     return NULL;
     198                 :   }
     199               0 :   AppendSnapshot(source);
     200               0 :   return source;
     201                 : }
     202                 : 
     203                 : SkShader::TileMode
     204               0 : ExtendModeToTileMode(ExtendMode aMode)
     205                 : {
     206               0 :   switch (aMode)
     207                 :   {
     208                 :     case EXTEND_CLAMP:
     209               0 :       return SkShader::kClamp_TileMode;
     210                 :     case EXTEND_REPEAT:
     211               0 :       return SkShader::kRepeat_TileMode;
     212                 :     case EXTEND_REFLECT:
     213               0 :       return SkShader::kMirror_TileMode;
     214                 :   }
     215               0 :   return SkShader::kClamp_TileMode;
     216                 : }
     217                 : 
     218               0 : void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0)
     219                 : {
     220               0 :   switch (aPattern.GetType()) {
     221                 :     case PATTERN_COLOR: {
     222               0 :       Color color = static_cast<const ColorPattern&>(aPattern).mColor;
     223               0 :       aPaint.setColor(ColorToSkColor(color, aAlpha));
     224               0 :       break;
     225                 :     }
     226                 :     case PATTERN_LINEAR_GRADIENT: {
     227               0 :       const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
     228               0 :       GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
     229               0 :       SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);
     230                 : 
     231               0 :       if (stops->mCount >= 2) {
     232                 :         SkPoint points[2];
     233               0 :         points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
     234               0 :         points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));
     235                 : 
     236                 :         SkShader* shader = SkGradientShader::CreateLinear(points, 
     237               0 :                                                           &stops->mColors.front(), 
     238               0 :                                                           &stops->mPositions.front(), 
     239                 :                                                           stops->mCount, 
     240               0 :                                                           mode);
     241                 :         SkMatrix mat;
     242               0 :         GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
     243               0 :         shader->setLocalMatrix(mat);
     244               0 :         SkSafeUnref(aPaint.setShader(shader));
     245                 :       } else {
     246               0 :         aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
     247                 :       }
     248               0 :       break;
     249                 :     }
     250                 :     case PATTERN_RADIAL_GRADIENT: {
     251               0 :       const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
     252               0 :       GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
     253               0 :       SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);
     254                 : 
     255               0 :       if (stops->mCount >= 2) {
     256                 :         SkPoint points[2];
     257               0 :         points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y));
     258               0 :         points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y));
     259                 : 
     260                 :         SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0], 
     261                 :                                                                   SkFloatToScalar(pat.mRadius1),
     262                 :                                                                   points[1], 
     263                 :                                                                   SkFloatToScalar(pat.mRadius2),
     264               0 :                                                                   &stops->mColors.front(), 
     265               0 :                                                                   &stops->mPositions.front(), 
     266                 :                                                                   stops->mCount, 
     267               0 :                                                                   mode);
     268                 :         SkMatrix mat;
     269               0 :         GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
     270               0 :         shader->setLocalMatrix(mat);
     271               0 :         SkSafeUnref(aPaint.setShader(shader));
     272                 :       } else {
     273               0 :         aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
     274                 :       }
     275               0 :       break;
     276                 :     }
     277                 :     case PATTERN_SURFACE: {
     278               0 :       const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
     279               0 :       const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(pat.mSurface.get())->GetBitmap();
     280                 : 
     281               0 :       SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode);
     282               0 :       SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode);
     283                 :       SkMatrix mat;
     284               0 :       GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
     285               0 :       shader->setLocalMatrix(mat);
     286               0 :       SkSafeUnref(aPaint.setShader(shader));
     287               0 :       if (pat.mFilter == FILTER_POINT) {
     288               0 :         aPaint.setFilterBitmap(false);
     289                 :       }
     290               0 :       break;
     291                 :     }
     292                 :   }
     293               0 : }
     294                 : 
     295                 : struct AutoPaintSetup {
     296               0 :   AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern)
     297               0 :     : mNeedsRestore(false), mAlpha(1.0)
     298                 :   {
     299               0 :     Init(aCanvas, aOptions);
     300               0 :     SetPaintPattern(mPaint, aPattern, mAlpha);
     301               0 :   }
     302                 : 
     303               0 :   AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions)
     304               0 :     : mNeedsRestore(false), mAlpha(1.0)
     305                 :   {
     306               0 :     Init(aCanvas, aOptions);
     307               0 :   }
     308                 : 
     309               0 :   ~AutoPaintSetup()
     310               0 :   {
     311               0 :     if (mNeedsRestore) {
     312               0 :       mCanvas->restore();
     313                 :     }
     314               0 :   }
     315                 : 
     316               0 :   void Init(SkCanvas *aCanvas, const DrawOptions& aOptions)
     317                 :   {
     318               0 :     mPaint.setXfermodeMode(GfxOpToSkiaOp(aOptions.mCompositionOp));
     319               0 :     mCanvas = aCanvas;
     320                 : 
     321                 :     //TODO: Can we set greyscale somehow?
     322               0 :     if (aOptions.mAntialiasMode != AA_NONE) {
     323               0 :       mPaint.setAntiAlias(true);
     324                 :     } else {
     325               0 :       mPaint.setAntiAlias(false);
     326                 :     }
     327                 : 
     328               0 :     NS_ASSERTION(aOptions.mSnapping == SNAP_NONE, "Pixel snapping not supported yet!");
     329                 :     
     330                 :     // TODO: We could skip the temporary for operator_source and just
     331                 :     // clear the clip rect. The other operators would be harder
     332                 :     // but could be worth it to skip pushing a group.
     333               0 :     if (!IsOperatorBoundByMask(aOptions.mCompositionOp)) {
     334               0 :       mPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
     335               0 :       SkPaint temp;
     336               0 :       temp.setXfermodeMode(GfxOpToSkiaOp(aOptions.mCompositionOp));
     337               0 :       temp.setAlpha(aOptions.mAlpha*255);
     338                 :       //TODO: Get a rect here
     339               0 :       mCanvas->saveLayer(NULL, &temp);
     340               0 :       mNeedsRestore = true;
     341                 :     } else {
     342               0 :       mPaint.setAlpha(aOptions.mAlpha*255.0);
     343               0 :       mAlpha = aOptions.mAlpha;
     344                 :     }
     345               0 :     mPaint.setFilterBitmap(true);
     346               0 :   }
     347                 : 
     348                 :   // TODO: Maybe add an operator overload to access this easier?
     349                 :   SkPaint mPaint;
     350                 :   bool mNeedsRestore;
     351                 :   SkCanvas* mCanvas;
     352                 :   Float mAlpha;
     353                 : };
     354                 : 
     355                 : void
     356               0 : DrawTargetSkia::Flush()
     357                 : {
     358               0 : }
     359                 : 
     360                 : void
     361               0 : DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
     362                 :                             const Rect &aDest,
     363                 :                             const Rect &aSource,
     364                 :                             const DrawSurfaceOptions &aSurfOptions,
     365                 :                             const DrawOptions &aOptions)
     366                 : {
     367               0 :   if (aSurface->GetType() != SURFACE_SKIA) {
     368               0 :     return;
     369                 :   }
     370                 : 
     371               0 :   if (aSource.IsEmpty()) {
     372               0 :     return;
     373                 :   }
     374                 : 
     375               0 :   MarkChanged();
     376                 : 
     377               0 :   SkRect destRect = RectToSkRect(aDest);
     378               0 :   SkRect sourceRect = RectToSkRect(aSource);
     379                 : 
     380                 :   SkMatrix matrix;
     381               0 :   matrix.setRectToRect(sourceRect, destRect, SkMatrix::kFill_ScaleToFit);
     382                 :   
     383               0 :   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
     384                 :  
     385               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions);
     386               0 :   SkShader *shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
     387               0 :   shader->setLocalMatrix(matrix);
     388               0 :   SkSafeUnref(paint.mPaint.setShader(shader));
     389               0 :   if (aSurfOptions.mFilter != FILTER_LINEAR) {
     390               0 :     paint.mPaint.setFilterBitmap(false);
     391                 :   }
     392               0 :   mCanvas->drawRect(destRect, paint.mPaint);
     393                 : }
     394                 : 
     395                 : void
     396               0 : DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface,
     397                 :                                       const Point &aDest,
     398                 :                                       const Color &aColor,
     399                 :                                       const Point &aOffset,
     400                 :                                       Float aSigma,
     401                 :                                       CompositionOp aOperator)
     402                 : {
     403               0 :   MarkChanged();
     404               0 :   mCanvas->save(SkCanvas::kMatrix_SaveFlag);
     405               0 :   mCanvas->resetMatrix();
     406                 : 
     407                 :   uint32_t blurFlags = SkBlurMaskFilter::kHighQuality_BlurFlag |
     408               0 :                        SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
     409               0 :   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
     410               0 :   SkShader* shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
     411                 :   SkMatrix matrix;
     412               0 :   matrix.reset();
     413               0 :   matrix.setTranslateX(SkFloatToScalar(aDest.x));
     414               0 :   matrix.setTranslateY(SkFloatToScalar(aDest.y));
     415               0 :   shader->setLocalMatrix(matrix);
     416               0 :   SkLayerDrawLooper* dl = new SkLayerDrawLooper;
     417               0 :   SkLayerDrawLooper::LayerInfo info;
     418               0 :   info.fPaintBits |= SkLayerDrawLooper::kShader_Bit;
     419               0 :   SkPaint *layerPaint = dl->addLayer(info);
     420               0 :   layerPaint->setShader(shader);
     421                 : 
     422               0 :   info.fPaintBits = 0;
     423               0 :   info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit;
     424               0 :   info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit;
     425               0 :   info.fColorMode = SkXfermode::kDst_Mode;
     426               0 :   info.fOffset.set(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y));
     427               0 :   info.fPostTranslate = true;
     428                 : 
     429               0 :   SkMaskFilter* mf = SkBlurMaskFilter::Create(aSigma, SkBlurMaskFilter::kNormal_BlurStyle, blurFlags);
     430               0 :   SkColor color = ColorToSkColor(aColor, 1);
     431               0 :   SkColorFilter* cf = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode);
     432                 : 
     433                 : 
     434               0 :   layerPaint = dl->addLayer(info);
     435               0 :   SkSafeUnref(layerPaint->setMaskFilter(mf));
     436               0 :   SkSafeUnref(layerPaint->setColorFilter(cf));
     437               0 :   layerPaint->setColor(color);
     438                 :   
     439                 :   // TODO: This is using the rasterizer to calculate an alpha mask
     440                 :   // on both the shadow and normal layers. We should fix this
     441                 :   // properly so it only happens for the shadow layer
     442               0 :   SkLayerRasterizer *raster = new SkLayerRasterizer();
     443               0 :   SkPaint maskPaint;
     444               0 :   SkSafeUnref(maskPaint.setShader(shader));
     445               0 :   raster->addLayer(maskPaint, 0, 0);
     446                 :   
     447               0 :   SkPaint paint;
     448               0 :   paint.setAntiAlias(true);
     449               0 :   SkSafeUnref(paint.setRasterizer(raster));
     450               0 :   paint.setXfermodeMode(GfxOpToSkiaOp(aOperator));
     451               0 :   SkSafeUnref(paint.setLooper(dl));
     452                 : 
     453               0 :   SkRect rect = RectToSkRect(Rect(aDest.x, aDest.y, bitmap.width(), bitmap.height()));
     454               0 :   mCanvas->drawRect(rect, paint);
     455               0 :   mCanvas->restore();
     456               0 : }
     457                 : 
     458                 : void
     459               0 : DrawTargetSkia::FillRect(const Rect &aRect,
     460                 :                          const Pattern &aPattern,
     461                 :                          const DrawOptions &aOptions)
     462                 : {
     463               0 :   MarkChanged();
     464               0 :   SkRect rect = RectToSkRect(aRect);
     465               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     466                 : 
     467               0 :   mCanvas->drawRect(rect, paint.mPaint);
     468               0 : }
     469                 : 
     470                 : void
     471               0 : DrawTargetSkia::Stroke(const Path *aPath,
     472                 :                        const Pattern &aPattern,
     473                 :                        const StrokeOptions &aStrokeOptions,
     474                 :                        const DrawOptions &aOptions)
     475                 : {
     476               0 :   MarkChanged();
     477               0 :   if (aPath->GetBackendType() != BACKEND_SKIA) {
     478               0 :     return;
     479                 :   }
     480                 : 
     481               0 :   const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
     482                 : 
     483                 : 
     484               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     485               0 :   if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
     486                 :     return;
     487                 :   }
     488                 : 
     489               0 :   mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
     490                 : }
     491                 : 
     492                 : void
     493               0 : DrawTargetSkia::StrokeRect(const Rect &aRect,
     494                 :                            const Pattern &aPattern,
     495                 :                            const StrokeOptions &aStrokeOptions,
     496                 :                            const DrawOptions &aOptions)
     497                 : {
     498               0 :   MarkChanged();
     499               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     500               0 :   if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
     501                 :     return;
     502                 :   }
     503                 : 
     504               0 :   mCanvas->drawRect(RectToSkRect(aRect), paint.mPaint);
     505                 : }
     506                 : 
     507                 : void 
     508               0 : DrawTargetSkia::StrokeLine(const Point &aStart,
     509                 :                            const Point &aEnd,
     510                 :                            const Pattern &aPattern,
     511                 :                            const StrokeOptions &aStrokeOptions,
     512                 :                            const DrawOptions &aOptions)
     513                 : {
     514               0 :   MarkChanged();
     515               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     516               0 :   if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
     517                 :     return;
     518                 :   }
     519                 : 
     520                 :   mCanvas->drawLine(SkFloatToScalar(aStart.x), SkFloatToScalar(aStart.y), 
     521                 :                     SkFloatToScalar(aEnd.x), SkFloatToScalar(aEnd.y), 
     522               0 :                     paint.mPaint);
     523                 : }
     524                 : 
     525                 : void
     526               0 : DrawTargetSkia::Fill(const Path *aPath,
     527                 :                     const Pattern &aPattern,
     528                 :                     const DrawOptions &aOptions)
     529                 : {
     530               0 :   MarkChanged();
     531               0 :   if (aPath->GetBackendType() != BACKEND_SKIA) {
     532               0 :     return;
     533                 :   }
     534                 : 
     535               0 :   const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
     536                 : 
     537               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     538                 : 
     539               0 :   mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
     540                 : }
     541                 : 
     542                 : void
     543               0 : DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
     544                 :                            const GlyphBuffer &aBuffer,
     545                 :                            const Pattern &aPattern,
     546                 :                            const DrawOptions &aOptions)
     547                 : {
     548               0 :   if (aFont->GetType() != FONT_MAC && aFont->GetType() != FONT_SKIA) {
     549               0 :     return;
     550                 :   }
     551                 : 
     552               0 :   MarkChanged();
     553                 : 
     554               0 :   ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont);
     555                 : 
     556               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
     557               0 :   paint.mPaint.setTypeface(skiaFont->GetSkTypeface());
     558               0 :   paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
     559               0 :   paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
     560                 :   
     561               0 :   std::vector<uint16_t> indices;
     562               0 :   std::vector<SkPoint> offsets;
     563               0 :   indices.resize(aBuffer.mNumGlyphs);
     564               0 :   offsets.resize(aBuffer.mNumGlyphs);
     565                 : 
     566               0 :   for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
     567               0 :     indices[i] = aBuffer.mGlyphs[i].mIndex;
     568               0 :     offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x);
     569               0 :     offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y);
     570                 :   }
     571                 : 
     572               0 :   mCanvas->drawPosText(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), paint.mPaint);
     573                 : }
     574                 : 
     575                 : void
     576               0 : DrawTargetSkia::Mask(const Pattern &aSource,
     577                 :                      const Pattern &aMask,
     578                 :                      const DrawOptions &aOptions)
     579                 : {
     580               0 :   MarkChanged();
     581               0 :   AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
     582                 : 
     583               0 :   SkPaint maskPaint;
     584               0 :   SetPaintPattern(maskPaint, aMask);
     585                 :   
     586               0 :   SkLayerRasterizer *raster = new SkLayerRasterizer();
     587               0 :   raster->addLayer(maskPaint);
     588               0 :   SkSafeUnref(paint.mPaint.setRasterizer(raster));
     589                 : 
     590                 :   // Skia only uses the mask rasterizer when we are drawing a path/rect.
     591                 :   // Take our destination bounds and convert them into user space to use
     592                 :   // as the path to draw.
     593               0 :   SkPath path;
     594               0 :   path.addRect(SkRect::MakeWH(mSize.width, mSize.height));
     595                 :  
     596               0 :   Matrix temp = mTransform;
     597               0 :   temp.Invert();
     598                 :   SkMatrix mat;
     599               0 :   GfxMatrixToSkiaMatrix(temp, mat);
     600               0 :   path.transform(mat);
     601                 : 
     602               0 :   mCanvas->drawPath(path, paint.mPaint);
     603               0 : }
     604                 : 
     605                 : TemporaryRef<SourceSurface>
     606               0 : DrawTargetSkia::CreateSourceSurfaceFromData(unsigned char *aData,
     607                 :                                              const IntSize &aSize,
     608                 :                                              int32_t aStride,
     609                 :                                              SurfaceFormat aFormat) const
     610                 : {
     611               0 :   RefPtr<SourceSurfaceSkia> newSurf = new SourceSurfaceSkia();
     612                 : 
     613               0 :   if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
     614               0 :     gfxDebug() << *this << ": Failure to create source surface from data. Size: " << aSize;
     615               0 :     return NULL;
     616                 :   }
     617                 :     
     618               0 :   return newSurf;
     619                 : }
     620                 : 
     621                 : TemporaryRef<DrawTarget>
     622               0 : DrawTargetSkia::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
     623                 : {
     624               0 :   RefPtr<DrawTargetSkia> target = new DrawTargetSkia();
     625               0 :   if (!target->Init(aSize, aFormat)) {
     626               0 :     return NULL;
     627                 :   }
     628               0 :   return target;
     629                 : }
     630                 : 
     631                 : TemporaryRef<SourceSurface>
     632               0 : DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const
     633                 : {
     634               0 :   return NULL;
     635                 : }
     636                 : 
     637                 : TemporaryRef<SourceSurface>
     638               0 : DrawTargetSkia::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
     639                 : {
     640               0 :   return NULL;
     641                 : }
     642                 : 
     643                 : void
     644               0 : DrawTargetSkia::CopySurface(SourceSurface *aSurface,
     645                 :                             const IntRect& aSourceRect,
     646                 :                             const IntPoint &aDestination)
     647                 : {
     648                 :   //TODO: We could just use writePixels() here if the sourceRect is the entire source
     649                 :   
     650               0 :     if (aSurface->GetType() != SURFACE_SKIA) {
     651               0 :     return;
     652                 :   }
     653                 : 
     654               0 :   MarkChanged();
     655                 :   
     656               0 :   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
     657                 : 
     658               0 :   mCanvas->save();
     659               0 :   mCanvas->resetMatrix();
     660               0 :   SkRect dest = IntRectToSkRect(IntRect(aDestination.x, aDestination.y, aSourceRect.width, aSourceRect.height)); 
     661               0 :   SkIRect source = IntRectToSkIRect(aSourceRect);
     662               0 :   mCanvas->clipRect(dest, SkRegion::kReplace_Op);
     663               0 :   SkPaint paint;
     664               0 :   paint.setXfermodeMode(GfxOpToSkiaOp(OP_SOURCE));
     665               0 :   mCanvas->drawBitmapRect(bitmap, &source, dest, &paint);
     666               0 :   mCanvas->restore();
     667                 : }
     668                 : 
     669                 : bool
     670               0 : DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
     671                 : {
     672               0 :   mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height);
     673               0 :   if (!mBitmap.allocPixels()) {
     674               0 :     return false;
     675                 :   }
     676               0 :   mBitmap.eraseARGB(0, 0, 0, 0);
     677               0 :   SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
     678               0 :   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
     679               0 :   mSize = aSize;
     680                 : 
     681               0 :   mDevice = device.get();
     682               0 :   mCanvas = canvas.get();
     683               0 :   mFormat = aFormat;
     684               0 :   return true;
     685                 : }
     686                 : 
     687                 : void
     688               0 : DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
     689                 : {
     690               0 :   mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
     691               0 :   mBitmap.setPixels(aData);
     692                 :   
     693               0 :   SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
     694               0 :   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
     695               0 :   mSize = aSize;
     696                 : 
     697               0 :   mDevice = device.get();
     698               0 :   mCanvas = canvas.get();
     699               0 :   mFormat = aFormat;
     700               0 : }
     701                 : 
     702                 : void
     703               0 : DrawTargetSkia::SetTransform(const Matrix& aTransform)
     704                 : {
     705                 :   SkMatrix mat;
     706               0 :   GfxMatrixToSkiaMatrix(aTransform, mat);
     707               0 :   mCanvas->setMatrix(mat);
     708               0 :   mTransform = aTransform;
     709               0 : }
     710                 : 
     711                 : TemporaryRef<PathBuilder> 
     712               0 : DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
     713                 : {
     714               0 :   RefPtr<PathBuilderSkia> pb = new PathBuilderSkia(aFillRule);
     715               0 :   return pb;
     716                 : }
     717                 : 
     718                 : void
     719               0 : DrawTargetSkia::ClearRect(const Rect &aRect)
     720                 : {
     721               0 :   MarkChanged();
     722               0 :   SkPaint paint;
     723               0 :   mCanvas->save();
     724               0 :   mCanvas->clipRect(RectToSkRect(aRect), SkRegion::kIntersect_Op, USE_SOFT_CLIPPING);
     725               0 :   paint.setColor(SkColorSetARGB(0, 0, 0, 0));
     726               0 :   paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     727               0 :   mCanvas->drawPaint(paint);
     728               0 :   mCanvas->restore();
     729               0 : }
     730                 : 
     731                 : void
     732               0 : DrawTargetSkia::PushClip(const Path *aPath)
     733                 : {
     734               0 :   if (aPath->GetBackendType() != BACKEND_SKIA) {
     735               0 :     return;
     736                 :   }
     737                 : 
     738               0 :   const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
     739               0 :   mCanvas->save(SkCanvas::kClip_SaveFlag);
     740               0 :   mCanvas->clipPath(skiaPath->GetPath(), SkRegion::kIntersect_Op, USE_SOFT_CLIPPING);
     741                 : }
     742                 : 
     743                 : void
     744               0 : DrawTargetSkia::PushClipRect(const Rect& aRect)
     745                 : {
     746               0 :   SkRect rect = RectToSkRect(aRect);
     747                 : 
     748               0 :   mCanvas->save(SkCanvas::kClip_SaveFlag);
     749               0 :   mCanvas->clipRect(rect, SkRegion::kIntersect_Op, USE_SOFT_CLIPPING);
     750               0 : }
     751                 : 
     752                 : void
     753               0 : DrawTargetSkia::PopClip()
     754                 : {
     755               0 :   mCanvas->restore();
     756               0 : }
     757                 : 
     758                 : TemporaryRef<GradientStops>
     759               0 : DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode) const
     760                 : {
     761               0 :   std::vector<GradientStop> stops;
     762               0 :   stops.resize(aNumStops);
     763               0 :   for (uint32_t i = 0; i < aNumStops; i++) {
     764               0 :     stops[i] = aStops[i];
     765                 :   }
     766               0 :   std::stable_sort(stops.begin(), stops.end());
     767                 :   
     768               0 :   return new GradientStopsSkia(stops, aNumStops, aExtendMode);
     769                 : }
     770                 : 
     771                 : void
     772               0 : DrawTargetSkia::AppendSnapshot(SourceSurfaceSkia* aSnapshot)
     773                 : {
     774               0 :   mSnapshots.push_back(aSnapshot);
     775               0 : }
     776                 : 
     777                 : void
     778               0 : DrawTargetSkia::RemoveSnapshot(SourceSurfaceSkia* aSnapshot)
     779                 : {
     780               0 :   std::vector<SourceSurfaceSkia*>::iterator iter = std::find(mSnapshots.begin(), mSnapshots.end(), aSnapshot);
     781               0 :   if (iter != mSnapshots.end()) {
     782               0 :     mSnapshots.erase(iter);
     783                 :   }
     784               0 : }
     785                 : 
     786                 : void
     787               0 : DrawTargetSkia::MarkChanged()
     788                 : {
     789               0 :   if (mSnapshots.size()) {
     790               0 :     for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
     791               0 :          iter != mSnapshots.end(); iter++) {
     792               0 :       (*iter)->DrawTargetWillChange();
     793                 :     }
     794                 :     // All snapshots will now have copied data.
     795               0 :     mSnapshots.clear();
     796                 :   }
     797               0 : }
     798                 : 
     799                 : }
     800                 : }

Generated by: LCOV version 1.7