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