1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/pdf/SkPDFFormXObject.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,95 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2010 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkPDFFormXObject.h" 1.14 + 1.15 +#include "SkMatrix.h" 1.16 +#include "SkPDFCatalog.h" 1.17 +#include "SkPDFDevice.h" 1.18 +#include "SkPDFResourceDict.h" 1.19 +#include "SkPDFUtils.h" 1.20 +#include "SkStream.h" 1.21 +#include "SkTypes.h" 1.22 + 1.23 +SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) { 1.24 + // We don't want to keep around device because we'd have two copies 1.25 + // of content, so reference or copy everything we need (content and 1.26 + // resources). 1.27 + SkTSet<SkPDFObject*> emptySet; 1.28 + SkPDFResourceDict* resourceDict = device->getResourceDict(); 1.29 + resourceDict->getReferencedResources(emptySet, &fResources, false); 1.30 + 1.31 + SkAutoTUnref<SkStream> content(device->content()); 1.32 + setData(content.get()); 1.33 + 1.34 + SkAutoTUnref<SkPDFArray> bboxArray(device->copyMediaBox()); 1.35 + init(NULL, resourceDict, bboxArray); 1.36 + 1.37 + // We invert the initial transform and apply that to the xobject so that 1.38 + // it doesn't get applied twice. We can't just undo it because it's 1.39 + // embedded in things like shaders and images. 1.40 + if (!device->initialTransform().isIdentity()) { 1.41 + SkMatrix inverse; 1.42 + if (!device->initialTransform().invert(&inverse)) { 1.43 + // The initial transform should be invertible. 1.44 + SkASSERT(false); 1.45 + inverse.reset(); 1.46 + } 1.47 + insert("Matrix", SkPDFUtils::MatrixToArray(inverse))->unref(); 1.48 + } 1.49 +} 1.50 + 1.51 +/** 1.52 + * Creates a FormXObject from a content stream and associated resources. 1.53 + */ 1.54 +SkPDFFormXObject::SkPDFFormXObject(SkStream* content, SkRect bbox, 1.55 + SkPDFResourceDict* resourceDict) { 1.56 + SkTSet<SkPDFObject*> emptySet; 1.57 + resourceDict->getReferencedResources(emptySet, &fResources, false); 1.58 + 1.59 + setData(content); 1.60 + 1.61 + SkAutoTUnref<SkPDFArray> bboxArray(SkPDFUtils::RectToArray(bbox)); 1.62 + init("DeviceRGB", resourceDict, bboxArray); 1.63 +} 1.64 + 1.65 +/** 1.66 + * Common initialization code. 1.67 + * Note that bbox is unreferenced here, so calling code does not need worry. 1.68 + */ 1.69 +void SkPDFFormXObject::init(const char* colorSpace, 1.70 + SkPDFDict* resourceDict, SkPDFArray* bbox) { 1.71 + insertName("Type", "XObject"); 1.72 + insertName("Subtype", "Form"); 1.73 + insert("Resources", resourceDict); 1.74 + insert("BBox", bbox); 1.75 + 1.76 + // Right now SkPDFFormXObject is only used for saveLayer, which implies 1.77 + // isolated blending. Do this conditionally if that changes. 1.78 + SkAutoTUnref<SkPDFDict> group(new SkPDFDict("Group")); 1.79 + group->insertName("S", "Transparency"); 1.80 + 1.81 + if (colorSpace != NULL) { 1.82 + group->insertName("CS", colorSpace); 1.83 + } 1.84 + group->insert("I", new SkPDFBool(true))->unref(); // Isolated. 1.85 + insert("Group", group.get()); 1.86 +} 1.87 + 1.88 +SkPDFFormXObject::~SkPDFFormXObject() { 1.89 + fResources.unrefAll(); 1.90 +} 1.91 + 1.92 +void SkPDFFormXObject::getResources( 1.93 + const SkTSet<SkPDFObject*>& knownResourceObjects, 1.94 + SkTSet<SkPDFObject*>* newResourceObjects) { 1.95 + GetResourcesHelper(&fResources.toArray(), 1.96 + knownResourceObjects, 1.97 + newResourceObjects); 1.98 +}