'../src/pdf/SkPDFImageStream.h',
'../src/pdf/SkPDFPage.cpp',
'../src/pdf/SkPDFPage.h',
- '../src/pdf/SkPDFResourceDict.cpp',
- '../src/pdf/SkPDFResourceDict.h',
'../src/pdf/SkPDFShader.cpp',
'../src/pdf/SkPDFShader.h',
'../src/pdf/SkPDFStream.cpp',
class SkPDFGlyphSetMap;
class SkPDFGraphicState;
class SkPDFObject;
-class SkPDFResourceDict;
class SkPDFShader;
class SkPDFStream;
template <typename T> class SkTSet;
/** Returns the resource dictionary for this device.
*/
- SK_API SkPDFResourceDict* getResourceDict();
+ SK_API SkPDFDict* getResourceDict();
+
+ /** Get the list of resources (PDF objects) used on this page.
+ * This method will add to newResourceObjects any objects that this method
+ * depends on, but not already in knownResourceObjects. This might operate
+ * recursively so if this object depends on another object and that object
+ * depends on two more, all three objects will be added.
+ *
+ * @param knownResourceObjects The set of resources to be ignored.
+ * @param newResourceObjects The set to append dependant resources to.
+ * @param recursive If recursive is true, get the resources of the
+ * device's resources recursively. (Useful for adding
+ * objects to the catalog.)
+ */
+ SK_API void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
+ SkTSet<SkPDFObject*>* newResourceObjects,
+ bool recursive) const;
/** Get the fonts used on this device.
*/
SkClipStack fExistingClipStack;
SkRegion fExistingClipRegion;
SkPDFArray* fAnnotations;
- SkPDFResourceDict* fResourceDict;
+ SkPDFDict* fResourceDict;
SkTDArray<NamedDestination*> fNamedDestinations;
SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
#include "SkPDFFormXObject.h"
#include "SkPDFGraphicState.h"
#include "SkPDFImage.h"
-#include "SkPDFResourceDict.h"
#include "SkPDFShader.h"
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
// PDF treats a shader as a color, so we only set one or the other.
if (state.fShaderIndex >= 0) {
if (state.fShaderIndex != currentEntry()->fShaderIndex) {
- SkString resourceName = SkPDFResourceDict::getResourceName(
- SkPDFResourceDict::kPattern_ResourceType,
- state.fShaderIndex);
- fContentStream->writeText("/Pattern CS /Pattern cs /");
- fContentStream->writeText(resourceName.c_str());
- fContentStream->writeText(" SCN /");
- fContentStream->writeText(resourceName.c_str());
+ fContentStream->writeText("/Pattern CS /Pattern cs /P");
+ fContentStream->writeDecAsText(state.fShaderIndex);
+ fContentStream->writeText(" SCN /P");
+ fContentStream->writeDecAsText(state.fShaderIndex);
fContentStream->writeText(" scn\n");
currentEntry()->fShaderIndex = state.fShaderIndex;
}
fDrawingArea = drawingArea;
}
-SkPDFResourceDict* SkPDFDevice::getResourceDict() {
+SkPDFDict* SkPDFDevice::getResourceDict() {
if (NULL == fResourceDict) {
- fResourceDict = SkNEW(SkPDFResourceDict);
+ fResourceDict = SkNEW(SkPDFDict);
if (fGraphicStateResources.count()) {
+ SkAutoTUnref<SkPDFDict> extGState(new SkPDFDict());
for (int i = 0; i < fGraphicStateResources.count(); i++) {
- fResourceDict->insertResourceAsRef(
- SkPDFResourceDict::kExtGState_ResourceType,
- i, fGraphicStateResources[i]);
+ SkString nameString("G");
+ nameString.appendS32(i);
+ extGState->insert(
+ nameString.c_str(),
+ new SkPDFObjRef(fGraphicStateResources[i]))->unref();
}
+ fResourceDict->insert("ExtGState", extGState.get());
}
if (fXObjectResources.count()) {
+ SkAutoTUnref<SkPDFDict> xObjects(new SkPDFDict());
for (int i = 0; i < fXObjectResources.count(); i++) {
- fResourceDict->insertResourceAsRef(
- SkPDFResourceDict::kXObject_ResourceType,
- i, fXObjectResources[i]);
+ SkString nameString("X");
+ nameString.appendS32(i);
+ xObjects->insert(
+ nameString.c_str(),
+ new SkPDFObjRef(fXObjectResources[i]))->unref();
}
+ fResourceDict->insert("XObject", xObjects.get());
}
if (fFontResources.count()) {
+ SkAutoTUnref<SkPDFDict> fonts(new SkPDFDict());
for (int i = 0; i < fFontResources.count(); i++) {
- fResourceDict->insertResourceAsRef(
- SkPDFResourceDict::kFont_ResourceType,
- i, fFontResources[i]);
+ SkString nameString("F");
+ nameString.appendS32(i);
+ fonts->insert(nameString.c_str(),
+ new SkPDFObjRef(fFontResources[i]))->unref();
}
+ fResourceDict->insert("Font", fonts.get());
}
if (fShaderResources.count()) {
SkAutoTUnref<SkPDFDict> patterns(new SkPDFDict());
for (int i = 0; i < fShaderResources.count(); i++) {
- fResourceDict->insertResourceAsRef(
- SkPDFResourceDict::kPattern_ResourceType,
- i, fShaderResources[i]);
+ SkString nameString("P");
+ nameString.appendS32(i);
+ patterns->insert(nameString.c_str(),
+ new SkPDFObjRef(fShaderResources[i]))->unref();
}
+ fResourceDict->insert("Pattern", patterns.get());
}
+
+ // For compatibility, add all proc sets (only used for output to PS
+ // devices).
+ const char procs[][7] = {"PDF", "Text", "ImageB", "ImageC", "ImageI"};
+ SkAutoTUnref<SkPDFArray> procSets(new SkPDFArray());
+ procSets->reserve(SK_ARRAY_COUNT(procs));
+ for (size_t i = 0; i < SK_ARRAY_COUNT(procs); i++)
+ procSets->appendName(procs[i]);
+ fResourceDict->insert("ProcSet", procSets.get());
}
return fResourceDict;
}
+void SkPDFDevice::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
+ SkTSet<SkPDFObject*>* newResourceObjects,
+ bool recursive) const {
+ // TODO: reserve not correct if we need to recursively explore.
+ newResourceObjects->setReserve(newResourceObjects->count() +
+ fGraphicStateResources.count() +
+ fXObjectResources.count() +
+ fFontResources.count() +
+ fShaderResources.count());
+ for (int i = 0; i < fGraphicStateResources.count(); i++) {
+ if (!knownResourceObjects.contains(fGraphicStateResources[i]) &&
+ !newResourceObjects->contains(fGraphicStateResources[i])) {
+ newResourceObjects->add(fGraphicStateResources[i]);
+ fGraphicStateResources[i]->ref();
+ if (recursive) {
+ fGraphicStateResources[i]->getResources(knownResourceObjects,
+ newResourceObjects);
+ }
+ }
+ }
+ for (int i = 0; i < fXObjectResources.count(); i++) {
+ if (!knownResourceObjects.contains(fXObjectResources[i]) &&
+ !newResourceObjects->contains(fXObjectResources[i])) {
+ newResourceObjects->add(fXObjectResources[i]);
+ fXObjectResources[i]->ref();
+ if (recursive) {
+ fXObjectResources[i]->getResources(knownResourceObjects,
+ newResourceObjects);
+ }
+ }
+ }
+ for (int i = 0; i < fFontResources.count(); i++) {
+ if (!knownResourceObjects.contains(fFontResources[i]) &&
+ !newResourceObjects->contains(fFontResources[i])) {
+ newResourceObjects->add(fFontResources[i]);
+ fFontResources[i]->ref();
+ if (recursive) {
+ fFontResources[i]->getResources(knownResourceObjects,
+ newResourceObjects);
+ }
+ }
+ }
+ for (int i = 0; i < fShaderResources.count(); i++) {
+ if (!knownResourceObjects.contains(fShaderResources[i]) &&
+ !newResourceObjects->contains(fShaderResources[i])) {
+ newResourceObjects->add(fShaderResources[i]);
+ fShaderResources[i]->ref();
+ if (recursive) {
+ fShaderResources[i]->getResources(knownResourceObjects,
+ newResourceObjects);
+ }
+ }
+ }
+}
+
const SkTDArray<SkPDFFont*>& SkPDFDevice::getFontResources() const {
return fFontResources;
}
contentEntry->fState.fTextSize != paint.getTextSize() ||
!contentEntry->fState.fFont->hasGlyph(glyphID)) {
int fontIndex = getFontResourceIndex(typeface, glyphID);
- contentEntry->fContent.writeText("/");
- contentEntry->fContent.writeText(SkPDFResourceDict::getResourceName(
- SkPDFResourceDict::kFont_ResourceType,
- fontIndex).c_str());
+ contentEntry->fContent.writeText("/F");
+ contentEntry->fContent.writeDecAsText(fontIndex);
contentEntry->fContent.writeText(" ");
SkPDFScalar::Append(paint.getTextSize(), &contentEntry->fContent);
contentEntry->fContent.writeText(" Tf\n");
#include "SkMatrix.h"
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
-#include "SkPDFResourceDict.h"
#include "SkPDFUtils.h"
#include "SkStream.h"
#include "SkTypes.h"
// of content, so reference or copy everything we need (content and
// resources).
SkTSet<SkPDFObject*> emptySet;
- SkPDFResourceDict* resourceDict = device->getResourceDict();
- resourceDict->getResources(emptySet, &fResources, false);
+ device->getResources(emptySet, &fResources, false);
SkAutoTUnref<SkStream> content(device->content());
setData(content.get());
insertName("Type", "XObject");
insertName("Subtype", "Form");
SkSafeUnref(this->insert("BBox", device->copyMediaBox()));
- insert("Resources", resourceDict);
+ insert("Resources", device->getResourceDict());
// We invert the initial transform and apply that to the xobject so that
// it doesn't get applied twice. We can't just undo it because it's
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
#include "SkPDFPage.h"
-#include "SkPDFResourceDict.h"
#include "SkStream.h"
SkPDFPage::SkPDFPage(SkPDFDevice* content)
void SkPDFPage::finalizePage(SkPDFCatalog* catalog, bool firstPage,
const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) {
- SkPDFResourceDict* resourceDict = fDevice->getResourceDict();
if (fContentStream.get() == NULL) {
- insert("Resources", resourceDict);
+ insert("Resources", fDevice->getResourceDict());
SkSafeUnref(this->insert("MediaBox", fDevice->copyMediaBox()));
if (!SkToBool(catalog->getDocumentFlags() &
SkPDFDocument::kNoLinks_Flags)) {
insert("Contents", new SkPDFObjRef(fContentStream.get()))->unref();
}
catalog->addObject(fContentStream.get(), firstPage);
- resourceDict->getResources(knownResourceObjects, newResourceObjects, true);
+ fDevice->getResources(knownResourceObjects, newResourceObjects, true);
}
off_t SkPDFPage::getPageSize(SkPDFCatalog* catalog, off_t fileOffset) {
+++ /dev/null
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkPDFResourceDict.h"
-#include "SkPostConfig.h"
-
-SK_DEFINE_INST_COUNT(SkPDFResourceDict)
-
-// Sanity check that the values of enum SkPDFResourceType correspond to the
-// expected values as defined in the arrays below.
-// If these are failing, you may need to update the resource_type_prefixes
-// and resource_type_names arrays below.
-SK_COMPILE_ASSERT(SkPDFResourceDict::kExtGState_ResourceType == 0,
- resource_type_mismatch);
-SK_COMPILE_ASSERT(SkPDFResourceDict::kPattern_ResourceType == 1,
- resource_type_mismatch);
-SK_COMPILE_ASSERT(SkPDFResourceDict::kXObject_ResourceType == 2,
- resource_type_mismatch);
-SK_COMPILE_ASSERT(SkPDFResourceDict::kFont_ResourceType == 3,
- resource_type_mismatch);
-
-static const char resource_type_prefixes[] = {
- 'G',
- 'P',
- 'X',
- 'F'
-};
-
-static const char* resource_type_names[] = {
- "ExtGState",
- "Pattern",
- "XObject",
- "Font"
-};
-
-static char get_resource_type_prefix(
- SkPDFResourceDict::SkPDFResourceType type) {
- SkASSERT(type >= 0);
- SkASSERT(type < SkPDFResourceDict::kResourceTypeCount);
-
- return resource_type_prefixes[type];
-}
-
-static const char* get_resource_type_name(
- SkPDFResourceDict::SkPDFResourceType type) {
- SkASSERT(type >= 0);
- SkASSERT(type < SkPDFResourceDict::kResourceTypeCount);
-
- return resource_type_names[type];
-}
-
-SkPDFResourceDict::SkPDFResourceDict() : SkPDFDict() {
- const char procs[][7] = {"PDF", "Text", "ImageB", "ImageC", "ImageI"};
- SkPDFArray* procSets = SkNEW(SkPDFArray());
-
- procSets->reserve(SK_ARRAY_COUNT(procs));
- for (size_t i = 0; i < SK_ARRAY_COUNT(procs); i++) {
- procSets->appendName(procs[i]);
- }
- insert("ProcSets", procSets)->unref();
-
- // Actual sub-dicts will be lazily added later
- fTypes.setCount(kResourceTypeCount);
- for (size_t i=0; i < kResourceTypeCount; i++) {
- fTypes[i] = NULL;
- }
-}
-
-SkPDFObject* SkPDFResourceDict::insertResourceAsRef(
- SkPDFResourceType type, int key, SkPDFObject* value) {
- SkAutoTUnref<SkPDFObjRef> ref(SkNEW_ARGS(SkPDFObjRef, (value)));
- insertResource(type, key, ref);
- fResources.add(value);
-
- return value;
-}
-
-void SkPDFResourceDict::getResources(
- const SkTSet<SkPDFObject*>& knownResourceObjects,
- SkTSet<SkPDFObject*>* newResourceObjects,
- bool recursive) const {
- // TODO: reserve not correct if we need to recursively explore.
- newResourceObjects->setReserve(newResourceObjects->count() +
- fResources.count());
-
- for (int i = 0; i < fResources.count(); i++) {
- if (!knownResourceObjects.contains(fResources[i]) &&
- !newResourceObjects->contains(fResources[i])) {
- newResourceObjects->add(fResources[i]);
- fResources[i]->ref();
- if (recursive) {
- fResources[i]->getResources(knownResourceObjects,
- newResourceObjects);
- }
- }
- }
-}
-
-SkString SkPDFResourceDict::getResourceName(
- SkPDFResourceType type, int key) {
- SkString keyString;
- keyString.printf("%c%d", get_resource_type_prefix(type), key);
- return keyString;
-}
-
-SkPDFObject* SkPDFResourceDict::insertResource(
- SkPDFResourceType type, int key, SkPDFObject* value) {
- SkPDFDict* typeDict = fTypes[type];
- if (NULL == typeDict) {
- SkAutoTUnref<SkPDFDict> newDict(SkNEW(SkPDFDict()));
- SkPDFName* typeName = SkNEW_ARGS(
- SkPDFName, (get_resource_type_name(type)));
- insert(typeName, newDict); // ref counting handled here
- fTypes[type] = newDict;
- typeDict = newDict.get();
- }
-
- SkPDFName* keyName = SkNEW_ARGS(SkPDFName, (getResourceName(type, key)));
- typeDict->insert(keyName, value);
- return value;
-}
+++ /dev/null
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkPDFResourceDict_DEFINED
-#define SkPDFResourceDict_DEFINED
-
-#include "SkPDFTypes.h"
-#include "SkTDArray.h"
-#include "SkTSet.h"
-#include "SkTypes.h"
-
-/** \class SkPDFResourceDict
-
- A resource dictionary, which maintains the relevant sub-dicts and
- allows generation of a list of referenced SkPDFObjects inserted with
- insertResourceAsRef.
-*/
-class SkPDFResourceDict : public SkPDFDict {
-public:
- SK_DECLARE_INST_COUNT(SkPDFResourceDict)
-
- enum SkPDFResourceType{
- kExtGState_ResourceType,
- kPattern_ResourceType,
- kXObject_ResourceType,
- kFont_ResourceType,
- // These additional types are defined by the spec, but not
- // currently used by Skia: ColorSpace, Shading, Properties
- kResourceTypeCount
- };
-
- /** Create a PDF resource dictionary.
- * The full set of ProcSet entries is automatically created for backwards
- * compatibility, as recommended by the PDF spec.
- */
- SkPDFResourceDict();
-
- /** Add the value SkPDFObject as a reference to the resource dictionary
- * with the give type and key.
- * The relevant sub-dicts will be automatically generated, and the
- * resource will be named by concatenating a type-specific prefix and
- * the input key.
- * This object will be part of the resource list when requested later.
- * @param type The type of resource being entered, like
- * kPattern_ResourceType or kExtGState_ResourceType.
- * @param key The resource key, should be unique within its type.
- * @param value The resource itself.
- * @return The value argument is returned.
- */
- SkPDFObject* insertResourceAsRef(SkPDFResourceType type, int key,
- SkPDFObject* value);
-
- /**
- * Gets resources inserted into this dictionary.
- *
- * @param knownResourceObjects Set containing currently known resources.
- * Resources in the dict and this set will not be added to the output.
- * @param newResourceObjects Output set to which non-preexisting resources
- * will be added.
- * @param recursive Whether or not to add resources of resources.
- */
- void getResources(
- const SkTSet<SkPDFObject*>& knownResourceObjects,
- SkTSet<SkPDFObject*>* newResourceObjects,
- bool recursive) const;
-
- /**
- * Returns the name for the resource that will be generated by the resource
- * dict.
- *
- * @param type The type of resource being entered, like
- * kPattern_ResourceType or kExtGState_ResourceType.
- * @param key The resource key, should be unique within its type.
- */
- static SkString getResourceName(SkPDFResourceType type, int key);
-
-private:
- /** Add the value to the dictionary with the given key. Refs value.
- * The relevant sub-dicts will be automatically generated, and the
- * resource will be named by concatenating a type-specific prefix and
- * the input key.
- * The object will NOT be part of the resource list when requested later.
- * @param type The type of resource being entered.
- * @param key The resource key, should be unique within its type.
- * @param value The resource itself.
- * @return The value argument is returned.
- */
- SkPDFObject* insertResource(SkPDFResourceType type, int key,
- SkPDFObject* value);
-
- SkTSet<SkPDFObject*> fResources;
-
- SkTDArray<SkPDFDict*> fTypes;
-};
-
-#endif
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
#include "SkPDFTypes.h"
-#include "SkPDFResourceDict.h"
#include "SkPDFUtils.h"
#include "SkScalar.h"
#include "SkStream.h"
// Put the canvas into the pattern stream (fContent).
SkAutoTUnref<SkStream> content(pattern.content());
setData(content.get());
- SkPDFResourceDict* resourceDict = pattern.getResourceDict();
- resourceDict->getResources(fResources, &fResources, false);
+ pattern.getResources(fResources, &fResources, false);
insertName("Type", "Pattern");
insertInt("PatternType", 1);
insert("BBox", patternBBoxArray.get());
insertScalar("XStep", patternBBox.width());
insertScalar("YStep", patternBBox.height());
- insert("Resources", resourceDict);
+ insert("Resources", pattern.getResourceDict());
insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref();
fState.get()->fImage.unlockPixels();
#include "SkGeometry.h"
#include "SkPaint.h"
#include "SkPath.h"
-#include "SkPDFResourceDict.h"
#include "SkPDFUtils.h"
#include "SkStream.h"
#include "SkString.h"
// static
void SkPDFUtils::DrawFormXObject(int objectIndex, SkWStream* content) {
- content->writeText("/");
- content->writeText(SkPDFResourceDict::getResourceName(
- SkPDFResourceDict::kXObject_ResourceType,
- objectIndex).c_str());
+ content->writeText("/X");
+ content->writeDecAsText(objectIndex);
content->writeText(" Do\n");
}
// static
void SkPDFUtils::ApplyGraphicState(int objectIndex, SkWStream* content) {
- content->writeText("/");
- content->writeText(SkPDFResourceDict::getResourceName(
- SkPDFResourceDict::kExtGState_ResourceType,
- objectIndex).c_str());
+ content->writeText("/G");
+ content->writeDecAsText(objectIndex);
content->writeText(" gs\n");
}