skia_safe/core/
document.rs1use std::{fmt, ptr};
2
3use skia_bindings::{self as sb, SkDocument, SkRefCntBase};
4
5use crate::{interop::RustWStream, prelude::*, Canvas, Rect, Size};
6
7pub struct Document<'a, State = state::Open> {
8 document: RCHandle<SkDocument>,
10 stream: RustWStream<'a>,
11
12 state: State,
13}
14
15require_type_equality!(sb::SkDocument_INHERITED, sb::SkRefCnt);
16
17impl NativeRefCountedBase for SkDocument {
18 type Base = SkRefCntBase;
19}
20
21impl<State: fmt::Debug> fmt::Debug for Document<'_, State> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("Document")
24 .field("state", &self.state)
25 .finish()
26 }
27}
28
29pub mod state {
30 use std::{fmt, ptr};
31
32 use skia_bindings::SkCanvas;
33
34 use crate::Canvas;
35
36 #[derive(Debug)]
38 pub struct Open {
39 pub(crate) pages: usize,
40 }
41
42 pub struct OnPage {
44 pub(crate) page: usize,
45 pub(crate) canvas: ptr::NonNull<SkCanvas>,
46 }
47
48 impl fmt::Debug for OnPage {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("OnPage")
51 .field("page", &self.page)
52 .field(
53 "canvas",
54 Canvas::borrow_from_native(unsafe { self.canvas.as_ref() }),
55 )
56 .finish()
57 }
58 }
59}
60
61impl<State> Document<'_, State> {
62 pub fn abort(mut self) {
63 unsafe { self.document.native_mut().abort() }
64 drop(self)
65 }
66}
67
68impl<'a> Document<'a, state::Open> {
69 #[allow(unused)]
70 pub(crate) fn new(stream: RustWStream<'a>, document: RCHandle<SkDocument>) -> Self {
71 Document {
72 document,
73 stream,
74 state: state::Open { pages: 0 },
75 }
76 }
77
78 pub fn pages(&self) -> usize {
80 self.state.pages
81 }
82
83 pub fn begin_page(
86 mut self,
87 size: impl Into<Size>,
88 content: Option<&Rect>,
89 ) -> Document<'a, state::OnPage> {
90 let size = size.into();
91 let canvas = unsafe {
92 self.document.native_mut().beginPage(
93 size.width,
94 size.height,
95 content.native_ptr_or_null(),
96 )
97 };
98
99 Document {
100 stream: self.stream,
101 document: self.document,
102 state: state::OnPage {
103 canvas: ptr::NonNull::new(canvas).unwrap(),
104 page: self.state.pages + 1,
105 },
106 }
107 }
108
109 pub fn close(mut self) {
113 unsafe {
114 self.document.native_mut().close();
115 };
116 }
117}
118
119impl<'a> Document<'a, state::OnPage> {
120 pub fn page(&self) -> usize {
122 self.state.page
123 }
124
125 pub fn canvas(&mut self) -> &Canvas {
127 Canvas::borrow_from_native(unsafe { self.state.canvas.as_ref() })
128 }
129
130 pub fn end_page(mut self) -> Document<'a> {
135 unsafe {
136 self.document.native_mut().endPage();
137 }
138
139 Document {
140 stream: self.stream,
141 document: self.document,
142 state: state::Open {
143 pages: self.state.page,
144 },
145 }
146
147 }
152}