h1

Masks as intermediate

May 8, 2010

One of the first things I knew about the structure of the new draw module was that I wanted to separate the definition of shapes and the actual drawing because shapes won’t change but the drawing methods and algorithms should be changeable. To easily implement this and also get a comfortable api that makes it easier to deal with (lots of?) optional parameters I decided to use an object-oriented approach and write a base class that defines the shapes and child classes that implement different algorithms by overwriting a certain method of the base class.

Now I needed some interface, a way to pass shapes to the draw method without drawing it.

First I thought I could call the draw method per pixel and directly set pixels on the destination surface like just passing the position of a pixel (that should be set) to the draw method, that then would calculate the color and set the pixel on the surface.

Then I started thinking about algorithms to define shapes and it became clear that it is a lot easier to operate on a “neutral” place where you just have two options per pixel:  to set or not to set, to draw or not to draw, to be or not to be. And this is exactly what masks are made for!

On a regular surface with any initial image data you don’t know if you have set a certain pixel or not because you don’t know the color it had before you started drawing. Of course it may be possible somehow and you could use a list of affected pixels and their initial color and then … but its easier and cleaner to use masks that are optimized and thus fast enough.

So the basic api layout will look something like this:

class Pen(object):
    """
    base class that defines all shape methods
    - do not use directly! -
    """
    def line(self, surf, ...):
        # ...

    # ... (more methods to draw all kinds of shapes)

    def draw_mask(self, surf, mask, offset):
        """
        draw ``mask`` onto ``surf`` with the given ``offset``
        - to be overwritten by child classes -
	"""
        raise NotImplementedError

class PlainColorPen(object):
    """
    fill shapes with a plain color
    """
    def __init__(self, color):
        self.color = color

    def draw_mask(self, surf, mask, offset):
        # ...

class TexturedPen(object):
    """
    create textured shapes
    """
    def __init__(self, texture):
        # ...

    def draw_mask(self, surf, mask, offset):
        # ...

# ... (more XXXPen classes)
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: