home *** CD-ROM | disk | FTP | other *** search
- /* test program for bezier curves */
-
- #include "std_headers.h"
- #include "newlib/yfunctions.h"
-
- struct Library *IntuitionBase,
- *GfxBase;
- struct Window *Window;
- struct Screen *Screen;
- struct RastPort *rp;
-
- USHORT colors[8] = { 0x000,0xFFF,0xE00,0xFE0,0x666,0xABB,0x0E0,0x0A0 };
- struct NewScreen NewScreen = { 0,0,320,200, 3, 0,1, NULL, CUSTOMSCREEN, };
-
- struct NewWindow back_ground =
- { 0,0,320,200, 0,1, MENUPICK | MOUSEMOVE,
- NOCAREREFRESH | ACTIVATE | SMART_REFRESH | BORDERLESS | REPORTMOUSE,
- NULL,NULL,NULL,NULL,NULL,320,200,320,200,CUSTOMSCREEN,
- };
-
- struct IntuiText quit_tx = { 5,1,JAM2,4,1,NULL,(UBYTE *)"Exit" };
- struct MenuItem quit_mi = { NULL,0,0,190,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,0,(APTR)&quit_tx,0,'X' };
- struct Menu menu1 = { NULL, 1,0,56,10, MENUENABLED | MIDRAWN, (BYTE *)"File", &quit_mi };
-
- void test(void);
-
- main()
- { if ((IntuitionBase = OpenLibrary("intuition.library",0)) == NULL) LEAVE;
- if ((GfxBase = OpenLibrary("graphics.library",0)) == NULL) LEAVE;
- if ((Screen = OpenScreen(&NewScreen)) == NULL) LEAVE;
- LoadRGB4(&(Screen->ViewPort),colors,elementsof(colors));
- back_ground.Screen = Screen;
-
- unless (Window = OpenWindow(&back_ground)) LEAVE;
- rp = Window->RPort;
- SetMenuStrip(Window,&menu1);
-
- SetAPen(rp,1); SetRast(rp,0);
-
- test();
-
- for (;;)
- { struct IntuiMessage *imsg;
-
- Wait(1 << Window->UserPort->mp_SigBit);
-
- while (imsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
- { ULONG class;
- USHORT code;
-
- class = imsg->Class;
- code = imsg->Code;
- ReplyMsg(&imsg->ExecMessage);
-
- if (class == MENUPICK && code != MENUNULL) LEAVE;
- }
- }
- exitit:
- if (Window){ ClearMenuStrip(Window); CloseWindow(Window); }
- if (Screen) CloseScreen(Screen);
- if (GfxBase) CloseLibrary(GfxBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- }
-
- typedef long Fixed;
-
- /* conversion routines for fixed-point numbers */
-
- #define FR(x) ((x) + 0x8000 >> 16) /* convert fixed to integer */
- #define ff(x) ((long)(x) << 16) /* convert integer to fixed */
- #define AVE(a,b) (((a) + (b)) / 2)
-
- typedef struct { /* A 2-D point */
- Fixed x,
- y;
- } point;
-
- typedef struct { /* 3 points make a curve */
- point start,
- control,
- end;
- } curve;
-
- /* An edgelist is the output of the scan conversion routine. It points
- to a block of memory which is an array of x coordinates. If there are
- more coordinates than will fit in the array, a new edgelist and a
- new array are created, and the 'next' pointer of the current edgelist
- points to the new edgelist.
- */
-
- typedef struct _edgelist {
- struct _edgelist *next; /* pointer to next in chain */
- WORD top, /* topmost scanline of this list*/
- bottom; /* bottom scanline of this list */
- UBYTE left_edge; /* a left edge or right edge? */
- UBYTE rising; /* a rising edge */
- WORD *points; /* next point to fill in */
- } edgelist;
-
- /* This structure defines the memory blocks which are allocated for
- storing the coordinates.
- */
-
- #define BLOCKSIZE 1024
-
- struct edge_block {
- struct edge_block *next;
- UBYTE point_data[BLOCKSIZE];
- };
-
- /* This structure contains all the variables used by the path drawer. */
- /* NOTE: Added start_xpos and start_ypos to keep track of the first
- "pen-adjusted" point we drew at.
- */
-
- typedef struct {
- struct edge_block *first_block, /* head of block chain */
- *current_block; /* currently filling block */
-
- edgelist *first_edge, /* head of edgelist chain */
- *current_edge; /* currently filling edgelist */
-
- WORD *first_available_point, /* marks available space in block*/
- *last_available_point;
-
- Fixed cx, /* current pen positions. */
- cy;
-
- WORD current_xpos, /* used for tracking edge moves */
- current_ypos,
- /* new */ start_xpos, /* original _adjusted_ points */
- /* new */ start_ypos;
-
- WORD pen_width, /* makes fill shapes thicker */
- pen_height;
-
- WORD pen_offset; /* used in pen calculations */
- UBYTE error_code; /* Set if there was an error */
- UBYTE is_hole; /* TRUE if shape is a 'hole' */
-
- WORD min_x, /* limits for drawing */
- min_y,
- max_x,
- max_y;
- } PathInfo;
-
- /* a global PathInfo structure, which will eventually become a parameter... */
-
- PathInfo testpath;
- PathInfo *thePath = &testpath;
-
- /* move and draw, using fixed-point numbers */
-
- #define fmoveto(path,x,y) { path->current_xpos = FR(path->cx = x); path->current_ypos = FR(path->cy = y); }
- #define flineto(path,x,y) LineEdge(path->cx, path->cy, x, y)
-
- /* test to determine if an array of coordinates is full */
-
- #define EDGELIST_FULL(e) (thePath->first_available_point >= thePath->last_available_point)
-
- /* As we finish an edge, we insert it into the list of edges in sorted order.
- Later the edge drawer will traverse that list in drawing the edges.
- */
-
- void insert_last_edge(void)
- {
- /* Look for insertion point, and insert there.
- */
-
- if (thePath->current_edge)
- { edgelist **s = &thePath->first_edge;
-
- for (;;)
- { if ( ((*s) == NULL) ||
- (*s)->top > thePath->current_edge->top ||
- ((*s)->top == thePath->current_edge->top &&
- *(*s)->points > *thePath->current_edge->points) )
- break;
- s = &(*s)->next;
- }
- thePath->current_edge->next = *s;
- *s = thePath->current_edge;
- }
- }
-
- /* Make a new edgelist. Note that there are two basic types of edgelists,
- Those that are drawing upwards (decreasing scanline order) and those
- that are drawing downwards (increasing scanline order). The upwards
- edgelists fill coordinates from the top of the array down, while
- the downward edgelists fill coordinates from the bottom of the array
- up. (If an edgelist switches direction, it is terminated and a new
- edgelist is begun). Eventually things meet in the middle, at which
- point the array is full and a new array and edglist are created.
- */
-
- edgelist *alloc_edgelist(int upwards)
- {
- /* put the now-completed previous edge into the sorted list */
-
- insert_last_edge();
-
- /* The edgelists themselves are actually stored in the buffer
- along with the coordinates. This checks to see if there is
- enough space in the current buffer for an edgelist.
- */
-
- if ( thePath->first_available_point + (sizeof *thePath->current_edge / 2) >=
- thePath->last_available_point )
- { struct edge_block *new;
-
- /* This is the part that actually allocates a new memory block.
- The Path drawer has been designed to allow the option of
- re-using the same blocks for each path drawn, rather than
- allocating and freeing them each time. That's why this
- next line of code.
- */
-
- if (thePath->current_block && thePath->current_block->next)
- new = thePath->current_block->next;
- else
- { unless (new = AllocMem(sizeof (*new),0L)) return NULL;
- new->next = NULL;
- }
-
- /* inform the path structure that there's a new block */
-
- thePath->first_available_point = (WORD *)(new->point_data);
- thePath->last_available_point = (WORD *)(new + 1);
- if (thePath->current_block) thePath->current_block->next = new;
- else thePath->first_block = new;
- thePath->current_block = new;
- }
-
- /* now, mark the space in the block as used by the edgelist header. */
-
- thePath->current_edge = (edgelist *)thePath->first_available_point;
- thePath->first_available_point += sizeof (edgelist) / 2;
-
- /* innitialize the new edgelist structure */
-
- thePath->current_edge->next = NULL;
- if (upwards)
- { thePath->current_edge->points = thePath->last_available_point;
- thePath->current_edge->bottom = thePath->current_ypos;
- }
- else
- { thePath->current_edge->points = thePath->first_available_point;
- thePath->current_edge->top = thePath->current_ypos;
- }
- thePath->current_edge->rising = upwards;
- thePath->current_edge->left_edge = upwards;
-
- /* This commented-out statement could eventually be used to
- provide "holes" by reverse the sense of left / right for
- a particular path.
- */
-
- /* thePath->current_edge->left_edge = is_hole ? !upwards : upwards; */
- return thePath->current_edge;
- }
-
- /* This routine clars out the PathInfo structure. If there are any memory
- blocks left over from the last path we drew, it resets them.
- */
-
- BOOL init_edgelists(void)
- {
- if ( (thePath->current_block = thePath->first_block) )
- { thePath->first_available_point = (WORD *)(thePath->current_block->point_data);
- thePath->last_available_point = (WORD *)(thePath->current_block + 1);
- }
- else
- { thePath->first_available_point = thePath->last_available_point = NULL;
- }
-
- thePath->first_edge = NULL;
- thePath->current_edge = NULL;
- }
-
- /* This routine frees all but the first memory block, unless "all" is
- non-zero, in which case it frees the first one too. The reason for
- this is that it you are drawing a lot of small splines, you may want
- to keep one block around always.
- */
-
- void flush_edgelists(BOOL all)
- {
- thePath->first_available_point = thePath->last_available_point = NULL;
- if (thePath->first_block)
- { struct edge_block *new;
-
- while (new = thePath->first_block->next)
- { thePath->first_block->next = new->next;
- FreeMem(new,sizeof *new);
- }
- if (all)
- { FreeMem(thePath->first_block,sizeof *thePath->first_block);
- thePath->first_block = thePath->current_block = NULL;
- }
- }
- }
-
- /* This (rather complicated looking) routine adds points to an edgelist.
-
- If the new point is on the same scanline as the previous point, then
- not very much happens. For each scanline of difference between the
- new point and the old, however, a new coordinate is added. Right now,
- the X coordinates of any newly added points will be the same as the
- X coordinte of the new point. This is mainly for the convenience of
- the higher-level line-drawing routines which may not wish to deal
- with vertical or horizontal lines (which some of them indeed do,
- for speed).
-
- Note that this means that each newly added coordinate represents
- the point on the old, not the new, scan line.
- */
-
- void add_edge_points(WORD x,WORD y)
- { WORD old_pen_offset = thePath->pen_offset;
-
- /* note that the ordering of the following operations is important */
-
- /* adjust y position for pen height */
-
- if (x < thePath->current_xpos) thePath->pen_offset = thePath->pen_height;
- else if (x > thePath->current_xpos) thePath->pen_offset = 0;
-
- /* clip y position to screen coords */
-
- y = clamp(thePath->min_y, y + thePath->pen_offset, thePath->max_y);
-
- /* new code */
-
- /* This code is a special case for the first generated point. Basically.
- it attempts to compensate for the fact that because of the pen width
- and height, the current_xpos and current_ypos may not be an actual
- point on the path. We can't adjust that beforehand since we don't
- yet know what direction we are going to be drawing in until we
- get to this point, and pen offsets are derived from drawing direction.
-
- What this does is adjust the current_xpos and current_ypos to
- the correct pen offset and save those points. Later, we will attempt
- to "hook up" to those same points as the last drawing stroke.
- */
-
- if (thePath->current_edge == NULL)
- {
- WORD upwards;
- WORD adjusted_current_ypos;
-
- adjusted_current_ypos =
- clamp(thePath->min_y, thePath->current_ypos + thePath->pen_offset, thePath->max_y);
-
- if (y == adjusted_current_ypos) /* if no change in y, do nothing... */
- return;
-
- /* At this point, we know we are definately going to draw _something_.
- We know the drawing direction. So set up all the variables
- we need to remember the start point.
- */
-
- thePath->current_ypos = adjusted_current_ypos;
- upwards = (thePath->current_ypos > y);
-
- thePath->start_xpos = thePath->current_xpos;
- thePath->start_ypos = thePath->current_ypos;
-
- /* All that remains is to make sure that the "first" point also gets
- added to the edge list.
-
- We do this by cheating -- basically, we lie about what scan line
- we're on.
- */
-
- if (upwards)
- { thePath->current_ypos++;
- }
- else
- { /* thePath->current_ypos--; */ /* I don't know why this doesn't work */
- thePath->current_xpos += thePath->pen_width;
- }
- }
- /* end new code */
-
- if (thePath->current_ypos < y) /* if line drawing down */
- {
- /* if old edge was rising, or full, then alloc a new edge */
-
- if (!thePath->current_edge || thePath->current_edge->rising)
- { unless (alloc_edgelist(FALSE)) return;
- }
-
- /* kludge for pen width */
-
- if (old_pen_offset != thePath->pen_offset)
- { while (thePath->current_ypos < y-1)
- {
- if (EDGELIST_FULL(thePath->current_edge))
- { unless (alloc_edgelist(FALSE)) return;
- }
-
- *thePath->first_available_point++ = thePath->current_xpos + thePath->pen_width;
- thePath->current_ypos++;
- }
- }
-
- /* draw edge down the page */
-
- while (thePath->current_ypos < y)
- {
- if (EDGELIST_FULL(thePath->current_edge))
- { unless (alloc_edgelist(FALSE)) return;
- }
-
- *thePath->first_available_point++ = x + thePath->pen_width;
- thePath->current_ypos++;
- }
- thePath->current_edge->bottom = y;
- }
- else if (thePath->current_ypos > y)
- {
- /* if old edge was falling, or full, then alloc a new edge */
-
- if (!thePath->current_edge || !thePath->current_edge->rising)
- { unless (alloc_edgelist(TRUE)) return;
- }
-
- /* kludge for pen offset */
-
- if (old_pen_offset != thePath->pen_offset)
- { while (thePath->current_ypos > y + 1)
- {
- if (EDGELIST_FULL(thePath->current_edge))
- { unless (alloc_edgelist(TRUE)) return;
- }
-
- *--thePath->last_available_point = thePath->current_xpos;
- thePath->current_ypos--;
- }
- }
-
- /* draw edge up the page */
-
- while (thePath->current_ypos > y)
- {
- if (EDGELIST_FULL(thePath->current_edge))
- { unless (alloc_edgelist(TRUE)) return;
- }
-
- *--thePath->last_available_point = x;
- thePath->current_ypos--;
- }
- thePath->current_edge->points = thePath->last_available_point;
- thePath->current_edge->top = y;
- }
-
- thePath->current_xpos = x;
- }
-
- /* This is just a glue function which converts fixed to integer and then
- adds the edge points.
- */
-
- void VLineEdgePoints(Fixed x, Fixed y)
- { add_edge_points(FR(x),FR(y));
- }
-
- /* This routine draws short lines (up to 256 pixels) with accurate jaggies
- based on sub-pixel positioning of endpoints.
-
- For longer lines, we should eventually subdivide and recurse...
- */
-
- void LineEdge(Fixed x1, Fixed y1, Fixed x2, Fixed y2)
- { Fixed dx = x2 - x1;
- Fixed dy;
- WORD height,
- y,
- yoffset;
-
- x1 += 0x8000;
- y1 += 0x8000;
- y2 += 0x8000;
- y = y1 >> 16;
-
- if (y1 < y2)
- {
- height = (y2 >> 16) - y;
- if (height == 0) return;
-
- /* We could check for very long lines and handle differently... */
-
- dy = (y2 - y1) >> 12;
-
- yoffset = (y1 >> 12) & 0x0f;
-
- if (dy < 1) dy = 1;
- dx = (dx << 4) / dy;
- x1 += (dx * (15 - yoffset)) >> 4;
-
- while (height--)
- { add_edge_points(x1>>16,++y);
- x1 += dx;
- }
- }
- else
- {
- height = y - (y2 >> 16);
- if (height == 0) return;
-
- /* We could check for very long lines and handle differently... */
-
- dy = (y1 - y2) >> 12;
-
- yoffset = (y1 >> 12) & 0x0f;
-
- if (dy < 1) dy = 1;
- dx = (dx << 4) / dy;
- x1 += (dx * yoffset) >> 4;
-
- while (height--)
- { add_edge_points(x1>>16,--y);
- x1 += dx;
- }
- }
- }
-
- /* A recursive curve-drawer */
-
- void CurveEdge(curve *cur, WORD level)
- {
- WORD dx = FR(cur->start.x) - FR(cur->end.x);
- WORD dy = FR(cur->start.y) - FR(cur->end.y);
-
- /* if all points are on the same scanline */
-
- if ( dy == 0 && FR(cur->start.y) == FR(cur->control.y) )
- { VLineEdgePoints(cur->control.x, cur->control.y);
- VLineEdgePoints(cur->end.x, cur->end.y);
- return;
- }
-
- /* if all points are in the same column */
-
- if ( dx == 0 && FR(cur->start.x) == FR(cur->control.x) )
- { VLineEdgePoints(cur->control.x, cur->control.y);
- VLineEdgePoints(cur->end.x, cur->end.y);
- return;
- }
-
- if (level)
- { curve left,
- right;
-
- left.start = cur->start;
- left.control.x = AVE(cur->start.x, cur->control.x);
- left.control.y = AVE(cur->start.y, cur->control.y);
- right.control.x = AVE(cur->control.x, cur->end.x);
- right.control.y = AVE(cur->control.y, cur->end.y);
- left.end.x = right.start.x = AVE(left.control.x, right.control.x);
- left.end.y = right.start.y = AVE(left.control.y, right.control.y);
-
- if ( ABS(cur->control.x - left.end.x) < 0x800 &&
- ABS(cur->control.y - left.end.y) < 0x800 )
- {
- LineEdge(cur->start.x, cur->start.y, cur->end.x, cur->end.y);
- return;
- }
-
- right.end = cur->end;
-
- CurveEdge(&left,level-1);
- CurveEdge(&right,level-1);
- }
- else
- { LineEdge(cur->start.x, cur->start.y, cur->end.x, cur->end.y);
- }
- }
-
- /* This part probably does't need to be downcoded... */
-
- typedef struct {
- long vectors;
- long controlBits[1];
- /* point vector[anyNumber]; */ /* variable-length data */
- } path;
-
- BOOL OnCurve(long *bits, long index)
- { bits += index >> 5;
- index &= 31;
- return (*bits & (0x80000000 >> index)) == 0;
- }
-
- typedef struct {
- int isLine;
- curve c;
-
- /* Private */
- long index;
- long ep;
- long *bits;
- point *p;
- } pathWalker;
-
- void InitPathWalker (pathWalker *w, path *aPath)
- { w->index = 0;
- w->ep = aPath->vectors - 1;
- w->bits = aPath->controlBits;
- /* skip path the controlbits to point to the first point */
- w->p = (point *)(w->bits + (aPath->vectors + 31 >> 5));
- }
-
- int NextPathSegment(pathWalker *w)
- { long prevIndex,
- nextIndex;
-
- if (w->index == 0)
- { if (OnCurve(w->bits, w->ep))
- w->c.start = w->p[w->ep];
- else
- { if (OnCurve(w->bits,0))
- { w->c.start = w->p[0];
- w->index = 1;
- }
- else /* start at an implied on-curve point */
- { w->c.start.x = AVE(w->p[0].x, w->p[w->ep].x);
- w->c.start.y = AVE(w->p[0].y, w->p[w->ep].y);
- }
- }
- }
- else
- w->c.start = w->c.end;
-
- NEXT_SEGMENT:
- /* Compute the point index before and after the current one.
- * This wraps around, since we assume the contour is closed. */
-
- prevIndex = w->index == 0 ? w->ep : w->index - 1;
- nextIndex = w->index == w->ep ? 0 : w->index + 1;
-
- if (OnCurve(w->bits, w->index))
- { if (OnCurve(w->bits, prevIndex))
- { w->isLine = TRUE; /* this means we have a line */
- w->c.end = w->p[w->index];
- }
- else if (w->index++ <= w->ep)
- goto NEXT_SEGMENT;
- }
- else
- { w->isLine = FALSE; /* this means we have a curve */
- w->c.control = w->p[w->index];
- if (OnCurve(w->bits,nextIndex))
- w->c.end = w->p[nextIndex];
- else
- { w->c.end.x = AVE(w->p[w->index].x, w->p[nextIndex].x);
- w->c.end.y = AVE(w->p[w->index].y, w->p[nextIndex].y);
- }
- }
- return w->index++ <= w->ep; /* return TRUE if there are still more segments */
- }
-
- path *NextPath(path *aPath)
- { return (path *)((long *)aPath + 1 + (aPath->vectors + 31 >> 5) +
- aPath->vectors * 2);
- }
-
- /* This routine traverses all the data structures we built, and calls
- a routine to paint the data onto the screen.
-
- This part should be downcoded, and in addition the part that does the
- actual drawing should be a callback.
- */
-
- #define kCurveLimit 4
-
- BOOL fill_edges(WORD *ystart, UWORD maxlines, UWORD windmask)
- { WORD ypos = *ystart;
- WORD start_x;
- WORD wind;
- edgelist *alist = NULL,
- *tlist,
- *edge,
- **edge_ptr;
-
- ypos = thePath->first_edge->top;
-
- while (maxlines--)
- { if (alist == NULL && thePath->first_edge == NULL) return FALSE;
-
- /* transfer polygons from thePath->first_edge to active edge list... */
-
- while (thePath->first_edge &&
- thePath->first_edge->top <= ypos) /* if scan line intersects next poly */
- { edge = thePath->first_edge;
- thePath->first_edge = edge->next;
-
- edge->next = alist;
- alist = edge;
- edge->bottom--;
- }
-
- /* if sorting needed, re-sort list of active edges */
-
- tlist = alist;
- alist = NULL;
-
- /* sort the list of active edges...
- Note that this sort takes advantage of existing coherency
- in the list and is therefore quite fast.
- */
-
- while (tlist)
- { edge = tlist;
- tlist = tlist->next;
- if (ypos >= edge->bottom) continue;
-
- for (edge_ptr = &alist; *edge_ptr; edge_ptr = &(*edge_ptr)->next )
- { if ( *(*edge_ptr)->points > *edge->points ) break;
- }
- edge->next = *edge_ptr;
- *edge_ptr = edge;
- }
-
- /* "winding fill" algorithm */
-
- wind = 0; /* initially outside of figure */
-
- for (edge = alist; edge; edge = edge->next)
- { WORD stop_x;
-
- /* stop_x = clamp(thePath->min_x, *edge->points++, thePath->max_x); */
- stop_x = *edge->points++;
-
- if ((wind & windmask) == 0) start_x = stop_x;
-
- if (edge->left_edge) ++wind; else --wind;
-
- /* Here's where we actualy draw the line. We can replace
- this with whatever code is appropriate... */
-
- if ((wind & windmask) == 0)
- PaintRect(rp,start_x,ypos,stop_x-start_x,1);
- }
-
- ypos++;
- }
- *ystart = ypos;
- return (alist || thePath->first_edge);
- }
-
- /* This is the overall routine which calls all the others */
-
- path *FramePath(path *cont)
- { pathWalker walker;
- WORD org_x,org_y;
- WORD ypos;
-
- unless (init_edgelists()) return NULL;
-
- InitPathWalker(&walker,cont);
-
- /* the first segment is special, since it calls fmoveto */
-
- if (NextPathSegment(&walker))
- { fmoveto(thePath,walker.c.start.x, walker.c.start.y);
- org_x = thePath->current_xpos;
- org_y = thePath->current_ypos;
- if (walker.isLine)
- flineto(thePath,walker.c.end.x, walker.c.end.y);
- else
- CurveEdge(&walker.c, kCurveLimit);
- }
-
- /* keep looping until we run out of segments */
-
- while (NextPathSegment(&walker))
- {
- if (walker.isLine)
- flineto(thePath,walker.c.end.x, walker.c.end.y);
- else
- CurveEdge(&walker.c, kCurveLimit);
- }
-
- #if 0
- add_edge_points(org_x,org_y);
- thePath->pen_offset = 0;
- add_edge_points(org_x,org_y);
- insert_last_edge();
- #endif
- /* new code */
- { WORD save_width, save_height;
-
- /* draw back to origin point */
-
- add_edge_points(org_x,org_y);
-
- /* now, draw back to EXACT (no pen adjustment) first point. */
-
- save_width = thePath->pen_width; thePath->pen_width = 0;
- save_height = thePath->pen_height; thePath->pen_height = 0;
- thePath->pen_offset = 0;
-
- add_edge_points(thePath->start_xpos,thePath->start_ypos);
-
- thePath->pen_width = save_width;
- thePath->pen_height = save_height;
-
- insert_last_edge();
- }
- /* end new code */
-
- /* now, traverse the lists... */
-
- ypos = thePath->first_edge->top;
- fill_edges(&ypos,-1,~0);
-
- /* return the next path, used if this path is one of several within
- a series of paths.
- */
-
- return NextPath(cont);
- }
-
- void test(void)
- {
- long myPath[] = {
- 4,
- 0x50000000,
- ff(47),ff(200-101),
- ff(146),ff(200-124),
- ff(225),ff(200-68),
- ff(146),ff(200-119),
- };
-
- long myPath2[] = {
- 4,
- 0x50000000,
- ff(17),ff(7),
- ff(30),ff(17),
- ff(42),ff(5),
- ff(30),ff(19),
- };
-
- int i;
- long sec1,sec2,mic1,mic2;
-
- thePath->min_x = 0;
- thePath->max_x = 320;
-
- thePath->min_y = 0;
- thePath->max_y = 200;
-
- thePath->pen_width = 1;
- thePath->pen_height = 1;
-
- FramePath( (path *)myPath2 );
-
- CurrentTime((ULONG *)&sec1,(ULONG *)&mic1);
- for (i=0; i<100; i++) FramePath( (path *)myPath );
- CurrentTime((ULONG *)&sec2,(ULONG *)&mic2);
-
- sec1 = sec1 * 1000 + mic1 / 1000;
- sec2 = sec2 * 1000 + mic2 / 1000;
-
- Printf("Elapsed time was %ld milliseconds\n",sec2-sec1);
-
- flush_edgelists(TRUE);
-
- };
-