OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkMultiPictureDocument.h" | |
9 #include "SkMultiPictureDocumentPriv.h" | |
10 #include "SkPicture.h" | |
11 #include "SkPictureRecorder.h" | |
12 #include "SkStream.h" | |
13 | |
14 /* | |
15 File format: | |
16 BEGINNING_OF_FILE: | |
17 kMagic | |
18 uint32_t version_number | |
19 uint32_t page_count | |
20 { | |
21 uint64_t offset | |
22 float sizeX | |
23 float sizeY | |
24 } * page_count | |
25 FIRST_OFFSET: | |
26 skp file | |
27 SECOND_OFFSET: | |
28 skp file | |
29 ... | |
30 LAST_OFFSET: | |
31 skp file | |
32 "\nEndOfMultiPicture\n" | |
33 */ | |
34 | |
35 namespace { | |
36 static SkCanvas* trim(SkCanvas* canvas, | |
37 const SkRect& size, | |
38 const SkRect* trimBox) { | |
39 if (trimBox && *trimBox != size) { | |
tomhudson
2016/06/01 16:55:00
I can't intuit your intent here. This is surprisin
hal.canary
2016/06/01 18:09:16
Only trim if necessary. SkPictures already have a
| |
40 canvas->clipRect(*trimBox); | |
41 canvas->translate(trimBox->x(), trimBox->y()); | |
42 } | |
43 return canvas; | |
44 } | |
45 | |
46 struct NullWStream : public SkWStream { | |
47 NullWStream() : fN(0) {} | |
48 bool write(const void*, size_t n) override { | |
49 fN += n; | |
50 return true; | |
51 } | |
52 size_t bytesWritten() const override { return fN; } | |
53 size_t fN; | |
54 }; | |
55 | |
56 struct MultiPictureDocument final : public SkDocument { | |
57 SkPictureRecorder fPictureRecorder; | |
58 SkTArray<sk_sp<SkPicture>> fPages; | |
59 MultiPictureDocument(SkWStream* s, void (*d)(SkWStream*, bool)) | |
60 : SkDocument(s, d) {} | |
61 ~MultiPictureDocument() { this->close(); } | |
62 | |
63 SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect& c) override { | |
64 return trim(fPictureRecorder.beginRecording(w, h), SkRect::MakeWH(w, h), | |
65 &c); | |
66 } | |
67 void onEndPage() override { | |
68 fPages.emplace_back(fPictureRecorder.finishRecordingAsPicture()); | |
69 } | |
70 bool onClose(SkWStream* wStream) override { | |
71 SkASSERT(wStream); | |
72 bool good = true; | |
73 good &= wStream->writeText(SkMultiPictureDocumentProtocol::kMagic); | |
tomhudson
2016/06/01 16:55:00
&&=?
hal.canary
2016/06/01 18:09:16
Logically, yes. C++ does not have a `&&=` operato
| |
74 good &= wStream->write32(SkToU32(1)); // version | |
75 good &= wStream->write32(SkToU32(fPages.count())); | |
76 uint64_t offset = wStream->bytesWritten(); | |
77 offset += fPages.count() * sizeof(SkMultiPictureDocumentProtocol::Entry) ; | |
78 for (const auto& page : fPages) { | |
79 SkRect cullRect = page->cullRect(); | |
80 SkMultiPictureDocumentProtocol::Entry entry{ | |
81 offset, (float)cullRect.right(), (float)cullRect.bottom()}; | |
tomhudson
2016/06/01 16:54:59
It's an inviolable fact that cullRects are always
hal.canary
2016/06/01 18:09:16
If the picture was created by the code in the othe
| |
82 good &= wStream->write(&entry, sizeof(entry)); | |
83 NullWStream buffer; | |
84 page->serialize(&buffer); | |
85 offset += buffer.bytesWritten(); | |
86 } | |
87 for (const auto& page : fPages) { | |
88 page->serialize(wStream); | |
89 } | |
90 good &= wStream->writeText("\nEndOfMultiPicture\n"); | |
tomhudson
2016/06/01 16:54:59
Any reason not to move this to another constexpr o
hal.canary
2016/06/01 18:09:16
I actually use it. It's there more for human debu
hal.canary
2016/06/02 13:24:04
I DON'T actually use it. It's there more for huma
| |
91 fPages.reset(); | |
92 return good; | |
93 } | |
94 void onAbort() override { fPages.reset(); } | |
95 }; | |
96 } | |
97 | |
98 sk_sp<SkDocument> SkMakeMultiPictureDocument(SkWStream* wStream) { | |
99 return sk_make_sp<MultiPictureDocument>(wStream, nullptr); | |
100 } | |
OLD | NEW |