gfx/2d/RecordedEvent.cpp

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

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

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

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */
     6 #include "RecordedEvent.h"
     7 #include "PathRecording.h"
     9 #include "Tools.h"
    10 #include "Filters.h"
    12 namespace mozilla {
    13 namespace gfx {
    15 using namespace std;
    17 static std::string NameFromBackend(BackendType aType)
    18 {
    19   switch (aType) {
    20   case BackendType::NONE:
    21     return "None";
    22   case BackendType::DIRECT2D:
    23     return "Direct2D";
    24   default:
    25     return "Unknown";
    26   }
    27 }
    29 #define LOAD_EVENT_TYPE(_typeenum, _class) \
    30   case _typeenum: return new _class(aStream)
    32 RecordedEvent *
    33 RecordedEvent::LoadEventFromStream(std::istream &aStream, EventType aType)
    34 {
    35   switch (aType) {
    36     LOAD_EVENT_TYPE(DRAWTARGETCREATION, RecordedDrawTargetCreation);
    37     LOAD_EVENT_TYPE(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction);
    38     LOAD_EVENT_TYPE(FILLRECT, RecordedFillRect);
    39     LOAD_EVENT_TYPE(STROKERECT, RecordedStrokeRect);
    40     LOAD_EVENT_TYPE(STROKELINE, RecordedStrokeLine);
    41     LOAD_EVENT_TYPE(CLEARRECT, RecordedClearRect);
    42     LOAD_EVENT_TYPE(COPYSURFACE, RecordedCopySurface);
    43     LOAD_EVENT_TYPE(SETTRANSFORM, RecordedSetTransform);
    44     LOAD_EVENT_TYPE(PUSHCLIPRECT, RecordedPushClipRect);
    45     LOAD_EVENT_TYPE(PUSHCLIP, RecordedPushClip);
    46     LOAD_EVENT_TYPE(POPCLIP, RecordedPopClip);
    47     LOAD_EVENT_TYPE(FILL, RecordedFill);
    48     LOAD_EVENT_TYPE(FILLGLYPHS, RecordedFillGlyphs);
    49     LOAD_EVENT_TYPE(MASK, RecordedMask);
    50     LOAD_EVENT_TYPE(STROKE, RecordedStroke);
    51     LOAD_EVENT_TYPE(DRAWSURFACE, RecordedDrawSurface);
    52     LOAD_EVENT_TYPE(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow);
    53     LOAD_EVENT_TYPE(DRAWFILTER, RecordedDrawFilter);
    54     LOAD_EVENT_TYPE(PATHCREATION, RecordedPathCreation);
    55     LOAD_EVENT_TYPE(PATHDESTRUCTION, RecordedPathDestruction);
    56     LOAD_EVENT_TYPE(SOURCESURFACECREATION, RecordedSourceSurfaceCreation);
    57     LOAD_EVENT_TYPE(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction);
    58     LOAD_EVENT_TYPE(FILTERNODECREATION, RecordedFilterNodeCreation);
    59     LOAD_EVENT_TYPE(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction);
    60     LOAD_EVENT_TYPE(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation);
    61     LOAD_EVENT_TYPE(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction);
    62     LOAD_EVENT_TYPE(SNAPSHOT, RecordedSnapshot);
    63     LOAD_EVENT_TYPE(SCALEDFONTCREATION, RecordedScaledFontCreation);
    64     LOAD_EVENT_TYPE(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction);
    65     LOAD_EVENT_TYPE(MASKSURFACE, RecordedMaskSurface);
    66     LOAD_EVENT_TYPE(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute);
    67     LOAD_EVENT_TYPE(FILTERNODESETINPUT, RecordedFilterNodeSetInput);
    68   default:
    69     return nullptr;
    70   }
    71 }
    73 string
    74 RecordedEvent::GetEventName(EventType aType)
    75 {
    76   switch (aType) {
    77   case DRAWTARGETCREATION:
    78     return "DrawTarget Creation";
    79   case DRAWTARGETDESTRUCTION:
    80     return "DrawTarget Destruction";
    81   case FILLRECT:
    82     return "FillRect";
    83   case STROKERECT:
    84     return "StrokeRect";
    85   case STROKELINE:
    86     return "StrokeLine";
    87   case CLEARRECT:
    88     return "ClearRect";
    89   case COPYSURFACE:
    90     return "CopySurface";
    91   case SETTRANSFORM:
    92     return "SetTransform";
    93   case PUSHCLIP:
    94     return "PushClip";
    95   case PUSHCLIPRECT:
    96     return "PushClipRect";
    97   case POPCLIP:
    98     return "PopClip";
    99   case FILL:
   100     return "Fill";
   101   case FILLGLYPHS:
   102     return "FillGlyphs";
   103   case MASK:
   104     return "Mask";
   105   case STROKE:
   106     return "Stroke";
   107   case DRAWSURFACE:
   108     return "DrawSurface";
   109   case DRAWSURFACEWITHSHADOW:
   110     return "DrawSurfaceWithShadow";
   111   case DRAWFILTER:
   112     return "DrawFilter";
   113   case PATHCREATION:
   114     return "PathCreation";
   115   case PATHDESTRUCTION:
   116     return "PathDestruction";
   117   case SOURCESURFACECREATION:
   118     return "SourceSurfaceCreation";
   119   case SOURCESURFACEDESTRUCTION:
   120     return "SourceSurfaceDestruction";
   121   case FILTERNODECREATION:
   122     return "FilterNodeCreation";
   123   case FILTERNODEDESTRUCTION:
   124     return "FilterNodeDestruction";
   125   case GRADIENTSTOPSCREATION:
   126     return "GradientStopsCreation";
   127   case GRADIENTSTOPSDESTRUCTION:
   128     return "GradientStopsDestruction";
   129   case SNAPSHOT:
   130     return "Snapshot";
   131   case SCALEDFONTCREATION:
   132     return "ScaledFontCreation";
   133   case SCALEDFONTDESTRUCTION:
   134     return "ScaledFontDestruction";
   135   case MASKSURFACE:
   136     return "MaskSurface";
   137   case FILTERNODESETATTRIBUTE:
   138     return "SetAttribute";
   139   case FILTERNODESETINPUT:
   140     return "SetInput";
   141   default:
   142     return "Unknown";
   143   }
   144 }
   146 void
   147 RecordedEvent::RecordPatternData(std::ostream &aStream, const PatternStorage &aPattern) const
   148 {
   149   WriteElement(aStream, aPattern.mType);
   151   switch (aPattern.mType) {
   152   case PatternType::COLOR:
   153     {
   154       WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(&aPattern.mStorage));
   155       return;
   156     }
   157   case PatternType::LINEAR_GRADIENT:
   158     {
   159       WriteElement(aStream, *reinterpret_cast<const LinearGradientPatternStorage*>(&aPattern.mStorage));
   160       return;
   161     }
   162   case PatternType::RADIAL_GRADIENT:
   163     {
   164       WriteElement(aStream, *reinterpret_cast<const RadialGradientPatternStorage*>(&aPattern.mStorage));
   165       return;
   166     }
   167   case PatternType::SURFACE:
   168     {
   169       WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(&aPattern.mStorage));
   170       return;
   171     }
   172   default:
   173     return;
   174   }
   175 }
   177 void
   178 RecordedEvent::ReadPatternData(std::istream &aStream, PatternStorage &aPattern) const
   179 {
   180   ReadElement(aStream, aPattern.mType);
   182   switch (aPattern.mType) {
   183   case PatternType::COLOR:
   184     {
   185       ReadElement(aStream, *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
   186       return;
   187     }
   188   case PatternType::LINEAR_GRADIENT:
   189     {
   190       ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(&aPattern.mStorage));
   191       return;
   192     }
   193   case PatternType::RADIAL_GRADIENT:
   194     {
   195       ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(&aPattern.mStorage));
   196       return;
   197     }
   198   case PatternType::SURFACE:
   199     {
   200       ReadElement(aStream, *reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage));
   201       return;
   202     }
   203   default:
   204     return;
   205   }
   206 }
   208 void
   209 RecordedEvent::StorePattern(PatternStorage &aDestination, const Pattern &aSource) const
   210 {
   211   aDestination.mType = aSource.GetType();
   213   switch (aSource.GetType()) {
   214   case PatternType::COLOR:
   215     {
   216       reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
   217         static_cast<const ColorPattern*>(&aSource)->mColor;
   218       return;
   219     }
   220   case PatternType::LINEAR_GRADIENT:
   221     {
   222       LinearGradientPatternStorage *store =
   223         reinterpret_cast<LinearGradientPatternStorage*>(&aDestination.mStorage);
   224       const LinearGradientPattern *pat =
   225         static_cast<const LinearGradientPattern*>(&aSource);
   226       store->mBegin = pat->mBegin;
   227       store->mEnd = pat->mEnd;
   228       store->mMatrix = pat->mMatrix;
   229       store->mStops = pat->mStops.get();
   230       return;
   231     }
   232   case PatternType::RADIAL_GRADIENT:
   233     {
   234       RadialGradientPatternStorage *store =
   235         reinterpret_cast<RadialGradientPatternStorage*>(&aDestination.mStorage);
   236       const RadialGradientPattern *pat =
   237         static_cast<const RadialGradientPattern*>(&aSource);
   238       store->mCenter1 = pat->mCenter1;
   239       store->mCenter2 = pat->mCenter2;
   240       store->mRadius1 = pat->mRadius1;
   241       store->mRadius2 = pat->mRadius2;
   242       store->mMatrix = pat->mMatrix;
   243       store->mStops = pat->mStops.get();
   244       return;
   245     }
   246   case PatternType::SURFACE:
   247     {
   248       SurfacePatternStorage *store =
   249         reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
   250       const SurfacePattern *pat =
   251         static_cast<const SurfacePattern*>(&aSource);
   252       store->mExtend = pat->mExtendMode;
   253       store->mFilter = pat->mFilter;
   254       store->mMatrix = pat->mMatrix;
   255       store->mSurface = pat->mSurface;
   256       return;
   257     }
   258   }
   259 }
   261 void
   262 RecordedEvent::RecordStrokeOptions(std::ostream &aStream, const StrokeOptions &aStrokeOptions) const
   263 {
   264   JoinStyle joinStyle = aStrokeOptions.mLineJoin;
   265   CapStyle capStyle = aStrokeOptions.mLineCap;
   267   WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
   268   WriteElement(aStream, aStrokeOptions.mDashOffset);
   269   WriteElement(aStream, aStrokeOptions.mLineWidth);
   270   WriteElement(aStream, aStrokeOptions.mMiterLimit);
   271   WriteElement(aStream, joinStyle);
   272   WriteElement(aStream, capStyle);
   274   if (!aStrokeOptions.mDashPattern) {
   275     return;
   276   }
   278   aStream.write((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength);
   279 }
   281 void
   282 RecordedEvent::ReadStrokeOptions(std::istream &aStream, StrokeOptions &aStrokeOptions)
   283 {
   284   uint64_t dashLength;
   285   JoinStyle joinStyle;
   286   CapStyle capStyle;
   288   ReadElement(aStream, dashLength);
   289   ReadElement(aStream, aStrokeOptions.mDashOffset);
   290   ReadElement(aStream, aStrokeOptions.mLineWidth);
   291   ReadElement(aStream, aStrokeOptions.mMiterLimit);
   292   ReadElement(aStream, joinStyle);
   293   ReadElement(aStream, capStyle);
   294   // On 32 bit we truncate the value of dashLength.
   295   // See also bug 811850 for history.
   296   aStrokeOptions.mDashLength = size_t(dashLength);
   297   aStrokeOptions.mLineJoin = joinStyle;
   298   aStrokeOptions.mLineCap = capStyle;
   300   if (!aStrokeOptions.mDashLength) {
   301     return;
   302   }
   304   mDashPatternStorage.resize(aStrokeOptions.mDashLength);
   305   aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
   306   aStream.read((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength);
   307 }
   309 void
   310 RecordedEvent::OutputSimplePatternInfo(const PatternStorage &aStorage, std::stringstream &aOutput) const
   311 {
   312   switch (aStorage.mType) {
   313   case PatternType::COLOR:
   314     {
   315       const Color color = reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)->mColor;
   316       aOutput << "Color: (" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << ")";
   317       return;
   318     }
   319   case PatternType::LINEAR_GRADIENT:
   320     {
   321       const LinearGradientPatternStorage *store =
   322         reinterpret_cast<const LinearGradientPatternStorage*>(&aStorage.mStorage);
   324       aOutput << "LinearGradient (" << store->mBegin.x << ", " << store->mBegin.y <<
   325         ") - (" << store->mEnd.x << ", " << store->mEnd.y << ") Stops: " << store->mStops;
   326       return;
   327     }
   328   case PatternType::RADIAL_GRADIENT:
   329     {
   330       const RadialGradientPatternStorage *store =
   331         reinterpret_cast<const RadialGradientPatternStorage*>(&aStorage.mStorage);
   332       aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", " <<
   333         store->mCenter2.y << ") Radius 2: " << store->mRadius2;
   334       return;
   335     }
   336   case PatternType::SURFACE:
   337     {
   338       const SurfacePatternStorage *store =
   339         reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
   340       aOutput << "Surface (0x" << store->mSurface << ")";
   341       return;
   342     }
   343   }
   344 }
   346 RecordedDrawingEvent::RecordedDrawingEvent(EventType aType, std::istream &aStream)
   347   : RecordedEvent(aType)
   348 {
   349   ReadElement(aStream, mDT);
   350 }
   352 void
   353 RecordedDrawingEvent::RecordToStream(ostream &aStream) const
   354 {
   355   WriteElement(aStream, mDT);
   356 }
   358 ReferencePtr
   359 RecordedDrawingEvent::GetObjectRef() const
   360 {
   361   return mDT;
   362 }
   364 void
   365 RecordedDrawTargetCreation::PlayEvent(Translator *aTranslator) const
   366 {
   367   RefPtr<DrawTarget> newDT =
   368     aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(mSize, mFormat);
   369   aTranslator->AddDrawTarget(mRefPtr, newDT);
   371   if (mHasExistingData) {
   372     Rect dataRect(0, 0, mExistingData->GetSize().width, mExistingData->GetSize().height);
   373     newDT->DrawSurface(mExistingData, dataRect, dataRect);
   374   }
   375 }
   377 void
   378 RecordedDrawTargetCreation::RecordToStream(ostream &aStream) const
   379 {
   380   WriteElement(aStream, mRefPtr);
   381   WriteElement(aStream, mBackendType);
   382   WriteElement(aStream, mSize);
   383   WriteElement(aStream, mFormat);
   384   WriteElement(aStream, mHasExistingData);
   386   if (mHasExistingData) {
   387     MOZ_ASSERT(mExistingData);
   388     MOZ_ASSERT(mExistingData->GetSize() == mSize);
   389     RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
   390     for (int y = 0; y < mSize.height; y++) {
   391       aStream.write((const char*)dataSurf->GetData() + y * dataSurf->Stride(),
   392                     BytesPerPixel(mFormat) * mSize.width);
   393     }
   394   }
   395 }
   397 RecordedDrawTargetCreation::RecordedDrawTargetCreation(istream &aStream)
   398   : RecordedEvent(DRAWTARGETCREATION)
   399 {
   400   ReadElement(aStream, mRefPtr);
   401   ReadElement(aStream, mBackendType);
   402   ReadElement(aStream, mSize);
   403   ReadElement(aStream, mFormat);
   404   ReadElement(aStream, mHasExistingData);
   406   if (mHasExistingData) {
   407     RefPtr<DataSourceSurface> dataSurf = Factory::CreateDataSourceSurface(mSize, mFormat);
   408     for (int y = 0; y < mSize.height; y++) {
   409       aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(),
   410                     BytesPerPixel(mFormat) * mSize.width);
   411     }
   412     mExistingData = dataSurf;
   413   }
   414 }
   416 void
   417 RecordedDrawTargetCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
   418 {
   419   aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: " << NameFromBackend(mBackendType) << ", Size: " << mSize.width << "x" << mSize.height << ")";
   420 }
   423 void
   424 RecordedDrawTargetDestruction::PlayEvent(Translator *aTranslator) const
   425 {
   426   aTranslator->RemoveDrawTarget(mRefPtr);
   427 }
   429 void
   430 RecordedDrawTargetDestruction::RecordToStream(ostream &aStream) const
   431 {
   432   WriteElement(aStream, mRefPtr);
   433 }
   435 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(istream &aStream)
   436   : RecordedEvent(DRAWTARGETDESTRUCTION)
   437 {
   438   ReadElement(aStream, mRefPtr);
   439 }
   441 void
   442 RecordedDrawTargetDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
   443 {
   444   aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
   445 }
   447 struct GenericPattern
   448 {
   449   GenericPattern(const PatternStorage &aStorage, Translator *aTranslator)
   450     : mPattern(nullptr), mTranslator(aTranslator)
   451   {
   452     mStorage = const_cast<PatternStorage*>(&aStorage);
   453   }
   455   ~GenericPattern() {
   456     if (mPattern) {
   457       mPattern->~Pattern();
   458     }
   459   }
   461   operator Pattern*()
   462   {
   463     switch(mStorage->mType) {
   464     case PatternType::COLOR:
   465       return new (mColPat) ColorPattern(reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)->mColor);
   466     case PatternType::SURFACE:
   467       {
   468         SurfacePatternStorage *storage = reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
   469         mPattern =
   470           new (mSurfPat) SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
   471                                         storage->mExtend, storage->mMatrix, storage->mFilter);
   472         return mPattern;
   473       }
   474     case PatternType::LINEAR_GRADIENT:
   475       {
   476         LinearGradientPatternStorage *storage = reinterpret_cast<LinearGradientPatternStorage*>(&mStorage->mStorage);
   477         mPattern =
   478           new (mLinGradPat) LinearGradientPattern(storage->mBegin, storage->mEnd,
   479                                                   mTranslator->LookupGradientStops(storage->mStops),
   480                                                   storage->mMatrix);
   481         return mPattern;
   482       }
   483     case PatternType::RADIAL_GRADIENT:
   484       {
   485         RadialGradientPatternStorage *storage = reinterpret_cast<RadialGradientPatternStorage*>(&mStorage->mStorage);
   486         mPattern =
   487           new (mRadGradPat) RadialGradientPattern(storage->mCenter1, storage->mCenter2,
   488                                                   storage->mRadius1, storage->mRadius2,
   489                                                   mTranslator->LookupGradientStops(storage->mStops),
   490                                                   storage->mMatrix);
   491         return mPattern;
   492       }
   493     default:
   494       return new (mColPat) ColorPattern(Color());
   495     }
   497     return mPattern;
   498   }
   500   union {
   501     char mColPat[sizeof(ColorPattern)];
   502     char mLinGradPat[sizeof(LinearGradientPattern)];
   503     char mRadGradPat[sizeof(RadialGradientPattern)];
   504     char mSurfPat[sizeof(SurfacePattern)];
   505   };
   507   PatternStorage *mStorage;
   508   Pattern *mPattern;
   509   Translator *mTranslator;
   510 };
   512 void
   513 RecordedFillRect::PlayEvent(Translator *aTranslator) const
   514 {
   515   aTranslator->LookupDrawTarget(mDT)->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
   516 }
   518 void
   519 RecordedFillRect::RecordToStream(ostream &aStream) const
   520 {
   521   RecordedDrawingEvent::RecordToStream(aStream);
   522   WriteElement(aStream, mRect);
   523   WriteElement(aStream, mOptions);
   524   RecordPatternData(aStream, mPattern);
   525 }
   527 RecordedFillRect::RecordedFillRect(istream &aStream)
   528   : RecordedDrawingEvent(FILLRECT, aStream)
   529 {
   530   ReadElement(aStream, mRect);
   531   ReadElement(aStream, mOptions);
   532   ReadPatternData(aStream, mPattern);
   533 }
   535 void
   536 RecordedFillRect::OutputSimpleEventInfo(stringstream &aStringStream) const
   537 {
   538   aStringStream << "[" << mDT << "] FillRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
   539   OutputSimplePatternInfo(mPattern, aStringStream);
   540 }
   542 void
   543 RecordedStrokeRect::PlayEvent(Translator *aTranslator) const
   544 {
   545   aTranslator->LookupDrawTarget(mDT)->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
   546 }
   548 void
   549 RecordedStrokeRect::RecordToStream(ostream &aStream) const
   550 {
   551   RecordedDrawingEvent::RecordToStream(aStream);
   552   WriteElement(aStream, mRect);
   553   WriteElement(aStream, mOptions);
   554   RecordPatternData(aStream, mPattern);
   555   RecordStrokeOptions(aStream, mStrokeOptions);
   556 }
   558 RecordedStrokeRect::RecordedStrokeRect(istream &aStream)
   559   : RecordedDrawingEvent(STROKERECT, aStream)
   560 {
   561   ReadElement(aStream, mRect);
   562   ReadElement(aStream, mOptions);
   563   ReadPatternData(aStream, mPattern);
   564   ReadStrokeOptions(aStream, mStrokeOptions);
   565 }
   567 void
   568 RecordedStrokeRect::OutputSimpleEventInfo(stringstream &aStringStream) const
   569 {
   570   aStringStream << "[" << mDT << "] StrokeRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height
   571                 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   572   OutputSimplePatternInfo(mPattern, aStringStream);
   573 }
   575 void
   576 RecordedStrokeLine::PlayEvent(Translator *aTranslator) const
   577 {
   578   aTranslator->LookupDrawTarget(mDT)->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
   579 }
   581 void
   582 RecordedStrokeLine::RecordToStream(ostream &aStream) const
   583 {
   584   RecordedDrawingEvent::RecordToStream(aStream);
   585   WriteElement(aStream, mBegin);
   586   WriteElement(aStream, mEnd);
   587   WriteElement(aStream, mOptions);
   588   RecordPatternData(aStream, mPattern);
   589   RecordStrokeOptions(aStream, mStrokeOptions);
   590 }
   592 RecordedStrokeLine::RecordedStrokeLine(istream &aStream)
   593   : RecordedDrawingEvent(STROKELINE, aStream)
   594 {
   595   ReadElement(aStream, mBegin);
   596   ReadElement(aStream, mEnd);
   597   ReadElement(aStream, mOptions);
   598   ReadPatternData(aStream, mPattern);
   599   ReadStrokeOptions(aStream, mStrokeOptions);
   600 }
   602 void
   603 RecordedStrokeLine::OutputSimpleEventInfo(stringstream &aStringStream) const
   604 {
   605   aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", " << mBegin.y << " - " << mEnd.x << ", " << mEnd.y
   606                 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   607   OutputSimplePatternInfo(mPattern, aStringStream);
   608 }
   610 void
   611 RecordedFill::PlayEvent(Translator *aTranslator) const
   612 {
   613   aTranslator->LookupDrawTarget(mDT)->Fill(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mOptions);
   614 }
   616 RecordedFill::RecordedFill(istream &aStream)
   617   : RecordedDrawingEvent(FILL, aStream)
   618 {
   619   ReadElement(aStream, mPath);
   620   ReadElement(aStream, mOptions);
   621   ReadPatternData(aStream, mPattern);
   622 }
   624 void
   625 RecordedFill::RecordToStream(ostream &aStream) const
   626 {
   627   RecordedDrawingEvent::RecordToStream(aStream);
   628   WriteElement(aStream, mPath);
   629   WriteElement(aStream, mOptions);
   630   RecordPatternData(aStream, mPattern);
   631 }
   633 void
   634 RecordedFill::OutputSimpleEventInfo(stringstream &aStringStream) const
   635 {
   636   aStringStream << "[" << mDT << "] Fill (" << mPath << ") ";
   637   OutputSimplePatternInfo(mPattern, aStringStream);
   638 }
   640 RecordedFillGlyphs::~RecordedFillGlyphs()
   641 {
   642   delete [] mGlyphs;
   643 }
   645 void
   646 RecordedFillGlyphs::PlayEvent(Translator *aTranslator) const
   647 {
   648   GlyphBuffer buffer;
   649   buffer.mGlyphs = mGlyphs;
   650   buffer.mNumGlyphs = mNumGlyphs;
   651   aTranslator->LookupDrawTarget(mDT)->FillGlyphs(aTranslator->LookupScaledFont(mScaledFont), buffer, *GenericPattern(mPattern, aTranslator), mOptions);
   652 }
   654 RecordedFillGlyphs::RecordedFillGlyphs(istream &aStream)
   655   : RecordedDrawingEvent(FILLGLYPHS, aStream)
   656 {
   657   ReadElement(aStream, mScaledFont);
   658   ReadElement(aStream, mOptions);
   659   ReadPatternData(aStream, mPattern);
   660   ReadElement(aStream, mNumGlyphs);
   661   mGlyphs = new Glyph[mNumGlyphs];
   662   aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
   663 }
   665 void
   666 RecordedFillGlyphs::RecordToStream(ostream &aStream) const
   667 {
   668   RecordedDrawingEvent::RecordToStream(aStream);
   669   WriteElement(aStream, mScaledFont);
   670   WriteElement(aStream, mOptions);
   671   RecordPatternData(aStream, mPattern);
   672   WriteElement(aStream, mNumGlyphs);
   673   aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
   674 }
   676 void
   677 RecordedFillGlyphs::OutputSimpleEventInfo(stringstream &aStringStream) const
   678 {
   679   aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") ";
   680   OutputSimplePatternInfo(mPattern, aStringStream);
   681 }
   683 void
   684 RecordedMask::PlayEvent(Translator *aTranslator) const
   685 {
   686   aTranslator->LookupDrawTarget(mDT)->Mask(*GenericPattern(mSource, aTranslator), *GenericPattern(mMask, aTranslator), mOptions);
   687 }
   689 RecordedMask::RecordedMask(istream &aStream)
   690   : RecordedDrawingEvent(MASK, aStream)
   691 {
   692   ReadElement(aStream, mOptions);
   693   ReadPatternData(aStream, mSource);
   694   ReadPatternData(aStream, mMask);
   695 }
   697 void
   698 RecordedMask::RecordToStream(ostream &aStream) const
   699 {
   700   RecordedDrawingEvent::RecordToStream(aStream);
   701   WriteElement(aStream, mOptions);
   702   RecordPatternData(aStream, mSource);
   703   RecordPatternData(aStream, mMask);
   704 }
   706 void
   707 RecordedMask::OutputSimpleEventInfo(stringstream &aStringStream) const
   708 {
   709   aStringStream << "[" << mDT << "] Mask (Source: ";
   710   OutputSimplePatternInfo(mSource, aStringStream);
   711   aStringStream << " Mask: ";
   712   OutputSimplePatternInfo(mMask, aStringStream);
   713 }
   715 void
   716 RecordedStroke::PlayEvent(Translator *aTranslator) const
   717 {
   718   aTranslator->LookupDrawTarget(mDT)->Stroke(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
   719 }
   721 void
   722 RecordedStroke::RecordToStream(ostream &aStream) const
   723 {
   724   RecordedDrawingEvent::RecordToStream(aStream);
   725   WriteElement(aStream, mPath);
   726   WriteElement(aStream, mOptions);
   727   RecordPatternData(aStream, mPattern);
   728   RecordStrokeOptions(aStream, mStrokeOptions);
   729 }
   731 RecordedStroke::RecordedStroke(istream &aStream)
   732   : RecordedDrawingEvent(STROKE, aStream)
   733 {
   734   ReadElement(aStream, mPath);
   735   ReadElement(aStream, mOptions);
   736   ReadPatternData(aStream, mPattern);
   737   ReadStrokeOptions(aStream, mStrokeOptions);
   738 }
   740 void
   741 RecordedStroke::OutputSimpleEventInfo(stringstream &aStringStream) const
   742 {
   743   aStringStream << "[" << mDT << "] Stroke ("<< mPath << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
   744   OutputSimplePatternInfo(mPattern, aStringStream);
   745 }
   747 void
   748 RecordedClearRect::PlayEvent(Translator *aTranslator) const
   749 {
   750   aTranslator->LookupDrawTarget(mDT)->ClearRect(mRect);
   751 }
   753 void
   754 RecordedClearRect::RecordToStream(ostream &aStream) const
   755 {
   756   RecordedDrawingEvent::RecordToStream(aStream);
   757   WriteElement(aStream, mRect);
   758 }
   760 RecordedClearRect::RecordedClearRect(istream &aStream)
   761   : RecordedDrawingEvent(CLEARRECT, aStream)
   762 {
   763     ReadElement(aStream, mRect);
   764 }
   766 void
   767 RecordedClearRect::OutputSimpleEventInfo(stringstream &aStringStream) const
   768 {
   769   aStringStream << "[" << mDT<< "] ClearRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
   770 }
   772 void
   773 RecordedCopySurface::PlayEvent(Translator *aTranslator) const
   774 {
   775 	aTranslator->LookupDrawTarget(mDT)->CopySurface(aTranslator->LookupSourceSurface(mSourceSurface),
   776                                                   mSourceRect, mDest);
   777 }
   779 void
   780 RecordedCopySurface::RecordToStream(ostream &aStream) const
   781 {
   782   RecordedDrawingEvent::RecordToStream(aStream);
   783   WriteElement(aStream, mSourceSurface);
   784   WriteElement(aStream, mSourceRect);
   785   WriteElement(aStream, mDest);
   786 }
   788 RecordedCopySurface::RecordedCopySurface(istream &aStream)
   789   : RecordedDrawingEvent(COPYSURFACE, aStream)
   790 {
   791   ReadElement(aStream, mSourceSurface);
   792   ReadElement(aStream, mSourceRect);
   793   ReadElement(aStream, mDest);
   794 }
   796 void
   797 RecordedCopySurface::OutputSimpleEventInfo(stringstream &aStringStream) const
   798 {
   799   aStringStream << "[" << mDT<< "] CopySurface (" << mSourceSurface << ")";
   800 }
   802 void
   803 RecordedPushClip::PlayEvent(Translator *aTranslator) const
   804 {
   805   aTranslator->LookupDrawTarget(mDT)->PushClip(aTranslator->LookupPath(mPath));
   806 }
   808 void
   809 RecordedPushClip::RecordToStream(ostream &aStream) const
   810 {
   811   RecordedDrawingEvent::RecordToStream(aStream);
   812   WriteElement(aStream, mPath);
   813 }
   815 RecordedPushClip::RecordedPushClip(istream &aStream)
   816   : RecordedDrawingEvent(PUSHCLIP, aStream)
   817 {
   818   ReadElement(aStream, mPath);
   819 }
   821 void
   822 RecordedPushClip::OutputSimpleEventInfo(stringstream &aStringStream) const
   823 {
   824   aStringStream << "[" << mDT << "] PushClip (" << mPath << ") ";
   825 }
   827 void
   828 RecordedPushClipRect::PlayEvent(Translator *aTranslator) const
   829 {
   830   aTranslator->LookupDrawTarget(mDT)->PushClipRect(mRect);
   831 }
   833 void
   834 RecordedPushClipRect::RecordToStream(ostream &aStream) const
   835 {
   836   RecordedDrawingEvent::RecordToStream(aStream);
   837   WriteElement(aStream, mRect);
   838 }
   840 RecordedPushClipRect::RecordedPushClipRect(istream &aStream)
   841   : RecordedDrawingEvent(PUSHCLIPRECT, aStream)
   842 {
   843   ReadElement(aStream, mRect);
   844 }
   846 void
   847 RecordedPushClipRect::OutputSimpleEventInfo(stringstream &aStringStream) const
   848 {
   849   aStringStream << "[" << mDT << "] PushClipRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
   850 }
   852 void
   853 RecordedPopClip::PlayEvent(Translator *aTranslator) const
   854 {
   855   aTranslator->LookupDrawTarget(mDT)->PopClip();
   856 }
   858 void
   859 RecordedPopClip::RecordToStream(ostream &aStream) const
   860 {
   861   RecordedDrawingEvent::RecordToStream(aStream);
   862 }
   864 RecordedPopClip::RecordedPopClip(istream &aStream)
   865   : RecordedDrawingEvent(POPCLIP, aStream)
   866 {
   867 }
   869 void
   870 RecordedPopClip::OutputSimpleEventInfo(stringstream &aStringStream) const
   871 {
   872   aStringStream << "[" << mDT << "] PopClip";
   873 }
   875 void
   876 RecordedSetTransform::PlayEvent(Translator *aTranslator) const
   877 {
   878   aTranslator->LookupDrawTarget(mDT)->SetTransform(mTransform);
   879 }
   881 void
   882 RecordedSetTransform::RecordToStream(ostream &aStream) const
   883 {
   884   RecordedDrawingEvent::RecordToStream(aStream);
   885   WriteElement(aStream, mTransform);
   886 }
   888 RecordedSetTransform::RecordedSetTransform(istream &aStream)
   889   : RecordedDrawingEvent(SETTRANSFORM, aStream)
   890 {
   891   ReadElement(aStream, mTransform);
   892 }
   894 void
   895 RecordedSetTransform::OutputSimpleEventInfo(stringstream &aStringStream) const
   896 {
   897   aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " " << mTransform._12 << " ; " <<
   898     mTransform._21 << " " << mTransform._22 << " ; " << mTransform._31 << " " << mTransform._32 << " ]";
   899 }
   901 void
   902 RecordedDrawSurface::PlayEvent(Translator *aTranslator) const
   903 {
   904   aTranslator->LookupDrawTarget(mDT)->
   905     DrawSurface(aTranslator->LookupSourceSurface(mRefSource), mDest, mSource,
   906                 mDSOptions, mOptions);
   907 }
   909 void
   910 RecordedDrawSurface::RecordToStream(ostream &aStream) const
   911 {
   912   RecordedDrawingEvent::RecordToStream(aStream);
   913   WriteElement(aStream, mRefSource);
   914   WriteElement(aStream, mDest);
   915   WriteElement(aStream, mSource);
   916   WriteElement(aStream, mDSOptions);
   917   WriteElement(aStream, mOptions);
   918 }
   920 RecordedDrawSurface::RecordedDrawSurface(istream &aStream)
   921   : RecordedDrawingEvent(DRAWSURFACE, aStream)
   922 {
   923   ReadElement(aStream, mRefSource);
   924   ReadElement(aStream, mDest);
   925   ReadElement(aStream, mSource);
   926   ReadElement(aStream, mDSOptions);
   927   ReadElement(aStream, mOptions);
   928 }
   930 void
   931 RecordedDrawSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
   932 {
   933   aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")";
   934 }
   936 void
   937 RecordedDrawFilter::PlayEvent(Translator *aTranslator) const
   938 {
   939   aTranslator->LookupDrawTarget(mDT)->
   940     DrawFilter(aTranslator->LookupFilterNode(mNode), mSourceRect,
   941                 mDestPoint, mOptions);
   942 }
   944 void
   945 RecordedDrawFilter::RecordToStream(ostream &aStream) const
   946 {
   947   RecordedDrawingEvent::RecordToStream(aStream);
   948   WriteElement(aStream, mNode);
   949   WriteElement(aStream, mSourceRect);
   950   WriteElement(aStream, mDestPoint);
   951   WriteElement(aStream, mOptions);
   952 }
   954 RecordedDrawFilter::RecordedDrawFilter(istream &aStream)
   955   : RecordedDrawingEvent(DRAWFILTER, aStream)
   956 {
   957   ReadElement(aStream, mNode);
   958   ReadElement(aStream, mSourceRect);
   959   ReadElement(aStream, mDestPoint);
   960   ReadElement(aStream, mOptions);
   961 }
   963 void
   964 RecordedDrawFilter::OutputSimpleEventInfo(stringstream &aStringStream) const
   965 {
   966   aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")";
   967 }
   969 void
   970 RecordedDrawSurfaceWithShadow::PlayEvent(Translator *aTranslator) const
   971 {
   972   aTranslator->LookupDrawTarget(mDT)->
   973     DrawSurfaceWithShadow(aTranslator->LookupSourceSurface(mRefSource),
   974                           mDest, mColor, mOffset, mSigma, mOp);
   975 }
   977 void
   978 RecordedDrawSurfaceWithShadow::RecordToStream(ostream &aStream) const
   979 {
   980   RecordedDrawingEvent::RecordToStream(aStream);
   981   WriteElement(aStream, mRefSource);
   982   WriteElement(aStream, mDest);
   983   WriteElement(aStream, mColor);
   984   WriteElement(aStream, mOffset);
   985   WriteElement(aStream, mSigma);
   986   WriteElement(aStream, mOp);
   987 }
   989 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(istream &aStream)
   990   : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aStream)
   991 {
   992   ReadElement(aStream, mRefSource);
   993   ReadElement(aStream, mDest);
   994   ReadElement(aStream, mColor);
   995   ReadElement(aStream, mOffset);
   996   ReadElement(aStream, mSigma);
   997   ReadElement(aStream, mOp);
   998 }
  1000 void
  1001 RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(stringstream &aStringStream) const
  1003   aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource << ") Color: (" <<
  1004     mColor.r << ", " << mColor.g << ", " << mColor.b << ", " << mColor.a << ")";
  1007 RecordedPathCreation::RecordedPathCreation(PathRecording *aPath)
  1008   : RecordedEvent(PATHCREATION), mRefPtr(aPath), mFillRule(aPath->mFillRule), mPathOps(aPath->mPathOps)
  1012 RecordedPathCreation::~RecordedPathCreation()
  1016 void
  1017 RecordedPathCreation::PlayEvent(Translator *aTranslator) const
  1019   RefPtr<PathBuilder> builder = 
  1020     aTranslator->GetReferenceDrawTarget()->CreatePathBuilder(mFillRule);
  1022   for (size_t i = 0; i < mPathOps.size(); i++) {
  1023     const PathOp &op = mPathOps[i];
  1024     switch (op.mType) {
  1025     case PathOp::OP_MOVETO:
  1026       builder->MoveTo(op.mP1);
  1027       break;
  1028     case PathOp::OP_LINETO:
  1029       builder->LineTo(op.mP1);
  1030       break;
  1031     case PathOp::OP_BEZIERTO:
  1032       builder->BezierTo(op.mP1, op.mP2, op.mP3);
  1033       break;
  1034     case PathOp::OP_QUADRATICBEZIERTO:
  1035       builder->QuadraticBezierTo(op.mP1, op.mP2);
  1036       break;
  1037     case PathOp::OP_CLOSE:
  1038       builder->Close();
  1039       break;
  1043   RefPtr<Path> path = builder->Finish();
  1044   aTranslator->AddPath(mRefPtr, path);
  1047 void
  1048 RecordedPathCreation::RecordToStream(ostream &aStream) const
  1050   WriteElement(aStream, mRefPtr);
  1051   WriteElement(aStream, uint64_t(mPathOps.size()));
  1052   WriteElement(aStream, mFillRule);
  1053   typedef std::vector<PathOp> pathOpVec;
  1054   for (pathOpVec::const_iterator iter = mPathOps.begin(); iter != mPathOps.end(); iter++) {
  1055     WriteElement(aStream, iter->mType);
  1056     if (sPointCount[iter->mType] >= 1) {
  1057       WriteElement(aStream, iter->mP1);
  1059     if (sPointCount[iter->mType] >= 2) {
  1060       WriteElement(aStream, iter->mP2);
  1062     if (sPointCount[iter->mType] >= 3) {
  1063       WriteElement(aStream, iter->mP3);
  1069 RecordedPathCreation::RecordedPathCreation(istream &aStream)
  1070   : RecordedEvent(PATHCREATION)
  1072   uint64_t size;
  1074   ReadElement(aStream, mRefPtr);
  1075   ReadElement(aStream, size);
  1076   ReadElement(aStream, mFillRule);
  1078   for (uint64_t i = 0; i < size; i++) {
  1079     PathOp newPathOp;
  1080     ReadElement(aStream, newPathOp.mType);
  1081     if (sPointCount[newPathOp.mType] >= 1) {
  1082       ReadElement(aStream, newPathOp.mP1);
  1084     if (sPointCount[newPathOp.mType] >= 2) {
  1085       ReadElement(aStream, newPathOp.mP2);
  1087     if (sPointCount[newPathOp.mType] >= 3) {
  1088       ReadElement(aStream, newPathOp.mP3);
  1091     mPathOps.push_back(newPathOp);
  1096 void
  1097 RecordedPathCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
  1099   aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << mPathOps.size() << ")";
  1101 void
  1102 RecordedPathDestruction::PlayEvent(Translator *aTranslator) const
  1104   aTranslator->RemovePath(mRefPtr);
  1107 void
  1108 RecordedPathDestruction::RecordToStream(ostream &aStream) const
  1110   WriteElement(aStream, mRefPtr);
  1113 RecordedPathDestruction::RecordedPathDestruction(istream &aStream)
  1114   : RecordedEvent(PATHDESTRUCTION)
  1116   ReadElement(aStream, mRefPtr);
  1119 void
  1120 RecordedPathDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
  1122   aStringStream << "[" << mRefPtr << "] Path Destroyed";
  1125 RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation()
  1127   if (mDataOwned) {
  1128     delete [] mData;
  1132 void
  1133 RecordedSourceSurfaceCreation::PlayEvent(Translator *aTranslator) const
  1135   RefPtr<SourceSurface> src = aTranslator->GetReferenceDrawTarget()->
  1136     CreateSourceSurfaceFromData(mData, mSize, mSize.width * BytesPerPixel(mFormat), mFormat);
  1137   aTranslator->AddSourceSurface(mRefPtr, src);
  1140 void
  1141 RecordedSourceSurfaceCreation::RecordToStream(ostream &aStream) const
  1143   WriteElement(aStream, mRefPtr);
  1144   WriteElement(aStream, mSize);
  1145   WriteElement(aStream, mFormat);
  1146   for (int y = 0; y < mSize.height; y++) {
  1147     aStream.write((const char*)mData + y * mStride, BytesPerPixel(mFormat) * mSize.width);
  1151 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(istream &aStream)
  1152   : RecordedEvent(SOURCESURFACECREATION), mDataOwned(true)
  1154   ReadElement(aStream, mRefPtr);
  1155   ReadElement(aStream, mSize);
  1156   ReadElement(aStream, mFormat);
  1157   mData = (uint8_t*)new char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
  1158   aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
  1161 void
  1162 RecordedSourceSurfaceCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
  1164   aStringStream << "[" << mRefPtr << "] SourceSurface created (Size: " << mSize.width << "x" << mSize.height << ")";
  1167 void
  1168 RecordedSourceSurfaceDestruction::PlayEvent(Translator *aTranslator) const
  1170   aTranslator->RemoveSourceSurface(mRefPtr);
  1173 void
  1174 RecordedSourceSurfaceDestruction::RecordToStream(ostream &aStream) const
  1176   WriteElement(aStream, mRefPtr);
  1179 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(istream &aStream)
  1180   : RecordedEvent(SOURCESURFACEDESTRUCTION)
  1182   ReadElement(aStream, mRefPtr);
  1185 void
  1186 RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
  1188   aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
  1191 RecordedFilterNodeCreation::~RecordedFilterNodeCreation()
  1195 void
  1196 RecordedFilterNodeCreation::PlayEvent(Translator *aTranslator) const
  1198   RefPtr<FilterNode> node = aTranslator->GetReferenceDrawTarget()->
  1199     CreateFilter(mType);
  1200   aTranslator->AddFilterNode(mRefPtr, node);
  1203 void
  1204 RecordedFilterNodeCreation::RecordToStream(ostream &aStream) const
  1206   WriteElement(aStream, mRefPtr);
  1207   WriteElement(aStream, mType);
  1210 RecordedFilterNodeCreation::RecordedFilterNodeCreation(istream &aStream)
  1211   : RecordedEvent(FILTERNODECREATION)
  1213   ReadElement(aStream, mRefPtr);
  1214   ReadElement(aStream, mType);
  1217 void
  1218 RecordedFilterNodeCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
  1220   aStringStream << "[" << mRefPtr << "] FilterNode created (Type: " << int(mType) << ")";
  1223 void
  1224 RecordedFilterNodeDestruction::PlayEvent(Translator *aTranslator) const
  1226   aTranslator->RemoveFilterNode(mRefPtr);
  1229 void
  1230 RecordedFilterNodeDestruction::RecordToStream(ostream &aStream) const
  1232   WriteElement(aStream, mRefPtr);
  1235 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(istream &aStream)
  1236   : RecordedEvent(FILTERNODEDESTRUCTION)
  1238   ReadElement(aStream, mRefPtr);
  1241 void
  1242 RecordedFilterNodeDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
  1244   aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
  1247 RecordedGradientStopsCreation::~RecordedGradientStopsCreation()
  1249   if (mDataOwned) {
  1250     delete [] mStops;
  1254 void
  1255 RecordedGradientStopsCreation::PlayEvent(Translator *aTranslator) const
  1257   RefPtr<GradientStops> src = aTranslator->GetReferenceDrawTarget()->
  1258     CreateGradientStops(mStops, mNumStops, mExtendMode);
  1259   aTranslator->AddGradientStops(mRefPtr, src);
  1262 void
  1263 RecordedGradientStopsCreation::RecordToStream(ostream &aStream) const
  1265   WriteElement(aStream, mRefPtr);
  1266   WriteElement(aStream, mExtendMode);
  1267   WriteElement(aStream, mNumStops);
  1268   aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
  1271 RecordedGradientStopsCreation::RecordedGradientStopsCreation(istream &aStream)
  1272   : RecordedEvent(GRADIENTSTOPSCREATION), mDataOwned(true)
  1274   ReadElement(aStream, mRefPtr);
  1275   ReadElement(aStream, mExtendMode);
  1276   ReadElement(aStream, mNumStops);
  1277   mStops = new GradientStop[mNumStops];
  1279   aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
  1282 void
  1283 RecordedGradientStopsCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
  1285   aStringStream << "[" << mRefPtr << "] GradientStops created (Stops: " << mNumStops << ")";
  1288 void
  1289 RecordedGradientStopsDestruction::PlayEvent(Translator *aTranslator) const
  1291   aTranslator->RemoveGradientStops(mRefPtr);
  1294 void
  1295 RecordedGradientStopsDestruction::RecordToStream(ostream &aStream) const
  1297   WriteElement(aStream, mRefPtr);
  1300 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(istream &aStream)
  1301   : RecordedEvent(GRADIENTSTOPSDESTRUCTION)
  1303   ReadElement(aStream, mRefPtr);
  1306 void
  1307 RecordedGradientStopsDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
  1309   aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
  1312 void
  1313 RecordedSnapshot::PlayEvent(Translator *aTranslator) const
  1315   RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->Snapshot();
  1316   aTranslator->AddSourceSurface(mRefPtr, src);
  1319 void
  1320 RecordedSnapshot::RecordToStream(ostream &aStream) const
  1322   WriteElement(aStream, mRefPtr);
  1323   WriteElement(aStream, mDT);
  1326 RecordedSnapshot::RecordedSnapshot(istream &aStream)
  1327   : RecordedEvent(SNAPSHOT)
  1329   ReadElement(aStream, mRefPtr);
  1330   ReadElement(aStream, mDT);
  1333 void
  1334 RecordedSnapshot::OutputSimpleEventInfo(stringstream &aStringStream) const
  1336   aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")";
  1339 RecordedScaledFontCreation::~RecordedScaledFontCreation()
  1341   delete [] mData;
  1344 void
  1345 RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
  1347   RefPtr<ScaledFont> scaledFont =
  1348     Factory::CreateScaledFontForTrueTypeData(mData, mSize, mIndex, mGlyphSize,
  1349                                              aTranslator->GetDesiredFontType());
  1350   aTranslator->AddScaledFont(mRefPtr, scaledFont);
  1353 void
  1354 RecordedScaledFontCreation::RecordToStream(std::ostream &aStream) const
  1356   WriteElement(aStream, mRefPtr);
  1357   WriteElement(aStream, mIndex);
  1358   WriteElement(aStream, mGlyphSize);
  1359   WriteElement(aStream, mSize);
  1360   aStream.write((const char*)mData, mSize);
  1363 void
  1364 RecordedScaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
  1366   aStringStream << "[" << mRefPtr << "] ScaledFont Created";
  1369 void
  1370 RecordedScaledFontCreation::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex, Float aGlyphSize)
  1372   mData = new uint8_t[aSize];
  1373   memcpy(mData, aData, aSize);
  1374   mSize = aSize;
  1375   mIndex = aIndex;
  1376   mGlyphSize = aGlyphSize;
  1379 RecordedScaledFontCreation::RecordedScaledFontCreation(istream &aStream)
  1380   : RecordedEvent(SCALEDFONTCREATION)
  1382   ReadElement(aStream, mRefPtr);
  1383   ReadElement(aStream, mIndex);
  1384   ReadElement(aStream, mGlyphSize);
  1385   ReadElement(aStream, mSize);
  1386   mData = new uint8_t[mSize];
  1387   aStream.read((char*)mData, mSize);
  1390 void
  1391 RecordedScaledFontDestruction::PlayEvent(Translator *aTranslator) const
  1393   aTranslator->RemoveScaledFont(mRefPtr);
  1396 void
  1397 RecordedScaledFontDestruction::RecordToStream(ostream &aStream) const
  1399   WriteElement(aStream, mRefPtr);
  1402 RecordedScaledFontDestruction::RecordedScaledFontDestruction(istream &aStream)
  1403   : RecordedEvent(SCALEDFONTDESTRUCTION)
  1405   ReadElement(aStream, mRefPtr);
  1408 void
  1409 RecordedScaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
  1411   aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
  1414 void
  1415 RecordedMaskSurface::PlayEvent(Translator *aTranslator) const
  1417   aTranslator->LookupDrawTarget(mDT)->
  1418     MaskSurface(*GenericPattern(mPattern, aTranslator),
  1419                 aTranslator->LookupSourceSurface(mRefMask),
  1420                 mOffset, mOptions);
  1423 void
  1424 RecordedMaskSurface::RecordToStream(ostream &aStream) const
  1426   RecordedDrawingEvent::RecordToStream(aStream);
  1427   RecordPatternData(aStream, mPattern);
  1428   WriteElement(aStream, mRefMask);
  1429   WriteElement(aStream, mOffset);
  1430   WriteElement(aStream, mOptions);
  1433 RecordedMaskSurface::RecordedMaskSurface(istream &aStream)
  1434   : RecordedDrawingEvent(MASKSURFACE, aStream)
  1436   ReadPatternData(aStream, mPattern);
  1437   ReadElement(aStream, mRefMask);
  1438   ReadElement(aStream, mOffset);
  1439   ReadElement(aStream, mOptions);
  1442 void
  1443 RecordedMaskSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
  1445   aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ")  Offset: (" << mOffset.x << "x" << mOffset.y << ") Pattern: ";
  1446   OutputSimplePatternInfo(mPattern, aStringStream);
  1449 template<typename T>
  1450 void
  1451 ReplaySetAttribute(FilterNode *aNode, uint32_t aIndex, T aValue)
  1453   aNode->SetAttribute(aIndex, aValue);
  1456 void
  1457 RecordedFilterNodeSetAttribute::PlayEvent(Translator *aTranslator) const
  1459 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
  1460   case ARGTYPE_##argtype: \
  1461   ReplaySetAttribute(aTranslator->LookupFilterNode(mNode), mIndex, *(type*)&mPayload.front()); \
  1462   break
  1464   switch (mArgType) {
  1465     REPLAY_SET_ATTRIBUTE(bool, BOOL);
  1466     REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
  1467     REPLAY_SET_ATTRIBUTE(Float, FLOAT);
  1468     REPLAY_SET_ATTRIBUTE(Size, SIZE);
  1469     REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
  1470     REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
  1471     REPLAY_SET_ATTRIBUTE(Rect, RECT);
  1472     REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
  1473     REPLAY_SET_ATTRIBUTE(Point, POINT);
  1474     REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
  1475     REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
  1476     REPLAY_SET_ATTRIBUTE(Color, COLOR);
  1477   case ARGTYPE_FLOAT_ARRAY:
  1478     aTranslator->LookupFilterNode(mNode)->SetAttribute(
  1479       mIndex,
  1480       reinterpret_cast<const Float*>(&mPayload.front()),
  1481       mPayload.size() / sizeof(Float));
  1482     break;
  1486 void
  1487 RecordedFilterNodeSetAttribute::RecordToStream(ostream &aStream) const
  1489   RecordedEvent::RecordToStream(aStream);
  1490   WriteElement(aStream, mNode);
  1491   WriteElement(aStream, mIndex);
  1492   WriteElement(aStream, mArgType);
  1493   WriteElement(aStream, uint64_t(mPayload.size()));
  1494   aStream.write((const char*)&mPayload.front(), mPayload.size());
  1497 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(istream &aStream)
  1498   : RecordedEvent(FILTERNODESETATTRIBUTE)
  1500   ReadElement(aStream, mNode);
  1501   ReadElement(aStream, mIndex);
  1502   ReadElement(aStream, mArgType);
  1503   uint64_t size;
  1504   ReadElement(aStream, size);
  1505   mPayload.resize(size_t(size));
  1506   aStream.read((char*)&mPayload.front(), size);
  1509 void
  1510 RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(stringstream &aStringStream) const
  1512   aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
  1515 void
  1516 RecordedFilterNodeSetInput::PlayEvent(Translator *aTranslator) const
  1518   if (mInputFilter) {
  1519     aTranslator->LookupFilterNode(mNode)->SetInput(
  1520       mIndex, aTranslator->LookupFilterNode(mInputFilter));
  1521   } else {
  1522     aTranslator->LookupFilterNode(mNode)->SetInput(
  1523       mIndex, aTranslator->LookupSourceSurface(mInputSurface));
  1527 void
  1528 RecordedFilterNodeSetInput::RecordToStream(ostream &aStream) const
  1530   RecordedEvent::RecordToStream(aStream);
  1531   WriteElement(aStream, mNode);
  1532   WriteElement(aStream, mIndex);
  1533   WriteElement(aStream, mInputFilter);
  1534   WriteElement(aStream, mInputSurface);
  1537 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(istream &aStream)
  1538   : RecordedEvent(FILTERNODESETINPUT)
  1540   ReadElement(aStream, mNode);
  1541   ReadElement(aStream, mIndex);
  1542   ReadElement(aStream, mInputFilter);
  1543   ReadElement(aStream, mInputSurface);
  1546 void
  1547 RecordedFilterNodeSetInput::OutputSimpleEventInfo(stringstream &aStringStream) const
  1549   aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
  1551   if (mInputFilter) {
  1552     aStringStream << "Filter: " << mInputFilter;
  1553   } else {
  1554     aStringStream << "Surface: " << mInputSurface;
  1557   aStringStream << ")";

mercurial