flo_canvas/
decoding.rs

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///
22/// Represents a partial or full decoding result
23///
24#[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
43///
44/// Represents the state of an operation decoding a string value
45///
46struct DecodeString {
47    length:             PartialResult<u64>,
48    string_encoding:    PartialResult<String>
49}
50
51///
52/// Represents the state of an operation decoding a list of glyph positions
53///
54struct DecodeGlyphPositions {
55    length: PartialResult<u64>,
56    glyphs: PartialResult<Vec<GlyphPosition>>
57}
58
59///
60/// Represents the state of an operation decoding a set of bytes
61///
62struct 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    ///
74    /// Creates a new string decoder that has matched 0 characters
75    ///
76    fn new() -> DecodeString {
77        DecodeString {
78            length:             PartialResult::new(),
79            string_encoding:    PartialResult::new()
80        }
81    }
82
83    ///
84    /// Indicates if this string decoder is ready or not
85    ///
86    #[inline] fn ready(&self) -> bool {
87        match (&self.length, &self.string_encoding) {
88            (PartialResult::FullMatch(_), PartialResult::FullMatch(_))  => true,
89            _                                                           => false
90        }
91    }
92
93    ///
94    /// Returns the string matched by this decoder (once it's ready)
95    ///
96    #[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    ///
104    /// Decodes a single character and returns the new state of the decoder
105    ///
106    fn decode(mut self, chr: char) -> Result<DecodeString, DecoderError> {
107        // Decode or fetch the length of the string
108        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        // Try to decode the rest of the string
125        match self.string_encoding {
126            PartialResult::FullMatch(string)    => {
127                // Nothing to do
128                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    ///
148    /// Creates a new byte string decoder
149    ///
150    fn new() -> DecodeBytes {
151        DecodeBytes {
152            length:         PartialResult::new(),
153            byte_encoding:  PartialResult::new()
154        }
155    }
156
157    ///
158    /// Indicates if this string decoder is ready or not
159    ///
160    #[inline] fn ready(&self) -> bool {
161        match (&self.length, &self.byte_encoding) {
162            (PartialResult::FullMatch(_), PartialResult::FullMatch(_))  => true,
163            _                                                           => false
164        }
165    }
166
167    ///
168    /// Returns the string matched by this decoder (once it's ready)
169    ///
170    #[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    ///
178    /// Decodes a single character and returns the new state of the decoder
179    ///
180    fn decode(mut self, chr: char) -> Result<DecodeBytes, DecoderError> {
181        use PartialResult::*;
182
183        // Decode or fetch the length of the bytes
184        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        // Try to decode the rest of the string
201        match self.byte_encoding {
202            FullMatch(_)                    => {
203                // Already finished matching
204                return Err(DecoderError::NotReady);
205            }
206
207            MatchMore(mut encoded_bytes)    => {
208                encoded_bytes.push(chr);
209
210                // Every 4 encoded bytes makes up 3 output bytes (and the encoding rounds up overall)
211                let encoded_length = (encoded_bytes.len()/4)*3;
212
213                if encoded_length >= length {
214                    // Decode the bytes
215                    let mut decoded_bytes = vec![];
216
217                    // 4 characters decode into 3 bytes
218                    for (a, b, c, d) in encoded_bytes.chars().tuples() {
219                        // Decode to 6-bit values
220                        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                        // Decode to 8-bit values
226                        let a = a | ((b<<6)&0xff);
227                        let b = (b>>2) | ((c<<4)&0xff);
228                        let c = (c>>4) | ((d<<2)&0xff);
229
230                        // Add to the result
231                        decoded_bytes.push(a);
232                        decoded_bytes.push(b);
233                        decoded_bytes.push(c);
234                    }
235
236                    // Trim to the actual required length
237                    decoded_bytes.truncate(length);
238
239                    // Have decoded the bytes for this object
240                    self.byte_encoding = FullMatch(decoded_bytes);
241                } else {
242                    // Not enough bytes to make up the full string yet
243                    self.byte_encoding = MatchMore(encoded_bytes);
244                }
245
246                return Ok(self);
247            }
248        }
249    }
250}
251
252impl DecodeGlyphPositions {
253    ///
254    /// Creates a new string decoder that has matched 0 characters
255    ///
256    fn new() -> DecodeGlyphPositions {
257        DecodeGlyphPositions {
258            length: PartialResult::new(),
259            glyphs: PartialResult::new()
260        }
261    }
262
263    ///
264    /// Indicates if this string decoder is ready or not
265    ///
266    #[inline] fn ready(&self) -> bool {
267        match (&self.length, &self.glyphs) {
268            (PartialResult::FullMatch(_), PartialResult::FullMatch(_))  => true,
269            _                                                           => false
270        }
271    }
272
273    ///
274    /// Returns the string matched by this decoder (once it's ready)
275    ///
276    #[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    ///
284    /// Decodes a single character and returns the new state of the decoder
285    ///
286    fn decode(mut self, chr: char) -> Result<DecodeGlyphPositions, DecoderError> {
287        // Decode or fetch the length of the string
288        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        // Try to decode the rest of the string
305        match self.glyphs {
306            PartialResult::FullMatch(glyphs)    => {
307                // Nothing to do
308                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                    // Each glyph consists of a glyph ID, an x and y coord and a em_size
319                    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
343///
344/// The possible states for a decoder to be in after accepting some characters from the source
345///
346enum DecoderState {
347    None,
348    Error,
349
350    New,                                        // 'N'
351    LineStyle,                                  // 'L'
352    Dash,                                       // 'D'
353    Color,                                      // 'C'
354    Sprite,                                     // 's'
355    Transform,                                  // 'T'
356    State,                                      // 'Z'
357
358    ClearCanvas(String),                        // 'NA' (r, g, b, a)
359
360    Move(String),                               // m (x, y)
361    Line(String),                               // l (x, y)
362    BezierCurve(String),                        // c (x, y, x, y, x, y)
363
364    LineStyleWidth(String),                     // 'Lw' (w)
365    LineStyleWidthPixels(String),               // 'Lp' (w)
366    LineStyleJoin(String),                      // 'Lj' (j)
367    LineStyleCap(String),                       // 'Lc' (c)
368    WindingRule,                                // 'W' (r)
369
370    DashLength(String),                         // 'Dl' (len)
371    DashOffset(String),                         // 'Do' (offset)
372
373    ColorStroke(String),                        // 'Cs' (r, g, b, a)
374    ColorFill(String),                          // 'Cf' (r, g, b, a)
375    ColorTexture(DecodeTextureId, String),      // 'Ct' (texture_id, x1, y1, x2, y2)
376    ColorGradient(DecodeGradientId, String),    // 'Cg' (gradient_id, x1, y1, x2, y2)
377    ColorTransform(String),                     // 'CT' (transform)
378
379    BlendMode(String),                          // 'M' (mode)
380
381    TransformHeight(String),                    // 'Th' (h)
382    TransformCenter(String),                    // 'Tc' (min, max)
383    TransformMultiply(String),                  // 'Tm' (transform)
384
385    NewLayerU32(String),                        // 'Nl' (id)
386    NewLayerBlendU32(String),                   // 'Nb' (id, mode)
387    NewLayer(String),                           // 'NL' (id)
388    NewLayerBlend(DecodeLayerId, String),       // 'NB' (id, mode)
389    SwapLayers(Option<LayerId>, String),        // 'NX' (layer1, layer2)
390
391    NewSprite(String),                          // 'Ns' (id)
392    SpriteDraw(String),                         // 'sD' (id)
393    SpriteTransform,                            // 'sT' (transform)
394    SpriteTransformTranslate(String),           // 'sTt' (x, y)
395    SpriteTransformScale(String),               // 'sTs' (x, y)
396    SpriteTransformRotate(String),              // 'sTr' (degrees)
397    SpriteTransformTransform(String),           // 'sTT' (transform)
398
399    FontDrawing,                                            // 't'
400    FontDrawText(DecodeFontId, DecodeString, String),       // 'tT' (font_id, string, x, y)
401    FontBeginLayout(String),                                // 'tl' (x, y, align)
402
403    FontOp(DecodeFontId),                                   // 'f' (id, op)
404    FontOpSize(FontId, String),                             // 'f<id>S' (size)
405    FontOpData(FontId),                                     // 'f<id>d'
406    FontOpTtf(FontId, DecodeBytes),                         // 'f<id>dT' (bytes)
407    FontOpLayoutText(FontId, DecodeString),                 // 'f<id>L' (string)
408    FontOpDrawGlyphs(FontId, DecodeGlyphPositions),         // 'f<id>G' (glyph positions)
409
410    TextureOp(DecodeTextureId),                             // 'B<id>' (id, op)
411    TextureOpCreate(TextureId, String),                     // 'B<id>N' (w, h, format)
412    TextureOpSetBytes(TextureId, String, DecodeBytes),      // 'B<id>D' (x, y, w, h, bytes)
413    TextureOpFillTransparency(TextureId, String),           // 'B<id>t' (alpha)
414
415    GradientOp(DecodeGradientId),                           // 'G' (id, op)
416    GradientOpNew(GradientId, String),                      // 'G<id>N' (r, g, b, a)
417    GradientOpAddStop(GradientId, String),                  // 'G<id>S' (pos, r, g, b, a)
418}
419
420///
421/// Possible error from the decoder
422///
423#[derive(Clone, Copy, Debug, PartialEq)]
424pub enum DecoderError {
425    /// The character was not valid for the current state of the decoder
426    InvalidCharacter(char),
427
428    /// The decoder tried to decode something before it had accepted all characters (probably a bug)
429    MissingCharacter,
430
431    /// A number could not be parsed for some reason
432    BadNumber,
433
434    /// A color had an unknown type
435    UnknownColorType,
436
437    /// The decoder previously encountered an error and cannot continue
438    IsInErrorState,
439
440    /// The decoder was asked for a result when it was not ready (usually indicates an internal bug)
441    NotReady
442}
443
444///
445/// Represents a (stateful) canvas decoder
446///
447pub struct CanvasDecoder {
448    state: DecoderState
449}
450
451impl CanvasDecoder {
452    ///
453    /// Creates a new canvas decoder
454    ///
455    pub fn new() -> CanvasDecoder {
456        CanvasDecoder {
457            state: DecoderState::None
458        }
459    }
460
461    ///
462    /// Decodes a character, returning the next Draw operation if there is one
463    ///
464    pub fn decode(&mut self, next_chr: char) -> Result<Option<Draw>, DecoderError> {
465        use self::DecoderState::*;
466
467        // Next state depends on the character and the current state
468        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    ///
550    /// Matches the first character of a canvas item
551    ///
552    #[inline] fn decode_none(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
553        match next_chr {
554            // Whitespace ignored if we're not parsing a command
555            '\n' | '\r' | ' ' => Ok((DecoderState::None, None)),
556
557            // Multi-character commands
558            '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            // Single character commands
568            '.' => 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            // Single character commands with a parameter
575            '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            // Other characters are not accepted
588            _   => Err(DecoderError::InvalidCharacter(next_chr))
589        }
590    }
591
592    #[inline] fn decode_new(next_chr: char) -> Result<(DecoderState, Option<Draw>), DecoderError> {
593        // Matched 'N' so far
594        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        // Matched 'L' so far
617        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        // Matched 'D' so far
629        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        // Matched 'C' so far
641        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        // Matched 's' so far
654        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        // Matched 'T' so far
665        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        // Matched 'Z' so far
677        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        // Decode the texture ID first
877        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        // There are 4 coordinates following the texture ID (at 6 bytes each)
887        param.push(next_chr);
888
889        if param.len() < 24 {
890            // More characters required
891            Ok((DecoderState::ColorTexture(FullMatch(texture_id), param), None))
892        } else {
893            // Decode the coordinates
894            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        // Decode the texture ID first
908        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        // There are 4 coordinates following the texture ID (at 6 bytes each)
918        param.push(next_chr);
919
920        if param.len() < 24 {
921            // More characters required
922            Ok((DecoderState::ColorGradient(FullMatch(gradient_id), param), None))
923        } else {
924            // Decode the coordinates
925            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    ///
1159    /// Consumes 2 characters to decode a blend mode
1160    ///
1161    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    ///
1187    /// Consumes characters until we have a u64 ID
1188    ///
1189    fn decode_compact_id(next_chr: char, mut param: String) -> Result<PartialResult<u64>, DecoderError> {
1190        // Add the next character
1191        param.push(next_chr);
1192
1193        // Decode to a u64 if the 0x20 bit is not set
1194        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    ///
1209    /// Consumes characters until we have a sprite ID
1210    ///
1211    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    ///
1217    /// Consumes characters until we have a layer ID
1218    ///
1219    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    ///
1225    /// Consumes characters until we have a font ID
1226    ///
1227    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    ///
1233    /// Consumes characters until we have a texture ID
1234    ///
1235    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    ///
1241    /// Consumes characters until we have a gradient ID
1242    ///
1243    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    ///
1249    /// Decodes a font drawing command
1250    ///
1251    #[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    ///
1261    /// Decodes the DrawText command (which is one of the more complicated ones, with a font ID, a string and a set of coordinates
1262    /// to deal with)
1263    ///
1264    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    ///
1296    /// Decodes the 'begin layout' instruction
1297    ///
1298    fn decode_font_begin_layout(chr: char, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1299        // Push the character
1300        let mut param = param;
1301        param.push(chr);
1302
1303        // 2x f32 + 1 character
1304        if param.len() < 13 {
1305            return Ok((DecoderState::FontBeginLayout(param), None));
1306        }
1307
1308        // Decode
1309        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    ///
1326    /// Decodes a FontOp command
1327    ///
1328    /// These all start with a font ID, followed by an operation identifier which determines how the
1329    /// rest of the decoding should go
1330    ///
1331    fn decode_font_op(chr: char, font_id: DecodeFontId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1332        use PartialResult::*;
1333
1334        // Decode the font ID first
1335        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        // The character following the font ID determines what state we move on to
1345        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    ///
1356    /// Decodes a FontSize fontop
1357    ///
1358    fn decode_font_op_size(chr: char, font_id: FontId, size: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1359        // Add the character to the size
1360        let mut size = size;
1361        size.push(chr);
1362
1363        // Can decode once we have 6 characters
1364        if size.len() >= 6 {
1365            Ok((DecoderState::None, Some(Draw::Font(font_id, FontOp::FontSize(Self::decode_f32(&mut size.chars())?)))))
1366        } else {
1367            // Haven't got enough characters yet
1368            Ok((DecoderState::FontOpSize(font_id, size), None))
1369        }
1370    }
1371
1372    ///
1373    /// Decodes a font data item
1374    ///
1375    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    ///
1383    /// Decodes TTF font data
1384    ///
1385    fn decode_font_data_ttf(chr: char, font_id: FontId, bytes: DecodeBytes) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1386        // Decode the next byte
1387        let bytes = bytes.decode(chr)?;
1388
1389        // Generate the result once finished
1390        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    ///
1400    /// Decides a text layout instruction
1401    ///
1402    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    ///
1414    /// Decides a text layout instruction
1415    ///
1416    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    ///
1428    /// Decodes a texture operation
1429    ///
1430    fn decode_texture_op(chr: char, texture_id: DecodeTextureId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1431        use PartialResult::*;
1432
1433        // Decode the texture ID first
1434        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        // The character following the texture ID determines what state we move on to
1444        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    ///
1455    /// Decodes a texture create operation
1456    ///
1457    fn decode_texture_create(chr: char, texture_id: TextureId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1458        // Follow-up is 2 u32s and 1 format character for 13 characters total
1459        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        // Decode the texture
1467        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    ///
1481    /// Decodes a texture 'set bytes' operation
1482    ///
1483    fn decode_texture_set_bytes(chr: char, texture_id: TextureId, param: String, bytes: DecodeBytes) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1484        // 4 u32s and some data
1485        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        // Decode the data
1498        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    ///
1508    /// Decodes a texture 'set fill transparency'
1509    ///
1510    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        // 1 f32 for the alpha
1515        if param.len() < 6 {
1516            return Ok((DecoderState::TextureOpFillTransparency(texture_id, param), None));
1517        }
1518
1519        // Decode
1520        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    ///
1527    /// Decodes a gradient ID and determines which gradient operation is being performed on it
1528    ///
1529    fn decode_gradient_op(chr: char, gradient_id: DecodeGradientId) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1530        use PartialResult::*;
1531
1532        // Decode the texture ID first
1533        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        // The gradient op is indicated by the next character
1543        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    ///
1552    /// Decodes the GradientOp::Create instruction
1553    ///
1554    fn decode_gradient_new(next_chr: char, gradient_id: GradientId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1555        // Parameter is the initial colour
1556        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    ///
1580    /// Decodes the GradientOp::AddStop instruction
1581    ///
1582    fn decode_gradient_add_stop(next_chr: char, gradient_id: GradientId, param: String) -> Result<(DecoderState, Option<Draw>), DecoderError> {
1583        // Parameter is a position followed by a colour
1584        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    ///
1609    /// Consumes 6 characters to decode a f32
1610    ///
1611    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    ///
1619    /// Consumes 6 characters to decode a u32
1620    ///
1621    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    ///
1636    /// Decodes a base64 character to a number (in the range 0x00 -> 0x3f)
1637    ///
1638    #[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
1655///
1656/// Decodes a canvas drawing represented as an iterator of characters. If there's an error in the stream, it will
1657/// be the last item decoded.
1658///
1659pub fn decode_drawing<In: IntoIterator<Item=char>>(source: In) -> impl Iterator<Item=Result<Draw, DecoderError>> {
1660    // The decoder represents the state machine used for decoding this item
1661    let mut decoder     = CanvasDecoder::new();
1662    let mut seen_error  = false;
1663
1664    // Map the source characters into draw actions via the decoder
1665    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                    // The decoder will just return errors once it hits a failure: only return the initial error
1672                    if !seen_error {
1673                        seen_error = true;
1674                        Some(Err(err))
1675                    } else {
1676                        None
1677                    }
1678                }
1679            }
1680        })
1681}
1682
1683///
1684/// Error from either a decoder or the stream that's feeding it
1685///
1686#[derive(Clone, Debug, PartialEq)]
1687pub enum StreamDecoderError<E> {
1688    /// Error from the decoder
1689    Decoder(DecoderError),
1690
1691    /// Error from the stream
1692    Stream(E)
1693}
1694
1695///
1696/// Decodes a canvas drawing represented as a stream of characters.
1697///
1698pub 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            // Only allow one error from the decoder (it remains in an error state after this)
1706            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    ///
1735    /// Checks if a particular drawing operation can be both encoded and decoded
1736    ///
1737    fn check_round_trip_single(instruction: Draw) {
1738        check_round_trip(vec![instruction])
1739    }
1740
1741    ///
1742    /// Checks if a particular string of drawing operations can be both encoded and decoded
1743    ///
1744    fn check_round_trip(instructions: Vec<Draw>) {
1745        // Encode the instruction
1746        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        // Try decoding it
1754        let decoded = decode_drawing(encoded.chars()).collect::<Vec<_>>();
1755
1756        println!("  -> {:?}", decoded);
1757
1758        // Should decode OK
1759        assert!(decoded.len() == instructions.len());
1760
1761        // Should be the same as the original instruction
1762        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}