1use crate::draw::*;
2use crate::path::*;
3use crate::font::*;
4use crate::color::*;
5use crate::texture::*;
6use crate::gradient::*;
7use crate::font_face::*;
8use crate::transform2d::*;
9
10use futures::*;
11use futures::stream;
12use futures::task::{Poll};
13
14use itertools::*;
15
16use std::mem;
17use std::str::*;
18use std::sync::*;
19use std::result::Result;
20
21#[derive(Debug)]
25enum PartialResult<T> {
26 MatchMore(String),
27 FullMatch(T)
28}
29
30impl<T> PartialResult<T> {
31 pub fn new() -> PartialResult<T> {
32 PartialResult::MatchMore(String::new())
33 }
34
35 pub fn map<TFn: FnOnce(T) -> S, S>(self, map_fn: TFn) -> PartialResult<S> {
36 match self {
37 PartialResult::FullMatch(result) => PartialResult::FullMatch(map_fn(result)),
38 PartialResult::MatchMore(data) => PartialResult::MatchMore(data)
39 }
40 }
41}
42
43struct DecodeString {
47 length: PartialResult<u64>,
48 string_encoding: PartialResult<String>
49}
50
51struct DecodeGlyphPositions {
55 length: PartialResult<u64>,
56 glyphs: PartialResult<Vec<GlyphPosition>>
57}
58
59struct DecodeBytes {
63 length: PartialResult<u64>,
64 byte_encoding: PartialResult<Vec<u8>>
65}
66
67type DecodeLayerId = PartialResult<LayerId>;
68type DecodeFontId = PartialResult<FontId>;
69type DecodeTextureId = PartialResult<TextureId>;
70type DecodeGradientId = PartialResult<GradientId>;
71
72impl DecodeString {
73 fn new() -> DecodeString {
77 DecodeString {
78 length: PartialResult::new(),
79 string_encoding: PartialResult::new()
80 }
81 }
82
83 #[inline] fn ready(&self) -> bool {
87 match (&self.length, &self.string_encoding) {
88 (PartialResult::FullMatch(_), PartialResult::FullMatch(_)) => true,
89 _ => false
90 }
91 }
92
93 #[inline] fn to_string(self) -> Result<String, DecoderError> {
97 match self.string_encoding {
98 PartialResult::FullMatch(string) => Ok(string),
99 PartialResult::MatchMore(_) => Err(DecoderError::NotReady)
100 }
101 }
102
103 fn decode(mut self, chr: char) -> Result<DecodeString, DecoderError> {
107 let length = match self.length {
109 PartialResult::MatchMore(so_far) => {
110 self.length = CanvasDecoder::decode_compact_id(chr, so_far)?;
111
112 if let &PartialResult::FullMatch(0) = &self.length {
113 self.string_encoding = PartialResult::FullMatch(String::new());
114 }
115 return Ok(self);
116 }
117
118 PartialResult::FullMatch(length) => {
119 self.length = PartialResult::FullMatch(length);
120 length as usize
121 }
122 };
123
124 match self.string_encoding {
126 PartialResult::FullMatch(string) => {
127 self.string_encoding = PartialResult::FullMatch(string);
129 }
130
131 PartialResult::MatchMore(mut string) => {
132 string.push(chr);
133
134 if string.len() >= length {
135 self.string_encoding = PartialResult::FullMatch(string);
136 } else {
137 self.string_encoding = PartialResult::MatchMore(string);
138 }
139 }
140 }
141
142 Ok(self)
143 }
144}
145
146impl DecodeBytes {
147 fn new() -> DecodeBytes {
151 DecodeBytes {
152 length: PartialResult::new(),
153 byte_encoding: PartialResult::new()
154 }
155 }
156
157 #[inline] fn ready(&self) -> bool {
161 match (&self.length, &self.byte_encoding) {
162 (PartialResult::FullMatch(_), PartialResult::FullMatch(_)) => true,
163 _ => false
164 }
165 }
166
167 #[inline] fn to_bytes(self) -> Result<Vec<u8>, DecoderError> {
171 match self.byte_encoding {
172 PartialResult::FullMatch(bytes) => Ok(bytes),
173 PartialResult::MatchMore(_) => Err(DecoderError::NotReady)
174 }
175 }
176
177 fn decode(mut self, chr: char) -> Result<DecodeBytes, DecoderError> {
181 use PartialResult::*;
182
183 let length = match self.length {
185 MatchMore(so_far) => {
186 self.length = CanvasDecoder::decode_compact_id(chr, so_far)?;
187
188 if let &FullMatch(0) = &self.length {
189 self.byte_encoding = FullMatch(vec![]);
190 }
191 return Ok(self);
192 }
193
194 FullMatch(length) => {
195 self.length = PartialResult::FullMatch(length);
196 length as usize
197 }
198 };
199
200 match self.byte_encoding {
202 FullMatch(_) => {
203 return Err(DecoderError::NotReady);
205 }
206
207 MatchMore(mut encoded_bytes) => {
208 encoded_bytes.push(chr);
209
210 let encoded_length = (encoded_bytes.len()/4)*3;
212
213 if encoded_length >= length {
214 let mut decoded_bytes = vec![];
216
217 for (a, b, c, d) in encoded_bytes.chars().tuples() {
219 let a = CanvasDecoder::decode_base64(a)?;
221 let b = CanvasDecoder::decode_base64(b)?;
222 let c = CanvasDecoder::decode_base64(c)?;
223 let d = CanvasDecoder::decode_base64(d)?;
224
225 let a = a | ((b<<6)&0xff);
227 let b = (b>>2) | ((c<<4)&0xff);
228 let c = (c>>4) | ((d<<2)&0xff);
229
230 decoded_bytes.push(a);
232 decoded_bytes.push(b);
233 decoded_bytes.push(c);
234 }
235
236 decoded_bytes.truncate(length);
238
239 self.byte_encoding = FullMatch(decoded_bytes);
241 } else {
242 self.byte_encoding = MatchMore(encoded_bytes);
244 }
245
246 return Ok(self);
247 }
248 }
249 }
250}
251
252impl DecodeGlyphPositions {
253 fn new() -> DecodeGlyphPositions {
257 DecodeGlyphPositions {
258 length: PartialResult::new(),
259 glyphs: PartialResult::new()
260 }
261 }
262
263 #[inline] fn ready(&self) -> bool {
267 match (&self.length, &self.glyphs) {
268 (PartialResult::FullMatch(_), PartialResult::FullMatch(_)) => true,
269 _ => false
270 }
271 }
272
273 #[inline] fn to_glyphs(self) -> Result<Vec<GlyphPosition>, DecoderError> {
277 match self.glyphs {
278 PartialResult::FullMatch(glyphs) => Ok(glyphs),
279 PartialResult::MatchMore(_) => Err(DecoderError::NotReady)
280 }
281 }
282
283 fn decode(mut self, chr: char) -> Result<DecodeGlyphPositions, DecoderError> {
287 let length = match self.length {
289 PartialResult::MatchMore(so_far) => {
290 self.length = CanvasDecoder::decode_compact_id(chr, so_far)?;
291
292 if let &PartialResult::FullMatch(0) = &self.length {
293 self.glyphs = PartialResult::FullMatch(vec![]);
294 }
295 return Ok(self);
296 }
297
298 PartialResult::FullMatch(length) => {
299 self.length = PartialResult::FullMatch(length);
300 length as usize
301 }
302 };
303
304 match self.glyphs {
306 PartialResult::FullMatch(glyphs) => {
307 self.glyphs = PartialResult::FullMatch(glyphs);
309 }
310
311 PartialResult::MatchMore(mut string) => {
312 string.push(chr);
313
314 if string.len() >= length * 24 {
315 let mut chrs = string.chars();
316 let mut glyphs = vec![];
317
318 for _ in 0..length {
320 let id = CanvasDecoder::decode_u32(&mut chrs)?;
321 let x = CanvasDecoder::decode_f32(&mut chrs)?;
322 let y = CanvasDecoder::decode_f32(&mut chrs)?;
323 let em_size = CanvasDecoder::decode_f32(&mut chrs)?;
324
325 glyphs.push(GlyphPosition {
326 id: GlyphId(id),
327 location: (x, y),
328 em_size: em_size
329 });
330 }
331
332 self.glyphs = PartialResult::FullMatch(glyphs);
333 } else {
334 self.glyphs = PartialResult::MatchMore(string);
335 }
336 }
337 }
338
339 Ok(self)
340 }
341}
342
343enum DecoderState {
347 None,
348 Error,
349
350 New, LineStyle, Dash, Color, Sprite, Transform, State, ClearCanvas(String), Move(String), Line(String), BezierCurve(String), LineStyleWidth(String), LineStyleWidthPixels(String), LineStyleJoin(String), LineStyleCap(String), WindingRule, DashLength(String), DashOffset(String), ColorStroke(String), ColorFill(String), ColorTexture(DecodeTextureId, String), ColorGradient(DecodeGradientId, String), ColorTransform(String), BlendMode(String), TransformHeight(String), TransformCenter(String), TransformMultiply(String), NewLayerU32(String), NewLayerBlendU32(String), NewLayer(String), NewLayerBlend(DecodeLayerId, String), SwapLayers(Option<LayerId>, String), NewSprite(String), SpriteDraw(String), SpriteTransform, SpriteTransformTranslate(String), SpriteTransformScale(String), SpriteTransformRotate(String), SpriteTransformTransform(String), FontDrawing, FontDrawText(DecodeFontId, DecodeString, String), FontBeginLayout(String), FontOp(DecodeFontId), FontOpSize(FontId, String), FontOpData(FontId), FontOpTtf(FontId, DecodeBytes), FontOpLayoutText(FontId, DecodeString), FontOpDrawGlyphs(FontId, DecodeGlyphPositions), TextureOp(DecodeTextureId), TextureOpCreate(TextureId, String), TextureOpSetBytes(TextureId, String, DecodeBytes), TextureOpFillTransparency(TextureId, String), GradientOp(DecodeGradientId), GradientOpNew(GradientId, String), GradientOpAddStop(GradientId, String), }
419
420#[derive(Clone, Copy, Debug, PartialEq)]
424pub enum DecoderError {
425 InvalidCharacter(char),
427
428 MissingCharacter,
430
431 BadNumber,
433
434 UnknownColorType,
436
437 IsInErrorState,
439
440 NotReady
442}
443
444pub struct CanvasDecoder {
448 state: DecoderState
449}
450
451impl CanvasDecoder {
452 pub fn new() -> CanvasDecoder {
456 CanvasDecoder {
457 state: DecoderState::None
458 }
459 }
460
461 pub fn decode(&mut self, next_chr: char) -> Result<Option<Draw>, DecoderError> {
465 use self::DecoderState::*;
466
467 let mut state = DecoderState::Error;
469 mem::swap(&mut self.state, &mut state);
470
471 let (next_state, result) = match state {
472 None => Self::decode_none(next_chr)?,
473 Error => Err(DecoderError::IsInErrorState)?,
474
475 New => Self::decode_new(next_chr)?,
476 LineStyle => Self::decode_line_style(next_chr)?,
477 Dash => Self::decode_dash(next_chr)?,
478 Color => Self::decode_color(next_chr)?,
479 Sprite => Self::decode_sprite(next_chr)?,
480 Transform => Self::decode_transform(next_chr)?,
481 State => Self::decode_state(next_chr)?,
482
483 Move(param) => Self::decode_move(next_chr, param)?,
484 Line(param) => Self::decode_line(next_chr, param)?,
485 BezierCurve(param) => Self::decode_bezier_curve(next_chr, param)?,
486
487 LineStyleWidth(param) => Self::decode_line_width(next_chr, param)?,
488 LineStyleWidthPixels(param) => Self::decode_line_width_pixels(next_chr, param)?,
489 LineStyleJoin(param) => Self::decode_line_style_join(next_chr, param)?,
490 LineStyleCap(param) => Self::decode_line_style_cap(next_chr, param)?,
491 WindingRule => Self::decode_winding_rule(next_chr)?,
492
493 DashLength(param) => Self::decode_dash_length(next_chr, param)?,
494 DashOffset(param) => Self::decode_dash_offset(next_chr, param)?,
495
496 ClearCanvas(param) => Self::decode_clear_canvas(next_chr, param)?,
497
498 ColorStroke(param) => Self::decode_color_stroke(next_chr, param)?,
499 ColorFill(param) => Self::decode_color_fill(next_chr, param)?,
500 ColorTexture(id, param) => Self::decode_color_texture(next_chr, id, param)?,
501 ColorGradient(id, param) => Self::decode_color_gradient(next_chr, id, param)?,
502 ColorTransform(param) => Self::decode_color_transform(next_chr, param)?,
503
504 BlendMode(param) => Self::decode_blend_mode(next_chr, param)?,
505
506 TransformHeight(param) => Self::decode_transform_height(next_chr, param)?,
507 TransformCenter(param) => Self::decode_transform_center(next_chr, param)?,
508 TransformMultiply(param) => Self::decode_transform_multiply(next_chr, param)?,
509
510 NewLayerU32(param) => Self::decode_new_layer_u32(next_chr, param)?,
511 NewLayerBlendU32(param) => Self::decode_new_layer_blend_u32(next_chr, param)?,
512 NewLayer(param) => Self::decode_new_layer(next_chr, param)?,
513 NewLayerBlend(layer, blend) => Self::decode_new_layer_blend(next_chr, layer, blend)?,
514 SwapLayers(layer1, param) => Self::decode_swap_layers(next_chr, layer1, param)?,
515
516 NewSprite(param) => Self::decode_new_sprite(next_chr, param)?,
517 SpriteDraw(param) => Self::decode_sprite_draw(next_chr, param)?,
518 SpriteTransform => Self::decode_sprite_transform(next_chr)?,
519 SpriteTransformTranslate(param) => Self::decode_sprite_transform_translate(next_chr, param)?,
520 SpriteTransformScale(param) => Self::decode_sprite_transform_scale(next_chr, param)?,
521 SpriteTransformRotate(param) => Self::decode_sprite_transform_rotate(next_chr, param)?,
522 SpriteTransformTransform(param) => Self::decode_sprite_transform_transform(next_chr, param)?,
523
524 FontDrawing => Self::decode_font_drawing(next_chr)?,
525 FontDrawText(font_id, string_decode, coords) => Self::decode_font_draw_text(next_chr, font_id, string_decode, coords)?,
526 FontBeginLayout(param) => Self::decode_font_begin_layout(next_chr, param)?,
527
528 FontOp(font_id) => Self::decode_font_op(next_chr, font_id)?,
529 FontOpSize(font_id, size) => Self::decode_font_op_size(next_chr, font_id, size)?,
530 FontOpData(font_id) => Self::decode_font_op_data(next_chr, font_id)?,
531 FontOpTtf(font_id, bytes) => Self::decode_font_data_ttf(next_chr, font_id, bytes)?,
532 FontOpLayoutText(font_id, string) => Self::decode_font_op_layout(next_chr, font_id, string)?,
533 FontOpDrawGlyphs(font_id, glyphs) => Self::decode_font_op_glyphs(next_chr, font_id, glyphs)?,
534
535 TextureOp(texture_id) => Self::decode_texture_op(next_chr, texture_id)?,
536 TextureOpCreate(texture_id, param) => Self::decode_texture_create(next_chr, texture_id, param)?,
537 TextureOpSetBytes(texture_id, param, bytes) => Self::decode_texture_set_bytes(next_chr, texture_id, param, bytes)?,
538 TextureOpFillTransparency(texture_id, param) => Self::decode_texture_fill_transparency(next_chr, texture_id, param)?,
539
540 GradientOp(gradient_id) => Self::decode_gradient_op(next_chr, gradient_id)?,
541 GradientOpNew(gradient_id, param) => Self::decode_gradient_new(next_chr, gradient_id, param)?,
542 GradientOpAddStop(gradient_id, param) => Self::decode_gradient_add_stop(next_chr, gradient_id, param)?,
543 };
544
545 self.state = next_state;
546 Ok(result)
547 }
548
549 #[inline] fn decode_none(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
553 match next_chr {
554 '\n' | '\r' | ' ' => Ok((DecoderState::None, None)),
556
557 'N' => Ok((DecoderState::New, None)),
559 'L' => Ok((DecoderState::LineStyle, None)),
560 'D' => Ok((DecoderState::Dash, None)),
561 'C' => Ok((DecoderState::Color, None)),
562 's' => Ok((DecoderState::Sprite, None)),
563 'T' => Ok((DecoderState::Transform, None)),
564 'Z' => Ok((DecoderState::State, None)),
565 'W' => Ok((DecoderState::WindingRule, None)),
566
567 '.' => Ok((DecoderState::None, Some(Draw::Path(PathOp::ClosePath)))),
569 'F' => Ok((DecoderState::None, Some(Draw::Fill))),
570 'S' => Ok((DecoderState::None, Some(Draw::Stroke))),
571 'P' => Ok((DecoderState::None, Some(Draw::PushState))),
572 'p' => Ok((DecoderState::None, Some(Draw::PopState))),
573
574 'm' => Ok((DecoderState::Move(String::new()), None)),
576 'l' => Ok((DecoderState::Line(String::new()), None)),
577 'c' => Ok((DecoderState::BezierCurve(String::new()), None)),
578 'M' => Ok((DecoderState::BlendMode(String::new()), None)),
579
580 't' => Ok((DecoderState::FontDrawing, None)),
581 'f' => Ok((DecoderState::FontOp(PartialResult::MatchMore(String::new())), None)),
582
583 'B' => Ok((DecoderState::TextureOp(PartialResult::new()), None)),
584
585 'G' => Ok((DecoderState::GradientOp(PartialResult::new()), None)),
586
587 _ => Err(DecoderError::InvalidCharacter(next_chr))
589 }
590 }
591
592 #[inline] fn decode_new(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
593 match next_chr {
595 'p' => Ok((DecoderState::None, Some(Draw::Path(PathOp::NewPath)))),
596 'A' => Ok((DecoderState::ClearCanvas(String::new()), None)),
597 'a' => Ok((DecoderState::None, Some(Draw::ClearAllLayers))),
598 'C' => Ok((DecoderState::None, Some(Draw::ClearLayer))),
599
600 'l' => Ok((DecoderState::NewLayerU32(String::new()), None)),
601 'b' => Ok((DecoderState::NewLayerBlendU32(String::new()), None)),
602 'L' => Ok((DecoderState::NewLayer(String::new()), None)),
603 'B' => Ok((DecoderState::NewLayerBlend(PartialResult::MatchMore(String::new()), String::new()), None)),
604 'X' => Ok((DecoderState::SwapLayers(None, String::new()), None)),
605 's' => Ok((DecoderState::NewSprite(String::new()), None)),
606
607 'F' => Ok((DecoderState::None, Some(Draw::StartFrame))),
608 'f' => Ok((DecoderState::None, Some(Draw::ShowFrame))),
609 'G' => Ok((DecoderState::None, Some(Draw::ResetFrame))),
610
611 _ => Err(DecoderError::InvalidCharacter(next_chr))
612 }
613 }
614
615 #[inline] fn decode_line_style(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
616 match next_chr {
618 'w' => Ok((DecoderState::LineStyleWidth(String::new()), None)),
619 'p' => Ok((DecoderState::LineStyleWidthPixels(String::new()), None)),
620 'j' => Ok((DecoderState::LineStyleJoin(String::new()), None)),
621 'c' => Ok((DecoderState::LineStyleCap(String::new()), None)),
622
623 _ => Err(DecoderError::InvalidCharacter(next_chr))
624 }
625 }
626
627 #[inline] fn decode_dash(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
628 match next_chr {
630 'n' => Ok((DecoderState::None, Some(Draw::NewDashPattern))),
631
632 'l' => Ok((DecoderState::DashLength(String::new()), None)),
633 'o' => Ok((DecoderState::DashOffset(String::new()), None)),
634
635 _ => Err(DecoderError::InvalidCharacter(next_chr))
636 }
637 }
638
639 #[inline] fn decode_color(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
640 match next_chr {
642 's' => Ok((DecoderState::ColorStroke(String::new()), None)),
643 'f' => Ok((DecoderState::ColorFill(String::new()), None)),
644 't' => Ok((DecoderState::ColorTexture(DecodeTextureId::new(), String::new()), None)),
645 'g' => Ok((DecoderState::ColorGradient(DecodeGradientId::new(), String::new()), None)),
646 'T' => Ok((DecoderState::ColorTransform(String::new()), None)),
647
648 _ => Err(DecoderError::InvalidCharacter(next_chr))
649 }
650 }
651
652 #[inline] fn decode_sprite(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
653 match next_chr {
655 'D' => Ok((DecoderState::SpriteDraw(String::new()), None)),
656 'C' => Ok((DecoderState::None, Some(Draw::ClearSprite))),
657 'T' => Ok((DecoderState::SpriteTransform, None)),
658
659 _ => Err(DecoderError::InvalidCharacter(next_chr))
660 }
661 }
662
663 #[inline] fn decode_transform(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
664 match next_chr {
666 'i' => Ok((DecoderState::None, Some(Draw::IdentityTransform))),
667 'h' => Ok((DecoderState::TransformHeight(String::new()), None)),
668 'c' => Ok((DecoderState::TransformCenter(String::new()), None)),
669 'm' => Ok((DecoderState::TransformMultiply(String::new()), None)),
670
671 _ => Err(DecoderError::InvalidCharacter(next_chr))
672 }
673 }
674
675 #[inline] fn decode_state(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
676 match next_chr {
678 'n' => Ok((DecoderState::None, Some(Draw::Unclip))),
679 'c' => Ok((DecoderState::None, Some(Draw::Clip))),
680 's' => Ok((DecoderState::None, Some(Draw::Store))),
681 'r' => Ok((DecoderState::None, Some(Draw::Restore))),
682 'f' => Ok((DecoderState::None, Some(Draw::FreeStoredBuffer))),
683
684 _ => Err(DecoderError::InvalidCharacter(next_chr))
685 }
686 }
687
688 #[inline] fn decode_line_width_pixels(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
689 if param.len() < 5 {
690 param.push(next_chr);
691 Ok((DecoderState::LineStyleWidthPixels(param), None))
692 } else {
693 param.push(next_chr);
694
695 let mut param = param.chars();
696 let width = Self::decode_f32(&mut param)?;
697
698 Ok((DecoderState::None, Some(Draw::LineWidthPixels(width))))
699 }
700 }
701
702 #[inline] fn decode_move(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
703 if param.len() < 11 {
704 param.push(next_chr);
705 Ok((DecoderState::Move(param), None))
706 } else {
707 param.push(next_chr);
708
709 let mut param = param.chars();
710 let x = Self::decode_f32(&mut param)?;
711 let y = Self::decode_f32(&mut param)?;
712
713 Ok((DecoderState::None, Some(Draw::Path(PathOp::Move(x, y)))))
714 }
715 }
716
717 #[inline] fn decode_line(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
718 if param.len() < 11 {
719 param.push(next_chr);
720 Ok((DecoderState::Line(param), None))
721 } else {
722 param.push(next_chr);
723
724 let mut param = param.chars();
725 let x = Self::decode_f32(&mut param)?;
726 let y = Self::decode_f32(&mut param)?;
727
728 Ok((DecoderState::None, Some(Draw::Path(PathOp::Line(x, y)))))
729 }
730 }
731
732 #[inline] fn decode_bezier_curve(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
733 if param.len() < 35 {
734 param.push(next_chr);
735 Ok((DecoderState::BezierCurve(param), None))
736 } else {
737 param.push(next_chr);
738
739 let mut param = param.chars();
740 let x1 = Self::decode_f32(&mut param)?;
741 let y1 = Self::decode_f32(&mut param)?;
742 let cp1x = Self::decode_f32(&mut param)?;
743 let cp1y = Self::decode_f32(&mut param)?;
744 let cp2x = Self::decode_f32(&mut param)?;
745 let cp2y = Self::decode_f32(&mut param)?;
746
747 Ok((DecoderState::None, Some(Draw::Path(PathOp::BezierCurve(((cp1x, cp1y), (cp2x, cp2y)), (x1, y1))))))
748 }
749 }
750
751 #[inline] fn decode_line_width(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
752 if param.len() < 5 {
753 param.push(next_chr);
754 Ok((DecoderState::LineStyleWidth(param), None))
755 } else {
756 param.push(next_chr);
757
758 let mut param = param.chars();
759 let width = Self::decode_f32(&mut param)?;
760
761 Ok((DecoderState::None, Some(Draw::LineWidth(width))))
762 }
763 }
764
765 #[inline] fn decode_line_style_join(next_chr: char, _param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
766 match next_chr {
767 'M' => Ok((DecoderState::None, Some(Draw::LineJoin(LineJoin::Miter)))),
768 'R' => Ok((DecoderState::None, Some(Draw::LineJoin(LineJoin::Round)))),
769 'B' => Ok((DecoderState::None, Some(Draw::LineJoin(LineJoin::Bevel)))),
770
771 _ => Err(DecoderError::InvalidCharacter(next_chr))
772 }
773 }
774
775 #[inline] fn decode_line_style_cap(next_chr: char, _param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
776 match next_chr {
777 'B' => Ok((DecoderState::None, Some(Draw::LineCap(LineCap::Butt)))),
778 'R' => Ok((DecoderState::None, Some(Draw::LineCap(LineCap::Round)))),
779 'S' => Ok((DecoderState::None, Some(Draw::LineCap(LineCap::Square)))),
780
781 _ => Err(DecoderError::InvalidCharacter(next_chr))
782 }
783 }
784
785 #[inline] fn decode_dash_length(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
786 if param.len() < 5 {
787 param.push(next_chr);
788 Ok((DecoderState::DashLength(param), None))
789 } else {
790 param.push(next_chr);
791 let mut param = param.chars();
792 Ok((DecoderState::None, Some(Draw::DashLength(Self::decode_f32(&mut param)?))))
793 }
794 }
795
796 #[inline] fn decode_dash_offset(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
797 if param.len() < 5 {
798 param.push(next_chr);
799 Ok((DecoderState::DashOffset(param), None))
800 } else {
801 param.push(next_chr);
802 let mut param = param.chars();
803 Ok((DecoderState::None, Some(Draw::DashOffset(Self::decode_f32(&mut param)?))))
804 }
805 }
806
807 #[inline] fn decode_clear_canvas(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
808 if param.len() < 24 {
809 param.push(next_chr);
810 Ok((DecoderState::ClearCanvas(param), None))
811 } else {
812 param.push(next_chr);
813
814 let mut param = param.chars();
815 let col_type = param.next();
816 let r = Self::decode_f32(&mut param)?;
817 let g = Self::decode_f32(&mut param)?;
818 let b = Self::decode_f32(&mut param)?;
819 let a = Self::decode_f32(&mut param)?;
820
821 if col_type != Some('R') {
822 Err(DecoderError::UnknownColorType)?;
823 }
824
825 Ok((DecoderState::None, Some(Draw::ClearCanvas(Color::Rgba(r, g, b, a)))))
826 }
827 }
828
829 #[inline] fn decode_color_stroke(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
830 if param.len() < 24 {
831 param.push(next_chr);
832 Ok((DecoderState::ColorStroke(param), None))
833 } else {
834 param.push(next_chr);
835
836 let mut param = param.chars();
837 let col_type = param.next();
838 let r = Self::decode_f32(&mut param)?;
839 let g = Self::decode_f32(&mut param)?;
840 let b = Self::decode_f32(&mut param)?;
841 let a = Self::decode_f32(&mut param)?;
842
843 if col_type != Some('R') {
844 Err(DecoderError::UnknownColorType)?;
845 }
846
847 Ok((DecoderState::None, Some(Draw::StrokeColor(Color::Rgba(r, g, b, a)))))
848 }
849 }
850
851 #[inline] fn decode_color_fill(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
852 if param.len() < 24 {
853 param.push(next_chr);
854 Ok((DecoderState::ColorFill(param), None))
855 } else {
856 param.push(next_chr);
857
858 let mut param = param.chars();
859 let col_type = param.next();
860 let r = Self::decode_f32(&mut param)?;
861 let g = Self::decode_f32(&mut param)?;
862 let b = Self::decode_f32(&mut param)?;
863 let a = Self::decode_f32(&mut param)?;
864
865 if col_type != Some('R') {
866 Err(DecoderError::UnknownColorType)?;
867 }
868
869 Ok((DecoderState::None, Some(Draw::FillColor(Color::Rgba(r, g, b, a)))))
870 }
871 }
872
873 #[inline] fn decode_color_texture(next_chr: char, texture_id: DecodeTextureId, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
874 use self::PartialResult::*;
875
876 let texture_id = match texture_id {
878 MatchMore(texture_id) => {
879 let texture_id = Self::decode_texture_id(next_chr, texture_id)?;
880 return Ok((DecoderState::ColorTexture(texture_id, param), None));
881 }
882
883 FullMatch(texture_id) => texture_id
884 };
885
886 param.push(next_chr);
888
889 if param.len() < 24 {
890 Ok((DecoderState::ColorTexture(FullMatch(texture_id), param), None))
892 } else {
893 let mut param = param.chars();
895 let x1 = Self::decode_f32(&mut param)?;
896 let y1 = Self::decode_f32(&mut param)?;
897 let x2 = Self::decode_f32(&mut param)?;
898 let y2 = Self::decode_f32(&mut param)?;
899
900 Ok((DecoderState::None, Some(Draw::FillTexture(texture_id, (x1, y1), (x2, y2)))))
901 }
902 }
903
904 #[inline] fn decode_color_gradient(next_chr: char, gradient_id: DecodeGradientId, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
905 use self::PartialResult::*;
906
907 let gradient_id = match gradient_id {
909 MatchMore(gradient_id) => {
910 let gradient_id = Self::decode_gradient_id(next_chr, gradient_id)?;
911 return Ok((DecoderState::ColorGradient(gradient_id, param), None));
912 }
913
914 FullMatch(gradient_id) => gradient_id
915 };
916
917 param.push(next_chr);
919
920 if param.len() < 24 {
921 Ok((DecoderState::ColorGradient(FullMatch(gradient_id), param), None))
923 } else {
924 let mut param = param.chars();
926 let x1 = Self::decode_f32(&mut param)?;
927 let y1 = Self::decode_f32(&mut param)?;
928 let x2 = Self::decode_f32(&mut param)?;
929 let y2 = Self::decode_f32(&mut param)?;
930
931 Ok((DecoderState::None, Some(Draw::FillGradient(gradient_id, (x1, y1), (x2, y2)))))
932 }
933 }
934
935 #[inline] fn decode_color_transform(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
936 if param.len() < 53 {
937 param.push(next_chr);
938 Ok((DecoderState::ColorTransform(param), None))
939 } else {
940 param.push(next_chr);
941 let mut param = param.chars();
942
943 let mut matrix = [0.0; 9];
944 for entry in 0..9 {
945 matrix[entry] = Self::decode_f32(&mut param)?;
946 }
947
948 let transform = Transform2D([[matrix[0], matrix[1], matrix[2]], [matrix[3], matrix[4], matrix[5]], [matrix[6], matrix[7], matrix[8]]]);
949
950 Ok((DecoderState::None, Some(Draw::FillTransform(transform))))
951 }
952 }
953
954 #[inline] fn decode_blend_mode(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
955 if param.len() < 1 {
956 param.push(next_chr);
957 Ok((DecoderState::BlendMode(param), None))
958 } else {
959 param.push(next_chr);
960 let mut param = param.chars();
961 Ok((DecoderState::None, Some(Draw::BlendMode(Self::decode_blend_mode_only(&mut param)?))))
962 }
963 }
964
965 #[inline] fn decode_transform_height(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
966 if param.len() < 5 {
967 param.push(next_chr);
968 Ok((DecoderState::TransformHeight(param), None))
969 } else {
970 param.push(next_chr);
971 let mut param = param.chars();
972 Ok((DecoderState::None, Some(Draw::CanvasHeight(Self::decode_f32(&mut param)?))))
973 }
974 }
975
976 #[inline] fn decode_transform_center(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
977 if param.len() < 23 {
978 param.push(next_chr);
979 Ok((DecoderState::TransformCenter(param), None))
980 } else {
981 param.push(next_chr);
982
983 let mut param = param.chars();
984 let min_x = Self::decode_f32(&mut param)?;
985 let min_y = Self::decode_f32(&mut param)?;
986 let max_x = Self::decode_f32(&mut param)?;
987 let max_y = Self::decode_f32(&mut param)?;
988
989 Ok((DecoderState::None, Some(Draw::CenterRegion((min_x, min_y), (max_x, max_y)))))
990 }
991 }
992
993 #[inline] fn decode_transform_multiply(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
994 if param.len() < 53 {
995 param.push(next_chr);
996 Ok((DecoderState::TransformMultiply(param), None))
997 } else {
998 param.push(next_chr);
999 let mut param = param.chars();
1000
1001 let mut matrix = [0.0; 9];
1002 for entry in 0..9 {
1003 matrix[entry] = Self::decode_f32(&mut param)?;
1004 }
1005
1006 let transform = Transform2D([[matrix[0], matrix[1], matrix[2]], [matrix[3], matrix[4], matrix[5]], [matrix[6], matrix[7], matrix[8]]]);
1007
1008 Ok((DecoderState::None, Some(Draw::MultiplyTransform(transform))))
1009 }
1010 }
1011
1012 #[inline] fn decode_new_layer_u32(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1013 if param.len() < 5 {
1014 param.push(next_chr);
1015 Ok((DecoderState::NewLayerU32(param), None))
1016 } else {
1017 param.push(next_chr);
1018 let mut param = param.chars();
1019 Ok((DecoderState::None, Some(Draw::Layer(LayerId(Self::decode_u32(&mut param)? as _)))))
1020 }
1021 }
1022
1023 #[inline] fn decode_new_layer_blend_u32(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1024 if param.len() < 7 {
1025 param.push(next_chr);
1026 Ok((DecoderState::NewLayerBlendU32(param), None))
1027 } else {
1028 param.push(next_chr);
1029
1030 let mut param = param.chars();
1031 let layer_id = Self::decode_u32(&mut param)?;
1032 let blend_mode = Self::decode_blend_mode_only(&mut param)?;
1033
1034 Ok((DecoderState::None, Some(Draw::LayerBlend(LayerId(layer_id as _), blend_mode))))
1035 }
1036 }
1037
1038 #[inline] fn decode_new_layer(next_chr: char, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1039 match Self::decode_layer_id(next_chr, param)? {
1040 PartialResult::FullMatch(layer_id) => Ok((DecoderState::None, Some(Draw::Layer(layer_id)))),
1041 PartialResult::MatchMore(param) => Ok((DecoderState::NewLayer(param), None))
1042 }
1043 }
1044
1045 #[inline] fn decode_swap_layers(next_chr: char, layer1: Option<LayerId>, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1046 match (layer1, Self::decode_layer_id(next_chr, param)?) {
1047 (None, PartialResult::FullMatch(layer_id)) => Ok((DecoderState::SwapLayers(Some(layer_id), String::new()), None)),
1048 (Some(layer1), PartialResult::FullMatch(layer2)) => Ok((DecoderState::None, Some(Draw::SwapLayers(layer1, layer2)))),
1049 (layer1, PartialResult::MatchMore(param)) => Ok((DecoderState::SwapLayers(layer1, param), None))
1050 }
1051 }
1052
1053 #[inline] fn decode_new_layer_blend(next_chr: char, layer_param: PartialResult<LayerId>, mut blend_mode: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1054 match (layer_param, blend_mode.len()) {
1055 (PartialResult::MatchMore(layer_param), _) => Ok((DecoderState::NewLayerBlend(Self::decode_layer_id(next_chr, layer_param)?, blend_mode), None)),
1056 (PartialResult::FullMatch(layer_id), 0) => { blend_mode.push(next_chr); Ok((DecoderState::NewLayerBlend(PartialResult::FullMatch(layer_id), blend_mode), None)) },
1057 (PartialResult::FullMatch(layer_id), _) => { blend_mode.push(next_chr); Ok((DecoderState::None, Some(Draw::LayerBlend(layer_id, Self::decode_blend_mode_only(&mut blend_mode.chars())?)))) }
1058 }
1059 }
1060
1061 #[inline] fn decode_new_sprite(next_chr: char, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1062 match Self::decode_sprite_id(next_chr, param)? {
1063 PartialResult::FullMatch(sprite_id) => Ok((DecoderState::None, Some(Draw::Sprite(sprite_id)))),
1064 PartialResult::MatchMore(param) => Ok((DecoderState::NewSprite(param), None))
1065 }
1066 }
1067
1068 #[inline] fn decode_sprite_draw(next_chr: char, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1069 match Self::decode_sprite_id(next_chr, param)? {
1070 PartialResult::FullMatch(sprite_id) => Ok((DecoderState::None, Some(Draw::DrawSprite(sprite_id)))),
1071 PartialResult::MatchMore(param) => Ok((DecoderState::SpriteDraw(param), None))
1072 }
1073 }
1074
1075 #[inline] fn decode_sprite_transform(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1076 match next_chr {
1077 'i' => Ok((DecoderState::None, Some(Draw::SpriteTransform(SpriteTransform::Identity)))),
1078 't' => Ok((DecoderState::SpriteTransformTranslate(String::new()), None)),
1079 's' => Ok((DecoderState::SpriteTransformScale(String::new()), None)),
1080 'r' => Ok((DecoderState::SpriteTransformRotate(String::new()), None)),
1081 'T' => Ok((DecoderState::SpriteTransformTransform(String::new()), None)),
1082
1083 _ => Err(DecoderError::InvalidCharacter(next_chr))
1084 }
1085 }
1086
1087 #[inline] fn decode_sprite_transform_translate(next_chr: char, mut param: String)-> Result<(DecoderState, Option<Draw>), DecoderError> {
1088 if param.len() < 11 {
1089 param.push(next_chr);
1090 Ok((DecoderState::SpriteTransformTranslate(param), None))
1091 } else {
1092 param.push(next_chr);
1093
1094 let mut param = param.chars();
1095 let x = Self::decode_f32(&mut param)?;
1096 let y = Self::decode_f32(&mut param)?;
1097
1098 Ok((DecoderState::None, Some(Draw::SpriteTransform(SpriteTransform::Translate(x, y)))))
1099 }
1100 }
1101
1102 #[inline] fn decode_sprite_transform_scale(next_chr: char, mut param: String)-> Result<(DecoderState, Option<Draw>), DecoderError> {
1103 if param.len() < 11 {
1104 param.push(next_chr);
1105 Ok((DecoderState::SpriteTransformScale(param), None))
1106 } else {
1107 param.push(next_chr);
1108
1109 let mut param = param.chars();
1110 let x = Self::decode_f32(&mut param)?;
1111 let y = Self::decode_f32(&mut param)?;
1112
1113 Ok((DecoderState::None, Some(Draw::SpriteTransform(SpriteTransform::Scale(x, y)))))
1114 }
1115 }
1116
1117 #[inline] fn decode_sprite_transform_rotate(next_chr: char, mut param: String)-> Result<(DecoderState, Option<Draw>), DecoderError> {
1118 if param.len() < 5 {
1119 param.push(next_chr);
1120 Ok((DecoderState::SpriteTransformRotate(param), None))
1121 } else {
1122 param.push(next_chr);
1123
1124 let mut param = param.chars();
1125 let degrees = Self::decode_f32(&mut param)?;
1126
1127 Ok((DecoderState::None, Some(Draw::SpriteTransform(SpriteTransform::Rotate(degrees)))))
1128 }
1129 }
1130
1131 #[inline] fn decode_sprite_transform_transform(next_chr: char, mut param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1132 if param.len() < 53 {
1133 param.push(next_chr);
1134 Ok((DecoderState::SpriteTransformTransform(param), None))
1135 } else {
1136 param.push(next_chr);
1137 let mut param = param.chars();
1138
1139 let mut matrix = [0.0; 9];
1140 for entry in 0..9 {
1141 matrix[entry] = Self::decode_f32(&mut param)?;
1142 }
1143
1144 let transform = Transform2D([[matrix[0], matrix[1], matrix[2]], [matrix[3], matrix[4], matrix[5]], [matrix[6], matrix[7], matrix[8]]]);
1145
1146 Ok((DecoderState::None, Some(Draw::SpriteTransform(SpriteTransform::Transform2D(transform)))))
1147 }
1148 }
1149
1150 #[inline] fn decode_winding_rule(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1151 match next_chr {
1152 'n' => Ok((DecoderState::None, Some(Draw::WindingRule(WindingRule::NonZero)))),
1153 'e' => Ok((DecoderState::None, Some(Draw::WindingRule(WindingRule::EvenOdd)))),
1154 _ => Err(DecoderError::InvalidCharacter(next_chr))
1155 }
1156 }
1157
1158 fn decode_blend_mode_only(param: &mut Chars) -> Result<BlendMode, DecoderError> {
1162 let (a, b) = (param.next(), param.next());
1163 let a = a.ok_or(DecoderError::MissingCharacter)?;
1164 let b = b.ok_or(DecoderError::MissingCharacter)?;
1165
1166 match (a, b) {
1167 ('S', 'V') => Ok(BlendMode::SourceOver),
1168 ('S', 'I') => Ok(BlendMode::SourceIn),
1169 ('S', 'O') => Ok(BlendMode::SourceOut),
1170 ('S', 'A') => Ok(BlendMode::SourceAtop),
1171
1172 ('D', 'V') => Ok(BlendMode::DestinationOver),
1173 ('D', 'I') => Ok(BlendMode::DestinationIn),
1174 ('D', 'O') => Ok(BlendMode::DestinationOut),
1175 ('D', 'A') => Ok(BlendMode::DestinationAtop),
1176
1177 ('E', 'M') => Ok(BlendMode::Multiply),
1178 ('E', 'S') => Ok(BlendMode::Screen),
1179 ('E', 'D') => Ok(BlendMode::Darken),
1180 ('E', 'L') => Ok(BlendMode::Lighten),
1181
1182 _ => Err(DecoderError::InvalidCharacter(a))
1183 }
1184 }
1185
1186 fn decode_compact_id(next_chr: char, mut param: String) -> Result<PartialResult<u64>, DecoderError> {
1190 param.push(next_chr);
1192
1193 if (Self::decode_base64(next_chr)? & 0x20) == 0 {
1195 let mut result = 0u64;
1196
1197 while let Some(chr) = param.pop() {
1198 result <<= 5;
1199 result |= (Self::decode_base64(chr)? & !0x20) as u64;
1200 }
1201
1202 Ok(PartialResult::FullMatch(result))
1203 } else {
1204 Ok(PartialResult::MatchMore(param))
1205 }
1206 }
1207
1208 fn decode_sprite_id(next_chr: char, param: String) -> Result<PartialResult<SpriteId>, DecoderError> {
1212 Self::decode_compact_id(next_chr, param)
1213 .map(|id| id.map(|id| SpriteId(id)))
1214 }
1215
1216 fn decode_layer_id(next_chr: char, param: String) -> Result<PartialResult<LayerId>, DecoderError> {
1220 Self::decode_compact_id(next_chr, param)
1221 .map(|id| id.map(|id| LayerId(id)))
1222 }
1223
1224 fn decode_font_id(next_chr: char, param: String) -> Result<PartialResult<FontId>, DecoderError> {
1228 Self::decode_compact_id(next_chr, param)
1229 .map(|id| id.map(|id| FontId(id)))
1230 }
1231
1232 fn decode_texture_id(next_chr: char, param: String) -> Result<PartialResult<TextureId>, DecoderError> {
1236 Self::decode_compact_id(next_chr, param)
1237 .map(|id| id.map(|id| TextureId(id)))
1238 }
1239
1240 fn decode_gradient_id(next_chr: char, param: String) -> Result<PartialResult<GradientId>, DecoderError> {
1244 Self::decode_compact_id(next_chr, param)
1245 .map(|id| id.map(|id| GradientId(id)))
1246 }
1247
1248 #[inline] fn decode_font_drawing(chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1252 match chr {
1253 'T' => Ok((DecoderState::FontDrawText(PartialResult::new(), DecodeString::new(), String::new()), None)),
1254 'R' => Ok((DecoderState::None, Some(Draw::DrawLaidOutText))),
1255 'l' => Ok((DecoderState::FontBeginLayout(String::new()), None)),
1256 _ => Err(DecoderError::InvalidCharacter(chr))
1257 }
1258 }
1259
1260 fn decode_font_draw_text(chr: char, font_id: DecodeFontId, string: DecodeString, mut coords: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1265 use PartialResult::*;
1266
1267 match (font_id, string.ready(), coords.len()) {
1268 (MatchMore(font_id), _, _) => Ok((DecoderState::FontDrawText(Self::decode_font_id(chr, font_id)?, string, coords), None)),
1269 (FullMatch(font_id), false, _) => Ok((DecoderState::FontDrawText(FullMatch(font_id), string.decode(chr)?, coords), None)),
1270
1271 (FullMatch(font_id), true, 0) |
1272 (FullMatch(font_id), true, 1) |
1273 (FullMatch(font_id), true, 2) |
1274 (FullMatch(font_id), true, 3) |
1275 (FullMatch(font_id), true, 4) |
1276 (FullMatch(font_id), true, 5) |
1277 (FullMatch(font_id), true, 6) |
1278 (FullMatch(font_id), true, 7) |
1279 (FullMatch(font_id), true, 8) |
1280 (FullMatch(font_id), true, 9) |
1281 (FullMatch(font_id), true, 10) => { coords.push(chr); Ok((DecoderState::FontDrawText(FullMatch(font_id), string, coords), None)) },
1282
1283 (FullMatch(font_id), true, _) => {
1284 coords.push(chr);
1285
1286 let mut coords = coords.chars();
1287 let x = Self::decode_f32(&mut coords)?;
1288 let y = Self::decode_f32(&mut coords)?;
1289
1290 Ok((DecoderState::None, Some(Draw::DrawText(font_id, string.to_string()?, x, y))))
1291 }
1292 }
1293 }
1294
1295 fn decode_font_begin_layout(chr: char, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1299 let mut param = param;
1301 param.push(chr);
1302
1303 if param.len() < 13 {
1305 return Ok((DecoderState::FontBeginLayout(param), None));
1306 }
1307
1308 let mut chrs = param.chars();
1310
1311 let x = Self::decode_f32(&mut chrs)?;
1312 let y = Self::decode_f32(&mut chrs)?;
1313
1314 let align = match chrs.next() {
1315 Some('l') => Ok(TextAlignment::Left),
1316 Some('r') => Ok(TextAlignment::Right),
1317 Some('c') => Ok(TextAlignment::Center),
1318 Some(other) => Err(DecoderError::InvalidCharacter(other)),
1319 None => Err(DecoderError::NotReady)
1320 }?;
1321
1322 Ok((DecoderState::None, Some(Draw::BeginLineLayout(x, y, align))))
1323 }
1324
1325 fn decode_font_op(chr: char, font_id: DecodeFontId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1332 use PartialResult::*;
1333
1334 let font_id = match font_id {
1336 MatchMore(font_id) => {
1337 let font_id = Self::decode_font_id(chr, font_id)?;
1338 return Ok((DecoderState::FontOp(font_id), None));
1339 }
1340
1341 FullMatch(font_id) => font_id
1342 };
1343
1344 match chr {
1346 'd' => Ok((DecoderState::FontOpData(font_id), None)),
1347 'S' => Ok((DecoderState::FontOpSize(font_id, String::new()), None)),
1348 'L' => Ok((DecoderState::FontOpLayoutText(font_id, DecodeString::new()), None)),
1349 'G' => Ok((DecoderState::FontOpDrawGlyphs(font_id, DecodeGlyphPositions::new()), None)),
1350
1351 _ => Err(DecoderError::InvalidCharacter(chr))
1352 }
1353 }
1354
1355 fn decode_font_op_size(chr: char, font_id: FontId, size: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1359 let mut size = size;
1361 size.push(chr);
1362
1363 if size.len() >= 6 {
1365 Ok((DecoderState::None, Some(Draw::Font(font_id, FontOp::FontSize(Self::decode_f32(&mut size.chars())?)))))
1366 } else {
1367 Ok((DecoderState::FontOpSize(font_id, size), None))
1369 }
1370 }
1371
1372 fn decode_font_op_data(chr: char, font_id: FontId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1376 match chr {
1377 'T' => Ok((DecoderState::FontOpTtf(font_id, DecodeBytes::new()), None)),
1378 _ => Err(DecoderError::InvalidCharacter(chr))
1379 }
1380 }
1381
1382 fn decode_font_data_ttf(chr: char, font_id: FontId, bytes: DecodeBytes) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1386 let bytes = bytes.decode(chr)?;
1388
1389 if bytes.ready() {
1391 let bytes = bytes.to_bytes()?;
1392 let font = CanvasFontFace::from_bytes(bytes);
1393 Ok((DecoderState::None, Some(Draw::Font(font_id, FontOp::UseFontDefinition(font)))))
1394 } else {
1395 Ok((DecoderState::FontOpTtf(font_id, bytes), None))
1396 }
1397 }
1398
1399 fn decode_font_op_layout(chr: char, font_id: FontId, string: DecodeString) -> Result<(DecoderState, Option<Draw>), DecoderError>{
1403 let string = string.decode(chr)?;
1404
1405 if string.ready() {
1406 let string = string.to_string()?;
1407 Ok((DecoderState::None, Some(Draw::Font(font_id, FontOp::LayoutText(string)))))
1408 } else {
1409 Ok((DecoderState::FontOpLayoutText(font_id, string), None))
1410 }
1411 }
1412
1413 fn decode_font_op_glyphs(chr: char, font_id: FontId, glyphs: DecodeGlyphPositions) -> Result<(DecoderState, Option<Draw>), DecoderError>{
1417 let glyphs = glyphs.decode(chr)?;
1418
1419 if glyphs.ready() {
1420 let glyphs = glyphs.to_glyphs()?;
1421 Ok((DecoderState::None, Some(Draw::Font(font_id, FontOp::DrawGlyphs(glyphs)))))
1422 } else {
1423 Ok((DecoderState::FontOpDrawGlyphs(font_id, glyphs), None))
1424 }
1425 }
1426
1427 fn decode_texture_op(chr: char, texture_id: DecodeTextureId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1431 use PartialResult::*;
1432
1433 let texture_id = match texture_id {
1435 MatchMore(texture_id) => {
1436 let texture_id = Self::decode_texture_id(chr, texture_id)?;
1437 return Ok((DecoderState::TextureOp(texture_id), None));
1438 }
1439
1440 FullMatch(texture_id) => texture_id
1441 };
1442
1443 match chr {
1445 'N' => Ok((DecoderState::TextureOpCreate(texture_id, String::new()), None)),
1446 'X' => Ok((DecoderState::None, Some(Draw::Texture(texture_id, TextureOp::Free)))),
1447 'D' => Ok((DecoderState::TextureOpSetBytes(texture_id, String::new(), DecodeBytes::new()), None)),
1448 't' => Ok((DecoderState::TextureOpFillTransparency(texture_id, String::new()), None)),
1449
1450 _ => Err(DecoderError::InvalidCharacter(chr))
1451 }
1452 }
1453
1454 fn decode_texture_create(chr: char, texture_id: TextureId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1458 let mut param = param;
1460 param.push(chr);
1461
1462 if param.len() < 13 {
1463 return Ok((DecoderState::TextureOpCreate(texture_id, param), None));
1464 }
1465
1466 let mut chars = param.chars();
1468 let w = Self::decode_u32(&mut chars)?;
1469 let h = Self::decode_u32(&mut chars)?;
1470
1471 let format = match chars.next() {
1472 Some('r') => TextureFormat::Rgba,
1473 Some(c) => { return Err(DecoderError::InvalidCharacter(c)); }
1474 None => { return Err(DecoderError::NotReady); }
1475 };
1476
1477 Ok((DecoderState::None, Some(Draw::Texture(texture_id, TextureOp::Create(w, h, format)))))
1478 }
1479
1480 fn decode_texture_set_bytes(chr: char, texture_id: TextureId, param: String, bytes: DecodeBytes) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1484 if param.len() < 24 {
1486 let mut param = param;
1487 param.push(chr);
1488 return Ok((DecoderState::TextureOpSetBytes(texture_id, param, bytes), None));
1489 }
1490
1491 let bytes = bytes.decode(chr)?;
1492
1493 if !bytes.ready() {
1494 return Ok((DecoderState::TextureOpSetBytes(texture_id, param, bytes), None));
1495 }
1496
1497 let mut chars = param.chars();
1499 let x = Self::decode_u32(&mut chars)?;
1500 let y = Self::decode_u32(&mut chars)?;
1501 let w = Self::decode_u32(&mut chars)?;
1502 let h = Self::decode_u32(&mut chars)?;
1503
1504 Ok((DecoderState::None, Some(Draw::Texture(texture_id, TextureOp::SetBytes(x, y, w, h, Arc::new(bytes.to_bytes()?))))))
1505 }
1506
1507 fn decode_texture_fill_transparency(chr: char, texture_id: TextureId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1511 let mut param = param;
1512 param.push(chr);
1513
1514 if param.len() < 6 {
1516 return Ok((DecoderState::TextureOpFillTransparency(texture_id, param), None));
1517 }
1518
1519 let mut chars = param.chars();
1521 let alpha = Self::decode_f32(&mut chars)?;
1522
1523 Ok((DecoderState::None, Some(Draw::Texture(texture_id, TextureOp::FillTransparency(alpha)))))
1524 }
1525
1526 fn decode_gradient_op(chr: char, gradient_id: DecodeGradientId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1530 use PartialResult::*;
1531
1532 let gradient_id = match gradient_id {
1534 MatchMore(gradient_id) => {
1535 let gradient_id = Self::decode_gradient_id(chr, gradient_id)?;
1536 return Ok((DecoderState::GradientOp(gradient_id), None));
1537 }
1538
1539 FullMatch(gradient_id) => gradient_id
1540 };
1541
1542 match chr {
1544 'N' => Ok((DecoderState::GradientOpNew(gradient_id, String::new()), None)),
1545 'S' => Ok((DecoderState::GradientOpAddStop(gradient_id, String::new()), None)),
1546
1547 _ => Err(DecoderError::InvalidCharacter(chr))
1548 }
1549 }
1550
1551 fn decode_gradient_new(next_chr: char, gradient_id: GradientId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1555 let mut param = param;
1557
1558 if param.len() < 24 {
1559 param.push(next_chr);
1560 Ok((DecoderState::GradientOpNew(gradient_id, param), None))
1561 } else {
1562 param.push(next_chr);
1563
1564 let mut param = param.chars();
1565 let col_type = param.next();
1566 let r = Self::decode_f32(&mut param)?;
1567 let g = Self::decode_f32(&mut param)?;
1568 let b = Self::decode_f32(&mut param)?;
1569 let a = Self::decode_f32(&mut param)?;
1570
1571 if col_type != Some('R') {
1572 Err(DecoderError::UnknownColorType)?;
1573 }
1574
1575 Ok((DecoderState::None, Some(Draw::Gradient(gradient_id, GradientOp::Create(Color::Rgba(r, g, b, a))))))
1576 }
1577 }
1578
1579 fn decode_gradient_add_stop(next_chr: char, gradient_id: GradientId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1583 let mut param = param;
1585
1586 if param.len() < 30 {
1587 param.push(next_chr);
1588 Ok((DecoderState::GradientOpAddStop(gradient_id, param), None))
1589 } else {
1590 param.push(next_chr);
1591
1592 let mut param = param.chars();
1593 let pos = Self::decode_f32(&mut param)?;
1594 let col_type = param.next();
1595 let r = Self::decode_f32(&mut param)?;
1596 let g = Self::decode_f32(&mut param)?;
1597 let b = Self::decode_f32(&mut param)?;
1598 let a = Self::decode_f32(&mut param)?;
1599
1600 if col_type != Some('R') {
1601 Err(DecoderError::UnknownColorType)?;
1602 }
1603
1604 Ok((DecoderState::None, Some(Draw::Gradient(gradient_id, GradientOp::AddStop(pos, Color::Rgba(r, g, b, a))))))
1605 }
1606 }
1607
1608 fn decode_f32(chrs: &mut Chars) -> Result<f32, DecoderError> {
1612 let as_u32 = Self::decode_u32(chrs)?;
1613 let as_f32 = f32::from_bits(as_u32);
1614
1615 Ok(as_f32)
1616 }
1617
1618 fn decode_u32(chrs: &mut Chars) -> Result<u32, DecoderError> {
1622 let mut result = 0;
1623 let mut shift = 0;
1624
1625 for _ in 0..6 {
1626 let next_chr = chrs.next().ok_or(DecoderError::BadNumber)?;
1627 result |= (Self::decode_base64(next_chr)? as u32) << shift;
1628 shift += 6;
1629 }
1630
1631
1632 Ok(result)
1633 }
1634
1635 #[inline] fn decode_base64(chr: char) -> Result<u8, DecoderError> {
1639 if chr >= 'A' && chr <= 'Z' {
1640 Ok((chr as u8) - ('A' as u8))
1641 } else if chr >= 'a' && chr <= 'z' {
1642 Ok((chr as u8) - ('a' as u8) + 26)
1643 } else if chr >= '0' && chr <= '9' {
1644 Ok((chr as u8) - ('0' as u8) + 52)
1645 } else if chr == '+' {
1646 Ok(62)
1647 } else if chr == '/' {
1648 Ok(63)
1649 } else {
1650 Err(DecoderError::BadNumber)
1651 }
1652 }
1653}
1654
1655pub fn decode_drawing<In: IntoIterator<Item=char>>(source: In) -> impl Iterator<Item=Result<Draw, DecoderError>> {
1660 let mut decoder = CanvasDecoder::new();
1662 let mut seen_error = false;
1663
1664 source.into_iter()
1666 .filter_map(move |chr| {
1667 match decoder.decode(chr) {
1668 Ok(Some(draw)) => Some(Ok(draw)),
1669 Ok(None) => None,
1670 Err(err) => {
1671 if !seen_error {
1673 seen_error = true;
1674 Some(Err(err))
1675 } else {
1676 None
1677 }
1678 }
1679 }
1680 })
1681}
1682
1683#[derive(Clone, Debug, PartialEq)]
1687pub enum StreamDecoderError<E> {
1688 Decoder(DecoderError),
1690
1691 Stream(E)
1693}
1694
1695pub fn decode_drawing_stream<In: Unpin+Stream<Item=Result<char, E>>, E>(source: In) -> impl Unpin+Stream<Item=Result<Draw, StreamDecoderError<E>>> {
1699 let mut source = source;
1700 let mut decoder = CanvasDecoder::new();
1701 let mut seen_error = false;
1702
1703 stream::poll_fn(move |context| {
1704 if seen_error {
1705 Poll::Ready(None)
1707 } else {
1708 loop {
1709 match source.poll_next_unpin(context) {
1710 Poll::Ready(None) => { return Poll::Ready(None); },
1711 Poll::Pending => { return Poll::Pending; },
1712 Poll::Ready(Some(Ok(c))) => {
1713 match decoder.decode(c) {
1714 Ok(None) => { continue; },
1715 Ok(Some(draw)) => { return Poll::Ready(Some(Ok(draw))); },
1716 Err(err) => { seen_error = true; return Poll::Ready(Some(Err(StreamDecoderError::Decoder(err)))); }
1717 }
1718 },
1719
1720 Poll::Ready(Some(Err(err))) => { return Poll::Ready(Some(Err(StreamDecoderError::Stream(err)))); }
1721 }
1722 }
1723 }
1724 })
1725}
1726
1727#[cfg(test)]
1728mod test {
1729 use super::*;
1730 use crate::encoding::*;
1731
1732 use futures::executor;
1733
1734 fn check_round_trip_single(instruction: Draw) {
1738 check_round_trip(vec![instruction])
1739 }
1740
1741 fn check_round_trip(instructions: Vec<Draw>) {
1745 let mut encoded = String::new();
1747 for instruction in instructions.iter() {
1748 instruction.encode_canvas(&mut encoded);
1749 }
1750
1751 println!("{:?} {:?}", instructions, encoded);
1752
1753 let decoded = decode_drawing(encoded.chars()).collect::<Vec<_>>();
1755
1756 println!(" -> {:?}", decoded);
1757
1758 assert!(decoded.len() == instructions.len());
1760
1761 assert!(decoded == instructions.into_iter().map(|draw| Ok(draw)).collect::<Vec<_>>());
1763 }
1764
1765 #[test]
1766 fn decode_start_frame() {
1767 check_round_trip_single(Draw::StartFrame);
1768 }
1769
1770 #[test]
1771 fn decode_show_frame() {
1772 check_round_trip_single(Draw::ShowFrame);
1773 }
1774
1775 #[test]
1776 fn decode_reset_frame() {
1777 check_round_trip_single(Draw::ResetFrame);
1778 }
1779
1780 #[test]
1781 fn decode_new_path() {
1782 check_round_trip_single(Draw::Path(PathOp::NewPath));
1783 }
1784
1785 #[test]
1786 fn decode_move() {
1787 check_round_trip_single(Draw::Path(PathOp::Move(10.0, 15.0)));
1788 }
1789
1790 #[test]
1791 fn decode_line() {
1792 check_round_trip_single(Draw::Path(PathOp::Line(20.0, 42.0)));
1793 }
1794
1795 #[test]
1796 fn decode_bezier_curve() {
1797 check_round_trip_single(Draw::Path(PathOp::BezierCurve(((1.0, 2.0), (3.0, 4.0)), (5.0, 6.0))));
1798 }
1799
1800 #[test]
1801 fn decode_close_path() {
1802 check_round_trip_single(Draw::Path(PathOp::ClosePath));
1803 }
1804
1805 #[test]
1806 fn decode_fill() {
1807 check_round_trip_single(Draw::Fill);
1808 }
1809
1810 #[test]
1811 fn decode_stroke() {
1812 check_round_trip_single(Draw::Stroke);
1813 }
1814
1815 #[test]
1816 fn decode_line_width() {
1817 check_round_trip_single(Draw::LineWidth(23.0));
1818 }
1819
1820 #[test]
1821 fn decode_line_width_pixels() {
1822 check_round_trip_single(Draw::LineWidthPixels(43.0));
1823 }
1824
1825 #[test]
1826 fn decode_line_join() {
1827 check_round_trip_single(Draw::LineJoin(LineJoin::Bevel));
1828 }
1829
1830 #[test]
1831 fn decode_line_cap() {
1832 check_round_trip_single(Draw::LineCap(LineCap::Round));
1833 }
1834
1835 #[test]
1836 fn decode_new_dash_pattern() {
1837 check_round_trip_single(Draw::NewDashPattern);
1838 }
1839
1840 #[test]
1841 fn decode_dash_length() {
1842 check_round_trip_single(Draw::DashLength(56.0));
1843 }
1844
1845 #[test]
1846 fn decode_dash_offset() {
1847 check_round_trip_single(Draw::DashOffset(13.0));
1848 }
1849
1850 #[test]
1851 fn decode_stroke_color() {
1852 check_round_trip_single(Draw::StrokeColor(Color::Rgba(0.1, 0.2, 0.3, 0.4)));
1853 }
1854
1855 #[test]
1856 fn decode_fill_color() {
1857 check_round_trip_single(Draw::FillColor(Color::Rgba(0.2, 0.3, 0.4, 0.5)));
1858 }
1859
1860 #[test]
1861 fn decode_fill_texture() {
1862 check_round_trip_single(Draw::FillTexture(TextureId(42), (1.0, 2.0), (3.0, 4.0)));
1863 }
1864
1865 #[test]
1866 fn decode_blend_mode() {
1867 check_round_trip_single(Draw::BlendMode(BlendMode::Lighten));
1868 }
1869
1870 #[test]
1871 fn decode_identity_transform() {
1872 check_round_trip_single(Draw::IdentityTransform);
1873 }
1874
1875 #[test]
1876 fn decode_canvas_height() {
1877 check_round_trip_single(Draw::CanvasHeight(81.0));
1878 }
1879
1880 #[test]
1881 fn decode_center_region() {
1882 check_round_trip_single(Draw::CenterRegion((6.0, 7.0), (8.0, 9.0)));
1883 }
1884
1885 #[test]
1886 fn decode_multiply_transform() {
1887 check_round_trip_single(Draw::MultiplyTransform(Transform2D([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]])));
1888 }
1889
1890 #[test]
1891 fn decode_unclip() {
1892 check_round_trip_single(Draw::Unclip);
1893 }
1894
1895 #[test]
1896 fn decode_clip() {
1897 check_round_trip_single(Draw::Clip)
1898 }
1899
1900 #[test]
1901 fn decode_store() {
1902 check_round_trip_single(Draw::Store);
1903 }
1904
1905 #[test]
1906 fn decode_restore() {
1907 check_round_trip_single(Draw::Restore);
1908 }
1909
1910 #[test]
1911 fn decode_free_stored_buffer() {
1912 check_round_trip_single(Draw::FreeStoredBuffer);
1913 }
1914
1915 #[test]
1916 fn decode_push_state() {
1917 check_round_trip_single(Draw::PushState);
1918 }
1919
1920 #[test]
1921 fn decode_pop_state() {
1922 check_round_trip_single(Draw::PopState);
1923 }
1924
1925 #[test]
1926 fn decode_clear_canvas() {
1927 check_round_trip_single(Draw::ClearCanvas(Color::Rgba(0.1, 0.2, 0.3, 0.4)));
1928 }
1929
1930 #[test]
1931 fn decode_layer() {
1932 check_round_trip_single(Draw::Layer(LayerId(21)));
1933 }
1934
1935 #[test]
1936 fn decode_layer_blend() {
1937 check_round_trip_single(Draw::LayerBlend(LayerId(76), BlendMode::Lighten))
1938 }
1939
1940 #[test]
1941 fn decode_clear_layer() {
1942 check_round_trip_single(Draw::ClearLayer);
1943 }
1944
1945 #[test]
1946 fn decode_clear_all_layers() {
1947 check_round_trip_single(Draw::ClearAllLayers);
1948 }
1949
1950 #[test]
1951 fn decode_swap_layers() {
1952 check_round_trip_single(Draw::SwapLayers(LayerId(1), LayerId(2)));
1953 }
1954
1955 #[test]
1956 fn decode_sprite() {
1957 check_round_trip_single(Draw::Sprite(SpriteId(0)));
1958 check_round_trip_single(Draw::Sprite(SpriteId(10)));
1959 check_round_trip_single(Draw::Sprite(SpriteId(1300)));
1960 check_round_trip_single(Draw::Sprite(SpriteId(1000000000)));
1961 }
1962
1963 #[test]
1964 fn decode_clear_sprite() {
1965 check_round_trip_single(Draw::ClearSprite);
1966 }
1967
1968 #[test]
1969 fn decode_transform_sprite_translate() {
1970 check_round_trip_single(Draw::SpriteTransform(SpriteTransform::Translate(4.0, 5.0)));
1971 }
1972
1973 #[test]
1974 fn decode_transform_sprite_scale() {
1975 check_round_trip_single(Draw::SpriteTransform(SpriteTransform::Scale(6.0, 7.0)));
1976 }
1977
1978 #[test]
1979 fn decode_transform_sprite_rotate() {
1980 check_round_trip_single(Draw::SpriteTransform(SpriteTransform::Rotate(42.0)));
1981 }
1982
1983 #[test]
1984 fn decode_transform_sprite_transform() {
1985 check_round_trip_single(Draw::SpriteTransform(SpriteTransform::Transform2D(Transform2D::scale(3.0, 4.0))));
1986 }
1987
1988 #[test]
1989 fn decode_winding_rule() {
1990 check_round_trip_single(Draw::WindingRule(WindingRule::NonZero));
1991 check_round_trip_single(Draw::WindingRule(WindingRule::EvenOdd));
1992 }
1993
1994 #[test]
1995 fn decode_draw_sprite() {
1996 check_round_trip_single(Draw::DrawSprite(SpriteId(0)));
1997 check_round_trip_single(Draw::DrawSprite(SpriteId(10)));
1998 check_round_trip_single(Draw::DrawSprite(SpriteId(1300)));
1999 check_round_trip_single(Draw::DrawSprite(SpriteId(1000000000)));
2000 }
2001
2002 #[test]
2003 fn will_accept_newlines() {
2004 let mut decoder = CanvasDecoder::new();
2005 assert!(decoder.decode('\n') == Ok(None));
2006 assert!(decoder.decode('\n') == Ok(None));
2007 assert!(decoder.decode('\n') == Ok(None));
2008 assert!(decoder.decode('N') == Ok(None));
2009 assert!(decoder.decode('p') == Ok(Some(Draw::Path(PathOp::NewPath))));
2010 }
2011
2012 #[test]
2013 fn error_on_bad_char() {
2014 let mut decoder = CanvasDecoder::new();
2015 assert!(decoder.decode('N') == Ok(None));
2016 assert!(decoder.decode('x') == Err(DecoderError::InvalidCharacter('x')));
2017 }
2018
2019 #[test]
2020 fn decode_font_data() {
2021 let font = CanvasFontFace::from_slice(include_bytes!("../test_data/Lato-Regular.ttf"));
2022
2023 check_round_trip_single(Draw::Font(FontId(42), FontOp::UseFontDefinition(font)));
2024 }
2025
2026 #[test]
2027 fn decode_font_size() {
2028 check_round_trip_single(Draw::Font(FontId(42), FontOp::FontSize(32.0)));
2029 }
2030
2031 #[test]
2032 fn decode_begin_line_layout() {
2033 check_round_trip_single(Draw::BeginLineLayout(1.0, 2.0, TextAlignment::Center));
2034 }
2035
2036 #[test]
2037 fn decode_perform_layout() {
2038 check_round_trip_single(Draw::DrawLaidOutText);
2039 }
2040
2041 #[test]
2042 fn decode_layout_text() {
2043 check_round_trip_single(Draw::Font(FontId(42), FontOp::LayoutText("Test".to_string())));
2044 }
2045
2046 #[test]
2047 fn decode_draw_glyphs() {
2048 check_round_trip_single(Draw::Font(FontId(42), FontOp::DrawGlyphs(vec![
2049 GlyphPosition {
2050 id: GlyphId(20),
2051 location: (2.0, 3.0),
2052 em_size: 18.0
2053 },
2054 GlyphPosition {
2055 id: GlyphId(25),
2056 location: (5.0, 3.0),
2057 em_size: 18.0
2058 },
2059 GlyphPosition {
2060 id: GlyphId(700),
2061 location: (9.0, 3.0),
2062 em_size: 18.0
2063 },
2064 ])));
2065 }
2066
2067 #[test]
2068 fn decode_draw_text() {
2069 check_round_trip_single(Draw::DrawText(FontId(42), "Hello, world".to_string(), 100.0, 200.0));
2070 }
2071
2072 #[test]
2073 fn decode_create_texture() {
2074 check_round_trip_single(Draw::Texture(TextureId(42), TextureOp::Create(100, 200, TextureFormat::Rgba)));
2075 }
2076
2077 #[test]
2078 fn decode_free_texture() {
2079 check_round_trip_single(Draw::Texture(TextureId(43), TextureOp::Free));
2080 }
2081
2082 #[test]
2083 fn decode_texture_set_bytes() {
2084 check_round_trip_single(Draw::Texture(TextureId(44), TextureOp::SetBytes(100, 200, 300, 400, Arc::new(vec![240, 230, 220, 210, 200, 190]))));
2085 }
2086
2087 #[test]
2088 fn decode_fill_transparency() {
2089 check_round_trip_single(Draw::Texture(TextureId(45), TextureOp::FillTransparency(0.75)));
2090 }
2091
2092 #[test]
2093 fn decode_gradient_new() {
2094 check_round_trip_single(Draw::Gradient(GradientId(42), GradientOp::Create(Color::Rgba(0.1, 0.2, 0.3, 0.4))));
2095 }
2096
2097 #[test]
2098 fn decode_gradient_add_stop() {
2099 check_round_trip_single(Draw::Gradient(GradientId(44), GradientOp::AddStop(0.5, Color::Rgba(0.1, 0.2, 0.3, 0.4))));
2100 }
2101
2102 #[test]
2103 fn decode_gradient_fill() {
2104 check_round_trip_single(Draw::FillGradient(GradientId(24), (42.0, 43.0), (44.0, 45.0)));
2105 }
2106
2107 #[test]
2108 fn decode_fill_transform() {
2109 check_round_trip_single(Draw::FillTransform(Transform2D::identity()));
2110 }
2111
2112 #[test]
2113 fn decode_all_iter() {
2114 check_round_trip(vec![
2115 Draw::Path(PathOp::NewPath),
2116 Draw::Path(PathOp::Move(10.0, 15.0)),
2117 Draw::Path(PathOp::Line(20.0, 42.0)),
2118 Draw::Path(PathOp::BezierCurve(((1.0, 2.0), (3.0, 4.0)), (5.0, 6.0))),
2119 Draw::Path(PathOp::ClosePath),
2120 Draw::Fill,
2121 Draw::Stroke,
2122 Draw::LineWidth(23.0),
2123 Draw::LineWidthPixels(43.0),
2124 Draw::LineJoin(LineJoin::Bevel),
2125 Draw::LineCap(LineCap::Round),
2126 Draw::WindingRule(WindingRule::NonZero),
2127 Draw::NewDashPattern,
2128 Draw::DashLength(56.0),
2129 Draw::DashOffset(13.0),
2130 Draw::StrokeColor(Color::Rgba(0.1, 0.2, 0.3, 0.4)),
2131 Draw::FillColor(Color::Rgba(0.2, 0.3, 0.4, 0.5)),
2132 Draw::FillTexture(TextureId(23), (42.0, 43.0), (44.0, 45.0)),
2133 Draw::FillGradient(GradientId(24), (42.0, 43.0), (44.0, 45.0)),
2134 Draw::FillTransform(Transform2D::identity()),
2135 Draw::BlendMode(BlendMode::Lighten),
2136 Draw::IdentityTransform,
2137 Draw::CanvasHeight(81.0),
2138 Draw::CenterRegion((6.0, 7.0), (8.0, 9.0)),
2139 Draw::MultiplyTransform(Transform2D([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]])),
2140 Draw::Unclip,
2141 Draw::Store,
2142 Draw::Restore,
2143 Draw::FreeStoredBuffer,
2144 Draw::PushState,
2145 Draw::PopState,
2146 Draw::ClearCanvas(Color::Rgba(0.1, 0.2, 0.3, 0.4)),
2147 Draw::Layer(LayerId(21)),
2148 Draw::ClearLayer,
2149 Draw::ClearAllLayers,
2150 Draw::SwapLayers(LayerId(1), LayerId(2)),
2151 Draw::Path(PathOp::NewPath),
2152 Draw::Sprite(SpriteId(1000)),
2153 Draw::ClearSprite,
2154 Draw::SpriteTransform(SpriteTransform::Translate(4.0, 5.0)),
2155 Draw::SpriteTransform(SpriteTransform::Transform2D(Transform2D::scale(3.0, 4.0))),
2156 Draw::DrawSprite(SpriteId(1300)),
2157
2158 Draw::Gradient(GradientId(42), GradientOp::Create(Color::Rgba(0.1, 0.2, 0.3, 0.4))),
2159 Draw::Gradient(GradientId(44), GradientOp::AddStop(0.5, Color::Rgba(0.1, 0.2, 0.3, 0.4))),
2160 ]);
2161 }
2162
2163 #[test]
2164 fn decode_all_stream() {
2165 let all = vec![
2166 Draw::Path(PathOp::NewPath),
2167 Draw::Path(PathOp::Move(10.0, 15.0)),
2168 Draw::Path(PathOp::Line(20.0, 42.0)),
2169 Draw::Path(PathOp::BezierCurve(((1.0, 2.0), (3.0, 4.0)), (5.0, 6.0))),
2170 Draw::Path(PathOp::ClosePath),
2171 Draw::Fill,
2172 Draw::FillTexture(TextureId(42), (1.0, 2.0), (3.0, 4.0)),
2173 Draw::Stroke,
2174 Draw::LineWidth(23.0),
2175 Draw::LineWidthPixels(43.0),
2176 Draw::LineJoin(LineJoin::Bevel),
2177 Draw::LineCap(LineCap::Round),
2178 Draw::WindingRule(WindingRule::EvenOdd),
2179 Draw::NewDashPattern,
2180 Draw::DashLength(56.0),
2181 Draw::DashOffset(13.0),
2182 Draw::StrokeColor(Color::Rgba(0.1, 0.2, 0.3, 0.4)),
2183 Draw::FillColor(Color::Rgba(0.2, 0.3, 0.4, 0.5)),
2184 Draw::FillTexture(TextureId(23), (42.0, 43.0), (44.0, 45.0)),
2185 Draw::FillGradient(GradientId(24), (42.0, 43.0), (44.0, 45.0)),
2186 Draw::FillTransform(Transform2D::identity()),
2187 Draw::BlendMode(BlendMode::Lighten),
2188 Draw::IdentityTransform,
2189 Draw::CanvasHeight(81.0),
2190 Draw::CenterRegion((6.0, 7.0), (8.0, 9.0)),
2191 Draw::MultiplyTransform(Transform2D([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]])),
2192 Draw::Unclip,
2193 Draw::Store,
2194 Draw::Restore,
2195 Draw::FreeStoredBuffer,
2196 Draw::PushState,
2197 Draw::PopState,
2198 Draw::ClearCanvas(Color::Rgba(0.1, 0.2, 0.3, 0.4)),
2199 Draw::Layer(LayerId(21)),
2200 Draw::ClearLayer,
2201 Draw::ClearAllLayers,
2202 Draw::SwapLayers(LayerId(1), LayerId(2)),
2203 Draw::Path(PathOp::NewPath),
2204 Draw::Sprite(SpriteId(1000)),
2205 Draw::ClearSprite,
2206 Draw::SpriteTransform(SpriteTransform::Translate(4.0, 5.0)),
2207 Draw::SpriteTransform(SpriteTransform::Transform2D(Transform2D::scale(3.0, 4.0))),
2208 Draw::DrawSprite(SpriteId(1300)),
2209 Draw::Texture(TextureId(42), TextureOp::Create(1024, 768, TextureFormat::Rgba)),
2210 Draw::Texture(TextureId(43), TextureOp::Free),
2211 Draw::Texture(TextureId(44), TextureOp::SetBytes(2, 3, 4, 5, Arc::new(vec![1,2,3,4,5]))),
2212 Draw::Texture(TextureId(45), TextureOp::FillTransparency(0.5)),
2213
2214 Draw::Gradient(GradientId(42), GradientOp::Create(Color::Rgba(0.1, 0.2, 0.3, 0.4))),
2215 Draw::Gradient(GradientId(44), GradientOp::AddStop(0.5, Color::Rgba(0.1, 0.2, 0.3, 0.4))),
2216 ];
2217 let mut encoded = String::new();
2218 all.encode_canvas(&mut encoded);
2219
2220 println!("{:?}", encoded);
2221
2222 let all_stream = stream::iter(encoded.chars().into_iter().map(|c| -> Result<_, ()> { Ok(c) }));
2223 let decoder = decode_drawing_stream(all_stream);
2224 let mut decoder = decoder;
2225
2226 executor::block_on(async {
2227 let mut decoded = vec![];
2228 while let Some(next) = decoder.next().await {
2229 decoded.push(next);
2230 }
2231
2232 println!(" -> {:?}", decoded);
2233
2234 let all = all.into_iter().map(|item| Ok(item)).collect::<Vec<_>>();
2235 assert!(all == decoded);
2236 });
2237 }
2238}