aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/pdf
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-01-06 09:54:13 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-06 09:54:14 -0800
commitefdac514a9846e4ef32e1160fe7f2dae471cef39 (patch)
tree53ab81d241b34d49e0d617e6e0c19f17b4ed8c18 /include/pdf
parent8b1f761365df6652ea9304b6572d2dd91917b9aa (diff)
Revert "Remove SkPDFDocument and SkPDFDevice from the public headers."
This reverts commit 8b1f761365df6652ea9304b6572d2dd91917b9aa. BUG=skia: TBR= NOTRY=True NOTREECHECKS=True Review URL: https://codereview.chromium.org/839603002
Diffstat (limited to 'include/pdf')
-rw-r--r--include/pdf/SkPDFDevice.h339
-rw-r--r--include/pdf/SkPDFDocument.h113
2 files changed, 452 insertions, 0 deletions
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
new file mode 100644
index 0000000000..495354a0be
--- /dev/null
+++ b/include/pdf/SkPDFDevice.h
@@ -0,0 +1,339 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPDFDevice_DEFINED
+#define SkPDFDevice_DEFINED
+
+#include "SkDevice.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPicture.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "SkTemplates.h"
+
+class SkPDFArray;
+class SkPDFDevice;
+class SkPDFDict;
+class SkPDFFont;
+class SkPDFFormXObject;
+class SkPDFGlyphSetMap;
+class SkPDFGraphicState;
+class SkPDFObject;
+class SkPDFResourceDict;
+class SkPDFShader;
+class SkPDFStream;
+class SkRRect;
+template <typename T> class SkTSet;
+
+// Private classes.
+struct ContentEntry;
+struct GraphicStateEntry;
+struct NamedDestination;
+
+/** \class SkPDFDevice
+
+ The drawing context for the PDF backend.
+*/
+class SkPDFDevice : public SkBaseDevice {
+public:
+ /** Create a PDF drawing context with the given width and height.
+ * 72 points/in means letter paper is 612x792.
+ * @param pageSize Page size in points.
+ * @param contentSize The content size of the page in points. This will be
+ * combined with the initial transform to determine the drawing area
+ * (as reported by the width and height methods). Anything outside
+ * of the drawing area will be clipped.
+ * @param initialTransform The initial transform to apply to the page.
+ * This may be useful to, for example, move the origin in and
+ * over a bit to account for a margin, scale the canvas,
+ * or apply a rotation. Note1: the SkPDFDevice also applies
+ * a scale+translate transform to move the origin from the
+ * bottom left (PDF default) to the top left. Note2: drawDevice
+ * (used by layer restore) draws the device after this initial
+ * transform is applied, so the PDF device does an
+ * inverse scale+translate to accommodate the one that SkPDFDevice
+ * always does.
+ */
+ // Deprecated, please use SkDocument::CreatePdf() instead.
+ SK_API SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize,
+ const SkMatrix& initialTransform);
+ SK_API virtual ~SkPDFDevice();
+
+ /** These are called inside the per-device-layer loop for each draw call.
+ When these are called, we have already applied any saveLayer operations,
+ and are handling any looping from the paint, and any effects from the
+ DrawFilter.
+ */
+ void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+ void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) SK_OVERRIDE;
+ void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) SK_OVERRIDE;
+ void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) SK_OVERRIDE;
+ void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) SK_OVERRIDE;
+ void drawPath(const SkDraw&, const SkPath& origpath,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) SK_OVERRIDE;
+ void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+ const SkRect* src, const SkRect& dst,
+ const SkPaint& paint,
+ SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
+ void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint&) SK_OVERRIDE;
+ void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
+ const SkPaint& paint) SK_OVERRIDE;
+ void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
+ void drawPosText(const SkDraw&, const void* text, size_t len,
+ const SkScalar pos[], int scalarsPerPos,
+ const SkPoint& offset, const SkPaint&) SK_OVERRIDE;
+ void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE;
+ void drawVertices(const SkDraw&, SkCanvas::VertexMode,
+ int vertexCount, const SkPoint verts[],
+ const SkPoint texs[], const SkColor colors[],
+ SkXfermode* xmode, const uint16_t indices[],
+ int indexCount, const SkPaint& paint) SK_OVERRIDE;
+ void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ const SkPaint&) SK_OVERRIDE;
+
+ void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
+ void onDetachFromCanvas() SK_OVERRIDE;
+ SkImageInfo imageInfo() const SK_OVERRIDE;
+
+ enum DrawingArea {
+ kContent_DrawingArea, // Drawing area for the page content.
+ kMargin_DrawingArea, // Drawing area for the margin content.
+ };
+
+ /** Sets the drawing area for the device. Subsequent draw calls are directed
+ * to the specific drawing area (margin or content). The default drawing
+ * area is the content drawing area.
+ *
+ * Currently if margin content is drawn and then a complex (for PDF) xfer
+ * mode is used, like SrcIn, Clear, etc, the margin content will get
+ * clipped. A simple way to avoid the bug is to always draw the margin
+ * content last.
+ */
+ SK_API void setDrawingArea(DrawingArea drawingArea);
+
+ /** Sets the DCTEncoder for images.
+ * @param encoder The encoder to encode a bitmap as JPEG (DCT).
+ * Result of encodings are cached, if the encoder changes the
+ * behaivor dynamically and an image is added to a second catalog,
+ * we will likely use the result of the first encoding call.
+ * By returning false from the encoder function, the encoder result
+ * is not used.
+ * Callers might not want to encode small images, as the time spent
+ * encoding and decoding might not be worth the space savings,
+ * if any at all.
+ */
+ void setDCTEncoder(SkPicture::EncodeBitmap encoder) {
+ fEncoder = encoder;
+ }
+
+ // PDF specific methods.
+
+ /** Returns the resource dictionary for this device.
+ */
+ SK_API SkPDFResourceDict* getResourceDict();
+
+ /** Get the fonts used on this device.
+ */
+ SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
+
+ /** Add our named destinations to the supplied dictionary.
+ * @param dict Dictionary to add destinations to.
+ * @param page The PDF object representing the page for this device.
+ */
+ void appendDestinations(SkPDFDict* dict, SkPDFObject* page);
+
+ /** Returns a copy of the media box for this device. The caller is required
+ * to unref() this when it is finished.
+ */
+ SK_API SkPDFArray* copyMediaBox() const;
+
+ /** Get the annotations from this page, or NULL if there are none.
+ */
+ SK_API SkPDFArray* getAnnotations() const { return fAnnotations; }
+
+ /** Returns a SkStream with the page contents. The caller is responsible
+ for a reference to the returned value.
+ DEPRECATED: use copyContentToData()
+ */
+ SK_API SkStream* content() const;
+
+ /** Returns a SkStream with the page contents. The caller is responsible
+ * for calling data->unref() when it is finished.
+ */
+ SK_API SkData* copyContentToData() const;
+
+ SK_API const SkMatrix& initialTransform() const {
+ return fInitialTransform;
+ }
+
+ /** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
+ * that shows on this device.
+ */
+ const SkPDFGlyphSetMap& getFontGlyphUsage() const {
+ return *(fFontGlyphUsage.get());
+ }
+
+
+ /**
+ * rasterDpi - the DPI at which features without native PDF support
+ * will be rasterized (e.g. draw image with perspective,
+ * draw text with perspective, ...)
+ * A larger DPI would create a PDF that reflects the original
+ * intent with better fidelity, but it can make for larger
+ * PDF files too, which would use more memory while rendering,
+ * and it would be slower to be processed or sent online or
+ * to printer.
+ */
+ void setRasterDpi(SkScalar rasterDpi) {
+ fRasterDpi = rasterDpi;
+ }
+
+protected:
+ virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
+ return fLegacyBitmap;
+ }
+
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
+
+private:
+ // TODO(vandebo): push most of SkPDFDevice's state into a core object in
+ // order to get the right access levels without using friend.
+ friend class ScopedContentEntry;
+
+ SkISize fPageSize;
+ SkISize fContentSize;
+ SkMatrix fInitialTransform;
+ SkClipStack fExistingClipStack;
+ SkRegion fExistingClipRegion;
+ SkPDFArray* fAnnotations;
+ SkPDFResourceDict* fResourceDict;
+ SkTDArray<NamedDestination*> fNamedDestinations;
+
+ SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
+ SkTDArray<SkPDFObject*> fXObjectResources;
+ SkTDArray<SkPDFFont*> fFontResources;
+ SkTDArray<SkPDFObject*> fShaderResources;
+
+ SkAutoTDelete<ContentEntry> fContentEntries;
+ ContentEntry* fLastContentEntry;
+ SkAutoTDelete<ContentEntry> fMarginContentEntries;
+ ContentEntry* fLastMarginContentEntry;
+ DrawingArea fDrawingArea;
+
+ const SkClipStack* fClipStack;
+
+ // Accessor and setter functions based on the current DrawingArea.
+ SkAutoTDelete<ContentEntry>* getContentEntries();
+ ContentEntry* getLastContentEntry();
+ void setLastContentEntry(ContentEntry* contentEntry);
+
+ // Glyph ids used for each font on this device.
+ SkAutoTDelete<SkPDFGlyphSetMap> fFontGlyphUsage;
+
+ SkPicture::EncodeBitmap fEncoder;
+ SkScalar fRasterDpi;
+
+ SkBitmap fLegacyBitmap;
+
+ SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
+ const SkRegion& existingClipRegion);
+
+ // override from SkBaseDevice
+ virtual SkBaseDevice* onCreateCompatibleDevice(const CreateInfo&) SK_OVERRIDE;
+
+ void init();
+ void cleanUp(bool clearFontUsage);
+ SkPDFFormXObject* createFormXObjectFromDevice();
+
+ void drawFormXObjectWithMask(int xObjectIndex,
+ SkPDFFormXObject* mask,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ SkXfermode::Mode mode,
+ bool invertClip);
+
+ // If the paint or clip is such that we shouldn't draw anything, this
+ // returns NULL and does not create a content entry.
+ // setUpContentEntry and finishContentEntry can be used directly, but
+ // the preferred method is to use the ScopedContentEntry helper class.
+ ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkMatrix& matrix,
+ const SkPaint& paint,
+ bool hasText,
+ SkPDFFormXObject** dst);
+ void finishContentEntry(SkXfermode::Mode xfermode,
+ SkPDFFormXObject* dst,
+ SkPath* shape);
+ bool isContentEmpty();
+
+ void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
+ const SkClipStack& clipStack,
+ const SkRegion& clipRegion,
+ const SkPaint& paint,
+ bool hasText,
+ GraphicStateEntry* entry);
+ int addGraphicStateResource(SkPDFGraphicState* gs);
+ int addXObjectResource(SkPDFObject* xObject);
+
+ void updateFont(const SkPaint& paint, uint16_t glyphID,
+ ContentEntry* contentEntry);
+ int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
+
+ void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
+ void internalDrawBitmap(const SkMatrix& matrix,
+ const SkClipStack* clipStack,
+ const SkRegion& clipRegion,
+ const SkBitmap& bitmap,
+ const SkIRect* srcRect,
+ const SkPaint& paint);
+
+ /** Helper method for copyContentToData. It is responsible for copying the
+ * list of content entries |entry| to |data|.
+ */
+ void copyContentEntriesToData(ContentEntry* entry, SkWStream* data) const;
+
+#ifdef SK_PDF_USE_PATHOPS
+ bool handleInversePath(const SkDraw& d, const SkPath& origPath,
+ const SkPaint& paint, bool pathIsMutable,
+ const SkMatrix* prePathMatrix = NULL);
+#endif
+ bool handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
+ const SkPaint& paint);
+ bool handlePointAnnotation(const SkPoint* points, size_t count,
+ const SkMatrix& matrix, const SkPaint& paint);
+ SkPDFDict* createLinkAnnotation(const SkRect& r, const SkMatrix& matrix);
+ void handleLinkToURL(SkData* urlData, const SkRect& r,
+ const SkMatrix& matrix);
+ void handleLinkToNamedDest(SkData* nameData, const SkRect& r,
+ const SkMatrix& matrix);
+ void defineNamedDestination(SkData* nameData, const SkPoint& point,
+ const SkMatrix& matrix);
+
+ typedef SkBaseDevice INHERITED;
+
+ // TODO(edisonn): Only SkDocument_PDF and SkPDFImageShader should be able to create
+ // an SkPDFDevice
+ //friend class SkDocument_PDF;
+ //friend class SkPDFImageShader;
+};
+
+#endif
diff --git a/include/pdf/SkPDFDocument.h b/include/pdf/SkPDFDocument.h
new file mode 100644
index 0000000000..07738a210b
--- /dev/null
+++ b/include/pdf/SkPDFDocument.h
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright 2010 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPDFDocument_DEFINED
+#define SkPDFDocument_DEFINED
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include "SkTemplates.h"
+
+class SkPDFCatalog;
+class SkPDFDevice;
+class SkPDFDict;
+class SkPDFPage;
+class SkPDFObject;
+class SkWStream;
+template <typename T> class SkTSet;
+
+/** \class SkPDFDocument
+
+ A SkPDFDocument assembles pages together and generates the final PDF file.
+*/
+class SkPDFDocument {
+public:
+ enum Flags {
+ kNoCompression_Flags = 0x01, //!< DEPRECATED.
+ kFavorSpeedOverSize_Flags = 0x01, //!< Don't compress the stream, but
+ // if it is already compressed return
+ // the compressed stream.
+ kNoLinks_Flags = 0x02, //!< do not honor link annotations.
+
+ kDraftMode_Flags = 0x01,
+ };
+ /** Create a PDF document.
+ */
+ explicit SK_API SkPDFDocument(Flags flags = (Flags)0);
+ SK_API ~SkPDFDocument();
+
+ /** Output the PDF to the passed stream. It is an error to call this (it
+ * will return false and not modify stream) if no pages have been added
+ * or there are pages missing (i.e. page 1 and 3 have been added, but not
+ * page 2).
+ *
+ * @param stream The writable output stream to send the PDF to.
+ */
+ SK_API bool emitPDF(SkWStream* stream);
+
+ /** Sets the specific page to the passed PDF device. If the specified
+ * page is already set, this overrides it. Returns true if successful.
+ * Will fail if the document has already been emitted.
+ *
+ * @param pageNumber The position to add the passed device (1 based).
+ * @param pdfDevice The page to add to this document.
+ */
+ SK_API bool setPage(int pageNumber, SkPDFDevice* pdfDevice);
+
+ /** Append the passed pdf device to the document as a new page. Returns
+ * true if successful. Will fail if the document has already been emitted.
+ *
+ * @param pdfDevice The page to add to this document.
+ */
+ SK_API bool appendPage(SkPDFDevice* pdfDevice);
+
+ /** Get the count of unique font types used in the document.
+ * DEPRECATED.
+ */
+ SK_API void getCountOfFontTypes(
+ int counts[SkAdvancedTypefaceMetrics::kOther_Font + 2]) const;
+
+ /** Get the count of unique font types used in the document.
+ */
+ SK_API void getCountOfFontTypes(
+ int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1],
+ int* notSubsettableCount,
+ int* notEmbedddableCount) const;
+
+private:
+ SkAutoTDelete<SkPDFCatalog> fCatalog;
+ int64_t fXRefFileOffset;
+
+ SkTDArray<SkPDFPage*> fPages;
+ SkTDArray<SkPDFDict*> fPageTree;
+ SkPDFDict* fDocCatalog;
+ SkTSet<SkPDFObject*>* fFirstPageResources;
+ SkTSet<SkPDFObject*>* fOtherPageResources;
+ SkTDArray<SkPDFObject*> fSubstitutes;
+
+ SkPDFDict* fTrailerDict;
+
+ /** Output the PDF header to the passed stream.
+ * @param stream The writable output stream to send the header to.
+ */
+ void emitHeader(SkWStream* stream);
+
+ /** Get the size of the header.
+ */
+ size_t headerSize();
+
+ /** Output the PDF footer to the passed stream.
+ * @param stream The writable output stream to send the footer to.
+ * @param objCount The number of objects in the PDF.
+ */
+ void emitFooter(SkWStream* stream, int64_t objCount);
+};
+
+#endif