зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1279654 - Create a PrintTargetRecording subclass of PrintTarget. r=mstange
This commit is contained in:
Родитель
4b40fd1bc1
Коммит
f048425035
|
@ -52,6 +52,10 @@ PrintTarget::MakeDrawTarget(const IntSize& aSize,
|
|||
MOZ_ASSERT(mCairoSurface,
|
||||
"We shouldn't have been constructed without a cairo surface");
|
||||
|
||||
MOZ_ASSERT(!aRecorder,
|
||||
"aRecorder should only be passed to an instance of "
|
||||
"PrintTargetRecording");
|
||||
|
||||
if (cairo_surface_status(mCairoSurface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -65,36 +69,6 @@ PrintTarget::MakeDrawTarget(const IntSize& aSize,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (aRecorder) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTarget::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRecorder);
|
||||
MOZ_ASSERT(aDrawTarget);
|
||||
|
||||
RefPtr<DrawTarget> dt;
|
||||
|
||||
if (aRecorder) {
|
||||
// It doesn't really matter what we pass as the DrawTarget here.
|
||||
dt = gfx::Factory::CreateRecordingDrawTarget(aRecorder, aDrawTarget);
|
||||
}
|
||||
|
||||
if (!dt || !dt->IsValid()) {
|
||||
gfxCriticalNote
|
||||
<< "Failed to create a recording DrawTarget for PrintTarget";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -99,8 +99,6 @@ public:
|
|||
* We'd need to check that our consumers always pass the same aRecorder for
|
||||
* our entire lifetime.
|
||||
*
|
||||
* XXX Once PrintTargetThebes is removed this can become non-virtual.
|
||||
*
|
||||
* XXX In the long run, this class and its sub-classes should be converted to
|
||||
* use STL classes and mozilla::RefCounted<> so the can be moved to Moz2D.
|
||||
*
|
||||
|
@ -119,10 +117,6 @@ protected:
|
|||
// Protected because we're refcounted
|
||||
virtual ~PrintTarget();
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
|
||||
cairo_surface_t* mCairoSurface;
|
||||
IntSize mSize;
|
||||
bool mIsFinished;
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "PrintTargetRecording.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
PrintTargetRecording::PrintTargetRecording(cairo_surface_t* aCairoSurface,
|
||||
const IntSize& aSize)
|
||||
: PrintTarget(aCairoSurface, aSize)
|
||||
{
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PrintTargetRecording>
|
||||
PrintTargetRecording::CreateOrNull(const IntSize& aSize)
|
||||
{
|
||||
if (!Factory::CheckSurfaceSize(aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Perhaps surprisingly, this surface is never actually drawn to. This class
|
||||
// creates a DrawTargetRecording using CreateRecordingDrawTarget, and that
|
||||
// needs another DrawTarget to be passed to it. You might expect the type of
|
||||
// the DrawTarget that is passed to matter because it would seem logical to
|
||||
// encoded its type in the recording, and on replaying the recording a
|
||||
// DrawTarget of the same type would be created. However, the passed
|
||||
// DrawTarget's type doesn't seem to be encoded any more accurately than just
|
||||
// "BackendType::CAIRO". Even if it were, the code that replays the
|
||||
// recording is PrintTranslator::TranslateRecording which (indirectly) calls
|
||||
// MakePrintTarget on the type of nsIDeviceContextSpecProxy that is created
|
||||
// for the platform that we're running on, and the type of DrawTarget that
|
||||
// that returns is hardcoded.
|
||||
//
|
||||
// The only reason that we use cairo_recording_surface_create here is:
|
||||
//
|
||||
// * It's pretty much the only cairo_*_surface_create methods that's both
|
||||
// available on all platforms and doesn't require allocating a
|
||||
// potentially large surface.
|
||||
//
|
||||
// * Since we need a DrawTarget to pass to CreateRecordingDrawTarget we
|
||||
// might as well leverage our base class's machinery to create a
|
||||
// DrawTarget (it's as good a way as any other that will work), and to do
|
||||
// that we need a cairo_surface_t.
|
||||
//
|
||||
// So the fact that this is a "recording" PrintTarget and the function that
|
||||
// we call here is cairo_recording_surface_create is simply a coincidence. We
|
||||
// could use any cairo_*_surface_create method and this class would still
|
||||
// work.
|
||||
//
|
||||
cairo_surface_t* surface =
|
||||
cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, nullptr);
|
||||
|
||||
if (cairo_surface_status(surface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The new object takes ownership of our surface reference.
|
||||
RefPtr<PrintTargetRecording> target =
|
||||
new PrintTargetRecording(surface, aSize);
|
||||
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTargetRecording::MakeDrawTarget(const IntSize& aSize,
|
||||
DrawEventRecorder* aRecorder)
|
||||
{
|
||||
MOZ_ASSERT(aRecorder, "A DrawEventRecorder is required");
|
||||
|
||||
if (!aRecorder) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt = PrintTarget::MakeDrawTarget(aSize, nullptr);
|
||||
if (dt) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTargetRecording::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRecorder);
|
||||
MOZ_ASSERT(aDrawTarget);
|
||||
|
||||
RefPtr<DrawTarget> dt;
|
||||
|
||||
if (aRecorder) {
|
||||
// It doesn't really matter what we pass as the DrawTarget here.
|
||||
dt = gfx::Factory::CreateRecordingDrawTarget(aRecorder, aDrawTarget);
|
||||
}
|
||||
|
||||
if (!dt || !dt->IsValid()) {
|
||||
gfxCriticalNote
|
||||
<< "Failed to create a recording DrawTarget for PrintTarget";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_PRINTTARGETRECORDING_H
|
||||
#define MOZILLA_GFX_PRINTTARGETRECORDING_H
|
||||
|
||||
#include "PrintTarget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* Recording printing target.
|
||||
*
|
||||
* This exists for use on e10s's content process in order to record print
|
||||
* output, send it over to the parent process, and replay it on a DrawTarget
|
||||
* there for printing.
|
||||
*/
|
||||
class PrintTargetRecording final : public PrintTarget
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<PrintTargetRecording>
|
||||
CreateOrNull(const IntSize& aSize);
|
||||
|
||||
virtual already_AddRefed<DrawTarget>
|
||||
MakeDrawTarget(const IntSize& aSize,
|
||||
DrawEventRecorder* aRecorder = nullptr) override;
|
||||
|
||||
private:
|
||||
PrintTargetRecording(cairo_surface_t* aCairoSurface,
|
||||
const IntSize& aSize);
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_PRINTTARGETRECORDING_H */
|
|
@ -36,19 +36,16 @@ already_AddRefed<DrawTarget>
|
|||
PrintTargetThebes::MakeDrawTarget(const IntSize& aSize,
|
||||
DrawEventRecorder* aRecorder)
|
||||
{
|
||||
MOZ_ASSERT(!aRecorder,
|
||||
"aRecorder should only be passed to an instance of "
|
||||
"PrintTargetRecording");
|
||||
|
||||
RefPtr<gfx::DrawTarget> dt =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mGfxSurface, aSize);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aRecorder) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@ namespace gfx {
|
|||
* This class should go away once all the logic from the gfxASurface subclasses
|
||||
* has been moved to new PrintTarget subclasses and we no longer need to
|
||||
* wrap a gfxASurface.
|
||||
*
|
||||
* When removing this class, be sure to make PrintTarget::MakeDrawTarget
|
||||
* non-virtual!
|
||||
*/
|
||||
class PrintTargetThebes final : public PrintTarget {
|
||||
public:
|
||||
|
|
|
@ -52,6 +52,7 @@ EXPORTS += [
|
|||
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'PrintTarget.h',
|
||||
'PrintTargetRecording.h',
|
||||
'PrintTargetThebes.h',
|
||||
]
|
||||
|
||||
|
@ -217,6 +218,7 @@ SOURCES += [
|
|||
'gfxPlatform.cpp',
|
||||
'gfxPrefs.cpp',
|
||||
'PrintTarget.cpp',
|
||||
'PrintTargetRecording.cpp',
|
||||
'PrintTargetThebes.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
|
||||
#include "nsDeviceContextSpecProxy.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/gfx/DrawEventRecorder.h"
|
||||
#include "mozilla/gfx/PrintTargetThebes.h"
|
||||
#include "mozilla/gfx/PrintTargetRecording.h"
|
||||
#include "mozilla/layout/RemotePrintJobChild.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
@ -80,25 +79,7 @@ nsDeviceContextSpecProxy::MakePrintTarget()
|
|||
width /= TWIPS_PER_POINT_FLOAT;
|
||||
height /= TWIPS_PER_POINT_FLOAT;
|
||||
|
||||
RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(mozilla::gfx::IntSize(width, height),
|
||||
mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The type of PrintTarget that we return here doesn't really matter since
|
||||
// our implementation of GetDrawEventRecorder returns an object, which means
|
||||
// the DrawTarget returned by the PrintTarget will be a DrawTargetRecording.
|
||||
// The recording will be serialized and sent over to the parent process where
|
||||
// PrintTranslator::TranslateRecording will call MakePrintTarget (indirectly
|
||||
// via PrintTranslator::CreateDrawTarget) on whatever type of
|
||||
// nsIDeviceContextSpecProxy is created for the platform that we are running
|
||||
// on. It is that DrawTarget that the recording will be replayed on to
|
||||
// print.
|
||||
RefPtr<PrintTarget> target = PrintTargetThebes::CreateOrNull(surface);
|
||||
|
||||
return target.forget();
|
||||
return PrintTargetRecording::CreateOrNull(IntSize(width, height));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче