         @y = 0
         @_lineGap = 0
         
+        # Keeps track of what has been set in the document
+        @_textState = 
+            font: null
+            fontSize: null
+            mode: 0
+            wordSpacing: 0
+            
+        # state of the wrapping algorithm
+        @_wrapState = {}
+        
     lineGap: (@_lineGap) ->
         return this
         

            .replace(/&lt;/g, '<')
            .replace(/&gt;/g, '>')
            .replace(/&amp;/g, '&')
    
    _wrap: (text, options) ->
        {_font: font, _fontSize: size} = this
        {width:lineWidth, height:maxHeight, align} = options
        width = @widthOfString.bind this
        maxY = @y + maxHeight
        
        options.lineWidth = lineWidth
        options.firstLine = true
        options.firstParagraph = true
        delete options.width
        delete options.height
        
        spaceLeft = lineWidth - (options.indent or 0)
        words = text.match(WORD_RE)
        lineHeight = @currentLineHeight(true)
        wordWidths = {}
        len = words.length
        buffer = ''
        
        for word, i in words
            w = wordWidths[word] ?= width(word)

            if w > spaceLeft or word is '\n'
                if options.lastLine
                    options.firstParagraph = false
                    options.firstLine = true
                    options.lastLine = false
                
                if word is '\n'
                    options.lastLine = true
                
                lastLine = buffer.trim()
                @text lastLine, options
                
                options.firstLine = false
                return if @y > maxY
                
                spaceLeft = lineWidth - w
                buffer = if word is '\n' then '' else word
                
            else
                spaceLeft -= w
                buffer += word
        
        # add the last line
        options.lastLine = true
        @text buffer.trim(), options
        
    moveDown: (lines = 1) ->
        @y += @currentLineHeight(true) * lines + @_lineGap
        return this
        
    moveUp: (lines = 1) ->
        @y -= @currentLineHeight(true) * lines + @_lineGap
        return this
        
    list: (array, @x, @y) ->
        gap = Math.round (@_font.ascender / 1000 * @_fontSize) / 2
        
        for item in array
            @circle x + 3, @y + gap + 3, 3
            @text item, x + 15
            @y += 3
            
        @fill()
            options = x
            x = null
        
        # Update the current position    
        @x = x or options.x or @x
        @y = y or options.y or @y
        
        # add current font to page if necessary
        @page.fonts[@_font.id] ?= @_font.ref
        
        # word wrapping
        if options.width
            @_wrap text, options
        
        # newlines    
        else if (matches = text.split '\n').length > 1
            @_line match, options for match in matches
        
        # single line    
        else
            @_line text, options
            
        return this
        
    moveDown: (lines = 1) ->
        @y += @currentLineHeight(true) * lines + @_lineGap
        return this

    moveUp: (lines = 1) ->
        @y -= @currentLineHeight(true) * lines + @_lineGap
        return this

    list: (array, @x, @y) ->
        gap = Math.round (@_font.ascender / 1000 * @_fontSize) / 2

        for item in array
            @circle x + 3, @y + gap + 3, 3
            @text item, x + 15
            @y += 3

        @fill()
        
    _escape: (text) ->
        ('' + text)
