SkPDF: allocate for single Canvas
Change-Id: I852717b30c687c1f2bba38cfa7ab59780b61c1f5
Reviewed-on: https://skia-review.googlesource.com/153100
Auto-Submit: Hal Canary <halcanary@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp
index 51f2e79..5fcdd88 100644
--- a/src/pdf/SkPDFDocument.cpp
+++ b/src/pdf/SkPDFDocument.cpp
@@ -7,7 +7,6 @@
#include "SkPDFDocument.h"
-#include "SkCanvas.h"
#include "SkMakeUnique.h"
#include "SkPDFCanon.h"
#include "SkPDFDevice.h"
@@ -15,6 +14,8 @@
#include "SkStream.h"
#include "SkTo.h"
+#include <utility>
+
SkPDFObjectSerializer::SkPDFObjectSerializer() : fBaseOffset(0), fNextToBeSerialized(0) {}
SkPDFObjectSerializer::~SkPDFObjectSerializer() {
@@ -173,6 +174,12 @@
return std::move(curNodes[0]);
}
+template<typename T, typename... Args>
+static void reset_object(T* dst, Args&&... args) {
+ dst->~T();
+ new (dst) T(std::forward<Args>(args)...);
+}
+
////////////////////////////////////////////////////////////////////////////////
SkPDFDocument::SkPDFDocument(SkWStream* stream,
@@ -192,7 +199,7 @@
}
SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height) {
- SkASSERT(!fCanvas.get()); // endPage() was called before this.
+ SkASSERT(fCanvas.imageInfo().dimensions().isZero());
if (fPages.empty()) {
// if this is the first page if the document.
fObjectSerializer.serializeHeader(this->getStream(), fMetadata);
@@ -216,9 +223,9 @@
fPageDevice = sk_make_sp<SkPDFDevice>(pageSize, this);
fPageDevice->setFlip(); // Only the top-level device needs to be flipped.
- fCanvas.reset(new SkCanvas(fPageDevice));
- fCanvas->scale(rasterScale, rasterScale);
- return fCanvas.get();
+ reset_object(&fCanvas, fPageDevice);
+ fCanvas.scale(rasterScale, rasterScale);
+ return &fCanvas;
}
static sk_sp<SkPDFArray> calculate_page_size(SkScalar rasterDpi, SkISize size) {
@@ -227,9 +234,9 @@
}
void SkPDFDocument::onEndPage() {
- SkASSERT(fCanvas.get());
- fCanvas->flush();
- fCanvas.reset(nullptr);
+ SkASSERT(!fCanvas.imageInfo().dimensions().isZero());
+ fCanvas.flush();
+ reset_object(&fCanvas);
SkASSERT(fPageDevice);
auto page = sk_make_sp<SkPDFDict>("Page");
@@ -258,11 +265,11 @@
void SkPDFDocument::reset() {
fObjectSerializer = SkPDFObjectSerializer();
fCanon = SkPDFCanon();
+ reset_object(&fCanvas);
fPages = std::vector<sk_sp<SkPDFDict>>();
fFonts.reset();
fDests = nullptr;
fPageDevice = nullptr;
- fCanvas = nullptr;
fID = nullptr;
fXMP = nullptr;
fMetadata = SkDocument::PDFMetadata();
@@ -412,7 +419,7 @@
}
void SkPDFDocument::onClose(SkWStream* stream) {
- SkASSERT(!fCanvas.get());
+ SkASSERT(fCanvas.imageInfo().dimensions().isZero());
if (fPages.empty()) {
this->reset();
return;
diff --git a/src/pdf/SkPDFDocument.h b/src/pdf/SkPDFDocument.h
index 35e65df..2d7be50 100644
--- a/src/pdf/SkPDFDocument.h
+++ b/src/pdf/SkPDFDocument.h
@@ -7,10 +7,11 @@
#ifndef SkPDFDocument_DEFINED
#define SkPDFDocument_DEFINED
+#include "SkCanvas.h"
#include "SkDocument.h"
#include "SkPDFCanon.h"
-#include "SkPDFMetadata.h"
#include "SkPDFFont.h"
+#include "SkPDFMetadata.h"
class SkPDFDevice;
@@ -81,11 +82,11 @@
private:
SkPDFObjectSerializer fObjectSerializer;
SkPDFCanon fCanon;
+ SkCanvas fCanvas;
std::vector<sk_sp<SkPDFDict>> fPages;
SkTHashSet<SkPDFFont*> fFonts;
sk_sp<SkPDFDict> fDests;
sk_sp<SkPDFDevice> fPageDevice;
- std::unique_ptr<SkCanvas> fCanvas;
sk_sp<SkPDFObject> fID;
sk_sp<SkPDFObject> fXMP;
SkDocument::PDFMetadata fMetadata;