(self, gml)
Execute a Graphics Macro Language string.
Execute a Graphics Macro Language string.
Execute a Graphics Macro Language string .
def _draw(self, gml):
        """Execute a Graphics Macro Language string."""
        # don't convert to uppercase as VARPTR$ elements are case sensitive
        gmls = mlparser.MLParser(gml, self._memory, self._values)
        plot, goback = True, False
        while True:
            c = gmls.skip_blank_read().upper()
            if c == b'':
                break
            elif c == b';':
                continue
            elif c == b'B':
                # do not draw
                plot = False
            elif c == b'N':
                # return to postiton after move
                goback = True
            elif c == b'X':
                # execute substring
                sub = gmls.parse_string()
                self._draw(sub)
            elif c == b'C':
                # set foreground colour
                # allow empty spec (default 0), but only if followed by a semicolon
                if gmls.skip_blank() == b';':
                    self._last_attr = 0
                else:
                    attr = gmls.parse_number()
                    # 100000 seems to be GW's limit
                    error.range_check(-99999, 99999, attr)
                    self._last_attr = attr
            elif c == b'S':
                # set scale
                scale = gmls.parse_number()
                error.range_check(1, 255, scale)
                self._draw_scale = scale
            elif c == b'A':
                # set angle
                # allow empty spec (default 0), but only if followed by a semicolon
                if gmls.skip_blank() == b';':
                    self._draw_angle = 0
                else:
                    angle = gmls.parse_number()
                    error.range_check(0, 3, angle)
                    self._draw_angle = 90 * angle
            elif c == b'T':
                # 'turn angle' - set (don't turn) the angle to any value
                if gmls.read(1).upper() != b'A':
                    raise error.BASICError(error.IFC)
                # allow empty spec (default 0), but only if followed by a semicolon
                if gmls.skip_blank() == b';':
                    self._draw_angle = 0
                else:
                    angle = gmls.parse_number()
                    error.range_check(-360, 360, angle)
                    self._draw_angle = angle
            # one-variable movement commands:
            elif c in (b'U', b'D', b'L', b'R', b'E', b'F', b'G', b'H'):
                step = gmls.parse_number(default=1)
                # 100000 seems to be GW's limit
                error.range_check(-99999, 99999, step)
                x0, y0 = self._last_point
                x1, y1 = 0, 0
                if c in (b'U', b'E', b'H'):
                    y1 -= step
                elif c in (b'D', b'F', b'G'):
                    y1 += step
                if c in (b'L', b'G', b'H'):
                    x1 -= step
                elif c in (b'R', b'E', b'F'):
                    x1 += step
                self._draw_step(x0, y0, x1, y1, plot, goback)
                plot = True
                goback = False
            # two-variable movement command
            elif c == b'M':
                relative = gmls.skip_blank() in (b'+', b'-')
                x = gmls.parse_number()
                error.range_check(-9999, 9999, x)
                if gmls.skip_blank() != b',':
                    raise error.BASICError(error.IFC)
                else:
                    gmls.read(1)
                y = gmls.parse_number()
                error.range_check(-9999, 9999, y)
                x0, y0 = self._last_point
                if relative:
                    self._draw_step(x0, y0, x, y, plot, goback)
                else:
                    if plot:
                        self._draw_line(x0, y0, x, y, self._last_attr)
                    self._last_point = x, y
                    if goback:
                        self._last_point = x0, y0
                plot = True
                goback = False
            elif c == b'P':
                # paint - flood fill
                fill_idx = gmls.parse_number()
                error.range_check(0, 9999, fill_idx)
                if gmls.skip_blank_read() != b',':
                    raise error.BASICError(error.IFC)
                border_idx = gmls.parse_number()
                error.range_check(0, 9999, border_idx)
                x, y = self._get_window_logical(*self._last_point)
                fill_attr = self._get_attr_index(fill_idx)
                border_attr = self._get_attr_index(border_idx)
                self._flood_fill((x, y, False), fill_attr, None, border_attr, None)
            else:
                raise error.BASICError(error.IFC)
