1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "RecordedEventImpl.h"
#include "PathRecording.h"
#include "RecordingTypes.h"
#include "Tools.h"
#include "Filters.h"
#include "Logging.h"
#include "ScaledFontBase.h"
#include "SFNTData.h"
#include "InlineTranslator.h"
namespace mozilla {
namespace gfx {
/* static */
bool RecordedEvent::DoWithEventFromStream(
EventStream& aStream, EventType aType,
const std::function<bool(RecordedEvent*)>& aAction) {
return DoWithEvent(aStream, aType, aAction);
}
/* static */
bool RecordedEvent::DoWithEventFromReader(
MemReader& aReader, EventType aType,
const std::function<bool(RecordedEvent*)>& aAction) {
return DoWithEvent(aReader, aType, aAction);
}
std::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 SETPERMITSUBPIXELAA:
return "SetPermitSubpixelAA";
case SETTRANSFORM:
return "SetTransform";
case PUSHCLIP:
return "PushClip";
case PUSHCLIPRECT:
return "PushClipRect";
case POPCLIP:
return "PopClip";
case REMOVEALLCLIPS:
return "RemoveAllClips";
case FILL:
return "Fill";
case FILLGLYPHS:
return "FillGlyphs";
case STROKEGLYPHS:
return "StrokeGlyphs";
case MASK:
return "Mask";
case STROKE:
return "Stroke";
case DRAWSURFACE:
return "DrawSurface";
case DRAWSURFACEDESCRIPTOR:
return "DrawSurfaceDescriptor";
case DRAWDEPENDENTSURFACE:
return "DrawDependentSurface";
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";
case EXTERNALSURFACECREATION:
return "ExternalSourceSurfaceCreation";
case LINK:
return "Link";
case DESTINATION:
return "Destination";
default:
return "Unknown";
}
}
template <class S>
void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont* aUnscaledFont,
S& aOutput) {
RecordedFontData fontData(aUnscaledFont);
RecordedFontDetails fontDetails;
if (fontData.GetFontDetails(fontDetails)) {
// Try to serialise the whole font, just in case this is a web font that
// is not present on the system.
WriteElement(aOutput, fontData.mType);
fontData.RecordToStream(aOutput);
auto r = RecordedUnscaledFontCreation(aUnscaledFont, fontDetails);
WriteElement(aOutput, r.mType);
r.RecordToStream(aOutput);
} else {
// If that fails, record just the font description and try to load it from
// the system on the other side.
RecordedFontDescriptor fontDesc(aUnscaledFont);
if (fontDesc.IsValid()) {
WriteElement(aOutput, fontDesc.RecordedEvent::mType);
fontDesc.RecordToStream(aOutput);
} else {
gfxWarning()
<< "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
}
}
}
void RecordedEvent::RecordUnscaledFont(UnscaledFont* aUnscaledFont,
std::ostream* aOutput) {
RecordUnscaledFontImpl(aUnscaledFont, *aOutput);
}
void RecordedEvent::RecordUnscaledFont(UnscaledFont* aUnscaledFont,
MemStream& aOutput) {
RecordUnscaledFontImpl(aUnscaledFont, aOutput);
}
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();
}
void Translator::DrawDependentSurface(uint64_t aKey, const Rect& aRect) {
if (!mDependentSurfaces || !mCurrentDT) {
return;
}
RefPtr<RecordedDependentSurface> recordedSurface =
mDependentSurfaces->Get(aKey);
if (!recordedSurface) {
return;
}
// Construct a new translator, so we can recurse into translating this
// sub-recording into the same DT. Set an initial transform for the
// translator, so that all commands get moved into the rect we want to draw.
//
// Because the recording may have filtered out SetTransform calls with the
// same value, we need to call SetTransform here to ensure it gets called at
// least once with the translated matrix.
const Matrix oldTransform = mCurrentDT->GetTransform();
Matrix dependentTransform = oldTransform;
dependentTransform.PreTranslate(aRect.TopLeft());
mCurrentDT->PushClipRect(aRect);
mCurrentDT->SetTransform(dependentTransform);
{
InlineTranslator translator(mCurrentDT, nullptr);
translator.SetReferenceDrawTargetTransform(dependentTransform);
translator.SetDependentSurfaces(mDependentSurfaces);
translator.TranslateRecording((char*)recordedSurface->mRecording.mData,
recordedSurface->mRecording.mLen);
}
mCurrentDT->SetTransform(oldTransform);
mCurrentDT->PopClip();
}
} // namespace gfx
} // namespace mozilla
|