--- /dev/null
+
+/*
+ * 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 SkBitSet_DEFINED
+#define SkBitSet_DEFINED
+
+#include "SkTypes.h"
+#include "SkTDArray.h"
+
+class SkBitSet {
+public:
+ /** NumberOfBits must be greater than zero.
+ */
+ explicit SkBitSet(int numberOfBits);
+ explicit SkBitSet(const SkBitSet& source);
+
+ const SkBitSet& operator=(const SkBitSet& rhs);
+ bool operator==(const SkBitSet& rhs);
+ bool operator!=(const SkBitSet& rhs);
+
+ /** Clear all data.
+ */
+ void clearAll();
+
+ /** Set the value of the index-th bit.
+ */
+ void setBit(int index, bool value);
+
+ /** Test if bit index is set.
+ */
+ bool isBitSet(int index) const;
+
+ /** Or bits from source. false is returned if this doesn't have the same
+ * bit count as source.
+ */
+ bool orBits(const SkBitSet& source);
+
+ /** Export indices of set bits to T array.
+ */
+ template<typename T>
+ void exportTo(SkTDArray<T>* array) const {
+ SkASSERT(array);
+ uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
+ for (unsigned int i = 0; i < fDwordCount; ++i) {
+ uint32_t value = data[i];
+ if (value) { // There are set bits
+ unsigned int index = i * 32;
+ for (unsigned int j = 0; j < 32; ++j) {
+ if (0x1 & (value >> j)) {
+ array->push(index + j);
+ }
+ }
+ }
+ }
+ }
+
+private:
+ SkAutoFree fBitData;
+ // Dword (32-bit) count of the bitset.
+ size_t fDwordCount;
+ size_t fBitCount;
+
+ uint32_t* internalGet(int index) const {
+ SkASSERT((size_t)index < fBitCount);
+ size_t internalIndex = index / 32;
+ SkASSERT(internalIndex < fDwordCount);
+ return reinterpret_cast<uint32_t*>(fBitData.get()) + internalIndex;
+ }
+};
+
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFCatalog_DEFINED
+#define SkPDFCatalog_DEFINED
+
+#include <sys/types.h>
+
+#include "SkPDFDocument.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+/** \class SkPDFCatalog
+
+ The PDF catalog manages object numbers and file offsets. It is used
+ to create the PDF cross reference table.
+*/
+class SK_API SkPDFCatalog {
+public:
+ /** Create a PDF catalog.
+ */
+ explicit SkPDFCatalog(SkPDFDocument::Flags flags);
+ ~SkPDFCatalog();
+
+ /** Add the passed object to the catalog. Refs obj.
+ * @param obj The object to add.
+ * @param onFirstPage Is the object on the first page.
+ * @return The obj argument is returned.
+ */
+ SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);
+
+ /** Inform the catalog of the object's position in the final stream.
+ * The object should already have been added to the catalog. Returns
+ * the object's size.
+ * @param obj The object to add.
+ * @param offset The byte offset in the output stream of this object.
+ */
+ size_t setFileOffset(SkPDFObject* obj, size_t offset);
+
+ /** Output the object number for the passed object.
+ * @param obj The object of interest.
+ * @param stream The writable output stream to send the output to.
+ */
+ void emitObjectNumber(SkWStream* stream, SkPDFObject* obj);
+
+ /** Return the number of bytes that would be emitted for the passed
+ * object's object number.
+ * @param obj The object of interest
+ */
+ size_t getObjectNumberSize(SkPDFObject* obj);
+
+ /** Return the document flags in effect for this catalog/document.
+ */
+ SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; }
+
+ /** Output the cross reference table for objects in the catalog.
+ * Returns the total number of objects.
+ * @param stream The writable output stream to send the output to.
+ * @param firstPage If true, include first page objects only, otherwise
+ * include all objects not on the first page.
+ */
+ int32_t emitXrefTable(SkWStream* stream, bool firstPage);
+
+ /** Set substitute object for the passed object.
+ */
+ void setSubstitute(SkPDFObject* original, SkPDFObject* substitute);
+
+ /** Find and return any substitute object set for the passed object. If
+ * there is none, return the passed object.
+ */
+ SkPDFObject* getSubstituteObject(SkPDFObject* object);
+
+ /** Set file offsets for the resources of substitute objects.
+ * @param fileOffset Accumulated offset of current document.
+ * @param firstPage Indicate whether this is for the first page only.
+ * @return Total size of resources of substitute objects.
+ */
+ off_t setSubstituteResourcesOffsets(off_t fileOffset, bool firstPage);
+
+ /** Emit the resources of substitute objects.
+ */
+ void emitSubstituteResources(SkWStream* stream, bool firstPage);
+
+private:
+ struct Rec {
+ Rec(SkPDFObject* object, bool onFirstPage)
+ : fObject(object),
+ fFileOffset(0),
+ fObjNumAssigned(false),
+ fOnFirstPage(onFirstPage) {
+ }
+ SkPDFObject* fObject;
+ off_t fFileOffset;
+ bool fObjNumAssigned;
+ bool fOnFirstPage;
+ };
+
+ struct SubstituteMapping {
+ SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute)
+ : fOriginal(original), fSubstitute(substitute) {
+ }
+ SkPDFObject* fOriginal;
+ SkPDFObject* fSubstitute;
+ };
+
+ // TODO(vandebo): Make this a hash if it's a performance problem.
+ SkTDArray<struct Rec> fCatalog;
+
+ // TODO(arthurhsu): Make this a hash if it's a performance problem.
+ SkTDArray<SubstituteMapping> fSubstituteMap;
+ SkTDArray<SkPDFObject*> fSubstituteResourcesFirstPage;
+ SkTDArray<SkPDFObject*> fSubstituteResourcesRemaining;
+
+ // Number of objects on the first page.
+ uint32_t fFirstPageCount;
+ // Next object number to assign (on page > 1).
+ uint32_t fNextObjNum;
+ // Next object number to assign on the first page.
+ uint32_t fNextFirstPageObjNum;
+
+ SkPDFDocument::Flags fDocumentFlags;
+
+ int findObjectIndex(SkPDFObject* obj) const;
+
+ int assignObjNum(SkPDFObject* obj);
+
+ SkTDArray<SkPDFObject*>* getSubstituteList(bool firstPage);
+};
+
+#endif
#ifndef SkPDFDocument_DEFINED
#define SkPDFDocument_DEFINED
-#include "SkAdvancedTypefaceMetrics.h"
+#include "SkPDFTypes.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"
#include "SkTScopedPtr.h"
class SkPDFCatalog;
class SkPDFDevice;
-class SkPDFDict;
class SkPDFPage;
-class SkPDFObject;
-class SkWStream;
+class SkWSteam;
/** \class SkPDFDocument
*/
SK_API bool appendPage(SkPDFDevice* pdfDevice);
- /** Get the count of unique font types used in the document.
+ /** Get the list of pages in this document.
*/
- SK_API void getCountOfFontTypes(
- int counts[SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1]) const;
+ SK_API const SkTDArray<SkPDFPage*>& getPages();
private:
SkTScopedPtr<SkPDFCatalog> fCatalog;
--- /dev/null
+
+/*
+ * 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 SkPDFFont_DEFINED
+#define SkPDFFont_DEFINED
+
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkBitSet.h"
+#include "SkPDFTypes.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+#include "SkTypeface.h"
+
+class SkPaint;
+class SkPDFCatalog;
+class SkPDFFont;
+
+class SkPDFGlyphSet : public SkNoncopyable {
+public:
+ SkPDFGlyphSet();
+
+ void set(const uint16_t* glyphIDs, int numGlyphs);
+ bool has(uint16_t glyphID) const;
+ void merge(const SkPDFGlyphSet& usage);
+ void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
+
+private:
+ SkBitSet fBitSet;
+};
+
+class SkPDFGlyphSetMap : public SkNoncopyable {
+public:
+ struct FontGlyphSetPair {
+ FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
+
+ SkPDFFont* fFont;
+ SkPDFGlyphSet* fGlyphSet;
+ };
+
+ SkPDFGlyphSetMap();
+ ~SkPDFGlyphSetMap();
+
+ class F2BIter {
+ public:
+ explicit F2BIter(const SkPDFGlyphSetMap& map);
+ FontGlyphSetPair* next() const;
+ void reset(const SkPDFGlyphSetMap& map);
+
+ private:
+ const SkTDArray<FontGlyphSetPair>* fMap;
+ mutable int fIndex;
+ };
+
+ void merge(const SkPDFGlyphSetMap& usage);
+ void reset();
+
+ void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
+ int numGlyphs);
+
+private:
+ SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
+
+ SkTDArray<FontGlyphSetPair> fMap;
+};
+
+
+/** \class SkPDFFont
+ A PDF Object class representing a font. The font may have resources
+ attached to it in order to embed the font. SkPDFFonts are canonicalized
+ so that resource deduplication will only include one copy of a font.
+ This class uses the same pattern as SkPDFGraphicState, a static weak
+ reference to each instantiated class.
+*/
+class SkPDFFont : public SkPDFDict {
+public:
+ SK_API virtual ~SkPDFFont();
+
+ SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Returns the typeface represented by this class. Returns NULL for the
+ * default typeface.
+ */
+ SK_API SkTypeface* typeface();
+
+ /** Returns the font type represented in this font. For Type0 fonts,
+ * returns the type of the decendant font.
+ */
+ SK_API virtual SkAdvancedTypefaceMetrics::FontType getType();
+
+ /** Returns true if this font encoding supports glyph IDs above 255.
+ */
+ SK_API virtual bool multiByteGlyphs() const = 0;
+
+ /** Return true if this font has an encoding for the passed glyph id.
+ */
+ SK_API bool hasGlyph(uint16_t glyphID);
+
+ /** Convert (in place) the input glyph IDs into the font encoding. If the
+ * font has more glyphs than can be encoded (like a type 1 font with more
+ * than 255 glyphs) this method only converts up to the first out of range
+ * glyph ID.
+ * @param glyphIDs The input text as glyph IDs.
+ * @param numGlyphs The number of input glyphs.
+ * @return Returns the number of glyphs consumed.
+ */
+ SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
+
+ /** Get the font resource for the passed typeface and glyphID. The
+ * reference count of the object is incremented and it is the caller's
+ * responsibility to unreference it when done. This is needed to
+ * accommodate the weak reference pattern used when the returned object
+ * is new and has no other references.
+ * @param typeface The typeface to find.
+ * @param glyphID Specify which section of a large font is of interest.
+ */
+ SK_API static SkPDFFont* GetFontResource(SkTypeface* typeface,
+ uint16_t glyphID);
+
+ /** Subset the font based on usage set. Returns a SkPDFFont instance with
+ * subset.
+ * @param usage Glyph subset requested.
+ * @return NULL if font does not support subsetting, a new instance
+ * of SkPDFFont otherwise.
+ */
+ SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
+
+protected:
+ // Common constructor to handle common members.
+ SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
+ uint16_t glyphID, bool descendantFont);
+
+ // Accessors for subclass.
+ SkAdvancedTypefaceMetrics* fontInfo();
+ void setFontInfo(SkAdvancedTypefaceMetrics* info);
+ uint16_t firstGlyphID() const;
+ uint16_t lastGlyphID() const;
+ void setLastGlyphID(uint16_t glyphID);
+
+ // Add object to resource list.
+ void addResource(SkPDFObject* object);
+
+ // Accessors for FontDescriptor associated with this object.
+ SkPDFDict* getFontDescriptor();
+ void setFontDescriptor(SkPDFDict* descriptor);
+
+ // Add common entries to FontDescriptor.
+ bool addCommonFontDescriptorEntries(int16_t defaultWidth);
+
+ /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
+ * including the passed glyphID.
+ */
+ void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
+
+ // Generate ToUnicode table according to glyph usage subset.
+ // If subset is NULL, all available glyph ids will be used.
+ void populateToUnicodeTable(const SkPDFGlyphSet* subset);
+
+ // Create instances of derived types based on fontInfo.
+ static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
+ SkTypeface* typeface, uint16_t glyphID,
+ SkPDFDict* fontDescriptor);
+
+ static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
+
+private:
+ class FontRec {
+ public:
+ SkPDFFont* fFont;
+ uint32_t fFontID;
+ uint16_t fGlyphID;
+
+ // A fGlyphID of 0 with no fFont always matches.
+ bool operator==(const FontRec& b) const;
+ FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
+ };
+
+ SkRefPtr<SkTypeface> fTypeface;
+
+ // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
+ // this will be a subset if the font has more than 255 glyphs.
+ uint16_t fFirstGlyphID;
+ uint16_t fLastGlyphID;
+ // The font info is only kept around after construction for large
+ // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
+ SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
+ SkTDArray<SkPDFObject*> fResources;
+ SkRefPtr<SkPDFDict> fDescriptor;
+
+ SkAdvancedTypefaceMetrics::FontType fFontType;
+
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<FontRec>& CanonicalFonts();
+ static SkBaseMutex& CanonicalFontsMutex();
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFFormXObject_DEFINED
+#define SkPDFFormXObject_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkMatrix;
+class SkPDFDevice;
+class SkPDFCatalog;
+
+/** \class SkPDFFormXObject
+
+ A form XObject; a self contained description of graphics objects. A form
+ XObject is basically a page object with slightly different syntax, that
+ can be drawn onto a page.
+*/
+
+// The caller could keep track of the form XObjects it creates and
+// canonicalize them, but the Skia API doesn't provide enough context to
+// automatically do it (trivially).
+class SkPDFFormXObject : public SkPDFStream {
+public:
+ /** Create a PDF form XObject. Entries for the dictionary entries are
+ * automatically added.
+ * @param device The set of graphical elements on this form.
+ */
+ explicit SkPDFFormXObject(SkPDFDevice* device);
+ virtual ~SkPDFFormXObject();
+
+ // The SkPDFObject interface.
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+private:
+ SkTDArray<SkPDFObject*> fResources;
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFGraphicState_DEFINED
+#define SkPDFGraphicState_DEFINED
+
+#include "SkPaint.h"
+#include "SkPDFTypes.h"
+#include "SkTemplates.h"
+#include "SkThread.h"
+
+class SkPDFFormXObject;
+
+/** \class SkPDFGraphicState
+ SkPaint objects roughly correspond to graphic state dictionaries that can
+ be installed. So that a given dictionary is only output to the pdf file
+ once, we want to canonicalize them. Static methods in this class manage
+ a weakly referenced set of SkPDFGraphicState objects: when the last
+ reference to a SkPDFGraphicState is removed, it removes itself from the
+ static set of objects.
+
+*/
+class SkPDFGraphicState : public SkPDFDict {
+public:
+ virtual ~SkPDFGraphicState();
+
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ // Override emitObject and getOutputSize so that we can populate
+ // the dictionary on demand.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** Get the graphic state for the passed SkPaint. The reference count of
+ * the object is incremented and it is the caller's responsibility to
+ * unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ * @param paint The SkPaint to emulate.
+ */
+ static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint);
+
+ /** Make a graphic state that only sets the passed soft mask. The
+ * reference count of the object is incremented and it is the caller's
+ * responsibility to unreference it when done.
+ * @param sMask The form xobject to use as a soft mask.
+ * @param invert Indicates if the alpha of the sMask should be inverted.
+ */
+ static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask,
+ bool invert);
+
+ /** Get a graphic state that only unsets the soft mask. The reference
+ * count of the object is incremented and it is the caller's responsibility
+ * to unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ */
+ static SkPDFGraphicState* GetNoSMaskGraphicState();
+
+private:
+ const SkPaint fPaint;
+ SkTDArray<SkPDFObject*> fResources;
+ bool fPopulated;
+ bool fSMask;
+
+ class GSCanonicalEntry {
+ public:
+ SkPDFGraphicState* fGraphicState;
+ const SkPaint* fPaint;
+
+ bool operator==(const GSCanonicalEntry& b) const;
+ explicit GSCanonicalEntry(SkPDFGraphicState* gs)
+ : fGraphicState(gs),
+ fPaint(&gs->fPaint) {}
+ explicit GSCanonicalEntry(const SkPaint* paint)
+ : fGraphicState(NULL),
+ fPaint(paint) {}
+ };
+
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<GSCanonicalEntry>& CanonicalPaints();
+ static SkBaseMutex& CanonicalPaintsMutex();
+
+ SkPDFGraphicState();
+ explicit SkPDFGraphicState(const SkPaint& paint);
+
+ void populateDict();
+
+ static SkPDFObject* GetInvertFunction();
+
+ static int Find(const SkPaint& paint);
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFImage_DEFINED
+#define SkPDFImage_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+
+class SkBitmap;
+class SkPaint;
+class SkPDFCatalog;
+struct SkIRect;
+
+/** \class SkPDFImage
+
+ An image XObject.
+*/
+
+// We could play the same trick here as is done in SkPDFGraphicState, storing
+// a copy of the Bitmap object (not the pixels), the pixel generation number,
+// and settings used from the paint to canonicalize image objects.
+class SkPDFImage : public SkPDFStream {
+public:
+ /** Create a new Image XObject to represent the passed bitmap.
+ * @param bitmap The image to encode.
+ * @param srcRect The rectangle to cut out of bitmap.
+ * @param paint Used to calculate alpha, masks, etc.
+ * @return The image XObject or NUll if there is nothing to draw for
+ * the given parameters.
+ */
+ static SkPDFImage* CreateImage(const SkBitmap& bitmap,
+ const SkIRect& srcRect,
+ const SkPaint& paint);
+
+ virtual ~SkPDFImage();
+
+ /** Add a Soft Mask (alpha or shape channel) to the image. Refs mask.
+ * @param mask A gray scale image representing the mask.
+ * @return The mask argument is returned.
+ */
+ SkPDFImage* addSMask(SkPDFImage* mask);
+
+ // The SkPDFObject interface.
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+private:
+ SkTDArray<SkPDFObject*> fResources;
+
+ /** Create a PDF image XObject. Entries for the image properties are
+ * automatically added to the stream dictionary.
+ * @param imageData The final raw bits representing the image.
+ * @param bitmap The image parameters to use (Config, etc).
+ * @param srcRect The clipping applied to bitmap before generating
+ * imageData.
+ * @param alpha Is this the alpha channel of the bitmap.
+ * @param paint Used to calculate alpha, masks, etc.
+ */
+ SkPDFImage(SkStream* imageData, const SkBitmap& bitmap,
+ const SkIRect& srcRect, bool alpha, const SkPaint& paint);
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFPage_DEFINED
+#define SkPDFPage_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkPDFStream.h"
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+
+class SkPDFCatalog;
+class SkPDFDevice;
+class SkWStream;
+
+/** \class SkPDFPage
+
+ A SkPDFPage contains meta information about a page, is used in the page
+ tree and points to the content of the page.
+*/
+class SkPDFPage : public SkPDFDict {
+public:
+ /** Create a PDF page with the passed PDF device. The device need not
+ * have content on it yet.
+ * @param content The page content.
+ */
+ explicit SkPDFPage(SkPDFDevice* content);
+ ~SkPDFPage();
+
+ /** Before a page and its contents can be sized and emitted, it must
+ * be finalized. No changes to the PDFDevice will be honored after
+ * finalizePage has been called. This function adds the page content
+ * to the passed catalog, so it must be called for each document
+ * that the page is part of.
+ * @param catalog The catalog to add page content objects to.
+ * @param firstPage Indicate if this is the first page of a document.
+ * @param resourceObjects All the resource objects (recursively) used on
+ * the page are added to this array. This gives
+ * the caller a chance to deduplicate resources
+ * across pages.
+ */
+ void finalizePage(SkPDFCatalog* catalog, bool firstPage,
+ SkTDArray<SkPDFObject*>* resourceObjects);
+
+ /** Determine the size of the page content and store to the catalog
+ * the offsets of all nonresource-indirect objects that make up the page
+ * content. This must be called before emitPage(), but after finalizePage.
+ * @param catalog The catalog to add the object offsets to.
+ * @param fileOffset The file offset where the page content will be
+ * emitted.
+ */
+ off_t getPageSize(SkPDFCatalog* catalog, off_t fileOffset);
+
+ /** Output the page content to the passed stream.
+ * @param stream The writable output stream to send the content to.
+ * @param catalog The active object catalog.
+ */
+ void emitPage(SkWStream* stream, SkPDFCatalog* catalog);
+
+ /** Generate a page tree for the passed vector of pages. New objects are
+ * added to the catalog. The pageTree vector is populated with all of
+ * the 'Pages' dictionaries as well as the 'Page' objects. Page trees
+ * have both parent and children links, creating reference cycles, so
+ * it must be torn down explicitly. The first page is not added to
+ * the pageTree dictionary array so the caller can handle it specially.
+ * @param pages The ordered vector of page objects.
+ * @param catalog The catalog to add new objects into.
+ * @param pageTree An output vector with all of the internal and leaf
+ * nodes of the pageTree.
+ * @param rootNode An output parameter set to the root node.
+ */
+ static void GeneratePageTree(const SkTDArray<SkPDFPage*>& pages,
+ SkPDFCatalog* catalog,
+ SkTDArray<SkPDFDict*>* pageTree,
+ SkPDFDict** rootNode);
+
+ /** Get the fonts used on this page.
+ */
+ SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
+
+ /** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
+ * that shows on this page.
+ */
+ const SkPDFGlyphSetMap& getFontGlyphUsage() const;
+
+private:
+ // Multiple pages may reference the content.
+ SkRefPtr<SkPDFDevice> fDevice;
+
+ // Once the content is finalized, put it into a stream for output.
+ SkRefPtr<SkPDFStream> fContentStream;
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFShader_DEFINED
+#define SkPDFShader_DEFINED
+
+#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
+#include "SkMatrix.h"
+#include "SkRefCnt.h"
+#include "SkShader.h"
+
+class SkObjRef;
+class SkPDFCatalog;
+
+/** \class SkPDFShader
+
+ In PDF parlance, this is a pattern, used in place of a color when the
+ pattern color space is selected.
+*/
+
+class SkPDFShader {
+public:
+ /** Get the PDF shader for the passed SkShader. If the SkShader is
+ * invalid in some way, returns NULL. The reference count of
+ * the object is incremented and it is the caller's responsibility to
+ * unreference it when done. This is needed to accommodate the weak
+ * reference pattern used when the returned object is new and has no
+ * other references.
+ * @param shader The SkShader to emulate.
+ * @param matrix The current transform. (PDF shaders are absolutely
+ * positioned, relative to where the page is drawn.)
+ * @param surfceBBox The bounding box of the drawing surface (with matrix
+ * already applied).
+ */
+ static SkPDFObject* GetPDFShader(const SkShader& shader,
+ const SkMatrix& matrix,
+ const SkIRect& surfaceBBox);
+
+protected:
+ class State;
+
+ class ShaderCanonicalEntry {
+ public:
+ ShaderCanonicalEntry(SkPDFObject* pdfShader, const State* state);
+ bool operator==(const ShaderCanonicalEntry& b) const;
+
+ SkPDFObject* fPDFShader;
+ const State* fState;
+ };
+ // This should be made a hash table if performance is a problem.
+ static SkTDArray<ShaderCanonicalEntry>& CanonicalShaders();
+ static SkBaseMutex& CanonicalShadersMutex();
+ static void RemoveShader(SkPDFObject* shader);
+
+ SkPDFShader();
+};
+
+#endif
--- /dev/null
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkPDFStream_DEFINED
+#define SkPDFStream_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+
+class SkPDFCatalog;
+
+/** \class SkPDFStream
+
+ A stream object in a PDF. Note, all streams must be indirect objects (via
+ SkObjRef).
+*/
+class SkPDFStream : public SkPDFDict {
+public:
+ /** Create a PDF stream. A Length entry is automatically added to the
+ * stream dictionary. The stream may be retained (stream->ref() may be
+ * called) so its contents must not be changed after calling this.
+ * @param data The data part of the stream.
+ */
+ explicit SkPDFStream(SkData* data);
+ /** Deprecated constructor. */
+ explicit SkPDFStream(SkStream* stream);
+ /** Create a PDF stream with the same content and dictionary entries
+ * as the passed one.
+ */
+ explicit SkPDFStream(const SkPDFStream& pdfStream);
+ virtual ~SkPDFStream();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+protected:
+ /* Create a PDF stream with no data. The setData method must be called to
+ * set the data.
+ */
+ SkPDFStream();
+
+ void setData(SkStream* stream);
+
+private:
+ enum State {
+ kUnused_State, //!< The stream hasn't been requested yet.
+ kNoCompression_State, //!< The stream's been requested in an
+ // uncompressed form.
+ kCompressed_State, //!< The stream's already been compressed.
+ };
+ // Indicates what form (or if) the stream has been requested.
+ State fState;
+
+ // TODO(vandebo): Use SkData (after removing deprecated constructor).
+ SkRefPtr<SkStream> fData;
+ SkRefPtr<SkPDFStream> fSubstitute;
+
+ typedef SkPDFDict INHERITED;
+
+ // Populate the stream dictionary. This method returns false if
+ // fSubstitute should be used.
+ bool populate(SkPDFCatalog* catalog);
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFTypes_DEFINED
+#define SkPDFTypes_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+#include "SkString.h"
+#include "SkTDArray.h"
+#include "SkTypes.h"
+
+class SkPDFCatalog;
+class SkWStream;
+
+/** \class SkPDFObject
+
+ A PDF Object is the base class for primitive elements in a PDF file. A
+ common subtype is used to ease the use of indirect object references,
+ which are common in the PDF format.
+*/
+class SkPDFObject : public SkRefCnt {
+public:
+ /** Create a PDF object.
+ */
+ SkPDFObject();
+ virtual ~SkPDFObject();
+
+ /** Return the size (number of bytes) of this object in the final output
+ * file. Compound objects or objects that are computationally intensive
+ * to output should override this method.
+ * @param catalog The object catalog to use.
+ * @param indirect If true, output an object identifier with the object.
+ */
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** For non-primitive objects (i.e. objects defined outside this file),
+ * this method will add to resourceList any objects that this method
+ * depends on. This operates recursively so if this object depends on
+ * another object and that object depends on two more, all three objects
+ * will be added.
+ * @param resourceList The list to append dependant resources to.
+ */
+ virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
+
+ /** Emit this object unless the catalog has a substitute object, in which
+ * case emit that.
+ * @see emitObject
+ */
+ void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect);
+
+ /** Helper function to output an indirect object.
+ * @param catalog The object catalog to use.
+ * @param stream The writable output stream to send the output to.
+ */
+ void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog);
+
+ /** Helper function to find the size of an indirect object.
+ * @param catalog The object catalog to use.
+ */
+ size_t getIndirectOutputSize(SkPDFCatalog* catalog);
+
+ /** Static helper function to add a resource to a list. The list takes
+ * a reference.
+ * @param resource The resource to add.
+ * @param list The list to add the resource to.
+ */
+ static void AddResourceHelper(SkPDFObject* resource,
+ SkTDArray<SkPDFObject*>* list);
+
+ /** Static helper function to copy and reference the resources (and all
+ * their subresources) into a new list.
+ * @param resources The resource list.
+ * @param result The list to add to.
+ */
+ static void GetResourcesHelper(SkTDArray<SkPDFObject*>* resources,
+ SkTDArray<SkPDFObject*>* result);
+
+protected:
+ /** Subclasses must implement this method to print the object to the
+ * PDF file.
+ * @param catalog The object catalog to use.
+ * @param indirect If true, output an object identifier with the object.
+ * @param stream The writable output stream to send the output to.
+ */
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect) = 0;
+};
+
+/** \class SkPDFObjRef
+
+ An indirect reference to a PDF object.
+*/
+class SkPDFObjRef : public SkPDFObject {
+public:
+ /** Create a reference to an existing SkPDFObject.
+ * @param obj The object to reference.
+ */
+ explicit SkPDFObjRef(SkPDFObject* obj);
+ virtual ~SkPDFObjRef();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ SkRefPtr<SkPDFObject> fObj;
+};
+
+/** \class SkPDFInt
+
+ An integer object in a PDF.
+*/
+class SkPDFInt : public SkPDFObject {
+public:
+ /** Create a PDF integer (usually for indirect reference purposes).
+ * @param value An integer value between 2^31 - 1 and -2^31.
+ */
+ explicit SkPDFInt(int32_t value);
+ virtual ~SkPDFInt();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+
+private:
+ int32_t fValue;
+};
+
+/** \class SkPDFBool
+
+ An boolean value in a PDF.
+*/
+class SkPDFBool : public SkPDFObject {
+public:
+ /** Create a PDF boolean.
+ * @param value true or false.
+ */
+ explicit SkPDFBool(bool value);
+ virtual ~SkPDFBool();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ bool fValue;
+};
+
+/** \class SkPDFScalar
+
+ A real number object in a PDF.
+*/
+class SkPDFScalar : public SkPDFObject {
+public:
+ /** Create a PDF real number.
+ * @param value A real value.
+ */
+ explicit SkPDFScalar(SkScalar value);
+ virtual ~SkPDFScalar();
+
+ static void Append(SkScalar value, SkWStream* stream);
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+
+private:
+ SkScalar fValue;
+};
+
+/** \class SkPDFString
+
+ A string object in a PDF.
+*/
+class SkPDFString : public SkPDFObject {
+public:
+ /** Create a PDF string. Maximum length (in bytes) is 65,535.
+ * @param value A string value.
+ */
+ explicit SkPDFString(const char value[]);
+ explicit SkPDFString(const SkString& value);
+
+ /** Create a PDF string. Maximum length (in bytes) is 65,535.
+ * @param value A string value.
+ * @param len The length of value.
+ * @param wideChars Indicates if the top byte in value is significant and
+ * should be encoded (true) or not (false).
+ */
+ SkPDFString(const uint16_t* value, size_t len, bool wideChars);
+ virtual ~SkPDFString();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ static SkString FormatString(const char* input, size_t len);
+ static SkString FormatString(const uint16_t* input, size_t len,
+ bool wideChars);
+private:
+ static const size_t kMaxLen = 65535;
+
+ const SkString fValue;
+
+ static SkString DoFormatString(const void* input, size_t len,
+ bool wideInput, bool wideOutput);
+};
+
+/** \class SkPDFName
+
+ A name object in a PDF.
+*/
+class SkPDFName : public SkPDFObject {
+public:
+ /** Create a PDF name object. Maximum length is 127 bytes.
+ * @param value The name.
+ */
+ explicit SkPDFName(const char name[]);
+ explicit SkPDFName(const SkString& name);
+ virtual ~SkPDFName();
+
+ bool operator==(const SkPDFName& b) const;
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+private:
+ static const size_t kMaxLen = 127;
+
+ const SkString fValue;
+
+ static SkString FormatName(const SkString& input);
+};
+
+/** \class SkPDFArray
+
+ An array object in a PDF.
+*/
+class SkPDFArray : public SkPDFObject {
+public:
+ /** Create a PDF array. Maximum length is 8191.
+ */
+ SkPDFArray();
+ virtual ~SkPDFArray();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** The size of the array.
+ */
+ int size() { return fValue.count(); }
+
+ /** Preallocate space for the given number of entries.
+ * @param length The number of array slots to preallocate.
+ */
+ void reserve(int length);
+
+ /** Returns the object at the given offset in the array.
+ * @param index The index into the array to retrieve.
+ */
+ SkPDFObject* getAt(int index) { return fValue[index]; }
+
+ /** Set the object at the given offset in the array. Ref's value.
+ * @param index The index into the array to set.
+ * @param value The value to add to the array.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* setAt(int index, SkPDFObject* value);
+
+ /** Append the object to the end of the array and increments its ref count.
+ * @param value The value to add to the array.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* append(SkPDFObject* value);
+
+ /** Creates a SkPDFInt object and appends it to the array.
+ * @param value The value to add to the array.
+ */
+ void appendInt(int32_t value);
+
+ /** Creates a SkPDFScalar object and appends it to the array.
+ * @param value The value to add to the array.
+ */
+ void appendScalar(SkScalar value);
+
+ /** Creates a SkPDFName object and appends it to the array.
+ * @param value The value to add to the array.
+ */
+ void appendName(const char name[]);
+
+private:
+ static const int kMaxLen = 8191;
+ SkTDArray<SkPDFObject*> fValue;
+};
+
+/** \class SkPDFDict
+
+ A dictionary object in a PDF.
+*/
+class SkPDFDict : public SkPDFObject {
+public:
+ /** Create a PDF dictionary. Maximum number of entries is 4095.
+ */
+ SkPDFDict();
+
+ /** Create a PDF dictionary with a Type entry.
+ * @param type The value of the Type entry.
+ */
+ explicit SkPDFDict(const char type[]);
+
+ virtual ~SkPDFDict();
+
+ // The SkPDFObject interface.
+ virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect);
+ virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
+
+ /** The size of the dictionary.
+ */
+ int size() { return fValue.count(); }
+
+ /** Add the value to the dictionary with the given key. Refs value.
+ * @param key The key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
+
+ /** Add the value to the dictionary with the given key. Refs value. The
+ * method will create the SkPDFName object.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The value for this dictionary entry.
+ * @return The value argument is returned.
+ */
+ SkPDFObject* insert(const char key[], SkPDFObject* value);
+
+ /** Add the int to the dictionary with the given key.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The int value for this dictionary entry.
+ */
+ void insertInt(const char key[], int32_t value);
+
+ /** Add the scalar to the dictionary with the given key.
+ * @param key The text of the key for this dictionary entry.
+ * @param value The scalar value for this dictionary entry.
+ */
+ void insertScalar(const char key[], SkScalar value);
+
+ /** Add the name to the dictionary with the given key.
+ * @param key The text of the key for this dictionary entry.
+ * @param name The name for this dictionary entry.
+ */
+ void insertName(const char key[], const char name[]);
+
+ /** Add the name to the dictionary with the given key.
+ * @param key The text of the key for this dictionary entry.
+ * @param name The name for this dictionary entry.
+ */
+ void insertName(const char key[], const SkString& name) {
+ this->insertName(key, name.c_str());
+ }
+
+ /** Remove all entries from the dictionary.
+ */
+ void clear();
+
+private:
+ struct Rec {
+ SkPDFName* key;
+ SkPDFObject* value;
+ };
+
+public:
+ class Iter {
+ public:
+ explicit Iter(const SkPDFDict& dict);
+ SkPDFName* next(SkPDFObject** value);
+
+ private:
+ Rec* fIter;
+ Rec* fStop;
+ };
+
+private:
+ static const int kMaxLen = 4095;
+
+ SkTDArray<struct Rec> fValue;
+};
+
+#endif
--- /dev/null
+
+/*
+ * 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 SkPDFUtils_DEFINED
+#define SkPDFUtils_DEFINED
+
+#include "SkPath.h"
+
+class SkMatrix;
+class SkPath;
+class SkPDFArray;
+struct SkRect;
+
+#if 0
+#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
+#else
+#define PRINT_NOT_IMPL(str)
+#endif
+
+#define NOT_IMPLEMENTED(condition, assert) \
+ do { \
+ if (condition) { \
+ PRINT_NOT_IMPL("NOT_IMPLEMENTED: " #condition "\n"); \
+ SkDEBUGCODE(SkASSERT(!assert);) \
+ } \
+ } while (0)
+
+class SkPDFUtils {
+public:
+ static SkPDFArray* MatrixToArray(const SkMatrix& matrix);
+ static void AppendTransform(const SkMatrix& matrix, SkWStream* content);
+
+ static void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
+ static void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
+ static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
+ SkScalar ctl2X, SkScalar ctl2Y,
+ SkScalar dstX, SkScalar dstY, SkWStream* content);
+ static void AppendRectangle(const SkRect& rect, SkWStream* content);
+ static void EmitPath(const SkPath& path, SkWStream* content);
+ static void ClosePath(SkWStream* content);
+ static void PaintPath(SkPaint::Style style, SkPath::FillType fill,
+ SkWStream* content);
+ static void StrokePath(SkWStream* content);
+ static void DrawFormXObject(int objectIndex, SkWStream* content);
+ static void ApplyGraphicState(int objectIndex, SkWStream* content);
+};
+
+#endif
+++ /dev/null
-
-/*
- * 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 SkBitSet_DEFINED
-#define SkBitSet_DEFINED
-
-#include "SkTypes.h"
-#include "SkTDArray.h"
-
-class SkBitSet {
-public:
- /** NumberOfBits must be greater than zero.
- */
- explicit SkBitSet(int numberOfBits);
- explicit SkBitSet(const SkBitSet& source);
-
- const SkBitSet& operator=(const SkBitSet& rhs);
- bool operator==(const SkBitSet& rhs);
- bool operator!=(const SkBitSet& rhs);
-
- /** Clear all data.
- */
- void clearAll();
-
- /** Set the value of the index-th bit.
- */
- void setBit(int index, bool value);
-
- /** Test if bit index is set.
- */
- bool isBitSet(int index) const;
-
- /** Or bits from source. false is returned if this doesn't have the same
- * bit count as source.
- */
- bool orBits(const SkBitSet& source);
-
- /** Export indices of set bits to T array.
- */
- template<typename T>
- void exportTo(SkTDArray<T>* array) const {
- SkASSERT(array);
- uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
- for (unsigned int i = 0; i < fDwordCount; ++i) {
- uint32_t value = data[i];
- if (value) { // There are set bits
- unsigned int index = i * 32;
- for (unsigned int j = 0; j < 32; ++j) {
- if (0x1 & (value >> j)) {
- array->push(index + j);
- }
- }
- }
- }
- }
-
-private:
- SkAutoFree fBitData;
- // Dword (32-bit) count of the bitset.
- size_t fDwordCount;
- size_t fBitCount;
-
- uint32_t* internalGet(int index) const {
- SkASSERT((size_t)index < fBitCount);
- size_t internalIndex = index / 32;
- SkASSERT(internalIndex < fDwordCount);
- return reinterpret_cast<uint32_t*>(fBitData.get()) + internalIndex;
- }
-};
-
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFCatalog_DEFINED
-#define SkPDFCatalog_DEFINED
-
-#include <sys/types.h>
-
-#include "SkPDFDocument.h"
-#include "SkPDFTypes.h"
-#include "SkRefCnt.h"
-#include "SkTDArray.h"
-
-/** \class SkPDFCatalog
-
- The PDF catalog manages object numbers and file offsets. It is used
- to create the PDF cross reference table.
-*/
-class SkPDFCatalog {
-public:
- /** Create a PDF catalog.
- */
- explicit SkPDFCatalog(SkPDFDocument::Flags flags);
- ~SkPDFCatalog();
-
- /** Add the passed object to the catalog. Refs obj.
- * @param obj The object to add.
- * @param onFirstPage Is the object on the first page.
- * @return The obj argument is returned.
- */
- SkPDFObject* addObject(SkPDFObject* obj, bool onFirstPage);
-
- /** Inform the catalog of the object's position in the final stream.
- * The object should already have been added to the catalog. Returns
- * the object's size.
- * @param obj The object to add.
- * @param offset The byte offset in the output stream of this object.
- */
- size_t setFileOffset(SkPDFObject* obj, size_t offset);
-
- /** Output the object number for the passed object.
- * @param obj The object of interest.
- * @param stream The writable output stream to send the output to.
- */
- void emitObjectNumber(SkWStream* stream, SkPDFObject* obj);
-
- /** Return the number of bytes that would be emitted for the passed
- * object's object number.
- * @param obj The object of interest
- */
- size_t getObjectNumberSize(SkPDFObject* obj);
-
- /** Return the document flags in effect for this catalog/document.
- */
- SkPDFDocument::Flags getDocumentFlags() const { return fDocumentFlags; }
-
- /** Output the cross reference table for objects in the catalog.
- * Returns the total number of objects.
- * @param stream The writable output stream to send the output to.
- * @param firstPage If true, include first page objects only, otherwise
- * include all objects not on the first page.
- */
- int32_t emitXrefTable(SkWStream* stream, bool firstPage);
-
- /** Set substitute object for the passed object.
- */
- void setSubstitute(SkPDFObject* original, SkPDFObject* substitute);
-
- /** Find and return any substitute object set for the passed object. If
- * there is none, return the passed object.
- */
- SkPDFObject* getSubstituteObject(SkPDFObject* object);
-
- /** Set file offsets for the resources of substitute objects.
- * @param fileOffset Accumulated offset of current document.
- * @param firstPage Indicate whether this is for the first page only.
- * @return Total size of resources of substitute objects.
- */
- off_t setSubstituteResourcesOffsets(off_t fileOffset, bool firstPage);
-
- /** Emit the resources of substitute objects.
- */
- void emitSubstituteResources(SkWStream* stream, bool firstPage);
-
-private:
- struct Rec {
- Rec(SkPDFObject* object, bool onFirstPage)
- : fObject(object),
- fFileOffset(0),
- fObjNumAssigned(false),
- fOnFirstPage(onFirstPage) {
- }
- SkPDFObject* fObject;
- off_t fFileOffset;
- bool fObjNumAssigned;
- bool fOnFirstPage;
- };
-
- struct SubstituteMapping {
- SubstituteMapping(SkPDFObject* original, SkPDFObject* substitute)
- : fOriginal(original), fSubstitute(substitute) {
- }
- SkPDFObject* fOriginal;
- SkPDFObject* fSubstitute;
- };
-
- // TODO(vandebo): Make this a hash if it's a performance problem.
- SkTDArray<struct Rec> fCatalog;
-
- // TODO(arthurhsu): Make this a hash if it's a performance problem.
- SkTDArray<SubstituteMapping> fSubstituteMap;
- SkTDArray<SkPDFObject*> fSubstituteResourcesFirstPage;
- SkTDArray<SkPDFObject*> fSubstituteResourcesRemaining;
-
- // Number of objects on the first page.
- uint32_t fFirstPageCount;
- // Next object number to assign (on page > 1).
- uint32_t fNextObjNum;
- // Next object number to assign on the first page.
- uint32_t fNextFirstPageObjNum;
-
- SkPDFDocument::Flags fDocumentFlags;
-
- int findObjectIndex(SkPDFObject* obj) const;
-
- int assignObjNum(SkPDFObject* obj);
-
- SkTDArray<SkPDFObject*>* getSubstituteList(bool firstPage);
-};
-
-#endif
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
-#include "SkPDFFont.h"
#include "SkPDFPage.h"
-#include "SkPDFTypes.h"
+#include "SkPDFFont.h"
#include "SkStream.h"
// Add the resources, starting at firstIndex to the catalog, removing any dupes.
return true;
}
-void SkPDFDocument::getCountOfFontTypes(
- int counts[SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1]) const {
- memset(counts, 0,
- sizeof(int)* SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1);
- SkTDArray<SkFontID> seenFonts;
-
- for (int pageNumber = 0; pageNumber < fPages.count(); pageNumber++) {
- const SkTDArray<SkPDFFont*>& fontResources =
- fPages[pageNumber]->getFontResources();
- for (int font = 0; font < fontResources.count(); font++) {
- SkFontID fontID = fontResources[font]->typeface()->uniqueID();
- if (seenFonts.find(fontID) != -1) {
- counts[fontResources[font]->getType()]++;
- seenFonts.push(fontID);
- }
- }
- }
+const SkTDArray<SkPDFPage*>& SkPDFDocument::getPages() {
+ return fPages;
}
void SkPDFDocument::emitHeader(SkWStream* stream) {
+++ /dev/null
-
-/*
- * 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 SkPDFFont_DEFINED
-#define SkPDFFont_DEFINED
-
-#include "SkAdvancedTypefaceMetrics.h"
-#include "SkBitSet.h"
-#include "SkPDFTypes.h"
-#include "SkTDArray.h"
-#include "SkThread.h"
-#include "SkTypeface.h"
-
-class SkPaint;
-class SkPDFCatalog;
-class SkPDFFont;
-
-class SkPDFGlyphSet : public SkNoncopyable {
-public:
- SkPDFGlyphSet();
-
- void set(const uint16_t* glyphIDs, int numGlyphs);
- bool has(uint16_t glyphID) const;
- void merge(const SkPDFGlyphSet& usage);
- void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
-
-private:
- SkBitSet fBitSet;
-};
-
-class SkPDFGlyphSetMap : public SkNoncopyable {
-public:
- struct FontGlyphSetPair {
- FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
-
- SkPDFFont* fFont;
- SkPDFGlyphSet* fGlyphSet;
- };
-
- SkPDFGlyphSetMap();
- ~SkPDFGlyphSetMap();
-
- class F2BIter {
- public:
- explicit F2BIter(const SkPDFGlyphSetMap& map);
- FontGlyphSetPair* next() const;
- void reset(const SkPDFGlyphSetMap& map);
-
- private:
- const SkTDArray<FontGlyphSetPair>* fMap;
- mutable int fIndex;
- };
-
- void merge(const SkPDFGlyphSetMap& usage);
- void reset();
-
- void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
- int numGlyphs);
-
-private:
- SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
-
- SkTDArray<FontGlyphSetPair> fMap;
-};
-
-
-/** \class SkPDFFont
- A PDF Object class representing a font. The font may have resources
- attached to it in order to embed the font. SkPDFFonts are canonicalized
- so that resource deduplication will only include one copy of a font.
- This class uses the same pattern as SkPDFGraphicState, a static weak
- reference to each instantiated class.
-*/
-class SkPDFFont : public SkPDFDict {
-public:
- virtual ~SkPDFFont();
-
- virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
-
- /** Returns the typeface represented by this class. Returns NULL for the
- * default typeface.
- */
- SkTypeface* typeface();
-
- /** Returns the font type represented in this font. For Type0 fonts,
- * returns the type of the decendant font.
- */
- virtual SkAdvancedTypefaceMetrics::FontType getType();
-
- /** Returns true if this font encoding supports glyph IDs above 255.
- */
- virtual bool multiByteGlyphs() const = 0;
-
- /** Return true if this font has an encoding for the passed glyph id.
- */
- bool hasGlyph(uint16_t glyphID);
-
- /** Convert (in place) the input glyph IDs into the font encoding. If the
- * font has more glyphs than can be encoded (like a type 1 font with more
- * than 255 glyphs) this method only converts up to the first out of range
- * glyph ID.
- * @param glyphIDs The input text as glyph IDs.
- * @param numGlyphs The number of input glyphs.
- * @return Returns the number of glyphs consumed.
- */
- size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
-
- /** Get the font resource for the passed typeface and glyphID. The
- * reference count of the object is incremented and it is the caller's
- * responsibility to unreference it when done. This is needed to
- * accommodate the weak reference pattern used when the returned object
- * is new and has no other references.
- * @param typeface The typeface to find.
- * @param glyphID Specify which section of a large font is of interest.
- */
- static SkPDFFont* GetFontResource(SkTypeface* typeface,
- uint16_t glyphID);
-
- /** Subset the font based on usage set. Returns a SkPDFFont instance with
- * subset.
- * @param usage Glyph subset requested.
- * @return NULL if font does not support subsetting, a new instance
- * of SkPDFFont otherwise.
- */
- virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
-
-protected:
- // Common constructor to handle common members.
- SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
- uint16_t glyphID, bool descendantFont);
-
- // Accessors for subclass.
- SkAdvancedTypefaceMetrics* fontInfo();
- void setFontInfo(SkAdvancedTypefaceMetrics* info);
- uint16_t firstGlyphID() const;
- uint16_t lastGlyphID() const;
- void setLastGlyphID(uint16_t glyphID);
-
- // Add object to resource list.
- void addResource(SkPDFObject* object);
-
- // Accessors for FontDescriptor associated with this object.
- SkPDFDict* getFontDescriptor();
- void setFontDescriptor(SkPDFDict* descriptor);
-
- // Add common entries to FontDescriptor.
- bool addCommonFontDescriptorEntries(int16_t defaultWidth);
-
- /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
- * including the passed glyphID.
- */
- void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
-
- // Generate ToUnicode table according to glyph usage subset.
- // If subset is NULL, all available glyph ids will be used.
- void populateToUnicodeTable(const SkPDFGlyphSet* subset);
-
- // Create instances of derived types based on fontInfo.
- static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
- SkTypeface* typeface, uint16_t glyphID,
- SkPDFDict* fontDescriptor);
-
- static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
-
-private:
- class FontRec {
- public:
- SkPDFFont* fFont;
- uint32_t fFontID;
- uint16_t fGlyphID;
-
- // A fGlyphID of 0 with no fFont always matches.
- bool operator==(const FontRec& b) const;
- FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
- };
-
- SkRefPtr<SkTypeface> fTypeface;
-
- // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
- // this will be a subset if the font has more than 255 glyphs.
- uint16_t fFirstGlyphID;
- uint16_t fLastGlyphID;
- // The font info is only kept around after construction for large
- // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
- SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
- SkTDArray<SkPDFObject*> fResources;
- SkRefPtr<SkPDFDict> fDescriptor;
-
- SkAdvancedTypefaceMetrics::FontType fFontType;
-
- // This should be made a hash table if performance is a problem.
- static SkTDArray<FontRec>& CanonicalFonts();
- static SkBaseMutex& CanonicalFontsMutex();
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFFormXObject_DEFINED
-#define SkPDFFormXObject_DEFINED
-
-#include "SkPDFStream.h"
-#include "SkPDFTypes.h"
-#include "SkRefCnt.h"
-#include "SkString.h"
-
-class SkMatrix;
-class SkPDFDevice;
-class SkPDFCatalog;
-
-/** \class SkPDFFormXObject
-
- A form XObject; a self contained description of graphics objects. A form
- XObject is basically a page object with slightly different syntax, that
- can be drawn onto a page.
-*/
-
-// The caller could keep track of the form XObjects it creates and
-// canonicalize them, but the Skia API doesn't provide enough context to
-// automatically do it (trivially).
-class SkPDFFormXObject : public SkPDFStream {
-public:
- /** Create a PDF form XObject. Entries for the dictionary entries are
- * automatically added.
- * @param device The set of graphical elements on this form.
- */
- explicit SkPDFFormXObject(SkPDFDevice* device);
- virtual ~SkPDFFormXObject();
-
- // The SkPDFObject interface.
- virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
-
-private:
- SkTDArray<SkPDFObject*> fResources;
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFGraphicState_DEFINED
-#define SkPDFGraphicState_DEFINED
-
-#include "SkPaint.h"
-#include "SkPDFTypes.h"
-#include "SkTemplates.h"
-#include "SkThread.h"
-
-class SkPDFFormXObject;
-
-/** \class SkPDFGraphicState
- SkPaint objects roughly correspond to graphic state dictionaries that can
- be installed. So that a given dictionary is only output to the pdf file
- once, we want to canonicalize them. Static methods in this class manage
- a weakly referenced set of SkPDFGraphicState objects: when the last
- reference to a SkPDFGraphicState is removed, it removes itself from the
- static set of objects.
-
-*/
-class SkPDFGraphicState : public SkPDFDict {
-public:
- virtual ~SkPDFGraphicState();
-
- virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
-
- // Override emitObject and getOutputSize so that we can populate
- // the dictionary on demand.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
- /** Get the graphic state for the passed SkPaint. The reference count of
- * the object is incremented and it is the caller's responsibility to
- * unreference it when done. This is needed to accommodate the weak
- * reference pattern used when the returned object is new and has no
- * other references.
- * @param paint The SkPaint to emulate.
- */
- static SkPDFGraphicState* GetGraphicStateForPaint(const SkPaint& paint);
-
- /** Make a graphic state that only sets the passed soft mask. The
- * reference count of the object is incremented and it is the caller's
- * responsibility to unreference it when done.
- * @param sMask The form xobject to use as a soft mask.
- * @param invert Indicates if the alpha of the sMask should be inverted.
- */
- static SkPDFGraphicState* GetSMaskGraphicState(SkPDFFormXObject* sMask,
- bool invert);
-
- /** Get a graphic state that only unsets the soft mask. The reference
- * count of the object is incremented and it is the caller's responsibility
- * to unreference it when done. This is needed to accommodate the weak
- * reference pattern used when the returned object is new and has no
- * other references.
- */
- static SkPDFGraphicState* GetNoSMaskGraphicState();
-
-private:
- const SkPaint fPaint;
- SkTDArray<SkPDFObject*> fResources;
- bool fPopulated;
- bool fSMask;
-
- class GSCanonicalEntry {
- public:
- SkPDFGraphicState* fGraphicState;
- const SkPaint* fPaint;
-
- bool operator==(const GSCanonicalEntry& b) const;
- explicit GSCanonicalEntry(SkPDFGraphicState* gs)
- : fGraphicState(gs),
- fPaint(&gs->fPaint) {}
- explicit GSCanonicalEntry(const SkPaint* paint)
- : fGraphicState(NULL),
- fPaint(paint) {}
- };
-
- // This should be made a hash table if performance is a problem.
- static SkTDArray<GSCanonicalEntry>& CanonicalPaints();
- static SkBaseMutex& CanonicalPaintsMutex();
-
- SkPDFGraphicState();
- explicit SkPDFGraphicState(const SkPaint& paint);
-
- void populateDict();
-
- static SkPDFObject* GetInvertFunction();
-
- static int Find(const SkPaint& paint);
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFImage_DEFINED
-#define SkPDFImage_DEFINED
-
-#include "SkPDFStream.h"
-#include "SkPDFTypes.h"
-#include "SkRefCnt.h"
-
-class SkBitmap;
-class SkPaint;
-class SkPDFCatalog;
-struct SkIRect;
-
-/** \class SkPDFImage
-
- An image XObject.
-*/
-
-// We could play the same trick here as is done in SkPDFGraphicState, storing
-// a copy of the Bitmap object (not the pixels), the pixel generation number,
-// and settings used from the paint to canonicalize image objects.
-class SkPDFImage : public SkPDFStream {
-public:
- /** Create a new Image XObject to represent the passed bitmap.
- * @param bitmap The image to encode.
- * @param srcRect The rectangle to cut out of bitmap.
- * @param paint Used to calculate alpha, masks, etc.
- * @return The image XObject or NUll if there is nothing to draw for
- * the given parameters.
- */
- static SkPDFImage* CreateImage(const SkBitmap& bitmap,
- const SkIRect& srcRect,
- const SkPaint& paint);
-
- virtual ~SkPDFImage();
-
- /** Add a Soft Mask (alpha or shape channel) to the image. Refs mask.
- * @param mask A gray scale image representing the mask.
- * @return The mask argument is returned.
- */
- SkPDFImage* addSMask(SkPDFImage* mask);
-
- // The SkPDFObject interface.
- virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
-
-private:
- SkTDArray<SkPDFObject*> fResources;
-
- /** Create a PDF image XObject. Entries for the image properties are
- * automatically added to the stream dictionary.
- * @param imageData The final raw bits representing the image.
- * @param bitmap The image parameters to use (Config, etc).
- * @param srcRect The clipping applied to bitmap before generating
- * imageData.
- * @param alpha Is this the alpha channel of the bitmap.
- * @param paint Used to calculate alpha, masks, etc.
- */
- SkPDFImage(SkStream* imageData, const SkBitmap& bitmap,
- const SkIRect& srcRect, bool alpha, const SkPaint& paint);
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFPage_DEFINED
-#define SkPDFPage_DEFINED
-
-#include "SkPDFTypes.h"
-#include "SkPDFStream.h"
-#include "SkRefCnt.h"
-#include "SkTDArray.h"
-
-class SkPDFCatalog;
-class SkPDFDevice;
-class SkWStream;
-
-/** \class SkPDFPage
-
- A SkPDFPage contains meta information about a page, is used in the page
- tree and points to the content of the page.
-*/
-class SkPDFPage : public SkPDFDict {
-public:
- /** Create a PDF page with the passed PDF device. The device need not
- * have content on it yet.
- * @param content The page content.
- */
- explicit SkPDFPage(SkPDFDevice* content);
- ~SkPDFPage();
-
- /** Before a page and its contents can be sized and emitted, it must
- * be finalized. No changes to the PDFDevice will be honored after
- * finalizePage has been called. This function adds the page content
- * to the passed catalog, so it must be called for each document
- * that the page is part of.
- * @param catalog The catalog to add page content objects to.
- * @param firstPage Indicate if this is the first page of a document.
- * @param resourceObjects All the resource objects (recursively) used on
- * the page are added to this array. This gives
- * the caller a chance to deduplicate resources
- * across pages.
- */
- void finalizePage(SkPDFCatalog* catalog, bool firstPage,
- SkTDArray<SkPDFObject*>* resourceObjects);
-
- /** Determine the size of the page content and store to the catalog
- * the offsets of all nonresource-indirect objects that make up the page
- * content. This must be called before emitPage(), but after finalizePage.
- * @param catalog The catalog to add the object offsets to.
- * @param fileOffset The file offset where the page content will be
- * emitted.
- */
- off_t getPageSize(SkPDFCatalog* catalog, off_t fileOffset);
-
- /** Output the page content to the passed stream.
- * @param stream The writable output stream to send the content to.
- * @param catalog The active object catalog.
- */
- void emitPage(SkWStream* stream, SkPDFCatalog* catalog);
-
- /** Generate a page tree for the passed vector of pages. New objects are
- * added to the catalog. The pageTree vector is populated with all of
- * the 'Pages' dictionaries as well as the 'Page' objects. Page trees
- * have both parent and children links, creating reference cycles, so
- * it must be torn down explicitly. The first page is not added to
- * the pageTree dictionary array so the caller can handle it specially.
- * @param pages The ordered vector of page objects.
- * @param catalog The catalog to add new objects into.
- * @param pageTree An output vector with all of the internal and leaf
- * nodes of the pageTree.
- * @param rootNode An output parameter set to the root node.
- */
- static void GeneratePageTree(const SkTDArray<SkPDFPage*>& pages,
- SkPDFCatalog* catalog,
- SkTDArray<SkPDFDict*>* pageTree,
- SkPDFDict** rootNode);
-
- /** Get the fonts used on this page.
- */
- const SkTDArray<SkPDFFont*>& getFontResources() const;
-
- /** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
- * that shows on this page.
- */
- const SkPDFGlyphSetMap& getFontGlyphUsage() const;
-
-private:
- // Multiple pages may reference the content.
- SkRefPtr<SkPDFDevice> fDevice;
-
- // Once the content is finalized, put it into a stream for output.
- SkRefPtr<SkPDFStream> fContentStream;
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFShader_DEFINED
-#define SkPDFShader_DEFINED
-
-#include "SkPDFStream.h"
-#include "SkPDFTypes.h"
-#include "SkMatrix.h"
-#include "SkRefCnt.h"
-#include "SkShader.h"
-
-class SkObjRef;
-class SkPDFCatalog;
-
-/** \class SkPDFShader
-
- In PDF parlance, this is a pattern, used in place of a color when the
- pattern color space is selected.
-*/
-
-class SkPDFShader {
-public:
- /** Get the PDF shader for the passed SkShader. If the SkShader is
- * invalid in some way, returns NULL. The reference count of
- * the object is incremented and it is the caller's responsibility to
- * unreference it when done. This is needed to accommodate the weak
- * reference pattern used when the returned object is new and has no
- * other references.
- * @param shader The SkShader to emulate.
- * @param matrix The current transform. (PDF shaders are absolutely
- * positioned, relative to where the page is drawn.)
- * @param surfceBBox The bounding box of the drawing surface (with matrix
- * already applied).
- */
- static SkPDFObject* GetPDFShader(const SkShader& shader,
- const SkMatrix& matrix,
- const SkIRect& surfaceBBox);
-
-protected:
- class State;
-
- class ShaderCanonicalEntry {
- public:
- ShaderCanonicalEntry(SkPDFObject* pdfShader, const State* state);
- bool operator==(const ShaderCanonicalEntry& b) const;
-
- SkPDFObject* fPDFShader;
- const State* fState;
- };
- // This should be made a hash table if performance is a problem.
- static SkTDArray<ShaderCanonicalEntry>& CanonicalShaders();
- static SkBaseMutex& CanonicalShadersMutex();
- static void RemoveShader(SkPDFObject* shader);
-
- SkPDFShader();
-};
-
-#endif
+++ /dev/null
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkPDFStream_DEFINED
-#define SkPDFStream_DEFINED
-
-#include "SkPDFTypes.h"
-#include "SkRefCnt.h"
-#include "SkStream.h"
-#include "SkTemplates.h"
-
-class SkPDFCatalog;
-
-/** \class SkPDFStream
-
- A stream object in a PDF. Note, all streams must be indirect objects (via
- SkObjRef).
-*/
-class SkPDFStream : public SkPDFDict {
-public:
- /** Create a PDF stream. A Length entry is automatically added to the
- * stream dictionary. The stream may be retained (stream->ref() may be
- * called) so its contents must not be changed after calling this.
- * @param data The data part of the stream.
- */
- explicit SkPDFStream(SkData* data);
- /** Deprecated constructor. */
- explicit SkPDFStream(SkStream* stream);
- /** Create a PDF stream with the same content and dictionary entries
- * as the passed one.
- */
- explicit SkPDFStream(const SkPDFStream& pdfStream);
- virtual ~SkPDFStream();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
-protected:
- /* Create a PDF stream with no data. The setData method must be called to
- * set the data.
- */
- SkPDFStream();
-
- void setData(SkStream* stream);
-
-private:
- enum State {
- kUnused_State, //!< The stream hasn't been requested yet.
- kNoCompression_State, //!< The stream's been requested in an
- // uncompressed form.
- kCompressed_State, //!< The stream's already been compressed.
- };
- // Indicates what form (or if) the stream has been requested.
- State fState;
-
- // TODO(vandebo): Use SkData (after removing deprecated constructor).
- SkRefPtr<SkStream> fData;
- SkRefPtr<SkPDFStream> fSubstitute;
-
- typedef SkPDFDict INHERITED;
-
- // Populate the stream dictionary. This method returns false if
- // fSubstitute should be used.
- bool populate(SkPDFCatalog* catalog);
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFTypes_DEFINED
-#define SkPDFTypes_DEFINED
-
-#include "SkRefCnt.h"
-#include "SkScalar.h"
-#include "SkString.h"
-#include "SkTDArray.h"
-#include "SkTypes.h"
-
-class SkPDFCatalog;
-class SkWStream;
-
-/** \class SkPDFObject
-
- A PDF Object is the base class for primitive elements in a PDF file. A
- common subtype is used to ease the use of indirect object references,
- which are common in the PDF format.
-*/
-class SkPDFObject : public SkRefCnt {
-public:
- /** Create a PDF object.
- */
- SkPDFObject();
- virtual ~SkPDFObject();
-
- /** Return the size (number of bytes) of this object in the final output
- * file. Compound objects or objects that are computationally intensive
- * to output should override this method.
- * @param catalog The object catalog to use.
- * @param indirect If true, output an object identifier with the object.
- */
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
- /** For non-primitive objects (i.e. objects defined outside this file),
- * this method will add to resourceList any objects that this method
- * depends on. This operates recursively so if this object depends on
- * another object and that object depends on two more, all three objects
- * will be added.
- * @param resourceList The list to append dependant resources to.
- */
- virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
-
- /** Emit this object unless the catalog has a substitute object, in which
- * case emit that.
- * @see emitObject
- */
- void emit(SkWStream* stream, SkPDFCatalog* catalog, bool indirect);
-
- /** Helper function to output an indirect object.
- * @param catalog The object catalog to use.
- * @param stream The writable output stream to send the output to.
- */
- void emitIndirectObject(SkWStream* stream, SkPDFCatalog* catalog);
-
- /** Helper function to find the size of an indirect object.
- * @param catalog The object catalog to use.
- */
- size_t getIndirectOutputSize(SkPDFCatalog* catalog);
-
- /** Static helper function to add a resource to a list. The list takes
- * a reference.
- * @param resource The resource to add.
- * @param list The list to add the resource to.
- */
- static void AddResourceHelper(SkPDFObject* resource,
- SkTDArray<SkPDFObject*>* list);
-
- /** Static helper function to copy and reference the resources (and all
- * their subresources) into a new list.
- * @param resources The resource list.
- * @param result The list to add to.
- */
- static void GetResourcesHelper(SkTDArray<SkPDFObject*>* resources,
- SkTDArray<SkPDFObject*>* result);
-
-protected:
- /** Subclasses must implement this method to print the object to the
- * PDF file.
- * @param catalog The object catalog to use.
- * @param indirect If true, output an object identifier with the object.
- * @param stream The writable output stream to send the output to.
- */
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect) = 0;
-};
-
-/** \class SkPDFObjRef
-
- An indirect reference to a PDF object.
-*/
-class SkPDFObjRef : public SkPDFObject {
-public:
- /** Create a reference to an existing SkPDFObject.
- * @param obj The object to reference.
- */
- explicit SkPDFObjRef(SkPDFObject* obj);
- virtual ~SkPDFObjRef();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
-private:
- SkRefPtr<SkPDFObject> fObj;
-};
-
-/** \class SkPDFInt
-
- An integer object in a PDF.
-*/
-class SkPDFInt : public SkPDFObject {
-public:
- /** Create a PDF integer (usually for indirect reference purposes).
- * @param value An integer value between 2^31 - 1 and -2^31.
- */
- explicit SkPDFInt(int32_t value);
- virtual ~SkPDFInt();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
-
-private:
- int32_t fValue;
-};
-
-/** \class SkPDFBool
-
- An boolean value in a PDF.
-*/
-class SkPDFBool : public SkPDFObject {
-public:
- /** Create a PDF boolean.
- * @param value true or false.
- */
- explicit SkPDFBool(bool value);
- virtual ~SkPDFBool();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
-private:
- bool fValue;
-};
-
-/** \class SkPDFScalar
-
- A real number object in a PDF.
-*/
-class SkPDFScalar : public SkPDFObject {
-public:
- /** Create a PDF real number.
- * @param value A real value.
- */
- explicit SkPDFScalar(SkScalar value);
- virtual ~SkPDFScalar();
-
- static void Append(SkScalar value, SkWStream* stream);
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
-
-private:
- SkScalar fValue;
-};
-
-/** \class SkPDFString
-
- A string object in a PDF.
-*/
-class SkPDFString : public SkPDFObject {
-public:
- /** Create a PDF string. Maximum length (in bytes) is 65,535.
- * @param value A string value.
- */
- explicit SkPDFString(const char value[]);
- explicit SkPDFString(const SkString& value);
-
- /** Create a PDF string. Maximum length (in bytes) is 65,535.
- * @param value A string value.
- * @param len The length of value.
- * @param wideChars Indicates if the top byte in value is significant and
- * should be encoded (true) or not (false).
- */
- SkPDFString(const uint16_t* value, size_t len, bool wideChars);
- virtual ~SkPDFString();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
- static SkString FormatString(const char* input, size_t len);
- static SkString FormatString(const uint16_t* input, size_t len,
- bool wideChars);
-private:
- static const size_t kMaxLen = 65535;
-
- const SkString fValue;
-
- static SkString DoFormatString(const void* input, size_t len,
- bool wideInput, bool wideOutput);
-};
-
-/** \class SkPDFName
-
- A name object in a PDF.
-*/
-class SkPDFName : public SkPDFObject {
-public:
- /** Create a PDF name object. Maximum length is 127 bytes.
- * @param value The name.
- */
- explicit SkPDFName(const char name[]);
- explicit SkPDFName(const SkString& name);
- virtual ~SkPDFName();
-
- bool operator==(const SkPDFName& b) const;
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
-private:
- static const size_t kMaxLen = 127;
-
- const SkString fValue;
-
- static SkString FormatName(const SkString& input);
-};
-
-/** \class SkPDFArray
-
- An array object in a PDF.
-*/
-class SkPDFArray : public SkPDFObject {
-public:
- /** Create a PDF array. Maximum length is 8191.
- */
- SkPDFArray();
- virtual ~SkPDFArray();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
- /** The size of the array.
- */
- int size() { return fValue.count(); }
-
- /** Preallocate space for the given number of entries.
- * @param length The number of array slots to preallocate.
- */
- void reserve(int length);
-
- /** Returns the object at the given offset in the array.
- * @param index The index into the array to retrieve.
- */
- SkPDFObject* getAt(int index) { return fValue[index]; }
-
- /** Set the object at the given offset in the array. Ref's value.
- * @param index The index into the array to set.
- * @param value The value to add to the array.
- * @return The value argument is returned.
- */
- SkPDFObject* setAt(int index, SkPDFObject* value);
-
- /** Append the object to the end of the array and increments its ref count.
- * @param value The value to add to the array.
- * @return The value argument is returned.
- */
- SkPDFObject* append(SkPDFObject* value);
-
- /** Creates a SkPDFInt object and appends it to the array.
- * @param value The value to add to the array.
- */
- void appendInt(int32_t value);
-
- /** Creates a SkPDFScalar object and appends it to the array.
- * @param value The value to add to the array.
- */
- void appendScalar(SkScalar value);
-
- /** Creates a SkPDFName object and appends it to the array.
- * @param value The value to add to the array.
- */
- void appendName(const char name[]);
-
-private:
- static const int kMaxLen = 8191;
- SkTDArray<SkPDFObject*> fValue;
-};
-
-/** \class SkPDFDict
-
- A dictionary object in a PDF.
-*/
-class SkPDFDict : public SkPDFObject {
-public:
- /** Create a PDF dictionary. Maximum number of entries is 4095.
- */
- SkPDFDict();
-
- /** Create a PDF dictionary with a Type entry.
- * @param type The value of the Type entry.
- */
- explicit SkPDFDict(const char type[]);
-
- virtual ~SkPDFDict();
-
- // The SkPDFObject interface.
- virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
- bool indirect);
- virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
-
- /** The size of the dictionary.
- */
- int size() { return fValue.count(); }
-
- /** Add the value to the dictionary with the given key. Refs value.
- * @param key The key for this dictionary entry.
- * @param value The value for this dictionary entry.
- * @return The value argument is returned.
- */
- SkPDFObject* insert(SkPDFName* key, SkPDFObject* value);
-
- /** Add the value to the dictionary with the given key. Refs value. The
- * method will create the SkPDFName object.
- * @param key The text of the key for this dictionary entry.
- * @param value The value for this dictionary entry.
- * @return The value argument is returned.
- */
- SkPDFObject* insert(const char key[], SkPDFObject* value);
-
- /** Add the int to the dictionary with the given key.
- * @param key The text of the key for this dictionary entry.
- * @param value The int value for this dictionary entry.
- */
- void insertInt(const char key[], int32_t value);
-
- /** Add the scalar to the dictionary with the given key.
- * @param key The text of the key for this dictionary entry.
- * @param value The scalar value for this dictionary entry.
- */
- void insertScalar(const char key[], SkScalar value);
-
- /** Add the name to the dictionary with the given key.
- * @param key The text of the key for this dictionary entry.
- * @param name The name for this dictionary entry.
- */
- void insertName(const char key[], const char name[]);
-
- /** Add the name to the dictionary with the given key.
- * @param key The text of the key for this dictionary entry.
- * @param name The name for this dictionary entry.
- */
- void insertName(const char key[], const SkString& name) {
- this->insertName(key, name.c_str());
- }
-
- /** Remove all entries from the dictionary.
- */
- void clear();
-
-private:
- struct Rec {
- SkPDFName* key;
- SkPDFObject* value;
- };
-
-public:
- class Iter {
- public:
- explicit Iter(const SkPDFDict& dict);
- SkPDFName* next(SkPDFObject** value);
-
- private:
- Rec* fIter;
- Rec* fStop;
- };
-
-private:
- static const int kMaxLen = 4095;
-
- SkTDArray<struct Rec> fValue;
-};
-
-#endif
+++ /dev/null
-
-/*
- * 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 SkPDFUtils_DEFINED
-#define SkPDFUtils_DEFINED
-
-#include "SkPath.h"
-
-class SkMatrix;
-class SkPath;
-class SkPDFArray;
-struct SkRect;
-
-#if 0
-#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
-#else
-#define PRINT_NOT_IMPL(str)
-#endif
-
-#define NOT_IMPLEMENTED(condition, assert) \
- do { \
- if (condition) { \
- PRINT_NOT_IMPL("NOT_IMPLEMENTED: " #condition "\n"); \
- SkDEBUGCODE(SkASSERT(!assert);) \
- } \
- } while (0)
-
-class SkPDFUtils {
-public:
- static SkPDFArray* MatrixToArray(const SkMatrix& matrix);
- static void AppendTransform(const SkMatrix& matrix, SkWStream* content);
-
- static void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
- static void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
- static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
- SkScalar ctl2X, SkScalar ctl2Y,
- SkScalar dstX, SkScalar dstY, SkWStream* content);
- static void AppendRectangle(const SkRect& rect, SkWStream* content);
- static void EmitPath(const SkPath& path, SkWStream* content);
- static void ClosePath(SkWStream* content);
- static void PaintPath(SkPaint::Style style, SkPath::FillType fill,
- SkWStream* content);
- static void StrokePath(SkWStream* content);
- static void DrawFormXObject(int objectIndex, SkWStream* content);
- static void ApplyGraphicState(int objectIndex, SkWStream* content);
-};
-
-#endif