michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "RecordedEvent.h" michael@0: #include "PathRecording.h" michael@0: michael@0: #include "Tools.h" michael@0: #include "Filters.h" michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: michael@0: using namespace std; michael@0: michael@0: static std::string NameFromBackend(BackendType aType) michael@0: { michael@0: switch (aType) { michael@0: case BackendType::NONE: michael@0: return "None"; michael@0: case BackendType::DIRECT2D: michael@0: return "Direct2D"; michael@0: default: michael@0: return "Unknown"; michael@0: } michael@0: } michael@0: michael@0: #define LOAD_EVENT_TYPE(_typeenum, _class) \ michael@0: case _typeenum: return new _class(aStream) michael@0: michael@0: RecordedEvent * michael@0: RecordedEvent::LoadEventFromStream(std::istream &aStream, EventType aType) michael@0: { michael@0: switch (aType) { michael@0: LOAD_EVENT_TYPE(DRAWTARGETCREATION, RecordedDrawTargetCreation); michael@0: LOAD_EVENT_TYPE(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); michael@0: LOAD_EVENT_TYPE(FILLRECT, RecordedFillRect); michael@0: LOAD_EVENT_TYPE(STROKERECT, RecordedStrokeRect); michael@0: LOAD_EVENT_TYPE(STROKELINE, RecordedStrokeLine); michael@0: LOAD_EVENT_TYPE(CLEARRECT, RecordedClearRect); michael@0: LOAD_EVENT_TYPE(COPYSURFACE, RecordedCopySurface); michael@0: LOAD_EVENT_TYPE(SETTRANSFORM, RecordedSetTransform); michael@0: LOAD_EVENT_TYPE(PUSHCLIPRECT, RecordedPushClipRect); michael@0: LOAD_EVENT_TYPE(PUSHCLIP, RecordedPushClip); michael@0: LOAD_EVENT_TYPE(POPCLIP, RecordedPopClip); michael@0: LOAD_EVENT_TYPE(FILL, RecordedFill); michael@0: LOAD_EVENT_TYPE(FILLGLYPHS, RecordedFillGlyphs); michael@0: LOAD_EVENT_TYPE(MASK, RecordedMask); michael@0: LOAD_EVENT_TYPE(STROKE, RecordedStroke); michael@0: LOAD_EVENT_TYPE(DRAWSURFACE, RecordedDrawSurface); michael@0: LOAD_EVENT_TYPE(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); michael@0: LOAD_EVENT_TYPE(DRAWFILTER, RecordedDrawFilter); michael@0: LOAD_EVENT_TYPE(PATHCREATION, RecordedPathCreation); michael@0: LOAD_EVENT_TYPE(PATHDESTRUCTION, RecordedPathDestruction); michael@0: LOAD_EVENT_TYPE(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); michael@0: LOAD_EVENT_TYPE(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); michael@0: LOAD_EVENT_TYPE(FILTERNODECREATION, RecordedFilterNodeCreation); michael@0: LOAD_EVENT_TYPE(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); michael@0: LOAD_EVENT_TYPE(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); michael@0: LOAD_EVENT_TYPE(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); michael@0: LOAD_EVENT_TYPE(SNAPSHOT, RecordedSnapshot); michael@0: LOAD_EVENT_TYPE(SCALEDFONTCREATION, RecordedScaledFontCreation); michael@0: LOAD_EVENT_TYPE(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); michael@0: LOAD_EVENT_TYPE(MASKSURFACE, RecordedMaskSurface); michael@0: LOAD_EVENT_TYPE(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); michael@0: LOAD_EVENT_TYPE(FILTERNODESETINPUT, RecordedFilterNodeSetInput); michael@0: default: michael@0: return nullptr; michael@0: } michael@0: } michael@0: michael@0: string michael@0: RecordedEvent::GetEventName(EventType aType) michael@0: { michael@0: switch (aType) { michael@0: case DRAWTARGETCREATION: michael@0: return "DrawTarget Creation"; michael@0: case DRAWTARGETDESTRUCTION: michael@0: return "DrawTarget Destruction"; michael@0: case FILLRECT: michael@0: return "FillRect"; michael@0: case STROKERECT: michael@0: return "StrokeRect"; michael@0: case STROKELINE: michael@0: return "StrokeLine"; michael@0: case CLEARRECT: michael@0: return "ClearRect"; michael@0: case COPYSURFACE: michael@0: return "CopySurface"; michael@0: case SETTRANSFORM: michael@0: return "SetTransform"; michael@0: case PUSHCLIP: michael@0: return "PushClip"; michael@0: case PUSHCLIPRECT: michael@0: return "PushClipRect"; michael@0: case POPCLIP: michael@0: return "PopClip"; michael@0: case FILL: michael@0: return "Fill"; michael@0: case FILLGLYPHS: michael@0: return "FillGlyphs"; michael@0: case MASK: michael@0: return "Mask"; michael@0: case STROKE: michael@0: return "Stroke"; michael@0: case DRAWSURFACE: michael@0: return "DrawSurface"; michael@0: case DRAWSURFACEWITHSHADOW: michael@0: return "DrawSurfaceWithShadow"; michael@0: case DRAWFILTER: michael@0: return "DrawFilter"; michael@0: case PATHCREATION: michael@0: return "PathCreation"; michael@0: case PATHDESTRUCTION: michael@0: return "PathDestruction"; michael@0: case SOURCESURFACECREATION: michael@0: return "SourceSurfaceCreation"; michael@0: case SOURCESURFACEDESTRUCTION: michael@0: return "SourceSurfaceDestruction"; michael@0: case FILTERNODECREATION: michael@0: return "FilterNodeCreation"; michael@0: case FILTERNODEDESTRUCTION: michael@0: return "FilterNodeDestruction"; michael@0: case GRADIENTSTOPSCREATION: michael@0: return "GradientStopsCreation"; michael@0: case GRADIENTSTOPSDESTRUCTION: michael@0: return "GradientStopsDestruction"; michael@0: case SNAPSHOT: michael@0: return "Snapshot"; michael@0: case SCALEDFONTCREATION: michael@0: return "ScaledFontCreation"; michael@0: case SCALEDFONTDESTRUCTION: michael@0: return "ScaledFontDestruction"; michael@0: case MASKSURFACE: michael@0: return "MaskSurface"; michael@0: case FILTERNODESETATTRIBUTE: michael@0: return "SetAttribute"; michael@0: case FILTERNODESETINPUT: michael@0: return "SetInput"; michael@0: default: michael@0: return "Unknown"; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::RecordPatternData(std::ostream &aStream, const PatternStorage &aPattern) const michael@0: { michael@0: WriteElement(aStream, aPattern.mType); michael@0: michael@0: switch (aPattern.mType) { michael@0: case PatternType::COLOR: michael@0: { michael@0: WriteElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::LINEAR_GRADIENT: michael@0: { michael@0: WriteElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::RADIAL_GRADIENT: michael@0: { michael@0: WriteElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::SURFACE: michael@0: { michael@0: WriteElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: default: michael@0: return; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::ReadPatternData(std::istream &aStream, PatternStorage &aPattern) const michael@0: { michael@0: ReadElement(aStream, aPattern.mType); michael@0: michael@0: switch (aPattern.mType) { michael@0: case PatternType::COLOR: michael@0: { michael@0: ReadElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::LINEAR_GRADIENT: michael@0: { michael@0: ReadElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::RADIAL_GRADIENT: michael@0: { michael@0: ReadElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: case PatternType::SURFACE: michael@0: { michael@0: ReadElement(aStream, *reinterpret_cast(&aPattern.mStorage)); michael@0: return; michael@0: } michael@0: default: michael@0: return; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::StorePattern(PatternStorage &aDestination, const Pattern &aSource) const michael@0: { michael@0: aDestination.mType = aSource.GetType(); michael@0: michael@0: switch (aSource.GetType()) { michael@0: case PatternType::COLOR: michael@0: { michael@0: reinterpret_cast(&aDestination.mStorage)->mColor = michael@0: static_cast(&aSource)->mColor; michael@0: return; michael@0: } michael@0: case PatternType::LINEAR_GRADIENT: michael@0: { michael@0: LinearGradientPatternStorage *store = michael@0: reinterpret_cast(&aDestination.mStorage); michael@0: const LinearGradientPattern *pat = michael@0: static_cast(&aSource); michael@0: store->mBegin = pat->mBegin; michael@0: store->mEnd = pat->mEnd; michael@0: store->mMatrix = pat->mMatrix; michael@0: store->mStops = pat->mStops.get(); michael@0: return; michael@0: } michael@0: case PatternType::RADIAL_GRADIENT: michael@0: { michael@0: RadialGradientPatternStorage *store = michael@0: reinterpret_cast(&aDestination.mStorage); michael@0: const RadialGradientPattern *pat = michael@0: static_cast(&aSource); michael@0: store->mCenter1 = pat->mCenter1; michael@0: store->mCenter2 = pat->mCenter2; michael@0: store->mRadius1 = pat->mRadius1; michael@0: store->mRadius2 = pat->mRadius2; michael@0: store->mMatrix = pat->mMatrix; michael@0: store->mStops = pat->mStops.get(); michael@0: return; michael@0: } michael@0: case PatternType::SURFACE: michael@0: { michael@0: SurfacePatternStorage *store = michael@0: reinterpret_cast(&aDestination.mStorage); michael@0: const SurfacePattern *pat = michael@0: static_cast(&aSource); michael@0: store->mExtend = pat->mExtendMode; michael@0: store->mFilter = pat->mFilter; michael@0: store->mMatrix = pat->mMatrix; michael@0: store->mSurface = pat->mSurface; michael@0: return; michael@0: } michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::RecordStrokeOptions(std::ostream &aStream, const StrokeOptions &aStrokeOptions) const michael@0: { michael@0: JoinStyle joinStyle = aStrokeOptions.mLineJoin; michael@0: CapStyle capStyle = aStrokeOptions.mLineCap; michael@0: michael@0: WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength)); michael@0: WriteElement(aStream, aStrokeOptions.mDashOffset); michael@0: WriteElement(aStream, aStrokeOptions.mLineWidth); michael@0: WriteElement(aStream, aStrokeOptions.mMiterLimit); michael@0: WriteElement(aStream, joinStyle); michael@0: WriteElement(aStream, capStyle); michael@0: michael@0: if (!aStrokeOptions.mDashPattern) { michael@0: return; michael@0: } michael@0: michael@0: aStream.write((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength); michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::ReadStrokeOptions(std::istream &aStream, StrokeOptions &aStrokeOptions) michael@0: { michael@0: uint64_t dashLength; michael@0: JoinStyle joinStyle; michael@0: CapStyle capStyle; michael@0: michael@0: ReadElement(aStream, dashLength); michael@0: ReadElement(aStream, aStrokeOptions.mDashOffset); michael@0: ReadElement(aStream, aStrokeOptions.mLineWidth); michael@0: ReadElement(aStream, aStrokeOptions.mMiterLimit); michael@0: ReadElement(aStream, joinStyle); michael@0: ReadElement(aStream, capStyle); michael@0: // On 32 bit we truncate the value of dashLength. michael@0: // See also bug 811850 for history. michael@0: aStrokeOptions.mDashLength = size_t(dashLength); michael@0: aStrokeOptions.mLineJoin = joinStyle; michael@0: aStrokeOptions.mLineCap = capStyle; michael@0: michael@0: if (!aStrokeOptions.mDashLength) { michael@0: return; michael@0: } michael@0: michael@0: mDashPatternStorage.resize(aStrokeOptions.mDashLength); michael@0: aStrokeOptions.mDashPattern = &mDashPatternStorage.front(); michael@0: aStream.read((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength); michael@0: } michael@0: michael@0: void michael@0: RecordedEvent::OutputSimplePatternInfo(const PatternStorage &aStorage, std::stringstream &aOutput) const michael@0: { michael@0: switch (aStorage.mType) { michael@0: case PatternType::COLOR: michael@0: { michael@0: const Color color = reinterpret_cast(&aStorage.mStorage)->mColor; michael@0: aOutput << "Color: (" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << ")"; michael@0: return; michael@0: } michael@0: case PatternType::LINEAR_GRADIENT: michael@0: { michael@0: const LinearGradientPatternStorage *store = michael@0: reinterpret_cast(&aStorage.mStorage); michael@0: michael@0: aOutput << "LinearGradient (" << store->mBegin.x << ", " << store->mBegin.y << michael@0: ") - (" << store->mEnd.x << ", " << store->mEnd.y << ") Stops: " << store->mStops; michael@0: return; michael@0: } michael@0: case PatternType::RADIAL_GRADIENT: michael@0: { michael@0: const RadialGradientPatternStorage *store = michael@0: reinterpret_cast(&aStorage.mStorage); michael@0: aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", " << michael@0: store->mCenter2.y << ") Radius 2: " << store->mRadius2; michael@0: return; michael@0: } michael@0: case PatternType::SURFACE: michael@0: { michael@0: const SurfacePatternStorage *store = michael@0: reinterpret_cast(&aStorage.mStorage); michael@0: aOutput << "Surface (0x" << store->mSurface << ")"; michael@0: return; michael@0: } michael@0: } michael@0: } michael@0: michael@0: RecordedDrawingEvent::RecordedDrawingEvent(EventType aType, std::istream &aStream) michael@0: : RecordedEvent(aType) michael@0: { michael@0: ReadElement(aStream, mDT); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawingEvent::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mDT); michael@0: } michael@0: michael@0: ReferencePtr michael@0: RecordedDrawingEvent::GetObjectRef() const michael@0: { michael@0: return mDT; michael@0: } michael@0: michael@0: void michael@0: RecordedDrawTargetCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr newDT = michael@0: aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(mSize, mFormat); michael@0: aTranslator->AddDrawTarget(mRefPtr, newDT); michael@0: michael@0: if (mHasExistingData) { michael@0: Rect dataRect(0, 0, mExistingData->GetSize().width, mExistingData->GetSize().height); michael@0: newDT->DrawSurface(mExistingData, dataRect, dataRect); michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedDrawTargetCreation::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mBackendType); michael@0: WriteElement(aStream, mSize); michael@0: WriteElement(aStream, mFormat); michael@0: WriteElement(aStream, mHasExistingData); michael@0: michael@0: if (mHasExistingData) { michael@0: MOZ_ASSERT(mExistingData); michael@0: MOZ_ASSERT(mExistingData->GetSize() == mSize); michael@0: RefPtr dataSurf = mExistingData->GetDataSurface(); michael@0: for (int y = 0; y < mSize.height; y++) { michael@0: aStream.write((const char*)dataSurf->GetData() + y * dataSurf->Stride(), michael@0: BytesPerPixel(mFormat) * mSize.width); michael@0: } michael@0: } michael@0: } michael@0: michael@0: RecordedDrawTargetCreation::RecordedDrawTargetCreation(istream &aStream) michael@0: : RecordedEvent(DRAWTARGETCREATION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mBackendType); michael@0: ReadElement(aStream, mSize); michael@0: ReadElement(aStream, mFormat); michael@0: ReadElement(aStream, mHasExistingData); michael@0: michael@0: if (mHasExistingData) { michael@0: RefPtr dataSurf = Factory::CreateDataSourceSurface(mSize, mFormat); michael@0: for (int y = 0; y < mSize.height; y++) { michael@0: aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(), michael@0: BytesPerPixel(mFormat) * mSize.width); michael@0: } michael@0: mExistingData = dataSurf; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedDrawTargetCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: " << NameFromBackend(mBackendType) << ", Size: " << mSize.width << "x" << mSize.height << ")"; michael@0: } michael@0: michael@0: michael@0: void michael@0: RecordedDrawTargetDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemoveDrawTarget(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawTargetDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(istream &aStream) michael@0: : RecordedEvent(DRAWTARGETDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawTargetDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] DrawTarget Destruction"; michael@0: } michael@0: michael@0: struct GenericPattern michael@0: { michael@0: GenericPattern(const PatternStorage &aStorage, Translator *aTranslator) michael@0: : mPattern(nullptr), mTranslator(aTranslator) michael@0: { michael@0: mStorage = const_cast(&aStorage); michael@0: } michael@0: michael@0: ~GenericPattern() { michael@0: if (mPattern) { michael@0: mPattern->~Pattern(); michael@0: } michael@0: } michael@0: michael@0: operator Pattern*() michael@0: { michael@0: switch(mStorage->mType) { michael@0: case PatternType::COLOR: michael@0: return new (mColPat) ColorPattern(reinterpret_cast(&mStorage->mStorage)->mColor); michael@0: case PatternType::SURFACE: michael@0: { michael@0: SurfacePatternStorage *storage = reinterpret_cast(&mStorage->mStorage); michael@0: mPattern = michael@0: new (mSurfPat) SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface), michael@0: storage->mExtend, storage->mMatrix, storage->mFilter); michael@0: return mPattern; michael@0: } michael@0: case PatternType::LINEAR_GRADIENT: michael@0: { michael@0: LinearGradientPatternStorage *storage = reinterpret_cast(&mStorage->mStorage); michael@0: mPattern = michael@0: new (mLinGradPat) LinearGradientPattern(storage->mBegin, storage->mEnd, michael@0: mTranslator->LookupGradientStops(storage->mStops), michael@0: storage->mMatrix); michael@0: return mPattern; michael@0: } michael@0: case PatternType::RADIAL_GRADIENT: michael@0: { michael@0: RadialGradientPatternStorage *storage = reinterpret_cast(&mStorage->mStorage); michael@0: mPattern = michael@0: new (mRadGradPat) RadialGradientPattern(storage->mCenter1, storage->mCenter2, michael@0: storage->mRadius1, storage->mRadius2, michael@0: mTranslator->LookupGradientStops(storage->mStops), michael@0: storage->mMatrix); michael@0: return mPattern; michael@0: } michael@0: default: michael@0: return new (mColPat) ColorPattern(Color()); michael@0: } michael@0: michael@0: return mPattern; michael@0: } michael@0: michael@0: union { michael@0: char mColPat[sizeof(ColorPattern)]; michael@0: char mLinGradPat[sizeof(LinearGradientPattern)]; michael@0: char mRadGradPat[sizeof(RadialGradientPattern)]; michael@0: char mSurfPat[sizeof(SurfacePattern)]; michael@0: }; michael@0: michael@0: PatternStorage *mStorage; michael@0: Pattern *mPattern; michael@0: Translator *mTranslator; michael@0: }; michael@0: michael@0: void michael@0: RecordedFillRect::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedFillRect::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRect); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: } michael@0: michael@0: RecordedFillRect::RecordedFillRect(istream &aStream) michael@0: : RecordedDrawingEvent(FILLRECT, aStream) michael@0: { michael@0: ReadElement(aStream, mRect); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: } michael@0: michael@0: void michael@0: RecordedFillRect::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] FillRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeRect::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeRect::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRect); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: RecordStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: RecordedStrokeRect::RecordedStrokeRect(istream &aStream) michael@0: : RecordedDrawingEvent(STROKERECT, aStream) michael@0: { michael@0: ReadElement(aStream, mRect); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: ReadStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeRect::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] StrokeRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height michael@0: << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeLine::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeLine::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mBegin); michael@0: WriteElement(aStream, mEnd); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: RecordStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: RecordedStrokeLine::RecordedStrokeLine(istream &aStream) michael@0: : RecordedDrawingEvent(STROKELINE, aStream) michael@0: { michael@0: ReadElement(aStream, mBegin); michael@0: ReadElement(aStream, mEnd); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: ReadStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStrokeLine::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", " << mBegin.y << " - " << mEnd.x << ", " << mEnd.y michael@0: << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedFill::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->Fill(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mOptions); michael@0: } michael@0: michael@0: RecordedFill::RecordedFill(istream &aStream) michael@0: : RecordedDrawingEvent(FILL, aStream) michael@0: { michael@0: ReadElement(aStream, mPath); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: } michael@0: michael@0: void michael@0: RecordedFill::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mPath); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: } michael@0: michael@0: void michael@0: RecordedFill::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] Fill (" << mPath << ") "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: RecordedFillGlyphs::~RecordedFillGlyphs() michael@0: { michael@0: delete [] mGlyphs; michael@0: } michael@0: michael@0: void michael@0: RecordedFillGlyphs::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: GlyphBuffer buffer; michael@0: buffer.mGlyphs = mGlyphs; michael@0: buffer.mNumGlyphs = mNumGlyphs; michael@0: aTranslator->LookupDrawTarget(mDT)->FillGlyphs(aTranslator->LookupScaledFont(mScaledFont), buffer, *GenericPattern(mPattern, aTranslator), mOptions); michael@0: } michael@0: michael@0: RecordedFillGlyphs::RecordedFillGlyphs(istream &aStream) michael@0: : RecordedDrawingEvent(FILLGLYPHS, aStream) michael@0: { michael@0: ReadElement(aStream, mScaledFont); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: ReadElement(aStream, mNumGlyphs); michael@0: mGlyphs = new Glyph[mNumGlyphs]; michael@0: aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs); michael@0: } michael@0: michael@0: void michael@0: RecordedFillGlyphs::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mScaledFont); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: WriteElement(aStream, mNumGlyphs); michael@0: aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs); michael@0: } michael@0: michael@0: void michael@0: RecordedFillGlyphs::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedMask::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->Mask(*GenericPattern(mSource, aTranslator), *GenericPattern(mMask, aTranslator), mOptions); michael@0: } michael@0: michael@0: RecordedMask::RecordedMask(istream &aStream) michael@0: : RecordedDrawingEvent(MASK, aStream) michael@0: { michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mSource); michael@0: ReadPatternData(aStream, mMask); michael@0: } michael@0: michael@0: void michael@0: RecordedMask::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mSource); michael@0: RecordPatternData(aStream, mMask); michael@0: } michael@0: michael@0: void michael@0: RecordedMask::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] Mask (Source: "; michael@0: OutputSimplePatternInfo(mSource, aStringStream); michael@0: aStringStream << " Mask: "; michael@0: OutputSimplePatternInfo(mMask, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedStroke::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->Stroke(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStroke::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mPath); michael@0: WriteElement(aStream, mOptions); michael@0: RecordPatternData(aStream, mPattern); michael@0: RecordStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: RecordedStroke::RecordedStroke(istream &aStream) michael@0: : RecordedDrawingEvent(STROKE, aStream) michael@0: { michael@0: ReadElement(aStream, mPath); michael@0: ReadElement(aStream, mOptions); michael@0: ReadPatternData(aStream, mPattern); michael@0: ReadStrokeOptions(aStream, mStrokeOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedStroke::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] Stroke ("<< mPath << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: void michael@0: RecordedClearRect::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->ClearRect(mRect); michael@0: } michael@0: michael@0: void michael@0: RecordedClearRect::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRect); michael@0: } michael@0: michael@0: RecordedClearRect::RecordedClearRect(istream &aStream) michael@0: : RecordedDrawingEvent(CLEARRECT, aStream) michael@0: { michael@0: ReadElement(aStream, mRect); michael@0: } michael@0: michael@0: void michael@0: RecordedClearRect::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT<< "] ClearRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") "; michael@0: } michael@0: michael@0: void michael@0: RecordedCopySurface::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->CopySurface(aTranslator->LookupSourceSurface(mSourceSurface), michael@0: mSourceRect, mDest); michael@0: } michael@0: michael@0: void michael@0: RecordedCopySurface::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mSourceSurface); michael@0: WriteElement(aStream, mSourceRect); michael@0: WriteElement(aStream, mDest); michael@0: } michael@0: michael@0: RecordedCopySurface::RecordedCopySurface(istream &aStream) michael@0: : RecordedDrawingEvent(COPYSURFACE, aStream) michael@0: { michael@0: ReadElement(aStream, mSourceSurface); michael@0: ReadElement(aStream, mSourceRect); michael@0: ReadElement(aStream, mDest); michael@0: } michael@0: michael@0: void michael@0: RecordedCopySurface::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT<< "] CopySurface (" << mSourceSurface << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedPushClip::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->PushClip(aTranslator->LookupPath(mPath)); michael@0: } michael@0: michael@0: void michael@0: RecordedPushClip::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mPath); michael@0: } michael@0: michael@0: RecordedPushClip::RecordedPushClip(istream &aStream) michael@0: : RecordedDrawingEvent(PUSHCLIP, aStream) michael@0: { michael@0: ReadElement(aStream, mPath); michael@0: } michael@0: michael@0: void michael@0: RecordedPushClip::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] PushClip (" << mPath << ") "; michael@0: } michael@0: michael@0: void michael@0: RecordedPushClipRect::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->PushClipRect(mRect); michael@0: } michael@0: michael@0: void michael@0: RecordedPushClipRect::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRect); michael@0: } michael@0: michael@0: RecordedPushClipRect::RecordedPushClipRect(istream &aStream) michael@0: : RecordedDrawingEvent(PUSHCLIPRECT, aStream) michael@0: { michael@0: ReadElement(aStream, mRect); michael@0: } michael@0: michael@0: void michael@0: RecordedPushClipRect::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] PushClipRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") "; michael@0: } michael@0: michael@0: void michael@0: RecordedPopClip::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->PopClip(); michael@0: } michael@0: michael@0: void michael@0: RecordedPopClip::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: } michael@0: michael@0: RecordedPopClip::RecordedPopClip(istream &aStream) michael@0: : RecordedDrawingEvent(POPCLIP, aStream) michael@0: { michael@0: } michael@0: michael@0: void michael@0: RecordedPopClip::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] PopClip"; michael@0: } michael@0: michael@0: void michael@0: RecordedSetTransform::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)->SetTransform(mTransform); michael@0: } michael@0: michael@0: void michael@0: RecordedSetTransform::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mTransform); michael@0: } michael@0: michael@0: RecordedSetTransform::RecordedSetTransform(istream &aStream) michael@0: : RecordedDrawingEvent(SETTRANSFORM, aStream) michael@0: { michael@0: ReadElement(aStream, mTransform); michael@0: } michael@0: michael@0: void michael@0: RecordedSetTransform::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " " << mTransform._12 << " ; " << michael@0: mTransform._21 << " " << mTransform._22 << " ; " << mTransform._31 << " " << mTransform._32 << " ]"; michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurface::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)-> michael@0: DrawSurface(aTranslator->LookupSourceSurface(mRefSource), mDest, mSource, michael@0: mDSOptions, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurface::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRefSource); michael@0: WriteElement(aStream, mDest); michael@0: WriteElement(aStream, mSource); michael@0: WriteElement(aStream, mDSOptions); michael@0: WriteElement(aStream, mOptions); michael@0: } michael@0: michael@0: RecordedDrawSurface::RecordedDrawSurface(istream &aStream) michael@0: : RecordedDrawingEvent(DRAWSURFACE, aStream) michael@0: { michael@0: ReadElement(aStream, mRefSource); michael@0: ReadElement(aStream, mDest); michael@0: ReadElement(aStream, mSource); michael@0: ReadElement(aStream, mDSOptions); michael@0: ReadElement(aStream, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurface::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedDrawFilter::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)-> michael@0: DrawFilter(aTranslator->LookupFilterNode(mNode), mSourceRect, michael@0: mDestPoint, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawFilter::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mNode); michael@0: WriteElement(aStream, mSourceRect); michael@0: WriteElement(aStream, mDestPoint); michael@0: WriteElement(aStream, mOptions); michael@0: } michael@0: michael@0: RecordedDrawFilter::RecordedDrawFilter(istream &aStream) michael@0: : RecordedDrawingEvent(DRAWFILTER, aStream) michael@0: { michael@0: ReadElement(aStream, mNode); michael@0: ReadElement(aStream, mSourceRect); michael@0: ReadElement(aStream, mDestPoint); michael@0: ReadElement(aStream, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawFilter::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurfaceWithShadow::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)-> michael@0: DrawSurfaceWithShadow(aTranslator->LookupSourceSurface(mRefSource), michael@0: mDest, mColor, mOffset, mSigma, mOp); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurfaceWithShadow::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mRefSource); michael@0: WriteElement(aStream, mDest); michael@0: WriteElement(aStream, mColor); michael@0: WriteElement(aStream, mOffset); michael@0: WriteElement(aStream, mSigma); michael@0: WriteElement(aStream, mOp); michael@0: } michael@0: michael@0: RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(istream &aStream) michael@0: : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aStream) michael@0: { michael@0: ReadElement(aStream, mRefSource); michael@0: ReadElement(aStream, mDest); michael@0: ReadElement(aStream, mColor); michael@0: ReadElement(aStream, mOffset); michael@0: ReadElement(aStream, mSigma); michael@0: ReadElement(aStream, mOp); michael@0: } michael@0: michael@0: void michael@0: RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource << ") Color: (" << michael@0: mColor.r << ", " << mColor.g << ", " << mColor.b << ", " << mColor.a << ")"; michael@0: } michael@0: michael@0: RecordedPathCreation::RecordedPathCreation(PathRecording *aPath) michael@0: : RecordedEvent(PATHCREATION), mRefPtr(aPath), mFillRule(aPath->mFillRule), mPathOps(aPath->mPathOps) michael@0: { michael@0: } michael@0: michael@0: RecordedPathCreation::~RecordedPathCreation() michael@0: { michael@0: } michael@0: michael@0: void michael@0: RecordedPathCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr builder = michael@0: aTranslator->GetReferenceDrawTarget()->CreatePathBuilder(mFillRule); michael@0: michael@0: for (size_t i = 0; i < mPathOps.size(); i++) { michael@0: const PathOp &op = mPathOps[i]; michael@0: switch (op.mType) { michael@0: case PathOp::OP_MOVETO: michael@0: builder->MoveTo(op.mP1); michael@0: break; michael@0: case PathOp::OP_LINETO: michael@0: builder->LineTo(op.mP1); michael@0: break; michael@0: case PathOp::OP_BEZIERTO: michael@0: builder->BezierTo(op.mP1, op.mP2, op.mP3); michael@0: break; michael@0: case PathOp::OP_QUADRATICBEZIERTO: michael@0: builder->QuadraticBezierTo(op.mP1, op.mP2); michael@0: break; michael@0: case PathOp::OP_CLOSE: michael@0: builder->Close(); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: RefPtr path = builder->Finish(); michael@0: aTranslator->AddPath(mRefPtr, path); michael@0: } michael@0: michael@0: void michael@0: RecordedPathCreation::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, uint64_t(mPathOps.size())); michael@0: WriteElement(aStream, mFillRule); michael@0: typedef std::vector pathOpVec; michael@0: for (pathOpVec::const_iterator iter = mPathOps.begin(); iter != mPathOps.end(); iter++) { michael@0: WriteElement(aStream, iter->mType); michael@0: if (sPointCount[iter->mType] >= 1) { michael@0: WriteElement(aStream, iter->mP1); michael@0: } michael@0: if (sPointCount[iter->mType] >= 2) { michael@0: WriteElement(aStream, iter->mP2); michael@0: } michael@0: if (sPointCount[iter->mType] >= 3) { michael@0: WriteElement(aStream, iter->mP3); michael@0: } michael@0: } michael@0: michael@0: } michael@0: michael@0: RecordedPathCreation::RecordedPathCreation(istream &aStream) michael@0: : RecordedEvent(PATHCREATION) michael@0: { michael@0: uint64_t size; michael@0: michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, size); michael@0: ReadElement(aStream, mFillRule); michael@0: michael@0: for (uint64_t i = 0; i < size; i++) { michael@0: PathOp newPathOp; michael@0: ReadElement(aStream, newPathOp.mType); michael@0: if (sPointCount[newPathOp.mType] >= 1) { michael@0: ReadElement(aStream, newPathOp.mP1); michael@0: } michael@0: if (sPointCount[newPathOp.mType] >= 2) { michael@0: ReadElement(aStream, newPathOp.mP2); michael@0: } michael@0: if (sPointCount[newPathOp.mType] >= 3) { michael@0: ReadElement(aStream, newPathOp.mP3); michael@0: } michael@0: michael@0: mPathOps.push_back(newPathOp); michael@0: } michael@0: michael@0: } michael@0: michael@0: void michael@0: RecordedPathCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << mPathOps.size() << ")"; michael@0: } michael@0: void michael@0: RecordedPathDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemovePath(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedPathDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedPathDestruction::RecordedPathDestruction(istream &aStream) michael@0: : RecordedEvent(PATHDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedPathDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] Path Destroyed"; michael@0: } michael@0: michael@0: RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() michael@0: { michael@0: if (mDataOwned) { michael@0: delete [] mData; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr src = aTranslator->GetReferenceDrawTarget()-> michael@0: CreateSourceSurfaceFromData(mData, mSize, mSize.width * BytesPerPixel(mFormat), mFormat); michael@0: aTranslator->AddSourceSurface(mRefPtr, src); michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceCreation::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mSize); michael@0: WriteElement(aStream, mFormat); michael@0: for (int y = 0; y < mSize.height; y++) { michael@0: aStream.write((const char*)mData + y * mStride, BytesPerPixel(mFormat) * mSize.width); michael@0: } michael@0: } michael@0: michael@0: RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(istream &aStream) michael@0: : RecordedEvent(SOURCESURFACECREATION), mDataOwned(true) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mSize); michael@0: ReadElement(aStream, mFormat); michael@0: mData = (uint8_t*)new char[mSize.width * mSize.height * BytesPerPixel(mFormat)]; michael@0: aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat)); michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] SourceSurface created (Size: " << mSize.width << "x" << mSize.height << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemoveSourceSurface(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(istream &aStream) michael@0: : RecordedEvent(SOURCESURFACEDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed"; michael@0: } michael@0: michael@0: RecordedFilterNodeCreation::~RecordedFilterNodeCreation() michael@0: { michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr node = aTranslator->GetReferenceDrawTarget()-> michael@0: CreateFilter(mType); michael@0: aTranslator->AddFilterNode(mRefPtr, node); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeCreation::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mType); michael@0: } michael@0: michael@0: RecordedFilterNodeCreation::RecordedFilterNodeCreation(istream &aStream) michael@0: : RecordedEvent(FILTERNODECREATION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mType); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] FilterNode created (Type: " << int(mType) << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemoveFilterNode(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(istream &aStream) michael@0: : RecordedEvent(FILTERNODEDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] FilterNode Destroyed"; michael@0: } michael@0: michael@0: RecordedGradientStopsCreation::~RecordedGradientStopsCreation() michael@0: { michael@0: if (mDataOwned) { michael@0: delete [] mStops; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr src = aTranslator->GetReferenceDrawTarget()-> michael@0: CreateGradientStops(mStops, mNumStops, mExtendMode); michael@0: aTranslator->AddGradientStops(mRefPtr, src); michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsCreation::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mExtendMode); michael@0: WriteElement(aStream, mNumStops); michael@0: aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop)); michael@0: } michael@0: michael@0: RecordedGradientStopsCreation::RecordedGradientStopsCreation(istream &aStream) michael@0: : RecordedEvent(GRADIENTSTOPSCREATION), mDataOwned(true) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mExtendMode); michael@0: ReadElement(aStream, mNumStops); michael@0: mStops = new GradientStop[mNumStops]; michael@0: michael@0: aStream.read((char*)mStops, mNumStops * sizeof(GradientStop)); michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] GradientStops created (Stops: " << mNumStops << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemoveGradientStops(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(istream &aStream) michael@0: : RecordedEvent(GRADIENTSTOPSDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedGradientStopsDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] GradientStops Destroyed"; michael@0: } michael@0: michael@0: void michael@0: RecordedSnapshot::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr src = aTranslator->LookupDrawTarget(mDT)->Snapshot(); michael@0: aTranslator->AddSourceSurface(mRefPtr, src); michael@0: } michael@0: michael@0: void michael@0: RecordedSnapshot::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mDT); michael@0: } michael@0: michael@0: RecordedSnapshot::RecordedSnapshot(istream &aStream) michael@0: : RecordedEvent(SNAPSHOT) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mDT); michael@0: } michael@0: michael@0: void michael@0: RecordedSnapshot::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")"; michael@0: } michael@0: michael@0: RecordedScaledFontCreation::~RecordedScaledFontCreation() michael@0: { michael@0: delete [] mData; michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: RefPtr scaledFont = michael@0: Factory::CreateScaledFontForTrueTypeData(mData, mSize, mIndex, mGlyphSize, michael@0: aTranslator->GetDesiredFontType()); michael@0: aTranslator->AddScaledFont(mRefPtr, scaledFont); michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontCreation::RecordToStream(std::ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: WriteElement(aStream, mIndex); michael@0: WriteElement(aStream, mGlyphSize); michael@0: WriteElement(aStream, mSize); michael@0: aStream.write((const char*)mData, mSize); michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] ScaledFont Created"; michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontCreation::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex, Float aGlyphSize) michael@0: { michael@0: mData = new uint8_t[aSize]; michael@0: memcpy(mData, aData, aSize); michael@0: mSize = aSize; michael@0: mIndex = aIndex; michael@0: mGlyphSize = aGlyphSize; michael@0: } michael@0: michael@0: RecordedScaledFontCreation::RecordedScaledFontCreation(istream &aStream) michael@0: : RecordedEvent(SCALEDFONTCREATION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: ReadElement(aStream, mIndex); michael@0: ReadElement(aStream, mGlyphSize); michael@0: ReadElement(aStream, mSize); michael@0: mData = new uint8_t[mSize]; michael@0: aStream.read((char*)mData, mSize); michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontDestruction::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->RemoveScaledFont(mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontDestruction::RecordToStream(ostream &aStream) const michael@0: { michael@0: WriteElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: RecordedScaledFontDestruction::RecordedScaledFontDestruction(istream &aStream) michael@0: : RecordedEvent(SCALEDFONTDESTRUCTION) michael@0: { michael@0: ReadElement(aStream, mRefPtr); michael@0: } michael@0: michael@0: void michael@0: RecordedScaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed"; michael@0: } michael@0: michael@0: void michael@0: RecordedMaskSurface::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: aTranslator->LookupDrawTarget(mDT)-> michael@0: MaskSurface(*GenericPattern(mPattern, aTranslator), michael@0: aTranslator->LookupSourceSurface(mRefMask), michael@0: mOffset, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedMaskSurface::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedDrawingEvent::RecordToStream(aStream); michael@0: RecordPatternData(aStream, mPattern); michael@0: WriteElement(aStream, mRefMask); michael@0: WriteElement(aStream, mOffset); michael@0: WriteElement(aStream, mOptions); michael@0: } michael@0: michael@0: RecordedMaskSurface::RecordedMaskSurface(istream &aStream) michael@0: : RecordedDrawingEvent(MASKSURFACE, aStream) michael@0: { michael@0: ReadPatternData(aStream, mPattern); michael@0: ReadElement(aStream, mRefMask); michael@0: ReadElement(aStream, mOffset); michael@0: ReadElement(aStream, mOptions); michael@0: } michael@0: michael@0: void michael@0: RecordedMaskSurface::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x << "x" << mOffset.y << ") Pattern: "; michael@0: OutputSimplePatternInfo(mPattern, aStringStream); michael@0: } michael@0: michael@0: template michael@0: void michael@0: ReplaySetAttribute(FilterNode *aNode, uint32_t aIndex, T aValue) michael@0: { michael@0: aNode->SetAttribute(aIndex, aValue); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetAttribute::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: #define REPLAY_SET_ATTRIBUTE(type, argtype) \ michael@0: case ARGTYPE_##argtype: \ michael@0: ReplaySetAttribute(aTranslator->LookupFilterNode(mNode), mIndex, *(type*)&mPayload.front()); \ michael@0: break michael@0: michael@0: switch (mArgType) { michael@0: REPLAY_SET_ATTRIBUTE(bool, BOOL); michael@0: REPLAY_SET_ATTRIBUTE(uint32_t, UINT32); michael@0: REPLAY_SET_ATTRIBUTE(Float, FLOAT); michael@0: REPLAY_SET_ATTRIBUTE(Size, SIZE); michael@0: REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE); michael@0: REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT); michael@0: REPLAY_SET_ATTRIBUTE(Rect, RECT); michael@0: REPLAY_SET_ATTRIBUTE(IntRect, INTRECT); michael@0: REPLAY_SET_ATTRIBUTE(Point, POINT); michael@0: REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4); michael@0: REPLAY_SET_ATTRIBUTE(Point3D, POINT3D); michael@0: REPLAY_SET_ATTRIBUTE(Color, COLOR); michael@0: case ARGTYPE_FLOAT_ARRAY: michael@0: aTranslator->LookupFilterNode(mNode)->SetAttribute( michael@0: mIndex, michael@0: reinterpret_cast(&mPayload.front()), michael@0: mPayload.size() / sizeof(Float)); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetAttribute::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mNode); michael@0: WriteElement(aStream, mIndex); michael@0: WriteElement(aStream, mArgType); michael@0: WriteElement(aStream, uint64_t(mPayload.size())); michael@0: aStream.write((const char*)&mPayload.front(), mPayload.size()); michael@0: } michael@0: michael@0: RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(istream &aStream) michael@0: : RecordedEvent(FILTERNODESETATTRIBUTE) michael@0: { michael@0: ReadElement(aStream, mNode); michael@0: ReadElement(aStream, mIndex); michael@0: ReadElement(aStream, mArgType); michael@0: uint64_t size; michael@0: ReadElement(aStream, size); michael@0: mPayload.resize(size_t(size)); michael@0: aStream.read((char*)&mPayload.front(), size); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")"; michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetInput::PlayEvent(Translator *aTranslator) const michael@0: { michael@0: if (mInputFilter) { michael@0: aTranslator->LookupFilterNode(mNode)->SetInput( michael@0: mIndex, aTranslator->LookupFilterNode(mInputFilter)); michael@0: } else { michael@0: aTranslator->LookupFilterNode(mNode)->SetInput( michael@0: mIndex, aTranslator->LookupSourceSurface(mInputSurface)); michael@0: } michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetInput::RecordToStream(ostream &aStream) const michael@0: { michael@0: RecordedEvent::RecordToStream(aStream); michael@0: WriteElement(aStream, mNode); michael@0: WriteElement(aStream, mIndex); michael@0: WriteElement(aStream, mInputFilter); michael@0: WriteElement(aStream, mInputSurface); michael@0: } michael@0: michael@0: RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(istream &aStream) michael@0: : RecordedEvent(FILTERNODESETINPUT) michael@0: { michael@0: ReadElement(aStream, mNode); michael@0: ReadElement(aStream, mIndex); michael@0: ReadElement(aStream, mInputFilter); michael@0: ReadElement(aStream, mInputSurface); michael@0: } michael@0: michael@0: void michael@0: RecordedFilterNodeSetInput::OutputSimpleEventInfo(stringstream &aStringStream) const michael@0: { michael@0: aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", "; michael@0: michael@0: if (mInputFilter) { michael@0: aStringStream << "Filter: " << mInputFilter; michael@0: } else { michael@0: aStringStream << "Surface: " << mInputSurface; michael@0: } michael@0: michael@0: aStringStream << ")"; michael@0: } michael@0: michael@0: } michael@0: }