def _draw ( self , gml ) : # don't convert to uppercase as VARPTR$ elements are case sensitive gmls = mlparser . MLParser ( gml , self . _memory , self . _values ) plot , goback = True , False while True : c = gmls . skip_blank_read ( ) . upper ( ) if c == b'' : break elif c == b';' : continue elif c == b'B' : # do not draw plot = False elif c == b'N' : # return to postiton after move goback = True elif c == b'X' : # execute substring sub = gmls . parse_string ( ) self . _draw ( sub ) elif c == b'C' : # set foreground colour # allow empty spec (default 0), but only if followed by a semicolon if gmls . skip_blank ( ) == b';' : self . _last_attr = 0 else : attr = gmls . parse_number ( ) # 100000 seems to be GW's limit error . range_check ( - 99999 , 99999 , attr ) self . _last_attr = attr elif c == b'S' : # set scale scale = gmls . parse_number ( ) error . range_check ( 1 , 255 , scale ) self . _draw_scale = scale elif c == b'A' : # set angle # allow empty spec (default 0), but only if followed by a semicolon if gmls . skip_blank ( ) == b';' : self . _draw_angle = 0 else : angle = gmls . parse_number ( ) error . range_check ( 0 , 3 , angle ) self . _draw_angle = 90 * angle elif c == b'T' : # 'turn angle' - set (don't turn) the angle to any value if gmls . read ( 1 ) . upper ( ) != b'A' : raise error . BASICError ( error . IFC ) # allow empty spec (default 0), but only if followed by a semicolon if gmls . skip_blank ( ) == b';' : self . _draw_angle = 0 else : angle = gmls . parse_number ( ) error . range_check ( - 360 , 360 , angle ) self . _draw_angle = angle # one-variable movement commands: elif c in ( b'U' , b'D' , b'L' , b'R' , b'E' , b'F' , b'G' , b'H' ) : step = gmls . parse_number ( default = 1 ) # 100000 seems to be GW's limit error . range_check ( - 99999 , 99999 , step ) x0 , y0 = self . _last_point x1 , y1 = 0 , 0 if c in ( b'U' , b'E' , b'H' ) : y1 -= step elif c in ( b'D' , b'F' , b'G' ) : y1 += step if c in ( b'L' , b'G' , b'H' ) : x1 -= step elif c in ( b'R' , b'E' , b'F' ) : x1 += step self . _draw_step ( x0 , y0 , x1 , y1 , plot , goback ) plot = True goback = False # two-variable movement command elif c == b'M' : relative = gmls . skip_blank ( ) in ( b'+' , b'-' ) x = gmls . parse_number ( ) error . range_check ( - 9999 , 9999 , x ) if gmls . skip_blank ( ) != b',' : raise error . BASICError ( error . IFC ) else : gmls . read ( 1 ) y = gmls . parse_number ( ) error . range_check ( - 9999 , 9999 , y ) x0 , y0 = self . _last_point if relative : self . _draw_step ( x0 , y0 , x , y , plot , goback ) else : if plot : self . _draw_line ( x0 , y0 , x , y , self . _last_attr ) self . _last_point = x , y if goback : self . _last_point = x0 , y0 plot = True goback = False elif c == b'P' : # paint - flood fill fill_idx = gmls . parse_number ( ) error . range_check ( 0 , 9999 , fill_idx ) if gmls . skip_blank_read ( ) != b',' : raise error . BASICError ( error . IFC ) border_idx = gmls . parse_number ( ) error . range_check ( 0 , 9999 , border_idx ) x , y = self . _get_window_logical ( * self . _last_point ) fill_attr = self . _get_attr_index ( fill_idx ) border_attr = self . _get_attr_index ( border_idx ) self . _flood_fill ( ( x , y , False ) , fill_attr , None , border_attr , None ) else : raise error . BASICError ( error . IFC )