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";
51 case SETPERMITSUBPIXELAA
:
52 return "SetPermitSubpixelAA";
54 return "SetTransform";
58 return "PushClipRect";
66 return "StrokeGlyphs";
73 case DRAWDEPENDENTSURFACE
:
74 return "DrawDependentSurface";
75 case DRAWSURFACEWITHSHADOW
:
76 return "DrawSurfaceWithShadow";
80 return "PathCreation";
82 return "PathDestruction";
83 case SOURCESURFACECREATION
:
84 return "SourceSurfaceCreation";
85 case SOURCESURFACEDESTRUCTION
:
86 return "SourceSurfaceDestruction";
87 case FILTERNODECREATION
:
88 return "FilterNodeCreation";
89 case FILTERNODEDESTRUCTION
:
90 return "FilterNodeDestruction";
91 case GRADIENTSTOPSCREATION
:
92 return "GradientStopsCreation";
93 case GRADIENTSTOPSDESTRUCTION
:
94 return "GradientStopsDestruction";
97 case SCALEDFONTCREATION
:
98 return "ScaledFontCreation";
99 case SCALEDFONTDESTRUCTION
:
100 return "ScaledFontDestruction";
102 return "MaskSurface";
103 case FILTERNODESETATTRIBUTE
:
104 return "SetAttribute";
105 case FILTERNODESETINPUT
:
107 case CREATESIMILARDRAWTARGET
:
108 return "CreateSimilarDrawTarget";
112 return "FontDescriptor";
117 case UNSCALEDFONTCREATION
:
118 return "UnscaledFontCreation";
119 case UNSCALEDFONTDESTRUCTION
:
120 return "UnscaledFontDestruction";
121 case EXTERNALSURFACECREATION
:
122 return "ExternalSourceSurfaceCreation";
126 return "Destination";
133 void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont
* aUnscaledFont
,
135 RecordedFontData
fontData(aUnscaledFont
);
136 RecordedFontDetails fontDetails
;
137 if (fontData
.GetFontDetails(fontDetails
)) {
138 // Try to serialise the whole font, just in case this is a web font that
139 // is not present on the system.
140 WriteElement(aOutput
, fontData
.mType
);
141 fontData
.RecordToStream(aOutput
);
143 auto r
= RecordedUnscaledFontCreation(aUnscaledFont
, fontDetails
);
144 WriteElement(aOutput
, r
.mType
);
145 r
.RecordToStream(aOutput
);
147 // If that fails, record just the font description and try to load it from
148 // the system on the other side.
149 RecordedFontDescriptor
fontDesc(aUnscaledFont
);
150 if (fontDesc
.IsValid()) {
151 WriteElement(aOutput
, fontDesc
.RecordedEvent::mType
);
152 fontDesc
.RecordToStream(aOutput
);
155 << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
160 void RecordedEvent::RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
161 std::ostream
* aOutput
) {
162 RecordUnscaledFontImpl(aUnscaledFont
, *aOutput
);
165 void RecordedEvent::RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
166 MemStream
& aOutput
) {
167 RecordUnscaledFontImpl(aUnscaledFont
, aOutput
);
170 already_AddRefed
<DrawTarget
> Translator::CreateDrawTarget(
171 ReferencePtr aRefPtr
, const IntSize
& aSize
, SurfaceFormat aFormat
) {
172 RefPtr
<DrawTarget
> newDT
=
173 GetReferenceDrawTarget()->CreateSimilarDrawTarget(aSize
, aFormat
);
174 AddDrawTarget(aRefPtr
, newDT
);
175 return newDT
.forget();
178 void Translator::DrawDependentSurface(uint64_t aKey
, const Rect
& aRect
) {
179 if (!mDependentSurfaces
|| !mCurrentDT
) {
183 RefPtr
<RecordedDependentSurface
> recordedSurface
=
184 mDependentSurfaces
->Get(aKey
);
185 if (!recordedSurface
) {
189 // Construct a new translator, so we can recurse into translating this
190 // sub-recording into the same DT. Set an initial transform for the
191 // translator, so that all commands get moved into the rect we want to draw.
193 // Because the recording may have filtered out SetTransform calls with the
194 // same value, we need to call SetTransform here to ensure it gets called at
195 // least once with the translated matrix.
196 const Matrix oldTransform
= mCurrentDT
->GetTransform();
198 Matrix dependentTransform
= oldTransform
;
199 dependentTransform
.PreTranslate(aRect
.TopLeft());
201 mCurrentDT
->PushClipRect(aRect
);
202 mCurrentDT
->SetTransform(dependentTransform
);
205 InlineTranslator
translator(mCurrentDT
, nullptr);
206 translator
.SetReferenceDrawTargetTransform(dependentTransform
);
207 translator
.SetDependentSurfaces(mDependentSurfaces
);
208 translator
.TranslateRecording((char*)recordedSurface
->mRecording
.mData
,
209 recordedSurface
->mRecording
.mLen
);
212 mCurrentDT
->SetTransform(oldTransform
);
213 mCurrentDT
->PopClip();
217 } // namespace mozilla