public function toPng($keywords = array()) 
    {
        $colorRanges = array();
        
        Rasterizer::rasterize(
            $colorRanges, $this->edges, 
            $this->width, $this->height);
        
        $backColor = ColorUtils::parse($this->backColor);
        if (ColorUtils::alpha($backColor) > 0) {
            $isColor = false;
            
            foreach ($colorRanges as & $value) {
                if ($isColor) {
                    $value = ColorUtils::over($value, $backColor);
                    $isColor = false;
                } else {
                    $isColor = true;
                }
            }
            
            unset($value);
        }

        $palette = new PngPalette($colorRanges);
        $png = new PngEncoder();

        $png->writeImageHeader($this->width, $this->height, $palette->isValid ?
            PngEncoder::INDEXED_COLOR : PngEncoder::TRUE_COLOR_WITH_ALPHA);

        $png->writeImageGamma();
        
        foreach ($keywords as $key => $value) {
            $png->writeTextualData($key, $value);
        }
        
        if ($palette && $palette->isValid) {
            $png->writePalette($palette);
            $png->writeTransparency($palette);
            $png->writeIndexed($colorRanges, $palette, 
                $this->width, $this->height);
        } else {
            $png->writeTrueColorWithAlpha($colorRanges, 
                $this->width, $this->height);
        }

        $png->writeImageEnd();
        return $png->getBuffer();
    }