1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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 "PrintTargetRecording.h"
9 #include "mozilla/gfx/2D.h"
10 #include "mozilla/gfx/Logging.h"
15 PrintTargetRecording::PrintTargetRecording(cairo_surface_t
* aCairoSurface
,
17 : PrintTarget(aCairoSurface
, aSize
)
21 /* static */ already_AddRefed
<PrintTargetRecording
>
22 PrintTargetRecording::CreateOrNull(const IntSize
& aSize
)
24 if (!Factory::CheckSurfaceSize(aSize
)) {
28 // Perhaps surprisingly, this surface is never actually drawn to. This class
29 // creates a DrawTargetWrapAndRecord using CreateWrapAndRecordDrawTarget, and that
30 // needs another DrawTarget to be passed to it. You might expect the type of
31 // the DrawTarget that is passed to matter because it would seem logical to
32 // encoded its type in the recording, and on replaying the recording a
33 // DrawTarget of the same type would be created. However, the passed
34 // DrawTarget's type doesn't seem to be encoded any more accurately than just
35 // "BackendType::CAIRO". Even if it were, the code that replays the
36 // recording is PrintTranslator::TranslateRecording which (indirectly) calls
37 // MakePrintTarget on the type of nsIDeviceContextSpecProxy that is created
38 // for the platform that we're running on, and the type of DrawTarget that
39 // that returns is hardcoded.
41 // The only reason that we use cairo_recording_surface_create here is:
43 // * It's pretty much the only cairo_*_surface_create methods that's both
44 // available on all platforms and doesn't require allocating a
45 // potentially large surface.
47 // * Since we need a DrawTarget to pass to CreateWrapAndRecordDrawTarget we
48 // might as well leverage our base class's machinery to create a
49 // DrawTarget (it's as good a way as any other that will work), and to do
50 // that we need a cairo_surface_t.
52 // So the fact that this is a "recording" PrintTarget and the function that
53 // we call here is cairo_recording_surface_create is simply a coincidence. We
54 // could use any cairo_*_surface_create method and this class would still
57 cairo_surface_t
* surface
=
58 cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA
, nullptr);
60 if (cairo_surface_status(surface
)) {
64 // The new object takes ownership of our surface reference.
65 RefPtr
<PrintTargetRecording
> target
=
66 new PrintTargetRecording(surface
, aSize
);
68 return target
.forget();
71 already_AddRefed
<DrawTarget
>
72 PrintTargetRecording::MakeDrawTarget(const IntSize
& aSize
,
73 DrawEventRecorder
* aRecorder
)
75 MOZ_ASSERT(aRecorder
, "A DrawEventRecorder is required");
81 RefPtr
<DrawTarget
> dt
= PrintTarget::MakeDrawTarget(aSize
, nullptr);
83 dt
= CreateWrapAndRecordDrawTarget(aRecorder
, dt
);
84 if (!dt
|| !dt
->IsValid()) {
92 already_AddRefed
<DrawTarget
>
93 PrintTargetRecording::CreateWrapAndRecordDrawTarget(DrawEventRecorder
* aRecorder
,
94 DrawTarget
* aDrawTarget
)
96 MOZ_ASSERT(aRecorder
);
97 MOZ_ASSERT(aDrawTarget
);
99 RefPtr
<DrawTarget
> dt
;
102 // It doesn't really matter what we pass as the DrawTarget here.
103 dt
= gfx::Factory::CreateWrapAndRecordDrawTarget(aRecorder
, aDrawTarget
);
106 if (!dt
|| !dt
->IsValid()) {
108 << "Failed to create a recording DrawTarget for PrintTarget";
116 } // namespace mozilla