aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf/SkPDFDevice.h
diff options
context:
space:
mode:
authorGravatar halcanary <halcanary@google.com>2015-01-06 09:30:10 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-06 09:30:10 -0800
commit8b1f761365df6652ea9304b6572d2dd91917b9aa (patch)
tree232ad41f3beeb6481f84dac93a7cb5e81c1100fc /src/pdf/SkPDFDevice.h
parentc4bd39c903cc5da16f50d711063b01723b59281c (diff)
Remove SkPDFDocument and SkPDFDevice from the public headers.
Diffstat (limited to 'src/pdf/SkPDFDevice.h')
-rw-r--r--src/pdf/SkPDFDevice.h339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
new file mode 100644
index 0000000000..495354a0be
--- /dev/null
+++ b/src/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