diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2017-02-19 01:09:59 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2017-02-19 01:09:59 +0000 |
commit | 0a8fd388d862a6f533c89860cf3dc77c38c20fa4 (patch) | |
tree | 5c7c4fbf7e1873438f5965862600033f8500cbec | |
parent | c6d45f18a46b81704548e0f87f53fcb911cf7330 (diff) | |
download | netpbm-mirror-0a8fd388d862a6f533c89860cf3dc77c38c20fa4.tar.gz netpbm-mirror-0a8fd388d862a6f533c89860cf3dc77c38c20fa4.tar.xz netpbm-mirror-0a8fd388d862a6f533c89860cf3dc77c38c20fa4.zip |
Add path builder
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2897 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | doc/HISTORY | 2 | ||||
-rw-r--r-- | lib/path.c | 155 | ||||
-rw-r--r-- | lib/ppmdraw.h | 65 |
3 files changed, 210 insertions, 12 deletions
diff --git a/doc/HISTORY b/doc/HISTORY index bdc00cc6..2e1af00d 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -15,6 +15,8 @@ not yet BJH Release 10.78.00 pnmcrop: Add -closeness + libnetpbm: Add ppmd_pathbuilder_* functions. + libnetpbm: ppmd_fill_path: remove debug trace. Always broken (ppmd_fill_path was new in Netpbm 10.34 (June 2006). diff --git a/lib/path.c b/lib/path.c index 42b410dd..8d53eb9e 100644 --- a/lib/path.c +++ b/lib/path.c @@ -65,6 +65,149 @@ */ +ppmd_pathleg +ppmd_makeLineLeg(ppmd_point const point) { + + ppmd_pathleg retval; + + retval. type = PPMD_PATHLEG_LINE; + + retval.u.linelegparms.end = point; + + return retval; +} + + + +ppmd_pathbuilder * +ppmd_pathbuilder_create() { + + ppmd_pathbuilder * retval; + + MALLOCVAR(retval); + + if (!retval) + pm_error("Failed to allocate memory " + "for a ppmd_pathuilder structure"); + + retval->path.version = 0; + retval->path.legCount = 0; + retval->path.legSize = sizeof(ppmd_pathleg); + retval->path.legs = NULL; + + retval->begIsSet = false; + retval->legsAreAutoAllocated = true; + retval->legsAllocSize = 0; + + return retval; +} + + + +void +ppmd_pathbuilder_destroy(ppmd_pathbuilder * const pathBuilderP) { + + if (pathBuilderP->legsAreAutoAllocated) { + if (pathBuilderP->path.legs) + free(pathBuilderP->path.legs); + } + free(pathBuilderP); +} + + + +void +ppmd_pathbuilder_setLegArray(ppmd_pathbuilder * const pathBuilderP, + ppmd_pathleg * const legs, + unsigned int const legCount) { + + if (pathBuilderP->path.legs) + pm_error("Legs array is already set up"); + + if (legCount < 1) + pm_error("Leg array size must be at least one leg in size"); + + if (legs == NULL) + pm_error("Leg array pointer is null"); + + pathBuilderP->legsAreAutoAllocated = false; + + pathBuilderP->legsAllocSize = legCount; + + pathBuilderP->path.legs = legs; +} + + + +void +ppmd_pathbuilder_preallocLegArray(ppmd_pathbuilder * const pathBuilderP, + unsigned int const legCount) { + + if (pathBuilderP->path.legs) + pm_error("Legs array is already set up"); + + if (legCount < 1) + pm_error("Leg array size must be at least one leg in size"); + + MALLOCARRAY(pathBuilderP->path.legs, legCount); + + if (!pathBuilderP->path.legs) + pm_error("Unable to allocate memory for %u legs", legCount); + + pathBuilderP->legsAllocSize = legCount; +} + + + +void +ppmd_pathbuilder_setBegPoint(ppmd_pathbuilder * const pathBuilderP, + ppmd_point const begPoint) { + + pathBuilderP->path.begPoint = begPoint; + + pathBuilderP->begIsSet = true; +} + + + +void +ppmd_pathbuilder_addLineLeg(ppmd_pathbuilder * const pathBuilderP, + ppmd_pathleg const leg) { + + if (!pathBuilderP->begIsSet) + pm_error("Attempt to add a leg to a path when the " + "beginning point of the path has not been set"); + + if (pathBuilderP->path.legCount + 1 > pathBuilderP->legsAllocSize) { + if (pathBuilderP->legsAreAutoAllocated) { + pathBuilderP->legsAllocSize = + MAX(16, pathBuilderP->legsAllocSize * 2); + + REALLOCARRAY(pathBuilderP->path.legs, + pathBuilderP->legsAllocSize); + + if (pathBuilderP->path.legs == NULL) + pm_error("Unable to allocate memory for %u legs", + pathBuilderP->legsAllocSize); + } else + pm_error("Out of space in user-supplied legs array " + "(has space for %u legs)", pathBuilderP->legsAllocSize); + } + + assert(pathBuilderP->path.legCount + 1 <= pathBuilderP->legsAllocSize); + + pathBuilderP->path.legs[pathBuilderP->path.legCount++] = leg; +} + + + +const ppmd_path * +ppmd_pathbuilder_pathP(ppmd_pathbuilder * const pathBuilderP) { + + return &pathBuilderP->path; +} + + static bool pointEqual(ppmd_point const comparator, @@ -411,12 +554,12 @@ fillLeg(ppmd_point const begPoint, void -ppmd_fill_path(pixel ** const pixels, - int const cols, - int const rows, - pixval const maxval, - ppmd_path * const pathP, - pixel const color) { +ppmd_fill_path(pixel ** const pixels, + int const cols, + int const rows, + pixval const maxval, + const ppmd_path * const pathP, + pixel const color) { /*---------------------------------------------------------------------------- Draw a path which defines a closed figure (or multiple closed figures) and fill it in. diff --git a/lib/ppmdraw.h b/lib/ppmdraw.h index df22b44d..5fd4148c 100644 --- a/lib/ppmdraw.h +++ b/lib/ppmdraw.h @@ -9,6 +9,7 @@ */ #include <netpbm/pm_config.h> +#include <netpbm/ppm.h> #ifdef __cplusplus extern "C" { @@ -59,6 +60,9 @@ typedef struct { } u; } ppmd_pathleg; +ppmd_pathleg +ppmd_makeLineLeg(ppmd_point const point); + typedef struct { /*---------------------------------------------------------------------------- A closed path @@ -75,9 +79,58 @@ typedef struct { as the definition of ppmd_pathleg changes. */ ppmd_pathleg * legs; + /* An array of the legs of the path, in order, starting at 'begPoint'. + */ } ppmd_path; +typedef struct { + + ppmd_path path; + /* The path we are building (or have built). + Null for path.legs means we don't have a leg array yet. + */ + + bool begIsSet; + /* User has set path.begPoint. If this is false, path.begPoint is + meaningless. + */ + + unsigned int legsAllocSize; + /* How many legs of space is allocated in the leg array path.legs */ + + bool legsAreAutoAllocated; + /* The array 'legs' is allocated or reallocated automatically by + ppmd_path_addlineline(), as opposed to being supplied by the + user as part of initializing this structure, never to be altered. + */ + +} ppmd_pathbuilder; + +ppmd_pathbuilder * +ppmd_pathbuilder_create(void); + +void +ppmd_pathbuilder_destroy(ppmd_pathbuilder * const pathBuilderP); + +void +ppmd_pathbuilder_setLegArray(ppmd_pathbuilder * const pathBuilderP, + ppmd_pathleg * const legs, + unsigned int const legCount); + +void +ppmd_pathbuilder_preallocLegArray(ppmd_pathbuilder * const pathBuilderP, + unsigned int const legCount); + +void +ppmd_pathbuilder_setBegPoint(ppmd_pathbuilder * const pathBuilderP, + ppmd_point const begPoint); + +void +ppmd_pathbuilder_addLineLeg(ppmd_pathbuilder * const pathBuilderP, + ppmd_pathleg const leg); +const ppmd_path * +ppmd_pathbuilder_pathP(ppmd_pathbuilder * const pathBuilderP); typedef void ppmd_drawprocp(pixel **, unsigned int, unsigned int, pixval, ppmd_point, const void *); @@ -272,12 +325,12 @@ ppmd_filledrectangle(pixel ** const pixels, void -ppmd_fill_path(pixel ** const pixels, - int const cols, - int const rows, - pixval const maxval, - ppmd_path * const pathP, - pixel const color); +ppmd_fill_path(pixel ** const pixels, + int const cols, + int const rows, + pixval const maxval, + const ppmd_path * const pathP, + pixel const color); /* Fills in a closed path. Not much different from ppmd_fill(), but with a different interface. */ |