Bug 1156742 Part 13: Create a Moz2D PrintTranslator. r=bas

A better solution to the ScaledFonts issue comes in Part 24.
This commit is contained in:
Bob Owen 2016-01-05 10:08:57 +00:00
parent e707786501
commit 20e589aec1
6 changed files with 266 additions and 2 deletions

View File

@ -12,8 +12,6 @@ namespace gfx {
using namespace std;
const uint32_t kMagicInt = 0xc001feed;
DrawEventRecorderPrivate::DrawEventRecorderPrivate(std::ostream *aStream)
: mOutputStream(aStream)
{

View File

@ -18,6 +18,8 @@ namespace gfx {
struct PathOp;
class PathRecording;
const uint32_t kMagicInt = 0xc001feed;
// A change in major revision means a change in event binary format, causing
// loss of backwards compatibility. Old streams will not work in a player
// using a newer major revision. And new streams will not work in a player

View File

@ -40,6 +40,7 @@ EXPORTS.mozilla.gfx += [
'Point.h',
'Quaternion.h',
'RecordedEvent.h',
'RecordingTypes.h',
'Rect.h',
'Scale.h',
'ScaleFactor.h',

View File

@ -0,0 +1,102 @@
/* -*- 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 "PrintTranslator.h"
#include "gfxContext.h"
#include "nsDeviceContext.h"
#include "mozilla/gfx/RecordedEvent.h"
#include "mozilla/gfx/RecordingTypes.h"
#include "mozilla/UniquePtr.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace layout {
PrintTranslator::PrintTranslator(nsDeviceContext* aDeviceContext)
: mDeviceContext(aDeviceContext)
{
RefPtr<gfxContext> context = mDeviceContext->CreateRenderingContext();
mBaseDT = context->GetDrawTarget();
}
bool
PrintTranslator::TranslateRecording(std::istream& aRecording)
{
uint32_t magicInt;
ReadElement(aRecording, magicInt);
if (magicInt != mozilla::gfx::kMagicInt) {
return false;
}
uint16_t majorRevision;
ReadElement(aRecording, majorRevision);
if (majorRevision != kMajorRevision) {
return false;
}
uint16_t minorRevision;
ReadElement(aRecording, minorRevision);
if (minorRevision > kMinorRevision) {
return false;
}
int32_t eventType;
ReadElement(aRecording, eventType);
while (aRecording.good()) {
UniquePtr<RecordedEvent> recordedEvent(
RecordedEvent::LoadEventFromStream(aRecording,
static_cast<RecordedEvent::EventType>(eventType)));
// Make sure that the whole event was read from the stream successfully.
if (!aRecording.good()) {
return false;
}
recordedEvent->PlayEvent(this);
ReadElement(aRecording, eventType);
}
return true;
}
already_AddRefed<DrawTarget>
PrintTranslator::CreateDrawTarget(ReferencePtr aRefPtr,
const gfx::IntSize &aSize,
gfx::SurfaceFormat aFormat)
{
RefPtr<gfxContext> context = mDeviceContext->CreateRenderingContext();
if (!context) {
NS_WARNING("Failed to create rendering context for print.");
return nullptr;
}
RefPtr<DrawTarget> drawTarget = context->GetDrawTarget();
AddDrawTarget(aRefPtr, drawTarget);
return drawTarget.forget();
}
FontType
PrintTranslator::GetDesiredFontType()
{
switch (mBaseDT->GetBackendType()) {
case BackendType::DIRECT2D:
return FontType::DWRITE;
case BackendType::CAIRO:
return FontType::CAIRO;
case BackendType::SKIA:
return FontType::SKIA;
case BackendType::COREGRAPHICS:
case BackendType::COREGRAPHICS_ACCELERATED:
return FontType::COREGRAPHICS;
default:
return FontType::CAIRO;
}
}
} // namespace layout
} // namespace mozilla

View File

@ -0,0 +1,160 @@
/* -*- 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/. */
#ifndef mozilla_layout_PrintTranslator_h
#define mozilla_layout_PrintTranslator_h
#include <istream>
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Filters.h"
#include "mozilla/gfx/RecordedEvent.h"
#include "mozilla/unused.h"
#include "nsRefPtrHashtable.h"
class nsDeviceContext;
namespace mozilla {
namespace layout {
using gfx::Translator;
using gfx::ReferencePtr;
using gfx::DrawTarget;
using gfx::Path;
using gfx::SourceSurface;
using gfx::FilterNode;
using gfx::GradientStops;
using gfx::ScaledFont;
class PrintTranslator final : public Translator
{
public:
explicit PrintTranslator(nsDeviceContext* aDeviceContext);
bool TranslateRecording(std::istream& aRecording);
DrawTarget* LookupDrawTarget(ReferencePtr aRefPtr) final
{
return mDrawTargets.GetWeak(aRefPtr);
}
Path* LookupPath(ReferencePtr aRefPtr) final
{
return mPaths.GetWeak(aRefPtr);
}
SourceSurface* LookupSourceSurface(ReferencePtr aRefPtr) final
{
return mSourceSurfaces.GetWeak(aRefPtr);
}
FilterNode* LookupFilterNode(ReferencePtr aRefPtr) final
{
return mFilterNodes.GetWeak(aRefPtr);
}
GradientStops* LookupGradientStops(ReferencePtr aRefPtr) final
{
return mGradientStops.GetWeak(aRefPtr);
}
ScaledFont* LookupScaledFont(ReferencePtr aRefPtr) final
{
return mScaledFonts.GetWeak(aRefPtr);
}
void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) final
{
mDrawTargets.Put(aRefPtr, aDT);
}
void AddPath(ReferencePtr aRefPtr, Path *aPath) final
{
mPaths.Put(aRefPtr, aPath);
}
void AddSourceSurface(ReferencePtr aRefPtr, SourceSurface *aSurface) final
{
mSourceSurfaces.Put(aRefPtr, aSurface);
}
void AddFilterNode(ReferencePtr aRefPtr, FilterNode *aFilter) final
{
mFilterNodes.Put(aRefPtr, aFilter);
}
void AddGradientStops(ReferencePtr aRefPtr, GradientStops *aStops) final
{
mGradientStops.Put(aRefPtr, aStops);
}
void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) final
{
mScaledFonts.Put(aRefPtr, aScaledFont);
Unused << mSavedScaledFonts.PutEntry(aScaledFont);
}
void RemoveDrawTarget(ReferencePtr aRefPtr) final
{
mDrawTargets.Remove(aRefPtr);
}
void RemovePath(ReferencePtr aRefPtr) final
{
mPaths.Remove(aRefPtr);
}
void RemoveSourceSurface(ReferencePtr aRefPtr) final
{
mSourceSurfaces.Remove(aRefPtr);
}
void RemoveFilterNode(ReferencePtr aRefPtr) final
{
mFilterNodes.Remove(aRefPtr);
}
void RemoveGradientStops(ReferencePtr aRefPtr) final
{
mGradientStops.Remove(aRefPtr);
}
void RemoveScaledFont(ReferencePtr aRefPtr) final
{
mScaledFonts.Remove(aRefPtr);
}
void ClearSavedFonts() { mSavedScaledFonts.Clear(); }
already_AddRefed<DrawTarget> CreateDrawTarget(ReferencePtr aRefPtr,
const gfx::IntSize &aSize,
gfx::SurfaceFormat aFormat) final;
mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; }
mozilla::gfx::FontType GetDesiredFontType() final;
private:
RefPtr<nsDeviceContext> mDeviceContext;
RefPtr<DrawTarget> mBaseDT;
nsRefPtrHashtable<nsPtrHashKey<void>, DrawTarget> mDrawTargets;
nsRefPtrHashtable<nsPtrHashKey<void>, Path> mPaths;
nsRefPtrHashtable<nsPtrHashKey<void>, SourceSurface> mSourceSurfaces;
nsRefPtrHashtable<nsPtrHashKey<void>, FilterNode> mFilterNodes;
nsRefPtrHashtable<nsPtrHashKey<void>, GradientStops> mGradientStops;
nsRefPtrHashtable<nsPtrHashKey<void>, ScaledFont> mScaledFonts;
// We keep an extra reference to each scaled font, because they currently
// always get removed immediately. These can be cleared using ClearSavedFonts,
// when we know that things have been flushed to the print device.
nsTHashtable<nsRefPtrHashKey<ScaledFont>> mSavedScaledFonts;
};
} // namespace layout
} // namespace mozilla
#endif // mozilla_layout_PrintTranslator_h

View File

@ -25,6 +25,7 @@ UNIFIED_SOURCES += [
'nsPrintEngine.cpp',
'nsPrintObject.cpp',
'nsPrintPreviewListener.cpp',
'PrintTranslator.cpp',
]
IPDL_SOURCES = [