• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "SkTArray.h"
14 
15 /*
16   File format:
17       BEGINNING_OF_FILE:
18         kMagic
19         uint32_t version_number (==2)
20         uint32_t page_count
21         {
22           float sizeX
23           float sizeY
24         } * page_count
25         skp file
26 */
27 
28 namespace {
trim(SkCanvas * canvas,SkScalar w,SkScalar h,const SkRect & trimBox)29 static SkCanvas* trim(SkCanvas* canvas,
30                       SkScalar w, SkScalar h,
31                       const SkRect& trimBox) {
32     // Only trim if necessary.
33     if (trimBox != SkRect::MakeWH(w, h)) {
34         // All SkDocument implementations implement trimBox using a
35         // clip+translate.
36         canvas->clipRect(trimBox);
37         canvas->translate(trimBox.x(), trimBox.y());
38     }
39     return canvas;
40 }
41 
42 struct MultiPictureDocument final : public SkDocument {
43     SkPictureRecorder fPictureRecorder;
44     SkSize fCurrentPageSize;
45     SkTArray<sk_sp<SkPicture>> fPages;
46     SkTArray<SkSize> fSizes;
MultiPictureDocument__anon73b624930111::MultiPictureDocument47     MultiPictureDocument(SkWStream* s, void (*d)(SkWStream*, bool))
48         : SkDocument(s, d) {}
~MultiPictureDocument__anon73b624930111::MultiPictureDocument49     ~MultiPictureDocument() override { this->close(); }
50 
onBeginPage__anon73b624930111::MultiPictureDocument51     SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect& c) override {
52         fCurrentPageSize.set(w, h);
53         return trim(fPictureRecorder.beginRecording(w, h), w, h, c);
54     }
onEndPage__anon73b624930111::MultiPictureDocument55     void onEndPage() override {
56         fSizes.push_back(fCurrentPageSize);
57         fPages.push_back(fPictureRecorder.finishRecordingAsPicture());
58     }
onClose__anon73b624930111::MultiPictureDocument59     void onClose(SkWStream* wStream) override {
60         SkASSERT(wStream);
61         SkASSERT(wStream->bytesWritten() == 0);
62         wStream->writeText(SkMultiPictureDocumentProtocol::kMagic);
63         wStream->write32(SkMultiPictureDocumentProtocol::kVersion);
64         wStream->write32(SkToU32(fPages.count()));
65         for (SkSize s : fSizes) {
66             wStream->write(&s, sizeof(s));
67         }
68         SkSize bigsize = SkMultiPictureDocumentProtocol::Join(fSizes);
69         SkCanvas* c = fPictureRecorder.beginRecording(SkRect::MakeSize(bigsize));
70         for (const sk_sp<SkPicture>& page : fPages) {
71             c->drawPicture(page);
72             c->drawAnnotation(SkRect::MakeEmpty(),
73                               SkMultiPictureDocumentProtocol::kEndPage,
74                               nullptr);
75         }
76         sk_sp<SkPicture> p = fPictureRecorder.finishRecordingAsPicture();
77         p->serialize(wStream);
78         fPages.reset();
79         fSizes.reset();
80         return;
81     }
onAbort__anon73b624930111::MultiPictureDocument82     void onAbort() override {
83         fPages.reset();
84         fSizes.reset();
85     }
86 };
87 }
88 
SkMakeMultiPictureDocument(SkWStream * wStream)89 sk_sp<SkDocument> SkMakeMultiPictureDocument(SkWStream* wStream) {
90     return sk_make_sp<MultiPictureDocument>(wStream, nullptr);
91 }
92