1/*
2 * Copyright 2013 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 "SkDocument.h"
9#include "SkStream.h"
10
11SkDocument::SkDocument(SkWStream* stream, void (*doneProc)(SkWStream*, bool)) {
12    fStream = stream;   // we do not own this object.
13    fDoneProc = doneProc;
14    fState = kBetweenPages_State;
15}
16
17SkDocument::~SkDocument() {
18    this->close();
19}
20
21SkCanvas* SkDocument::beginPage(SkScalar width, SkScalar height,
22                                const SkRect* content) {
23    if (width <= 0 || height <= 0) {
24        return nullptr;
25    }
26
27    SkRect outer = SkRect::MakeWH(width, height);
28    SkRect inner;
29    if (content) {
30        inner = *content;
31        if (!inner.intersect(outer)) {
32            return nullptr;
33        }
34    } else {
35        inner = outer;
36    }
37
38    for (;;) {
39        switch (fState) {
40            case kBetweenPages_State:
41                fState = kInPage_State;
42                return this->onBeginPage(width, height, inner);
43            case kInPage_State:
44                this->endPage();
45                break;
46            case kClosed_State:
47                return nullptr;
48        }
49    }
50    SkDEBUGFAIL("never get here");
51    return nullptr;
52}
53
54void SkDocument::endPage() {
55    if (kInPage_State == fState) {
56        fState = kBetweenPages_State;
57        this->onEndPage();
58    }
59}
60
61bool SkDocument::close() {
62    for (;;) {
63        switch (fState) {
64            case kBetweenPages_State: {
65                fState = kClosed_State;
66                bool success = this->onClose(fStream);
67
68                if (fDoneProc) {
69                    fDoneProc(fStream, false);
70                }
71                // we don't own the stream, but we mark it nullptr since we can
72                // no longer write to it.
73                fStream = nullptr;
74                return success;
75            }
76            case kInPage_State:
77                this->endPage();
78                break;
79            case kClosed_State:
80                return false;
81        }
82    }
83}
84
85void SkDocument::abort() {
86    this->onAbort();
87
88    fState = kClosed_State;
89    if (fDoneProc) {
90        fDoneProc(fStream, true);
91    }
92    // we don't own the stream, but we mark it nullptr since we can
93    // no longer write to it.
94    fStream = nullptr;
95}
96