1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "RecordedEventImpl.h"
9 #include "PathRecording.h"
10 #include "RecordingTypes.h"
14 #include "ScaledFontBase.h"
16 #include "InlineTranslator.h"
22 bool RecordedEvent::DoWithEventFromStream(
23 EventStream
& aStream
, EventType aType
,
24 const std::function
<bool(RecordedEvent
*)>& aAction
) {
25 return DoWithEvent(aStream
, aType
, aAction
);
29 bool RecordedEvent::DoWithEventFromReader(
30 MemReader
& aReader
, EventType aType
,
31 const std::function
<bool(RecordedEvent
*)>& aAction
) {
32 return DoWithEvent(aReader
, aType
, aAction
);
35 std::string
RecordedEvent::GetEventName(EventType aType
) {
37 case DRAWTARGETCREATION
:
38 return "DrawTarget Creation";
39 case DRAWTARGETDESTRUCTION
:
40 return "DrawTarget Destruction";
52 return "SetTransform";
56 return "PushClipRect";
69 case DRAWDEPENDENTSURFACE
:
70 return "DrawDependentSurface";
71 case DRAWSURFACEWITHSHADOW
:
72 return "DrawSurfaceWithShadow";
76 return "PathCreation";
78 return "PathDestruction";
79 case SOURCESURFACECREATION
:
80 return "SourceSurfaceCreation";
81 case SOURCESURFACEDESTRUCTION
:
82 return "SourceSurfaceDestruction";
83 case FILTERNODECREATION
:
84 return "FilterNodeCreation";
85 case FILTERNODEDESTRUCTION
:
86 return "FilterNodeDestruction";
87 case GRADIENTSTOPSCREATION
:
88 return "GradientStopsCreation";
89 case GRADIENTSTOPSDESTRUCTION
:
90 return "GradientStopsDestruction";
93 case SCALEDFONTCREATION
:
94 return "ScaledFontCreation";
95 case SCALEDFONTDESTRUCTION
:
96 return "ScaledFontDestruction";
99 case FILTERNODESETATTRIBUTE
:
100 return "SetAttribute";
101 case FILTERNODESETINPUT
:
103 case CREATESIMILARDRAWTARGET
:
104 return "CreateSimilarDrawTarget";
108 return "FontDescriptor";
113 case UNSCALEDFONTCREATION
:
114 return "UnscaledFontCreation";
115 case UNSCALEDFONTDESTRUCTION
:
116 return "UnscaledFontDestruction";
117 case EXTERNALSURFACECREATION
:
118 return "ExternalSourceSurfaceCreation";
122 return "Destination";
129 void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont
* aUnscaledFont
,
131 RecordedFontData
fontData(aUnscaledFont
);
132 RecordedFontDetails fontDetails
;
133 if (fontData
.GetFontDetails(fontDetails
)) {
134 // Try to serialise the whole font, just in case this is a web font that
135 // is not present on the system.
136 WriteElement(aOutput
, fontData
.mType
);
137 fontData
.RecordToStream(aOutput
);
139 auto r
= RecordedUnscaledFontCreation(aUnscaledFont
, fontDetails
);
140 WriteElement(aOutput
, r
.mType
);
141 r
.RecordToStream(aOutput
);
143 // If that fails, record just the font description and try to load it from
144 // the system on the other side.
145 RecordedFontDescriptor
fontDesc(aUnscaledFont
);
146 if (fontDesc
.IsValid()) {
147 WriteElement(aOutput
, fontDesc
.RecordedEvent::mType
);
148 fontDesc
.RecordToStream(aOutput
);
151 << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
156 void RecordedEvent::RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
157 std::ostream
* aOutput
) {
158 RecordUnscaledFontImpl(aUnscaledFont
, *aOutput
);
161 void RecordedEvent::RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
162 MemStream
& aOutput
) {
163 RecordUnscaledFontImpl(aUnscaledFont
, aOutput
);
166 already_AddRefed
<DrawTarget
> Translator::CreateDrawTarget(
167 ReferencePtr aRefPtr
, const IntSize
& aSize
, SurfaceFormat aFormat
) {
168 RefPtr
<DrawTarget
> newDT
=
169 GetReferenceDrawTarget()->CreateSimilarDrawTarget(aSize
, aFormat
);
170 AddDrawTarget(aRefPtr
, newDT
);
171 return newDT
.forget();
174 void Translator::DrawDependentSurface(uint64_t aKey
, const Rect
& aRect
) {
175 if (!mDependentSurfaces
|| !mCurrentDT
) {
179 RefPtr
<RecordedDependentSurface
> recordedSurface
=
180 mDependentSurfaces
->Get(aKey
);
181 if (!recordedSurface
) {
185 // Construct a new translator, so we can recurse into translating this
186 // sub-recording into the same DT. Set an initial transform for the
187 // translator, so that all commands get moved into the rect we want to draw.
189 // Because the recording may have filtered out SetTransform calls with the
190 // same value, we need to call SetTransform here to ensure it gets called at
191 // least once with the translated matrix.
192 const Matrix oldTransform
= mCurrentDT
->GetTransform();
194 Matrix dependentTransform
= oldTransform
;
195 dependentTransform
.PreTranslate(aRect
.TopLeft());
197 mCurrentDT
->PushClipRect(aRect
);
198 mCurrentDT
->SetTransform(dependentTransform
);
201 InlineTranslator
translator(mCurrentDT
, nullptr);
202 translator
.SetReferenceDrawTargetTransform(dependentTransform
);
203 translator
.SetDependentSurfaces(mDependentSurfaces
);
204 translator
.TranslateRecording((char*)recordedSurface
->mRecording
.mData
,
205 recordedSurface
->mRecording
.mLen
);
208 mCurrentDT
->SetTransform(oldTransform
);
209 mCurrentDT
->PopClip();
213 } // namespace mozilla