LCOV - code coverage report
Current view: top level - gfx/2d - DrawTargetTiled.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 183 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       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/. */
       5             : 
       6             : #include "DrawTargetTiled.h"
       7             : #include "Logging.h"
       8             : #include "PathHelpers.h"
       9             : 
      10             : using namespace std;
      11             : 
      12             : namespace mozilla {
      13             : namespace gfx {
      14             : 
      15           0 : DrawTargetTiled::DrawTargetTiled()
      16             : {
      17           0 : }
      18             : 
      19             : bool
      20           0 : DrawTargetTiled::Init(const TileSet& aTiles)
      21             : {
      22           0 :   if (!aTiles.mTileCount) {
      23           0 :     return false;
      24             :   }
      25             : 
      26           0 :   mTiles.reserve(aTiles.mTileCount);
      27           0 :   for (size_t i = 0; i < aTiles.mTileCount; ++i) {
      28           0 :     mTiles.push_back(TileInternal(aTiles.mTiles[i]));
      29           0 :     if (!aTiles.mTiles[i].mDrawTarget) {
      30           0 :       return false;
      31             :     }
      32           0 :     if (mTiles[0].mDrawTarget->GetFormat() != mTiles.back().mDrawTarget->GetFormat() ||
      33           0 :         mTiles[0].mDrawTarget->GetBackendType() != mTiles.back().mDrawTarget->GetBackendType()) {
      34           0 :       return false;
      35             :     }
      36           0 :     uint32_t newXMost = max(mRect.XMost(),
      37           0 :                             mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
      38           0 :     uint32_t newYMost = max(mRect.YMost(),
      39           0 :                             mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
      40           0 :     mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x);
      41           0 :     mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y);
      42           0 :     mRect.width = newXMost - mRect.x;
      43           0 :     mRect.height = newYMost - mRect.y;
      44           0 :     mTiles[i].mDrawTarget->SetTransform(Matrix::Translation(mTiles[i].mTileOrigin.x,
      45           0 :                                                             mTiles[i].mTileOrigin.y));
      46             :   }
      47           0 :   mFormat = mTiles[0].mDrawTarget->GetFormat();
      48           0 :   SetPermitSubpixelAA(IsOpaque(mFormat));
      49           0 :   return true;
      50             : }
      51             : 
      52             : already_AddRefed<SourceSurface>
      53           0 : DrawTargetTiled::Snapshot()
      54             : {
      55           0 :   return MakeAndAddRef<SnapshotTiled>(mTiles, mRect);
      56             : }
      57             : 
      58             : void
      59           0 : DrawTargetTiled::DetachAllSnapshots()
      60           0 : {}
      61             : 
      62             : // Skip the mClippedOut check since this is only used for Flush() which
      63             : // should happen even if we're clipped.
      64             : #define TILED_COMMAND(command) \
      65             :   void \
      66             :   DrawTargetTiled::command() \
      67             :   { \
      68             :     for (size_t i = 0; i < mTiles.size(); i++) { \
      69             :       mTiles[i].mDrawTarget->command(); \
      70             :     } \
      71             :   }
      72             : #define TILED_COMMAND1(command, type1) \
      73             :   void \
      74             :   DrawTargetTiled::command(type1 arg1) \
      75             :   { \
      76             :     for (size_t i = 0; i < mTiles.size(); i++) { \
      77             :       if (!mTiles[i].mClippedOut) \
      78             :         mTiles[i].mDrawTarget->command(arg1); \
      79             :     } \
      80             :   }
      81             : #define TILED_COMMAND3(command, type1, type2, type3) \
      82             :   void \
      83             :   DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3) \
      84             :   { \
      85             :     for (size_t i = 0; i < mTiles.size(); i++) { \
      86             :       if (!mTiles[i].mClippedOut) \
      87             :         mTiles[i].mDrawTarget->command(arg1, arg2, arg3); \
      88             :     } \
      89             :   }
      90             : #define TILED_COMMAND4(command, type1, type2, type3, type4) \
      91             :   void \
      92             :   DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
      93             :   { \
      94             :     for (size_t i = 0; i < mTiles.size(); i++) { \
      95             :       if (!mTiles[i].mClippedOut) \
      96             :         mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4); \
      97             :     } \
      98             :   }
      99             : #define TILED_COMMAND5(command, type1, type2, type3, type4, type5) \
     100             :   void \
     101             :   DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
     102             :   { \
     103             :     for (size_t i = 0; i < mTiles.size(); i++) { \
     104             :       if (!mTiles[i].mClippedOut) \
     105             :         mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4, arg5); \
     106             :     } \
     107             :   }
     108             : 
     109           0 : TILED_COMMAND(Flush)
     110           0 : TILED_COMMAND4(DrawFilter, FilterNode*, const Rect&, const Point&, const DrawOptions&)
     111           0 : TILED_COMMAND1(ClearRect, const Rect&)
     112           0 : TILED_COMMAND4(MaskSurface, const Pattern&, SourceSurface*, Point, const DrawOptions&)
     113           0 : TILED_COMMAND5(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&, const GlyphRenderingOptions*)
     114           0 : TILED_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&)
     115             : 
     116             : void
     117           0 : DrawTargetTiled::PushClip(const Path* aPath)
     118             : {
     119           0 :   mClippedOutTilesStack.push_back(std::vector<uint32_t>());
     120           0 :   std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
     121             : 
     122           0 :   Rect deviceRect = aPath->GetBounds(mTransform);
     123             : 
     124           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     125           0 :     if (!mTiles[i].mClippedOut) {
     126           0 :       if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     127           0 :                                    mTiles[i].mTileOrigin.y,
     128           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     129           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     130           0 :         mTiles[i].mDrawTarget->PushClip(aPath);
     131             :       } else {
     132           0 :         mTiles[i].mClippedOut = true;
     133           0 :         clippedTiles.push_back(i);
     134             :       }
     135             :     }
     136             :   }
     137           0 : }
     138             : 
     139             : void
     140           0 : DrawTargetTiled::PushClipRect(const Rect& aRect)
     141             : {
     142           0 :   mClippedOutTilesStack.push_back(std::vector<uint32_t>());
     143           0 :   std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
     144             : 
     145           0 :   Rect deviceRect = mTransform.TransformBounds(aRect);
     146             : 
     147           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     148           0 :     if (!mTiles[i].mClippedOut) {
     149           0 :       if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     150           0 :                                    mTiles[i].mTileOrigin.y,
     151           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     152           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     153           0 :         mTiles[i].mDrawTarget->PushClipRect(aRect);
     154             :       } else {
     155           0 :         mTiles[i].mClippedOut = true;
     156           0 :         clippedTiles.push_back(i);
     157             :       }
     158             :     }
     159             :   }
     160           0 : }
     161             : 
     162             : void
     163           0 : DrawTargetTiled::PopClip()
     164             : {
     165           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     166           0 :     if (!mTiles[i].mClippedOut) {
     167           0 :       mTiles[i].mDrawTarget->PopClip();
     168             :     }
     169             :   }
     170             : 
     171           0 :   std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
     172           0 :   for (size_t i = 0; i < clippedTiles.size(); i++) {
     173           0 :     mTiles[clippedTiles[i]].mClippedOut = false;
     174             :   }
     175             : 
     176           0 :   mClippedOutTilesStack.pop_back();
     177           0 : }
     178             : 
     179             : void
     180           0 : DrawTargetTiled::CopySurface(SourceSurface *aSurface,
     181             :                              const IntRect &aSourceRect,
     182             :                              const IntPoint &aDestination)
     183             : {
     184           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     185           0 :     IntPoint tileOrigin = mTiles[i].mTileOrigin;
     186           0 :     IntSize tileSize = mTiles[i].mDrawTarget->GetSize();
     187           0 :     if (!IntRect(aDestination, aSourceRect.Size()).Intersects(IntRect(tileOrigin, tileSize))) {
     188           0 :       continue;
     189             :     }
     190             :     // CopySurface ignores the transform, account for that here.
     191           0 :     mTiles[i].mDrawTarget->CopySurface(aSurface, aSourceRect, aDestination - tileOrigin);
     192             :   }
     193           0 : }
     194             : 
     195             : void
     196           0 : DrawTargetTiled::SetTransform(const Matrix& aTransform)
     197             : {
     198           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     199           0 :     Matrix mat = aTransform;
     200           0 :     mat.PostTranslate(Float(-mTiles[i].mTileOrigin.x), Float(-mTiles[i].mTileOrigin.y));
     201           0 :     mTiles[i].mDrawTarget->SetTransform(mat);
     202             :   }
     203           0 :   DrawTarget::SetTransform(aTransform);
     204           0 : }
     205             : 
     206             : void
     207           0 : DrawTargetTiled::SetPermitSubpixelAA(bool aPermitSubpixelAA)
     208             : {
     209           0 :   DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA);
     210           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     211           0 :     mTiles[i].mDrawTarget->SetPermitSubpixelAA(aPermitSubpixelAA);
     212             :   }
     213           0 : }
     214             : 
     215             : void
     216           0 : DrawTargetTiled::DrawSurface(SourceSurface* aSurface, const Rect& aDest, const Rect& aSource, const DrawSurfaceOptions& aSurfaceOptions, const DrawOptions& aDrawOptions)
     217             : {
     218           0 :   Rect deviceRect = mTransform.TransformBounds(aDest);
     219           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     220           0 :     if (!mTiles[i].mClippedOut &&
     221           0 :         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     222           0 :                                    mTiles[i].mTileOrigin.y,
     223           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     224           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     225           0 :       mTiles[i].mDrawTarget->DrawSurface(aSurface, aDest, aSource, aSurfaceOptions, aDrawOptions);
     226             :     }
     227             :   }
     228           0 : }
     229             : 
     230             : void
     231           0 : DrawTargetTiled::FillRect(const Rect& aRect, const Pattern& aPattern, const DrawOptions& aDrawOptions)
     232             : {
     233           0 :   Rect deviceRect = mTransform.TransformBounds(aRect);
     234           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     235           0 :     if (!mTiles[i].mClippedOut &&
     236           0 :         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     237           0 :                                    mTiles[i].mTileOrigin.y,
     238           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     239           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     240           0 :       mTiles[i].mDrawTarget->FillRect(aRect, aPattern, aDrawOptions);
     241             :     }
     242             :   }
     243           0 : }
     244             : 
     245             : void
     246           0 : DrawTargetTiled::Stroke(const Path* aPath, const Pattern& aPattern, const StrokeOptions& aStrokeOptions, const DrawOptions& aDrawOptions)
     247             : {
     248             :   // Approximate the stroke extents, since Path::GetStrokeExtents can be slow
     249           0 :   Rect deviceRect = aPath->GetBounds(mTransform);
     250           0 :   deviceRect.Inflate(MaxStrokeExtents(aStrokeOptions, mTransform));
     251           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     252           0 :     if (!mTiles[i].mClippedOut &&
     253           0 :         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     254           0 :                                    mTiles[i].mTileOrigin.y,
     255           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     256           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     257           0 :       mTiles[i].mDrawTarget->Stroke(aPath, aPattern, aStrokeOptions, aDrawOptions);
     258             :     }
     259             :   }
     260           0 : }
     261             : 
     262             : void
     263           0 : DrawTargetTiled::StrokeRect(const Rect& aRect, const Pattern& aPattern, const StrokeOptions &aStrokeOptions, const DrawOptions& aDrawOptions)
     264             : {
     265           0 :   Rect deviceRect = mTransform.TransformBounds(aRect);
     266           0 :   Margin strokeMargin = MaxStrokeExtents(aStrokeOptions, mTransform);
     267           0 :   Rect outerRect = deviceRect;
     268           0 :   outerRect.Inflate(strokeMargin);
     269           0 :   Rect innerRect;
     270           0 :   if (mTransform.IsRectilinear()) {
     271             :     // If rects are mapped to rects, we can compute the inner rect
     272             :     // of the stroked rect.
     273           0 :     innerRect = deviceRect;
     274           0 :     innerRect.Deflate(strokeMargin);
     275             :   }
     276           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     277           0 :     if (mTiles[i].mClippedOut) {
     278           0 :       continue;
     279             :     }
     280           0 :     Rect tileRect(mTiles[i].mTileOrigin.x,
     281           0 :                   mTiles[i].mTileOrigin.y,
     282           0 :                   mTiles[i].mDrawTarget->GetSize().width,
     283           0 :                   mTiles[i].mDrawTarget->GetSize().height);
     284           0 :     if (outerRect.Intersects(tileRect) && !innerRect.Contains(tileRect)) {
     285           0 :       mTiles[i].mDrawTarget->StrokeRect(aRect, aPattern, aStrokeOptions, aDrawOptions);
     286             :     }
     287             :   }
     288           0 : }
     289             : 
     290             : void
     291           0 : DrawTargetTiled::StrokeLine(const Point& aStart, const Point& aEnd, const Pattern& aPattern, const StrokeOptions &aStrokeOptions, const DrawOptions& aDrawOptions)
     292             : {
     293           0 :   Rect lineBounds = Rect(aStart, Size()).UnionEdges(Rect(aEnd, Size()));
     294           0 :   Rect deviceRect = mTransform.TransformBounds(lineBounds);
     295           0 :   deviceRect.Inflate(MaxStrokeExtents(aStrokeOptions, mTransform));
     296           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     297           0 :     if (!mTiles[i].mClippedOut &&
     298           0 :         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     299           0 :                                    mTiles[i].mTileOrigin.y,
     300           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     301           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     302           0 :       mTiles[i].mDrawTarget->StrokeLine(aStart, aEnd, aPattern, aStrokeOptions, aDrawOptions);
     303             :     }
     304             :   }
     305           0 : }
     306             : 
     307             : void
     308           0 : DrawTargetTiled::Fill(const Path* aPath, const Pattern& aPattern, const DrawOptions& aDrawOptions)
     309             : {
     310           0 :   Rect deviceRect = aPath->GetBounds(mTransform);
     311           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     312           0 :     if (!mTiles[i].mClippedOut &&
     313           0 :         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
     314           0 :                                    mTiles[i].mTileOrigin.y,
     315           0 :                                    mTiles[i].mDrawTarget->GetSize().width,
     316           0 :                                    mTiles[i].mDrawTarget->GetSize().height))) {
     317           0 :       mTiles[i].mDrawTarget->Fill(aPath, aPattern, aDrawOptions);
     318             :     }
     319             :   }
     320           0 : }
     321             : 
     322             : void
     323           0 : DrawTargetTiled::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
     324             :                            const Matrix& aMaskTransform, const IntRect& aBounds,
     325             :                            bool aCopyBackground)
     326             : {
     327             :   // XXX - not sure this is what we want or whether we want to continue drawing to a larger
     328             :   // intermediate surface, that would require tweaking the code in here a little though.
     329           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     330           0 :     if (!mTiles[i].mClippedOut) {
     331           0 :       IntRect bounds = aBounds;
     332           0 :       bounds.MoveBy(-mTiles[i].mTileOrigin);
     333           0 :       mTiles[i].mDrawTarget->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, bounds, aCopyBackground);
     334             :     }
     335             :   }
     336             : 
     337           0 :   PushedLayer layer(GetPermitSubpixelAA());
     338           0 :   mPushedLayers.push_back(layer);
     339           0 :   SetPermitSubpixelAA(aOpaque);
     340           0 : }
     341             : 
     342             : void
     343           0 : DrawTargetTiled::PopLayer()
     344             : {
     345             :   // XXX - not sure this is what we want or whether we want to continue drawing to a larger
     346             :   // intermediate surface, that would require tweaking the code in here a little though.
     347           0 :   for (size_t i = 0; i < mTiles.size(); i++) {
     348           0 :     if (!mTiles[i].mClippedOut) {
     349           0 :       mTiles[i].mDrawTarget->PopLayer();
     350             :     }
     351             :   }
     352             : 
     353           0 :   MOZ_ASSERT(mPushedLayers.size());
     354           0 :   const PushedLayer& layer = mPushedLayers.back();
     355           0 :   SetPermitSubpixelAA(layer.mOldPermitSubpixelAA);
     356           0 : }
     357             : 
     358             : } // namespace gfx
     359             : } // namespace mozilla

Generated by: LCOV version 1.13