1
2 /*
3 * Copyright 2010 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10 #include "SkPDFFormXObject.h"
11
12 #include "SkMatrix.h"
13 #include "SkPDFDevice.h"
14 #include "SkPDFUtils.h"
15 #include "SkStream.h"
16 #include "SkTypes.h"
17
SkPDFFormXObject(SkPDFDevice * device)18 SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) {
19 // We don't want to keep around device because we'd have two copies
20 // of content, so reference or copy everything we need (content and
21 // resources).
22 SkAutoTUnref<SkPDFDict> resourceDict(device->createResourceDict());
23
24 SkAutoTDelete<SkStreamAsset> content(device->content());
25 this->setData(content.get());
26
27 SkAutoTUnref<SkPDFArray> bboxArray(device->copyMediaBox());
28 this->init(nullptr, resourceDict.get(), bboxArray);
29
30 // We invert the initial transform and apply that to the xobject so that
31 // it doesn't get applied twice. We can't just undo it because it's
32 // embedded in things like shaders and images.
33 if (!device->initialTransform().isIdentity()) {
34 SkMatrix inverse;
35 if (!device->initialTransform().invert(&inverse)) {
36 // The initial transform should be invertible.
37 SkASSERT(false);
38 inverse.reset();
39 }
40 this->insertObject("Matrix", SkPDFUtils::MatrixToArray(inverse));
41 }
42 }
43
44 /**
45 * Creates a FormXObject from a content stream and associated resources.
46 */
SkPDFFormXObject(SkStream * content,SkRect bbox,SkPDFDict * resourceDict)47 SkPDFFormXObject::SkPDFFormXObject(SkStream* content, SkRect bbox,
48 SkPDFDict* resourceDict) {
49 setData(content);
50
51 SkAutoTUnref<SkPDFArray> bboxArray(SkPDFUtils::RectToArray(bbox));
52 init("DeviceRGB", resourceDict, bboxArray);
53 }
54
55 /**
56 * Common initialization code.
57 * Note that bbox is unreferenced here, so calling code does not need worry.
58 */
init(const char * colorSpace,SkPDFDict * resourceDict,SkPDFArray * bbox)59 void SkPDFFormXObject::init(const char* colorSpace,
60 SkPDFDict* resourceDict, SkPDFArray* bbox) {
61 this->insertName("Type", "XObject");
62 this->insertName("Subtype", "Form");
63 this->insertObject("Resources", SkRef(resourceDict));
64 this->insertObject("BBox", SkRef(bbox));
65
66 // Right now SkPDFFormXObject is only used for saveLayer, which implies
67 // isolated blending. Do this conditionally if that changes.
68 SkAutoTUnref<SkPDFDict> group(new SkPDFDict("Group"));
69 group->insertName("S", "Transparency");
70
71 if (colorSpace != nullptr) {
72 group->insertName("CS", colorSpace);
73 }
74 group->insertBool("I", true); // Isolated.
75 this->insertObject("Group", group.detach());
76 }
77
~SkPDFFormXObject()78 SkPDFFormXObject::~SkPDFFormXObject() {}
79