skia_safe/modules/svg/
dom.rs1use std::{
2 error::Error,
3 fmt,
4 io::{self},
5};
6
7use crate::{
8 interop::{MemoryStream, NativeStreamBase, RustStream},
9 prelude::*,
10 resources::NativeResourceProvider,
11 Canvas, Size,
12};
13use skia_bindings::{self as sb, SkRefCntBase};
14
15use super::Svg;
16
17pub type Dom = RCHandle<sb::SkSVGDOM>;
18require_base_type!(sb::SkSVGDOM, sb::SkRefCnt);
19
20impl NativeRefCountedBase for sb::SkSVGDOM {
21 type Base = SkRefCntBase;
22}
23
24impl fmt::Debug for Dom {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.debug_struct("Dom").finish()
27 }
28}
29
30impl Dom {
54 pub fn read<R: io::Read>(
55 mut reader: R,
56 resource_provider: impl Into<NativeResourceProvider>,
57 ) -> Result<Self, LoadError> {
58 let mut reader = RustStream::new(&mut reader);
59 let stream = reader.stream_mut();
60 let resource_provider = resource_provider.into();
61
62 let out = unsafe { sb::C_SkSVGDOM_MakeFromStream(stream, resource_provider.into_ptr()) };
63
64 Self::from_ptr(out).ok_or(LoadError)
65 }
66
67 pub fn from_str(
68 svg: impl AsRef<str>,
69 resource_provider: impl Into<NativeResourceProvider>,
70 ) -> Result<Self, LoadError> {
71 Self::from_bytes(svg.as_ref().as_bytes(), resource_provider)
72 }
73
74 pub fn from_bytes(
75 svg: &[u8],
76 resource_provider: impl Into<NativeResourceProvider>,
77 ) -> Result<Self, LoadError> {
78 let mut ms = MemoryStream::from_bytes(svg);
79 let resource_provider = resource_provider.into();
80
81 let out = unsafe {
82 sb::C_SkSVGDOM_MakeFromStream(
83 ms.native_mut().as_stream_mut(),
84 resource_provider.into_ptr(),
85 )
86 };
87 Self::from_ptr(out).ok_or(LoadError)
88 }
89
90 pub fn root(&self) -> Svg {
91 unsafe {
92 Svg::from_unshared_ptr(sb::C_SkSVGDOM_getRoot(self.native()) as *mut _)
93 .unwrap_unchecked()
94 }
95 }
96
97 pub fn render(&self, canvas: &Canvas) {
98 #[cfg(all(feature = "embed-icudtl", feature = "textlayout"))]
100 crate::icu::init();
101
102 unsafe { sb::SkSVGDOM::render(self.native() as &_, canvas.native_mut()) }
103 }
104
105 pub fn set_container_size(&mut self, size: impl Into<Size>) {
106 let size = size.into();
107 unsafe { sb::C_SkSVGDOM_setContainerSize(self.native_mut(), size.native()) }
108 }
109}
110
111#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
115pub struct LoadError;
116
117impl fmt::Display for LoadError {
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 write!(f, "Failed to load svg (reason unknown)")
120 }
121}
122
123impl Error for LoadError {
124 fn description(&self) -> &str {
125 "Failed to load svg (reason unknown)"
126 }
127}
128
129impl From<LoadError> for io::Error {
130 fn from(other: LoadError) -> Self {
131 io::Error::other(other)
132 }
133}