mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
28471864af
MozReview-Commit-ID: 3d1XMoe2BKj
1956 lines
54 KiB
C++
1956 lines
54 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "RecordedEvent.h"
|
|
|
|
#include "PathRecording.h"
|
|
#include "RecordingTypes.h"
|
|
#include "Tools.h"
|
|
#include "Filters.h"
|
|
#include "Logging.h"
|
|
#include "ScaledFontBase.h"
|
|
#include "SFNTData.h"
|
|
|
|
namespace mozilla {
|
|
namespace gfx {
|
|
|
|
using namespace std;
|
|
|
|
static std::string NameFromBackend(BackendType aType)
|
|
{
|
|
switch (aType) {
|
|
case BackendType::NONE:
|
|
return "None";
|
|
case BackendType::DIRECT2D:
|
|
return "Direct2D";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
already_AddRefed<DrawTarget>
|
|
Translator::CreateDrawTarget(ReferencePtr aRefPtr, const IntSize &aSize,
|
|
SurfaceFormat aFormat)
|
|
{
|
|
RefPtr<DrawTarget> newDT =
|
|
GetReferenceDrawTarget()->CreateSimilarDrawTarget(aSize, aFormat);
|
|
AddDrawTarget(aRefPtr, newDT);
|
|
return newDT.forget();
|
|
}
|
|
|
|
#define LOAD_EVENT_TYPE(_typeenum, _class) \
|
|
case _typeenum: return new _class(aStream)
|
|
|
|
RecordedEvent *
|
|
RecordedEvent::LoadEventFromStream(std::istream &aStream, EventType aType)
|
|
{
|
|
switch (aType) {
|
|
LOAD_EVENT_TYPE(DRAWTARGETCREATION, RecordedDrawTargetCreation);
|
|
LOAD_EVENT_TYPE(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction);
|
|
LOAD_EVENT_TYPE(FILLRECT, RecordedFillRect);
|
|
LOAD_EVENT_TYPE(STROKERECT, RecordedStrokeRect);
|
|
LOAD_EVENT_TYPE(STROKELINE, RecordedStrokeLine);
|
|
LOAD_EVENT_TYPE(CLEARRECT, RecordedClearRect);
|
|
LOAD_EVENT_TYPE(COPYSURFACE, RecordedCopySurface);
|
|
LOAD_EVENT_TYPE(SETTRANSFORM, RecordedSetTransform);
|
|
LOAD_EVENT_TYPE(PUSHCLIPRECT, RecordedPushClipRect);
|
|
LOAD_EVENT_TYPE(PUSHCLIP, RecordedPushClip);
|
|
LOAD_EVENT_TYPE(POPCLIP, RecordedPopClip);
|
|
LOAD_EVENT_TYPE(FILL, RecordedFill);
|
|
LOAD_EVENT_TYPE(FILLGLYPHS, RecordedFillGlyphs);
|
|
LOAD_EVENT_TYPE(MASK, RecordedMask);
|
|
LOAD_EVENT_TYPE(STROKE, RecordedStroke);
|
|
LOAD_EVENT_TYPE(DRAWSURFACE, RecordedDrawSurface);
|
|
LOAD_EVENT_TYPE(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow);
|
|
LOAD_EVENT_TYPE(DRAWFILTER, RecordedDrawFilter);
|
|
LOAD_EVENT_TYPE(PATHCREATION, RecordedPathCreation);
|
|
LOAD_EVENT_TYPE(PATHDESTRUCTION, RecordedPathDestruction);
|
|
LOAD_EVENT_TYPE(SOURCESURFACECREATION, RecordedSourceSurfaceCreation);
|
|
LOAD_EVENT_TYPE(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction);
|
|
LOAD_EVENT_TYPE(FILTERNODECREATION, RecordedFilterNodeCreation);
|
|
LOAD_EVENT_TYPE(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction);
|
|
LOAD_EVENT_TYPE(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation);
|
|
LOAD_EVENT_TYPE(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction);
|
|
LOAD_EVENT_TYPE(SNAPSHOT, RecordedSnapshot);
|
|
LOAD_EVENT_TYPE(SCALEDFONTCREATION, RecordedScaledFontCreation);
|
|
LOAD_EVENT_TYPE(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction);
|
|
LOAD_EVENT_TYPE(MASKSURFACE, RecordedMaskSurface);
|
|
LOAD_EVENT_TYPE(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute);
|
|
LOAD_EVENT_TYPE(FILTERNODESETINPUT, RecordedFilterNodeSetInput);
|
|
LOAD_EVENT_TYPE(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget);
|
|
LOAD_EVENT_TYPE(FONTDATA, RecordedFontData);
|
|
LOAD_EVENT_TYPE(FONTDESC, RecordedFontDescriptor);
|
|
LOAD_EVENT_TYPE(PUSHLAYER, RecordedPushLayer);
|
|
LOAD_EVENT_TYPE(POPLAYER, RecordedPopLayer);
|
|
LOAD_EVENT_TYPE(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation);
|
|
LOAD_EVENT_TYPE(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
string
|
|
RecordedEvent::GetEventName(EventType aType)
|
|
{
|
|
switch (aType) {
|
|
case DRAWTARGETCREATION:
|
|
return "DrawTarget Creation";
|
|
case DRAWTARGETDESTRUCTION:
|
|
return "DrawTarget Destruction";
|
|
case FILLRECT:
|
|
return "FillRect";
|
|
case STROKERECT:
|
|
return "StrokeRect";
|
|
case STROKELINE:
|
|
return "StrokeLine";
|
|
case CLEARRECT:
|
|
return "ClearRect";
|
|
case COPYSURFACE:
|
|
return "CopySurface";
|
|
case SETTRANSFORM:
|
|
return "SetTransform";
|
|
case PUSHCLIP:
|
|
return "PushClip";
|
|
case PUSHCLIPRECT:
|
|
return "PushClipRect";
|
|
case POPCLIP:
|
|
return "PopClip";
|
|
case FILL:
|
|
return "Fill";
|
|
case FILLGLYPHS:
|
|
return "FillGlyphs";
|
|
case MASK:
|
|
return "Mask";
|
|
case STROKE:
|
|
return "Stroke";
|
|
case DRAWSURFACE:
|
|
return "DrawSurface";
|
|
case DRAWSURFACEWITHSHADOW:
|
|
return "DrawSurfaceWithShadow";
|
|
case DRAWFILTER:
|
|
return "DrawFilter";
|
|
case PATHCREATION:
|
|
return "PathCreation";
|
|
case PATHDESTRUCTION:
|
|
return "PathDestruction";
|
|
case SOURCESURFACECREATION:
|
|
return "SourceSurfaceCreation";
|
|
case SOURCESURFACEDESTRUCTION:
|
|
return "SourceSurfaceDestruction";
|
|
case FILTERNODECREATION:
|
|
return "FilterNodeCreation";
|
|
case FILTERNODEDESTRUCTION:
|
|
return "FilterNodeDestruction";
|
|
case GRADIENTSTOPSCREATION:
|
|
return "GradientStopsCreation";
|
|
case GRADIENTSTOPSDESTRUCTION:
|
|
return "GradientStopsDestruction";
|
|
case SNAPSHOT:
|
|
return "Snapshot";
|
|
case SCALEDFONTCREATION:
|
|
return "ScaledFontCreation";
|
|
case SCALEDFONTDESTRUCTION:
|
|
return "ScaledFontDestruction";
|
|
case MASKSURFACE:
|
|
return "MaskSurface";
|
|
case FILTERNODESETATTRIBUTE:
|
|
return "SetAttribute";
|
|
case FILTERNODESETINPUT:
|
|
return "SetInput";
|
|
case CREATESIMILARDRAWTARGET:
|
|
return "CreateSimilarDrawTarget";
|
|
case FONTDATA:
|
|
return "FontData";
|
|
case FONTDESC:
|
|
return "FontDescriptor";
|
|
case PUSHLAYER:
|
|
return "PushLayer";
|
|
case POPLAYER:
|
|
return "PopLayer";
|
|
case UNSCALEDFONTCREATION:
|
|
return "UnscaledFontCreation";
|
|
case UNSCALEDFONTDESTRUCTION:
|
|
return "UnscaledFontDestruction";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedEvent::RecordPatternData(std::ostream &aStream, const PatternStorage &aPattern) const
|
|
{
|
|
WriteElement(aStream, aPattern.mType);
|
|
|
|
switch (aPattern.mType) {
|
|
case PatternType::COLOR:
|
|
{
|
|
WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::LINEAR_GRADIENT:
|
|
{
|
|
WriteElement(aStream, *reinterpret_cast<const LinearGradientPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::RADIAL_GRADIENT:
|
|
{
|
|
WriteElement(aStream, *reinterpret_cast<const RadialGradientPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::SURFACE:
|
|
{
|
|
WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedEvent::ReadPatternData(std::istream &aStream, PatternStorage &aPattern) const
|
|
{
|
|
ReadElement(aStream, aPattern.mType);
|
|
|
|
switch (aPattern.mType) {
|
|
case PatternType::COLOR:
|
|
{
|
|
ReadElement(aStream, *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::LINEAR_GRADIENT:
|
|
{
|
|
ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::RADIAL_GRADIENT:
|
|
{
|
|
ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
case PatternType::SURFACE:
|
|
{
|
|
ReadElement(aStream, *reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage));
|
|
return;
|
|
}
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedEvent::StorePattern(PatternStorage &aDestination, const Pattern &aSource) const
|
|
{
|
|
aDestination.mType = aSource.GetType();
|
|
|
|
switch (aSource.GetType()) {
|
|
case PatternType::COLOR:
|
|
{
|
|
reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
|
|
static_cast<const ColorPattern*>(&aSource)->mColor;
|
|
return;
|
|
}
|
|
case PatternType::LINEAR_GRADIENT:
|
|
{
|
|
LinearGradientPatternStorage *store =
|
|
reinterpret_cast<LinearGradientPatternStorage*>(&aDestination.mStorage);
|
|
const LinearGradientPattern *pat =
|
|
static_cast<const LinearGradientPattern*>(&aSource);
|
|
store->mBegin = pat->mBegin;
|
|
store->mEnd = pat->mEnd;
|
|
store->mMatrix = pat->mMatrix;
|
|
store->mStops = pat->mStops.get();
|
|
return;
|
|
}
|
|
case PatternType::RADIAL_GRADIENT:
|
|
{
|
|
RadialGradientPatternStorage *store =
|
|
reinterpret_cast<RadialGradientPatternStorage*>(&aDestination.mStorage);
|
|
const RadialGradientPattern *pat =
|
|
static_cast<const RadialGradientPattern*>(&aSource);
|
|
store->mCenter1 = pat->mCenter1;
|
|
store->mCenter2 = pat->mCenter2;
|
|
store->mRadius1 = pat->mRadius1;
|
|
store->mRadius2 = pat->mRadius2;
|
|
store->mMatrix = pat->mMatrix;
|
|
store->mStops = pat->mStops.get();
|
|
return;
|
|
}
|
|
case PatternType::SURFACE:
|
|
{
|
|
SurfacePatternStorage *store =
|
|
reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
|
|
const SurfacePattern *pat =
|
|
static_cast<const SurfacePattern*>(&aSource);
|
|
store->mExtend = pat->mExtendMode;
|
|
store->mSamplingFilter = pat->mSamplingFilter;
|
|
store->mMatrix = pat->mMatrix;
|
|
store->mSurface = pat->mSurface;
|
|
store->mSamplingRect = pat->mSamplingRect;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedEvent::RecordStrokeOptions(std::ostream &aStream, const StrokeOptions &aStrokeOptions) const
|
|
{
|
|
JoinStyle joinStyle = aStrokeOptions.mLineJoin;
|
|
CapStyle capStyle = aStrokeOptions.mLineCap;
|
|
|
|
WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
|
|
WriteElement(aStream, aStrokeOptions.mDashOffset);
|
|
WriteElement(aStream, aStrokeOptions.mLineWidth);
|
|
WriteElement(aStream, aStrokeOptions.mMiterLimit);
|
|
WriteElement(aStream, joinStyle);
|
|
WriteElement(aStream, capStyle);
|
|
|
|
if (!aStrokeOptions.mDashPattern) {
|
|
return;
|
|
}
|
|
|
|
aStream.write((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength);
|
|
}
|
|
|
|
void
|
|
RecordedEvent::ReadStrokeOptions(std::istream &aStream, StrokeOptions &aStrokeOptions)
|
|
{
|
|
uint64_t dashLength;
|
|
JoinStyle joinStyle;
|
|
CapStyle capStyle;
|
|
|
|
ReadElement(aStream, dashLength);
|
|
ReadElement(aStream, aStrokeOptions.mDashOffset);
|
|
ReadElement(aStream, aStrokeOptions.mLineWidth);
|
|
ReadElement(aStream, aStrokeOptions.mMiterLimit);
|
|
ReadElement(aStream, joinStyle);
|
|
ReadElement(aStream, capStyle);
|
|
// On 32 bit we truncate the value of dashLength.
|
|
// See also bug 811850 for history.
|
|
aStrokeOptions.mDashLength = size_t(dashLength);
|
|
aStrokeOptions.mLineJoin = joinStyle;
|
|
aStrokeOptions.mLineCap = capStyle;
|
|
|
|
if (!aStrokeOptions.mDashLength) {
|
|
return;
|
|
}
|
|
|
|
mDashPatternStorage.resize(aStrokeOptions.mDashLength);
|
|
aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
|
|
aStream.read((char*)aStrokeOptions.mDashPattern, sizeof(Float) * aStrokeOptions.mDashLength);
|
|
}
|
|
|
|
void
|
|
RecordedEvent::OutputSimplePatternInfo(const PatternStorage &aStorage, std::stringstream &aOutput) const
|
|
{
|
|
switch (aStorage.mType) {
|
|
case PatternType::COLOR:
|
|
{
|
|
const Color color = reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)->mColor;
|
|
aOutput << "Color: (" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << ")";
|
|
return;
|
|
}
|
|
case PatternType::LINEAR_GRADIENT:
|
|
{
|
|
const LinearGradientPatternStorage *store =
|
|
reinterpret_cast<const LinearGradientPatternStorage*>(&aStorage.mStorage);
|
|
|
|
aOutput << "LinearGradient (" << store->mBegin.x << ", " << store->mBegin.y <<
|
|
") - (" << store->mEnd.x << ", " << store->mEnd.y << ") Stops: " << store->mStops;
|
|
return;
|
|
}
|
|
case PatternType::RADIAL_GRADIENT:
|
|
{
|
|
const RadialGradientPatternStorage *store =
|
|
reinterpret_cast<const RadialGradientPatternStorage*>(&aStorage.mStorage);
|
|
aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", " <<
|
|
store->mCenter2.y << ") Radius 2: " << store->mRadius2;
|
|
return;
|
|
}
|
|
case PatternType::SURFACE:
|
|
{
|
|
const SurfacePatternStorage *store =
|
|
reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
|
|
aOutput << "Surface (0x" << store->mSurface << ")";
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
RecordedDrawingEvent::RecordedDrawingEvent(EventType aType, std::istream &aStream)
|
|
: RecordedEvent(aType)
|
|
{
|
|
ReadElement(aStream, mDT);
|
|
}
|
|
|
|
void
|
|
RecordedDrawingEvent::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mDT);
|
|
}
|
|
|
|
ReferencePtr
|
|
RecordedDrawingEvent::GetObjectRef() const
|
|
{
|
|
return mDT;
|
|
}
|
|
|
|
bool
|
|
RecordedDrawTargetCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<DrawTarget> newDT =
|
|
aTranslator->CreateDrawTarget(mRefPtr, mSize, mFormat);
|
|
|
|
// If we couldn't create a DrawTarget this will probably cause us to crash
|
|
// with nullptr later in the playback, so return false to abort.
|
|
if (!newDT) {
|
|
return false;
|
|
}
|
|
|
|
if (mHasExistingData) {
|
|
Rect dataRect(0, 0, mExistingData->GetSize().width, mExistingData->GetSize().height);
|
|
newDT->DrawSurface(mExistingData, dataRect, dataRect);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedDrawTargetCreation::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mBackendType);
|
|
WriteElement(aStream, mSize);
|
|
WriteElement(aStream, mFormat);
|
|
WriteElement(aStream, mHasExistingData);
|
|
|
|
if (mHasExistingData) {
|
|
MOZ_ASSERT(mExistingData);
|
|
MOZ_ASSERT(mExistingData->GetSize() == mSize);
|
|
RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
|
|
for (int y = 0; y < mSize.height; y++) {
|
|
aStream.write((const char*)dataSurf->GetData() + y * dataSurf->Stride(),
|
|
BytesPerPixel(mFormat) * mSize.width);
|
|
}
|
|
}
|
|
}
|
|
|
|
RecordedDrawTargetCreation::RecordedDrawTargetCreation(istream &aStream)
|
|
: RecordedEvent(DRAWTARGETCREATION)
|
|
, mExistingData(nullptr)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mBackendType);
|
|
ReadElement(aStream, mSize);
|
|
ReadElement(aStream, mFormat);
|
|
ReadElement(aStream, mHasExistingData);
|
|
|
|
if (mHasExistingData) {
|
|
RefPtr<DataSourceSurface> dataSurf = Factory::CreateDataSourceSurface(mSize, mFormat);
|
|
if (!dataSurf) {
|
|
gfxWarning() << "RecordedDrawTargetCreation had to reset mHasExistingData";
|
|
mHasExistingData = false;
|
|
return;
|
|
}
|
|
|
|
for (int y = 0; y < mSize.height; y++) {
|
|
aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(),
|
|
BytesPerPixel(mFormat) * mSize.width);
|
|
}
|
|
mExistingData = dataSurf;
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedDrawTargetCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: " << NameFromBackend(mBackendType) << ", Size: " << mSize.width << "x" << mSize.height << ")";
|
|
}
|
|
|
|
|
|
bool
|
|
RecordedDrawTargetDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveDrawTarget(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedDrawTargetDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(istream &aStream)
|
|
: RecordedEvent(DRAWTARGETDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedDrawTargetDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
|
|
}
|
|
|
|
bool
|
|
RecordedCreateSimilarDrawTarget::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<DrawTarget> newDT =
|
|
aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(mSize, mFormat);
|
|
|
|
// If we couldn't create a DrawTarget this will probably cause us to crash
|
|
// with nullptr later in the playback, so return false to abort.
|
|
if (!newDT) {
|
|
return false;
|
|
}
|
|
|
|
aTranslator->AddDrawTarget(mRefPtr, newDT);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedCreateSimilarDrawTarget::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mSize);
|
|
WriteElement(aStream, mFormat);
|
|
}
|
|
|
|
RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(istream &aStream)
|
|
: RecordedEvent(CREATESIMILARDRAWTARGET)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mSize);
|
|
ReadElement(aStream, mFormat);
|
|
}
|
|
|
|
void
|
|
RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x" << mSize.height << ")";
|
|
}
|
|
|
|
struct GenericPattern
|
|
{
|
|
GenericPattern(const PatternStorage &aStorage, Translator *aTranslator)
|
|
: mPattern(nullptr), mTranslator(aTranslator)
|
|
{
|
|
mStorage = const_cast<PatternStorage*>(&aStorage);
|
|
}
|
|
|
|
~GenericPattern() {
|
|
if (mPattern) {
|
|
mPattern->~Pattern();
|
|
}
|
|
}
|
|
|
|
operator Pattern*()
|
|
{
|
|
switch(mStorage->mType) {
|
|
case PatternType::COLOR:
|
|
return new (mColPat) ColorPattern(reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)->mColor);
|
|
case PatternType::SURFACE:
|
|
{
|
|
SurfacePatternStorage *storage = reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
|
|
mPattern =
|
|
new (mSurfPat) SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
|
|
storage->mExtend, storage->mMatrix,
|
|
storage->mSamplingFilter,
|
|
storage->mSamplingRect);
|
|
return mPattern;
|
|
}
|
|
case PatternType::LINEAR_GRADIENT:
|
|
{
|
|
LinearGradientPatternStorage *storage = reinterpret_cast<LinearGradientPatternStorage*>(&mStorage->mStorage);
|
|
mPattern =
|
|
new (mLinGradPat) LinearGradientPattern(storage->mBegin, storage->mEnd,
|
|
mTranslator->LookupGradientStops(storage->mStops),
|
|
storage->mMatrix);
|
|
return mPattern;
|
|
}
|
|
case PatternType::RADIAL_GRADIENT:
|
|
{
|
|
RadialGradientPatternStorage *storage = reinterpret_cast<RadialGradientPatternStorage*>(&mStorage->mStorage);
|
|
mPattern =
|
|
new (mRadGradPat) RadialGradientPattern(storage->mCenter1, storage->mCenter2,
|
|
storage->mRadius1, storage->mRadius2,
|
|
mTranslator->LookupGradientStops(storage->mStops),
|
|
storage->mMatrix);
|
|
return mPattern;
|
|
}
|
|
default:
|
|
return new (mColPat) ColorPattern(Color());
|
|
}
|
|
|
|
return mPattern;
|
|
}
|
|
|
|
union {
|
|
char mColPat[sizeof(ColorPattern)];
|
|
char mLinGradPat[sizeof(LinearGradientPattern)];
|
|
char mRadGradPat[sizeof(RadialGradientPattern)];
|
|
char mSurfPat[sizeof(SurfacePattern)];
|
|
};
|
|
|
|
PatternStorage *mStorage;
|
|
Pattern *mPattern;
|
|
Translator *mTranslator;
|
|
};
|
|
|
|
bool
|
|
RecordedFillRect::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFillRect::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRect);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
}
|
|
|
|
RecordedFillRect::RecordedFillRect(istream &aStream)
|
|
: RecordedDrawingEvent(FILLRECT, aStream)
|
|
{
|
|
ReadElement(aStream, mRect);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
}
|
|
|
|
void
|
|
RecordedFillRect::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] FillRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedStrokeRect::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedStrokeRect::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRect);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
RecordStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
RecordedStrokeRect::RecordedStrokeRect(istream &aStream)
|
|
: RecordedDrawingEvent(STROKERECT, aStream)
|
|
{
|
|
ReadElement(aStream, mRect);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
ReadStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
void
|
|
RecordedStrokeRect::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] StrokeRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height
|
|
<< ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedStrokeLine::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedStrokeLine::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mBegin);
|
|
WriteElement(aStream, mEnd);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
RecordStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
RecordedStrokeLine::RecordedStrokeLine(istream &aStream)
|
|
: RecordedDrawingEvent(STROKELINE, aStream)
|
|
{
|
|
ReadElement(aStream, mBegin);
|
|
ReadElement(aStream, mEnd);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
ReadStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
void
|
|
RecordedStrokeLine::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", " << mBegin.y << " - " << mEnd.x << ", " << mEnd.y
|
|
<< ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedFill::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->Fill(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mOptions);
|
|
return true;
|
|
}
|
|
|
|
RecordedFill::RecordedFill(istream &aStream)
|
|
: RecordedDrawingEvent(FILL, aStream)
|
|
{
|
|
ReadElement(aStream, mPath);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
}
|
|
|
|
void
|
|
RecordedFill::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mPath);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
}
|
|
|
|
void
|
|
RecordedFill::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] Fill (" << mPath << ") ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
RecordedFillGlyphs::~RecordedFillGlyphs()
|
|
{
|
|
delete [] mGlyphs;
|
|
}
|
|
|
|
bool
|
|
RecordedFillGlyphs::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
GlyphBuffer buffer;
|
|
buffer.mGlyphs = mGlyphs;
|
|
buffer.mNumGlyphs = mNumGlyphs;
|
|
aTranslator->LookupDrawTarget(mDT)->FillGlyphs(aTranslator->LookupScaledFont(mScaledFont), buffer, *GenericPattern(mPattern, aTranslator), mOptions);
|
|
return true;
|
|
}
|
|
|
|
RecordedFillGlyphs::RecordedFillGlyphs(istream &aStream)
|
|
: RecordedDrawingEvent(FILLGLYPHS, aStream)
|
|
{
|
|
ReadElement(aStream, mScaledFont);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
ReadElement(aStream, mNumGlyphs);
|
|
mGlyphs = new Glyph[mNumGlyphs];
|
|
aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
|
|
}
|
|
|
|
void
|
|
RecordedFillGlyphs::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mScaledFont);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
WriteElement(aStream, mNumGlyphs);
|
|
aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
|
|
}
|
|
|
|
void
|
|
RecordedFillGlyphs::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedMask::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->Mask(*GenericPattern(mSource, aTranslator), *GenericPattern(mMask, aTranslator), mOptions);
|
|
return true;
|
|
}
|
|
|
|
RecordedMask::RecordedMask(istream &aStream)
|
|
: RecordedDrawingEvent(MASK, aStream)
|
|
{
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mSource);
|
|
ReadPatternData(aStream, mMask);
|
|
}
|
|
|
|
void
|
|
RecordedMask::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mSource);
|
|
RecordPatternData(aStream, mMask);
|
|
}
|
|
|
|
void
|
|
RecordedMask::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] Mask (Source: ";
|
|
OutputSimplePatternInfo(mSource, aStringStream);
|
|
aStringStream << " Mask: ";
|
|
OutputSimplePatternInfo(mMask, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedStroke::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->Stroke(aTranslator->LookupPath(mPath), *GenericPattern(mPattern, aTranslator), mStrokeOptions, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedStroke::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mPath);
|
|
WriteElement(aStream, mOptions);
|
|
RecordPatternData(aStream, mPattern);
|
|
RecordStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
RecordedStroke::RecordedStroke(istream &aStream)
|
|
: RecordedDrawingEvent(STROKE, aStream)
|
|
{
|
|
ReadElement(aStream, mPath);
|
|
ReadElement(aStream, mOptions);
|
|
ReadPatternData(aStream, mPattern);
|
|
ReadStrokeOptions(aStream, mStrokeOptions);
|
|
}
|
|
|
|
void
|
|
RecordedStroke::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] Stroke ("<< mPath << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
bool
|
|
RecordedClearRect::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->ClearRect(mRect);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedClearRect::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRect);
|
|
}
|
|
|
|
RecordedClearRect::RecordedClearRect(istream &aStream)
|
|
: RecordedDrawingEvent(CLEARRECT, aStream)
|
|
{
|
|
ReadElement(aStream, mRect);
|
|
}
|
|
|
|
void
|
|
RecordedClearRect::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT<< "] ClearRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
|
|
}
|
|
|
|
bool
|
|
RecordedCopySurface::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->CopySurface(aTranslator->LookupSourceSurface(mSourceSurface),
|
|
mSourceRect, mDest);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedCopySurface::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mSourceSurface);
|
|
WriteElement(aStream, mSourceRect);
|
|
WriteElement(aStream, mDest);
|
|
}
|
|
|
|
RecordedCopySurface::RecordedCopySurface(istream &aStream)
|
|
: RecordedDrawingEvent(COPYSURFACE, aStream)
|
|
{
|
|
ReadElement(aStream, mSourceSurface);
|
|
ReadElement(aStream, mSourceRect);
|
|
ReadElement(aStream, mDest);
|
|
}
|
|
|
|
void
|
|
RecordedCopySurface::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT<< "] CopySurface (" << mSourceSurface << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedPushClip::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->PushClip(aTranslator->LookupPath(mPath));
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPushClip::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mPath);
|
|
}
|
|
|
|
RecordedPushClip::RecordedPushClip(istream &aStream)
|
|
: RecordedDrawingEvent(PUSHCLIP, aStream)
|
|
{
|
|
ReadElement(aStream, mPath);
|
|
}
|
|
|
|
void
|
|
RecordedPushClip::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] PushClip (" << mPath << ") ";
|
|
}
|
|
|
|
bool
|
|
RecordedPushClipRect::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->PushClipRect(mRect);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPushClipRect::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRect);
|
|
}
|
|
|
|
RecordedPushClipRect::RecordedPushClipRect(istream &aStream)
|
|
: RecordedDrawingEvent(PUSHCLIPRECT, aStream)
|
|
{
|
|
ReadElement(aStream, mRect);
|
|
}
|
|
|
|
void
|
|
RecordedPushClipRect::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] PushClipRect (" << mRect.x << ", " << mRect.y << " - " << mRect.width << " x " << mRect.height << ") ";
|
|
}
|
|
|
|
bool
|
|
RecordedPopClip::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->PopClip();
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPopClip::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
}
|
|
|
|
RecordedPopClip::RecordedPopClip(istream &aStream)
|
|
: RecordedDrawingEvent(POPCLIP, aStream)
|
|
{
|
|
}
|
|
|
|
void
|
|
RecordedPopClip::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] PopClip";
|
|
}
|
|
|
|
bool
|
|
RecordedPushLayer::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
SourceSurface* mask = mMask ? aTranslator->LookupSourceSurface(mMask)
|
|
: nullptr;
|
|
aTranslator->LookupDrawTarget(mDT)->
|
|
PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds, mCopyBackground);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPushLayer::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mOpaque);
|
|
WriteElement(aStream, mOpacity);
|
|
WriteElement(aStream, mMask);
|
|
WriteElement(aStream, mMaskTransform);
|
|
WriteElement(aStream, mBounds);
|
|
WriteElement(aStream, mCopyBackground);
|
|
}
|
|
|
|
RecordedPushLayer::RecordedPushLayer(istream &aStream)
|
|
: RecordedDrawingEvent(PUSHLAYER, aStream)
|
|
{
|
|
ReadElement(aStream, mOpaque);
|
|
ReadElement(aStream, mOpacity);
|
|
ReadElement(aStream, mMask);
|
|
ReadElement(aStream, mMaskTransform);
|
|
ReadElement(aStream, mBounds);
|
|
ReadElement(aStream, mCopyBackground);
|
|
}
|
|
|
|
void
|
|
RecordedPushLayer::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] PushPLayer (Opaque=" << mOpaque <<
|
|
", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
|
|
}
|
|
|
|
bool
|
|
RecordedPopLayer::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->PopLayer();
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPopLayer::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
}
|
|
|
|
RecordedPopLayer::RecordedPopLayer(istream &aStream)
|
|
: RecordedDrawingEvent(POPLAYER, aStream)
|
|
{
|
|
}
|
|
|
|
void
|
|
RecordedPopLayer::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] PopLayer";
|
|
}
|
|
|
|
bool
|
|
RecordedSetTransform::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->SetTransform(mTransform);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedSetTransform::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mTransform);
|
|
}
|
|
|
|
RecordedSetTransform::RecordedSetTransform(istream &aStream)
|
|
: RecordedDrawingEvent(SETTRANSFORM, aStream)
|
|
{
|
|
ReadElement(aStream, mTransform);
|
|
}
|
|
|
|
void
|
|
RecordedSetTransform::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " " << mTransform._12 << " ; " <<
|
|
mTransform._21 << " " << mTransform._22 << " ; " << mTransform._31 << " " << mTransform._32 << " ]";
|
|
}
|
|
|
|
bool
|
|
RecordedDrawSurface::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->
|
|
DrawSurface(aTranslator->LookupSourceSurface(mRefSource), mDest, mSource,
|
|
mDSOptions, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedDrawSurface::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRefSource);
|
|
WriteElement(aStream, mDest);
|
|
WriteElement(aStream, mSource);
|
|
WriteElement(aStream, mDSOptions);
|
|
WriteElement(aStream, mOptions);
|
|
}
|
|
|
|
RecordedDrawSurface::RecordedDrawSurface(istream &aStream)
|
|
: RecordedDrawingEvent(DRAWSURFACE, aStream)
|
|
{
|
|
ReadElement(aStream, mRefSource);
|
|
ReadElement(aStream, mDest);
|
|
ReadElement(aStream, mSource);
|
|
ReadElement(aStream, mDSOptions);
|
|
ReadElement(aStream, mOptions);
|
|
}
|
|
|
|
void
|
|
RecordedDrawSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedDrawFilter::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->
|
|
DrawFilter(aTranslator->LookupFilterNode(mNode), mSourceRect,
|
|
mDestPoint, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedDrawFilter::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mNode);
|
|
WriteElement(aStream, mSourceRect);
|
|
WriteElement(aStream, mDestPoint);
|
|
WriteElement(aStream, mOptions);
|
|
}
|
|
|
|
RecordedDrawFilter::RecordedDrawFilter(istream &aStream)
|
|
: RecordedDrawingEvent(DRAWFILTER, aStream)
|
|
{
|
|
ReadElement(aStream, mNode);
|
|
ReadElement(aStream, mSourceRect);
|
|
ReadElement(aStream, mDestPoint);
|
|
ReadElement(aStream, mOptions);
|
|
}
|
|
|
|
void
|
|
RecordedDrawFilter::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedDrawSurfaceWithShadow::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->
|
|
DrawSurfaceWithShadow(aTranslator->LookupSourceSurface(mRefSource),
|
|
mDest, mColor, mOffset, mSigma, mOp);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedDrawSurfaceWithShadow::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mRefSource);
|
|
WriteElement(aStream, mDest);
|
|
WriteElement(aStream, mColor);
|
|
WriteElement(aStream, mOffset);
|
|
WriteElement(aStream, mSigma);
|
|
WriteElement(aStream, mOp);
|
|
}
|
|
|
|
RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(istream &aStream)
|
|
: RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aStream)
|
|
{
|
|
ReadElement(aStream, mRefSource);
|
|
ReadElement(aStream, mDest);
|
|
ReadElement(aStream, mColor);
|
|
ReadElement(aStream, mOffset);
|
|
ReadElement(aStream, mSigma);
|
|
ReadElement(aStream, mOp);
|
|
}
|
|
|
|
void
|
|
RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource << ") Color: (" <<
|
|
mColor.r << ", " << mColor.g << ", " << mColor.b << ", " << mColor.a << ")";
|
|
}
|
|
|
|
RecordedPathCreation::RecordedPathCreation(PathRecording *aPath)
|
|
: RecordedEvent(PATHCREATION), mRefPtr(aPath), mFillRule(aPath->mFillRule), mPathOps(aPath->mPathOps)
|
|
{
|
|
}
|
|
|
|
RecordedPathCreation::~RecordedPathCreation()
|
|
{
|
|
}
|
|
|
|
bool
|
|
RecordedPathCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<PathBuilder> builder =
|
|
aTranslator->GetReferenceDrawTarget()->CreatePathBuilder(mFillRule);
|
|
|
|
for (size_t i = 0; i < mPathOps.size(); i++) {
|
|
const PathOp &op = mPathOps[i];
|
|
switch (op.mType) {
|
|
case PathOp::OP_MOVETO:
|
|
builder->MoveTo(op.mP1);
|
|
break;
|
|
case PathOp::OP_LINETO:
|
|
builder->LineTo(op.mP1);
|
|
break;
|
|
case PathOp::OP_BEZIERTO:
|
|
builder->BezierTo(op.mP1, op.mP2, op.mP3);
|
|
break;
|
|
case PathOp::OP_QUADRATICBEZIERTO:
|
|
builder->QuadraticBezierTo(op.mP1, op.mP2);
|
|
break;
|
|
case PathOp::OP_CLOSE:
|
|
builder->Close();
|
|
break;
|
|
}
|
|
}
|
|
|
|
RefPtr<Path> path = builder->Finish();
|
|
aTranslator->AddPath(mRefPtr, path);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPathCreation::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, uint64_t(mPathOps.size()));
|
|
WriteElement(aStream, mFillRule);
|
|
typedef std::vector<PathOp> pathOpVec;
|
|
for (pathOpVec::const_iterator iter = mPathOps.begin(); iter != mPathOps.end(); iter++) {
|
|
WriteElement(aStream, iter->mType);
|
|
if (sPointCount[iter->mType] >= 1) {
|
|
WriteElement(aStream, iter->mP1);
|
|
}
|
|
if (sPointCount[iter->mType] >= 2) {
|
|
WriteElement(aStream, iter->mP2);
|
|
}
|
|
if (sPointCount[iter->mType] >= 3) {
|
|
WriteElement(aStream, iter->mP3);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
RecordedPathCreation::RecordedPathCreation(istream &aStream)
|
|
: RecordedEvent(PATHCREATION)
|
|
{
|
|
uint64_t size;
|
|
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, size);
|
|
ReadElement(aStream, mFillRule);
|
|
|
|
for (uint64_t i = 0; i < size; i++) {
|
|
PathOp newPathOp;
|
|
ReadElement(aStream, newPathOp.mType);
|
|
if (sPointCount[newPathOp.mType] >= 1) {
|
|
ReadElement(aStream, newPathOp.mP1);
|
|
}
|
|
if (sPointCount[newPathOp.mType] >= 2) {
|
|
ReadElement(aStream, newPathOp.mP2);
|
|
}
|
|
if (sPointCount[newPathOp.mType] >= 3) {
|
|
ReadElement(aStream, newPathOp.mP3);
|
|
}
|
|
|
|
mPathOps.push_back(newPathOp);
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
RecordedPathCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << mPathOps.size() << ")";
|
|
}
|
|
bool
|
|
RecordedPathDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemovePath(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedPathDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedPathDestruction::RecordedPathDestruction(istream &aStream)
|
|
: RecordedEvent(PATHDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedPathDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] Path Destroyed";
|
|
}
|
|
|
|
RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation()
|
|
{
|
|
if (mDataOwned) {
|
|
delete [] mData;
|
|
}
|
|
}
|
|
|
|
bool
|
|
RecordedSourceSurfaceCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
if (!mData) {
|
|
return false;
|
|
}
|
|
|
|
RefPtr<SourceSurface> src = aTranslator->GetReferenceDrawTarget()->
|
|
CreateSourceSurfaceFromData(mData, mSize, mSize.width * BytesPerPixel(mFormat), mFormat);
|
|
aTranslator->AddSourceSurface(mRefPtr, src);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedSourceSurfaceCreation::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mSize);
|
|
WriteElement(aStream, mFormat);
|
|
MOZ_ASSERT(mData);
|
|
for (int y = 0; y < mSize.height; y++) {
|
|
aStream.write((const char*)mData + y * mStride, BytesPerPixel(mFormat) * mSize.width);
|
|
}
|
|
}
|
|
|
|
RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(istream &aStream)
|
|
: RecordedEvent(SOURCESURFACECREATION), mDataOwned(true)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mSize);
|
|
ReadElement(aStream, mFormat);
|
|
mData = (uint8_t*)new (fallible) char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
|
|
if (!mData) {
|
|
gfxWarning() << "RecordedSourceSurfaceCreation failed to allocate data";
|
|
} else {
|
|
aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
|
}
|
|
}
|
|
|
|
void
|
|
RecordedSourceSurfaceCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] SourceSurface created (Size: " << mSize.width << "x" << mSize.height << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedSourceSurfaceDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveSourceSurface(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedSourceSurfaceDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(istream &aStream)
|
|
: RecordedEvent(SOURCESURFACEDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
|
|
}
|
|
|
|
RecordedFilterNodeCreation::~RecordedFilterNodeCreation()
|
|
{
|
|
}
|
|
|
|
bool
|
|
RecordedFilterNodeCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<FilterNode> node = aTranslator->GetReferenceDrawTarget()->
|
|
CreateFilter(mType);
|
|
aTranslator->AddFilterNode(mRefPtr, node);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeCreation::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mType);
|
|
}
|
|
|
|
RecordedFilterNodeCreation::RecordedFilterNodeCreation(istream &aStream)
|
|
: RecordedEvent(FILTERNODECREATION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mType);
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] FilterNode created (Type: " << int(mType) << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedFilterNodeDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveFilterNode(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(istream &aStream)
|
|
: RecordedEvent(FILTERNODEDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
|
|
}
|
|
|
|
RecordedGradientStopsCreation::~RecordedGradientStopsCreation()
|
|
{
|
|
if (mDataOwned) {
|
|
delete [] mStops;
|
|
}
|
|
}
|
|
|
|
bool
|
|
RecordedGradientStopsCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<GradientStops> src = aTranslator->GetReferenceDrawTarget()->
|
|
CreateGradientStops(mStops, mNumStops, mExtendMode);
|
|
aTranslator->AddGradientStops(mRefPtr, src);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedGradientStopsCreation::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mExtendMode);
|
|
WriteElement(aStream, mNumStops);
|
|
aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
|
|
}
|
|
|
|
RecordedGradientStopsCreation::RecordedGradientStopsCreation(istream &aStream)
|
|
: RecordedEvent(GRADIENTSTOPSCREATION), mDataOwned(true)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mExtendMode);
|
|
ReadElement(aStream, mNumStops);
|
|
mStops = new GradientStop[mNumStops];
|
|
|
|
aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
|
|
}
|
|
|
|
void
|
|
RecordedGradientStopsCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] GradientStops created (Stops: " << mNumStops << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedGradientStopsDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveGradientStops(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedGradientStopsDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(istream &aStream)
|
|
: RecordedEvent(GRADIENTSTOPSDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedGradientStopsDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
|
|
}
|
|
|
|
bool
|
|
RecordedSnapshot::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->Snapshot();
|
|
aTranslator->AddSourceSurface(mRefPtr, src);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedSnapshot::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mDT);
|
|
}
|
|
|
|
RecordedSnapshot::RecordedSnapshot(istream &aStream)
|
|
: RecordedEvent(SNAPSHOT)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mDT);
|
|
}
|
|
|
|
void
|
|
RecordedSnapshot::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")";
|
|
}
|
|
|
|
RecordedFontData::~RecordedFontData()
|
|
{
|
|
delete[] mData;
|
|
}
|
|
|
|
bool
|
|
RecordedFontData::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<NativeFontResource> fontResource =
|
|
Factory::CreateNativeFontResource(mData, mFontDetails.size,
|
|
aTranslator->GetDesiredFontType());
|
|
if (!fontResource) {
|
|
return false;
|
|
}
|
|
|
|
aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFontData::RecordToStream(std::ostream &aStream) const
|
|
{
|
|
MOZ_ASSERT(mGetFontFileDataSucceeded);
|
|
|
|
WriteElement(aStream, mFontDetails.fontDataKey);
|
|
WriteElement(aStream, mFontDetails.size);
|
|
aStream.write((const char*)mData, mFontDetails.size);
|
|
}
|
|
|
|
void
|
|
RecordedFontData::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "Font Data of size " << mFontDetails.size;
|
|
}
|
|
|
|
void
|
|
RecordedFontData::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex)
|
|
{
|
|
mData = new uint8_t[aSize];
|
|
memcpy(mData, aData, aSize);
|
|
mFontDetails.fontDataKey =
|
|
SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
|
|
mFontDetails.size = aSize;
|
|
mFontDetails.index = aIndex;
|
|
}
|
|
|
|
bool
|
|
RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails)
|
|
{
|
|
if (!mGetFontFileDataSucceeded) {
|
|
return false;
|
|
}
|
|
|
|
fontDetails.fontDataKey = mFontDetails.fontDataKey;
|
|
fontDetails.size = mFontDetails.size;
|
|
fontDetails.index = mFontDetails.index;
|
|
return true;
|
|
}
|
|
|
|
RecordedFontData::RecordedFontData(istream &aStream)
|
|
: RecordedEvent(FONTDATA)
|
|
, mData(nullptr)
|
|
{
|
|
ReadElement(aStream, mFontDetails.fontDataKey);
|
|
ReadElement(aStream, mFontDetails.size);
|
|
mData = new uint8_t[mFontDetails.size];
|
|
aStream.read((char*)mData, mFontDetails.size);
|
|
}
|
|
|
|
RecordedFontDescriptor::~RecordedFontDescriptor()
|
|
{
|
|
}
|
|
|
|
bool
|
|
RecordedFontDescriptor::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
RefPtr<UnscaledFont> font =
|
|
Factory::CreateUnscaledFontFromFontDescriptor(mType, mData.data(), mData.size());
|
|
if (!font) {
|
|
gfxDevCrash(LogReason::InvalidFont) <<
|
|
"Failed creating UnscaledFont of type " << int(mType) << " from font descriptor";
|
|
return false;
|
|
}
|
|
|
|
aTranslator->AddUnscaledFont(mRefPtr, font);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFontDescriptor::RecordToStream(std::ostream &aStream) const
|
|
{
|
|
MOZ_ASSERT(mHasDesc);
|
|
WriteElement(aStream, mType);
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, (size_t)mData.size());
|
|
aStream.write((char*)mData.data(), mData.size());
|
|
}
|
|
|
|
void
|
|
RecordedFontDescriptor::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] Font Descriptor";
|
|
}
|
|
|
|
void
|
|
RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize)
|
|
{
|
|
mData.assign(aData, aData + aSize);
|
|
}
|
|
|
|
RecordedFontDescriptor::RecordedFontDescriptor(istream &aStream)
|
|
: RecordedEvent(FONTDESC)
|
|
{
|
|
ReadElement(aStream, mType);
|
|
ReadElement(aStream, mRefPtr);
|
|
|
|
size_t size;
|
|
ReadElement(aStream, size);
|
|
mData.resize(size);
|
|
aStream.read((char*)mData.data(), size);
|
|
}
|
|
|
|
bool
|
|
RecordedUnscaledFontCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
NativeFontResource *fontResource = aTranslator->LookupNativeFontResource(mFontDataKey);
|
|
if (!fontResource) {
|
|
gfxDevCrash(LogReason::NativeFontResourceNotFound) <<
|
|
"NativeFontResource lookup failed for key |" << hexa(mFontDataKey) << "|.";
|
|
return false;
|
|
}
|
|
|
|
RefPtr<UnscaledFont> unscaledFont =
|
|
fontResource->CreateUnscaledFont(mIndex, mInstanceData.data(), mInstanceData.size());
|
|
aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedUnscaledFontCreation::RecordToStream(std::ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mFontDataKey);
|
|
WriteElement(aStream, mIndex);
|
|
WriteElement(aStream, (size_t)mInstanceData.size());
|
|
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
|
}
|
|
|
|
void
|
|
RecordedUnscaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
|
|
}
|
|
|
|
void
|
|
RecordedUnscaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
|
|
{
|
|
mInstanceData.assign(aData, aData + aSize);
|
|
}
|
|
|
|
RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(istream &aStream)
|
|
: RecordedEvent(UNSCALEDFONTCREATION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mFontDataKey);
|
|
ReadElement(aStream, mIndex);
|
|
|
|
size_t size;
|
|
ReadElement(aStream, size);
|
|
mInstanceData.resize(size);
|
|
aStream.read((char*)mInstanceData.data(), size);
|
|
}
|
|
|
|
bool
|
|
RecordedUnscaledFontDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveUnscaledFont(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedUnscaledFontDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(istream &aStream)
|
|
: RecordedEvent(UNSCALEDFONTDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedUnscaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
|
|
}
|
|
|
|
bool
|
|
RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
|
|
if (!unscaledFont) {
|
|
gfxDevCrash(LogReason::UnscaledFontNotFound) <<
|
|
"UnscaledFont lookup failed for key |" << hexa(mUnscaledFont) << "|.";
|
|
return false;
|
|
}
|
|
|
|
RefPtr<ScaledFont> scaledFont =
|
|
unscaledFont->CreateScaledFont(mGlyphSize, mInstanceData.data(), mInstanceData.size());
|
|
aTranslator->AddScaledFont(mRefPtr, scaledFont);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedScaledFontCreation::RecordToStream(std::ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
WriteElement(aStream, mUnscaledFont);
|
|
WriteElement(aStream, mGlyphSize);
|
|
WriteElement(aStream, (size_t)mInstanceData.size());
|
|
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
|
}
|
|
|
|
void
|
|
RecordedScaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] ScaledFont Created";
|
|
}
|
|
|
|
void
|
|
RecordedScaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
|
|
{
|
|
mInstanceData.assign(aData, aData + aSize);
|
|
}
|
|
|
|
RecordedScaledFontCreation::RecordedScaledFontCreation(istream &aStream)
|
|
: RecordedEvent(SCALEDFONTCREATION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
ReadElement(aStream, mUnscaledFont);
|
|
ReadElement(aStream, mGlyphSize);
|
|
|
|
size_t size;
|
|
ReadElement(aStream, size);
|
|
mInstanceData.resize(size);
|
|
aStream.read((char*)mInstanceData.data(), size);
|
|
}
|
|
|
|
bool
|
|
RecordedScaledFontDestruction::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->RemoveScaledFont(mRefPtr);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedScaledFontDestruction::RecordToStream(ostream &aStream) const
|
|
{
|
|
WriteElement(aStream, mRefPtr);
|
|
}
|
|
|
|
RecordedScaledFontDestruction::RecordedScaledFontDestruction(istream &aStream)
|
|
: RecordedEvent(SCALEDFONTDESTRUCTION)
|
|
{
|
|
ReadElement(aStream, mRefPtr);
|
|
}
|
|
|
|
void
|
|
RecordedScaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
|
|
}
|
|
|
|
bool
|
|
RecordedMaskSurface::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
aTranslator->LookupDrawTarget(mDT)->
|
|
MaskSurface(*GenericPattern(mPattern, aTranslator),
|
|
aTranslator->LookupSourceSurface(mRefMask),
|
|
mOffset, mOptions);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedMaskSurface::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedDrawingEvent::RecordToStream(aStream);
|
|
RecordPatternData(aStream, mPattern);
|
|
WriteElement(aStream, mRefMask);
|
|
WriteElement(aStream, mOffset);
|
|
WriteElement(aStream, mOptions);
|
|
}
|
|
|
|
RecordedMaskSurface::RecordedMaskSurface(istream &aStream)
|
|
: RecordedDrawingEvent(MASKSURFACE, aStream)
|
|
{
|
|
ReadPatternData(aStream, mPattern);
|
|
ReadElement(aStream, mRefMask);
|
|
ReadElement(aStream, mOffset);
|
|
ReadElement(aStream, mOptions);
|
|
}
|
|
|
|
void
|
|
RecordedMaskSurface::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x << "x" << mOffset.y << ") Pattern: ";
|
|
OutputSimplePatternInfo(mPattern, aStringStream);
|
|
}
|
|
|
|
template<typename T>
|
|
void
|
|
ReplaySetAttribute(FilterNode *aNode, uint32_t aIndex, T aValue)
|
|
{
|
|
aNode->SetAttribute(aIndex, aValue);
|
|
}
|
|
|
|
bool
|
|
RecordedFilterNodeSetAttribute::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
#define REPLAY_SET_ATTRIBUTE(type, argtype) \
|
|
case ARGTYPE_##argtype: \
|
|
ReplaySetAttribute(aTranslator->LookupFilterNode(mNode), mIndex, *(type*)&mPayload.front()); \
|
|
break
|
|
|
|
switch (mArgType) {
|
|
REPLAY_SET_ATTRIBUTE(bool, BOOL);
|
|
REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
|
|
REPLAY_SET_ATTRIBUTE(Float, FLOAT);
|
|
REPLAY_SET_ATTRIBUTE(Size, SIZE);
|
|
REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
|
|
REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
|
|
REPLAY_SET_ATTRIBUTE(Rect, RECT);
|
|
REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
|
|
REPLAY_SET_ATTRIBUTE(Point, POINT);
|
|
REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
|
|
REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
|
|
REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
|
|
REPLAY_SET_ATTRIBUTE(Color, COLOR);
|
|
case ARGTYPE_FLOAT_ARRAY:
|
|
aTranslator->LookupFilterNode(mNode)->SetAttribute(
|
|
mIndex,
|
|
reinterpret_cast<const Float*>(&mPayload.front()),
|
|
mPayload.size() / sizeof(Float));
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeSetAttribute::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mNode);
|
|
WriteElement(aStream, mIndex);
|
|
WriteElement(aStream, mArgType);
|
|
WriteElement(aStream, uint64_t(mPayload.size()));
|
|
aStream.write((const char*)&mPayload.front(), mPayload.size());
|
|
}
|
|
|
|
RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(istream &aStream)
|
|
: RecordedEvent(FILTERNODESETATTRIBUTE)
|
|
{
|
|
ReadElement(aStream, mNode);
|
|
ReadElement(aStream, mIndex);
|
|
ReadElement(aStream, mArgType);
|
|
uint64_t size;
|
|
ReadElement(aStream, size);
|
|
mPayload.resize(size_t(size));
|
|
aStream.read((char*)&mPayload.front(), size);
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
|
|
}
|
|
|
|
bool
|
|
RecordedFilterNodeSetInput::PlayEvent(Translator *aTranslator) const
|
|
{
|
|
if (mInputFilter) {
|
|
aTranslator->LookupFilterNode(mNode)->SetInput(
|
|
mIndex, aTranslator->LookupFilterNode(mInputFilter));
|
|
} else {
|
|
aTranslator->LookupFilterNode(mNode)->SetInput(
|
|
mIndex, aTranslator->LookupSourceSurface(mInputSurface));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeSetInput::RecordToStream(ostream &aStream) const
|
|
{
|
|
RecordedEvent::RecordToStream(aStream);
|
|
WriteElement(aStream, mNode);
|
|
WriteElement(aStream, mIndex);
|
|
WriteElement(aStream, mInputFilter);
|
|
WriteElement(aStream, mInputSurface);
|
|
}
|
|
|
|
RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(istream &aStream)
|
|
: RecordedEvent(FILTERNODESETINPUT)
|
|
{
|
|
ReadElement(aStream, mNode);
|
|
ReadElement(aStream, mIndex);
|
|
ReadElement(aStream, mInputFilter);
|
|
ReadElement(aStream, mInputSurface);
|
|
}
|
|
|
|
void
|
|
RecordedFilterNodeSetInput::OutputSimpleEventInfo(stringstream &aStringStream) const
|
|
{
|
|
aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
|
|
|
|
if (mInputFilter) {
|
|
aStringStream << "Filter: " << mInputFilter;
|
|
} else {
|
|
aStringStream << "Surface: " << mInputSurface;
|
|
}
|
|
|
|
aStringStream << ")";
|
|
}
|
|
|
|
} // namespace gfx
|
|
} // namespace mozilla
|