Loading gfx/thebes/PrintTargetSkPDF.cpp 0 → 100644 +159 −0 Original line number Diff line number Diff line /* -*- 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 "PrintTargetSkPDF.h" #include "mozilla/gfx/2D.h" #include "nsString.h" #include <vector> namespace mozilla { namespace gfx { PrintTargetSkPDF::PrintTargetSkPDF(const IntSize& aSize, UniquePtr<SkWStream> aStream) : PrintTarget(/* not using cairo_surface_t */ nullptr, aSize) , mOStream(Move(aStream)) , mPageCanvas(nullptr) { } PrintTargetSkPDF::~PrintTargetSkPDF() { Finish(); // ensure stream is flushed // Make sure mPDFDoc and mRefPDFDoc are destroyed before our member streams // (which they wrap) are destroyed: mPDFDoc = nullptr; mRefPDFDoc = nullptr; } /* static */ already_AddRefed<PrintTargetSkPDF> PrintTargetSkPDF::CreateOrNull(UniquePtr<SkWStream> aStream, const IntSize& aSizeInPoints) { return do_AddRef(new PrintTargetSkPDF(aSizeInPoints, Move(aStream))); } nsresult PrintTargetSkPDF::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName, int32_t aStartPage, int32_t aEndPage) { // We need to create the SkPDFDocument here rather than in CreateOrNull // because it's only now that we are given aTitle which we want for the // PDF metadata. SkDocument::PDFMetadata metadata; metadata.fTitle = NS_ConvertUTF16toUTF8(aTitle).get(); metadata.fCreator = "Firefox"; SkTime::DateTime now; SkTime::GetDateTime(&now); metadata.fCreation.fEnabled = true; metadata.fCreation.fDateTime = now; metadata.fModified.fEnabled = true; metadata.fModified.fDateTime = now; // SkDocument stores a non-owning raw pointer to aStream mPDFDoc = SkDocument::MakePDF(mOStream.get(), SK_ScalarDefaultRasterDPI, metadata, /*jpegEncoder*/ nullptr, true); return mPDFDoc ? NS_OK : NS_ERROR_FAILURE; } nsresult PrintTargetSkPDF::BeginPage() { mPageCanvas = sk_ref_sp(mPDFDoc->beginPage(mSize.width, mSize.height)); return !mPageCanvas ? NS_ERROR_FAILURE : PrintTarget::BeginPage(); } nsresult PrintTargetSkPDF::EndPage() { mPageCanvas = nullptr; mPageDT = nullptr; return PrintTarget::EndPage(); } nsresult PrintTargetSkPDF::EndPrinting() { mPDFDoc->close(); if (mRefPDFDoc) { mRefPDFDoc->close(); } mPageCanvas = nullptr; mPageDT = nullptr; return NS_OK; } void PrintTargetSkPDF::Finish() { if (mIsFinished) { return; } mOStream->flush(); PrintTarget::Finish(); } already_AddRefed<DrawTarget> PrintTargetSkPDF::MakeDrawTarget(const IntSize& aSize, DrawEventRecorder* aRecorder) { if (aRecorder) { return PrintTarget::MakeDrawTarget(aSize, aRecorder); } //MOZ_ASSERT(aSize == mSize, "Should mPageCanvas size match?"); if (!mPageCanvas) { return nullptr; } mPageDT = Factory::CreateDrawTargetWithSkCanvas(mPageCanvas.get()); if (!mPageDT) { mPageCanvas = nullptr; return nullptr; } return do_AddRef(mPageDT); } already_AddRefed<DrawTarget> PrintTargetSkPDF::GetReferenceDrawTarget(DrawEventRecorder* aRecorder) { if (!mRefDT) { SkDocument::PDFMetadata metadata; // SkDocument stores a non-owning raw pointer to aStream mRefPDFDoc = SkDocument::MakePDF(&mRefOStream, SK_ScalarDefaultRasterDPI, metadata, nullptr, true); if (!mRefPDFDoc) { return nullptr; } mRefCanvas = sk_ref_sp(mRefPDFDoc->beginPage(mSize.width, mSize.height)); if (!mRefCanvas) { return nullptr; } RefPtr<DrawTarget> dt = Factory::CreateDrawTargetWithSkCanvas(mRefCanvas.get()); if (!dt) { return nullptr; } if (aRecorder) { dt = CreateRecordingDrawTarget(aRecorder, dt); if (!dt || !dt->IsValid()) { return nullptr; } } mRefDT = dt.forget(); } return do_AddRef(mRefDT); } } // namespace gfx } // namespace mozilla gfx/thebes/PrintTargetSkPDF.h 0 → 100644 +75 −0 Original line number Diff line number Diff line /* -*- 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_PRINTTARGETSKPDF_H #define MOZILLA_GFX_PRINTTARGETSKPDF_H #include "mozilla/UniquePtr.h" #include "nsCOMPtr.h" #include "PrintTarget.h" #include "SkCanvas.h" #include "SkDocument.h" #include "SkStream.h" namespace mozilla { namespace gfx { /** * Skia PDF printing target. */ class PrintTargetSkPDF final : public PrintTarget { public: // The returned PrintTargetSkPDF keeps a raw pointer to the passed SkWStream // but does not own it. Callers are responsible for ensuring that passed // stream outlives the returned PrintTarget. static already_AddRefed<PrintTargetSkPDF> CreateOrNull(UniquePtr<SkWStream> aStream, const IntSize& aSizeInPoints); virtual nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName, int32_t aStartPage, int32_t aEndPage) override; virtual nsresult EndPrinting() override; virtual void Finish() override; virtual nsresult BeginPage() override; virtual nsresult EndPage() override; virtual already_AddRefed<DrawTarget> MakeDrawTarget(const IntSize& aSize, DrawEventRecorder* aRecorder = nullptr) final; virtual already_AddRefed<DrawTarget> GetReferenceDrawTarget(DrawEventRecorder* aRecorder) override final; private: PrintTargetSkPDF(const IntSize& aSize, UniquePtr<SkWStream> aStream); virtual ~PrintTargetSkPDF(); // Do not hand out references to this object. It holds a non-owning // reference to mOStreame, so must not outlive mOStream. sk_sp<SkDocument> mPDFDoc; // The stream that the SkDocument outputs to. UniquePtr<SkWStream> mOStream; // The current page's SkCanvas and its wrapping DrawTarget: sk_sp<SkCanvas> mPageCanvas; RefPtr<DrawTarget> mPageDT; // Members needed to provide a reference DrawTarget: sk_sp<SkDocument> mRefPDFDoc; sk_sp<SkCanvas> mRefCanvas; SkDynamicMemoryWStream mRefOStream; RefPtr<DrawTarget> mRefDT; }; } // namespace gfx } // namespace mozilla #endif /* MOZILLA_GFX_PRINTTARGETSKPDF_H */ gfx/thebes/moz.build +8 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,14 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': 'DeviceManagerDx.cpp', ] if CONFIG['MOZ_ENABLE_SKIA_PDF']: EXPORTS.mozilla.gfx += [ 'PrintTargetSkPDF.h', ] SOURCES += [ 'PrintTargetSkPDF.cpp', ] # We prefer to use ICU for normalization functions, but currently it is only # available if we're building with the Intl API enabled: if CONFIG['ENABLE_INTL_API']: Loading Loading
gfx/thebes/PrintTargetSkPDF.cpp 0 → 100644 +159 −0 Original line number Diff line number Diff line /* -*- 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 "PrintTargetSkPDF.h" #include "mozilla/gfx/2D.h" #include "nsString.h" #include <vector> namespace mozilla { namespace gfx { PrintTargetSkPDF::PrintTargetSkPDF(const IntSize& aSize, UniquePtr<SkWStream> aStream) : PrintTarget(/* not using cairo_surface_t */ nullptr, aSize) , mOStream(Move(aStream)) , mPageCanvas(nullptr) { } PrintTargetSkPDF::~PrintTargetSkPDF() { Finish(); // ensure stream is flushed // Make sure mPDFDoc and mRefPDFDoc are destroyed before our member streams // (which they wrap) are destroyed: mPDFDoc = nullptr; mRefPDFDoc = nullptr; } /* static */ already_AddRefed<PrintTargetSkPDF> PrintTargetSkPDF::CreateOrNull(UniquePtr<SkWStream> aStream, const IntSize& aSizeInPoints) { return do_AddRef(new PrintTargetSkPDF(aSizeInPoints, Move(aStream))); } nsresult PrintTargetSkPDF::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName, int32_t aStartPage, int32_t aEndPage) { // We need to create the SkPDFDocument here rather than in CreateOrNull // because it's only now that we are given aTitle which we want for the // PDF metadata. SkDocument::PDFMetadata metadata; metadata.fTitle = NS_ConvertUTF16toUTF8(aTitle).get(); metadata.fCreator = "Firefox"; SkTime::DateTime now; SkTime::GetDateTime(&now); metadata.fCreation.fEnabled = true; metadata.fCreation.fDateTime = now; metadata.fModified.fEnabled = true; metadata.fModified.fDateTime = now; // SkDocument stores a non-owning raw pointer to aStream mPDFDoc = SkDocument::MakePDF(mOStream.get(), SK_ScalarDefaultRasterDPI, metadata, /*jpegEncoder*/ nullptr, true); return mPDFDoc ? NS_OK : NS_ERROR_FAILURE; } nsresult PrintTargetSkPDF::BeginPage() { mPageCanvas = sk_ref_sp(mPDFDoc->beginPage(mSize.width, mSize.height)); return !mPageCanvas ? NS_ERROR_FAILURE : PrintTarget::BeginPage(); } nsresult PrintTargetSkPDF::EndPage() { mPageCanvas = nullptr; mPageDT = nullptr; return PrintTarget::EndPage(); } nsresult PrintTargetSkPDF::EndPrinting() { mPDFDoc->close(); if (mRefPDFDoc) { mRefPDFDoc->close(); } mPageCanvas = nullptr; mPageDT = nullptr; return NS_OK; } void PrintTargetSkPDF::Finish() { if (mIsFinished) { return; } mOStream->flush(); PrintTarget::Finish(); } already_AddRefed<DrawTarget> PrintTargetSkPDF::MakeDrawTarget(const IntSize& aSize, DrawEventRecorder* aRecorder) { if (aRecorder) { return PrintTarget::MakeDrawTarget(aSize, aRecorder); } //MOZ_ASSERT(aSize == mSize, "Should mPageCanvas size match?"); if (!mPageCanvas) { return nullptr; } mPageDT = Factory::CreateDrawTargetWithSkCanvas(mPageCanvas.get()); if (!mPageDT) { mPageCanvas = nullptr; return nullptr; } return do_AddRef(mPageDT); } already_AddRefed<DrawTarget> PrintTargetSkPDF::GetReferenceDrawTarget(DrawEventRecorder* aRecorder) { if (!mRefDT) { SkDocument::PDFMetadata metadata; // SkDocument stores a non-owning raw pointer to aStream mRefPDFDoc = SkDocument::MakePDF(&mRefOStream, SK_ScalarDefaultRasterDPI, metadata, nullptr, true); if (!mRefPDFDoc) { return nullptr; } mRefCanvas = sk_ref_sp(mRefPDFDoc->beginPage(mSize.width, mSize.height)); if (!mRefCanvas) { return nullptr; } RefPtr<DrawTarget> dt = Factory::CreateDrawTargetWithSkCanvas(mRefCanvas.get()); if (!dt) { return nullptr; } if (aRecorder) { dt = CreateRecordingDrawTarget(aRecorder, dt); if (!dt || !dt->IsValid()) { return nullptr; } } mRefDT = dt.forget(); } return do_AddRef(mRefDT); } } // namespace gfx } // namespace mozilla
gfx/thebes/PrintTargetSkPDF.h 0 → 100644 +75 −0 Original line number Diff line number Diff line /* -*- 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_PRINTTARGETSKPDF_H #define MOZILLA_GFX_PRINTTARGETSKPDF_H #include "mozilla/UniquePtr.h" #include "nsCOMPtr.h" #include "PrintTarget.h" #include "SkCanvas.h" #include "SkDocument.h" #include "SkStream.h" namespace mozilla { namespace gfx { /** * Skia PDF printing target. */ class PrintTargetSkPDF final : public PrintTarget { public: // The returned PrintTargetSkPDF keeps a raw pointer to the passed SkWStream // but does not own it. Callers are responsible for ensuring that passed // stream outlives the returned PrintTarget. static already_AddRefed<PrintTargetSkPDF> CreateOrNull(UniquePtr<SkWStream> aStream, const IntSize& aSizeInPoints); virtual nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName, int32_t aStartPage, int32_t aEndPage) override; virtual nsresult EndPrinting() override; virtual void Finish() override; virtual nsresult BeginPage() override; virtual nsresult EndPage() override; virtual already_AddRefed<DrawTarget> MakeDrawTarget(const IntSize& aSize, DrawEventRecorder* aRecorder = nullptr) final; virtual already_AddRefed<DrawTarget> GetReferenceDrawTarget(DrawEventRecorder* aRecorder) override final; private: PrintTargetSkPDF(const IntSize& aSize, UniquePtr<SkWStream> aStream); virtual ~PrintTargetSkPDF(); // Do not hand out references to this object. It holds a non-owning // reference to mOStreame, so must not outlive mOStream. sk_sp<SkDocument> mPDFDoc; // The stream that the SkDocument outputs to. UniquePtr<SkWStream> mOStream; // The current page's SkCanvas and its wrapping DrawTarget: sk_sp<SkCanvas> mPageCanvas; RefPtr<DrawTarget> mPageDT; // Members needed to provide a reference DrawTarget: sk_sp<SkDocument> mRefPDFDoc; sk_sp<SkCanvas> mRefCanvas; SkDynamicMemoryWStream mRefOStream; RefPtr<DrawTarget> mRefDT; }; } // namespace gfx } // namespace mozilla #endif /* MOZILLA_GFX_PRINTTARGETSKPDF_H */
gfx/thebes/moz.build +8 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,14 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': 'DeviceManagerDx.cpp', ] if CONFIG['MOZ_ENABLE_SKIA_PDF']: EXPORTS.mozilla.gfx += [ 'PrintTargetSkPDF.h', ] SOURCES += [ 'PrintTargetSkPDF.cpp', ] # We prefer to use ICU for normalization functions, but currently it is only # available if we're building with the Intl API enabled: if CONFIG['ENABLE_INTL_API']: Loading