/* Copyright (C) 2001-2007 Peter Selinger and nitoyon. Original code(Potrace v1.8) by Peter Selinger. Ported to ActionScript 3.0 by nitoyon. This file is part of PotrAs. It is free software and it is covered by the GNU General Public License. See the file COPYING for details. */ package com.nitoyon.potras { import flash.display.BitmapData; import flash.geom.Point; import flash.geom.Rectangle; import flash.geom.Matrix; import flash.filters.ColorMatrixFilter; /** * Decompose the given bitmap into paths. */ public class PathList { /** * Decompose the given bitmap into paths. * * @param bitmapData BitmapData to create paths. * @return paths. */ public static function create(bitmapData:BitmapData):Array { var pathList:Array = []; var y:int = 0; var bmdCopy:BitmapData = bitmapData.clone(); var param:Object = {turdSize : 3}; // XOR var filter:ColorMatrixFilter = new ColorMatrixFilter([ -1, 0, 0, 0, 255, -1, 0, 0, 0, 255, -1, 0, 0, 0, 255, 0, 0, 0, 1, 0 ]); var point:Point = new Point(); while(findNext(bmdCopy, point)) { // calculate the sign by looking at the original var sign:String = bmdCopy.getPixel(point.x, point.y) == 0 ? '+' : '-'; // calculate the path var p:Object = findPath(bmdCopy, new Point(point.x, point.y - 1), sign, param.turnPolicy); if(!p) { pathList = null; break; } // update buffered image xorPath(bmdCopy, p, filter); // if it's a turd, eliminate it, else append it to the list if(p.area > param.turdSize) { pathList.push(p); } } bmdCopy.dispose(); return pathList; } /** * find the next set pixel in a row <= y. * *
Pixels are searched first left-to-right, then top-down.
* *If found, return Point object. Else return null.
*/ private static function findNext(bmd:BitmapData, pt:Point):Boolean { for(var y:int = pt.y; y < bmd.height; y++) { for(var x:int = 0; x < bmd.width; x++) { if(bmd.getPixel(x, y) == 0x000000) { pt.x = x; pt.y = y; return true; } } } return false; } /** * compute a path in the given pixmap, separating black from white. * *Start path at the startPoint, which must be an upper
* left corner of the path.
* Also compute the area enclosed by the path. Return a
* new path object. (note that a legitimate path
* cannot have length 0).