123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747 |
- /* This file is part of the GNU libxmi package.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, X Consortium. For an
- associated permission notice, see the accompanying file README-X.
-
- GNU enhancements Copyright (C) 1998, 1999, 2000, 2005, Free Software
- Foundation, Inc.
- The GNU libxmi package is free software. You may redistribute it
- and/or modify it under the terms of the GNU General Public License as
- published by the Free Software foundation; either version 2, or (at your
- option) any later version.
- The GNU libxmi package is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with the GNU plotutils package; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
- Boston, MA 02110-1301, USA. */
- /* This module contains the miZeroLine() and miZeroDash() functions. They
- a rasterize single-pixel (i.e., `zero-width') Bresenham polyline, either
- solid or dashed.
- The cap mode and join mode in the graphics context are ignored, except
- that if the cap mode is MI_CAP_NOT_LAST, the final pixel of the polyline
- is omitted.
- All painting goes through the low-level MI_PAINT_SPANS() and
- MI_COPY_AND_PAINT_SPANS() macros. */
- /* Historical note: this is a merger of MI code from X11, written by Ken
- Whaley, with low-level X11 CFB (color frame-buffer) code, of unknown
- authorship. (I wrote Ken, and he remembers writing the monochrome frame
- buffer code, but not the color code.) That's because the X11 MI code
- included miZeroLine(), but not miZeroDash(). I based the latter on the
- CFB routines. I needed to hack them extensively so that they would
- generate a list of spans to paint. I also removed clipping code. --rsm */
- #include "sys-defines.h"
- #include "extern.h"
- #include "xmi.h"
- #include "mi_spans.h"
- #include "mi_gc.h"
- #include "mi_api.h"
- #include "mi_line.h"
- /* Comment on drawing solid lines (from Ken Whaley):
- NON-SLOPED LINES
- Horizontal lines are always drawn left to right; we have to move the
- endpoints right by one after they're swapped. Vertical lines are always
- drawn top to bottom (y-increasing). This requires adding one to the
- y-coordinate of each endpoint after swapping. */
- /* forward references */
- static void cfbBresD (miPaintedSet *paintedSet, const miGC *pGC, int *pdashNum, int *pdashIndex, const unsigned int *pDash, int numInDashList, int *pdashOffset, bool isDoubleDash, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e2, int len);
- static void cfbBresS (miPaintedSet *paintedSet, const miGC *pGC, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e2, int len);
- static void cfbHorzS (miPaintedSet *paintedSet, const miGC *pGC, int x1, int y1, int len);
- static void cfbVertS (miPaintedSet *paintedSet, const miGC *pGC, int x1, int y1, int len);
- /* Macro for painting a single point. Used for ending line segments. */
- #define MI_PAINT_POINT(paintedSet, pixel, xx, yy) \
- {\
- miPoint *point;\
- unsigned int *width;\
- point = (miPoint *)mi_xmalloc(sizeof(miPoint));\
- width = (unsigned int *)mi_xmalloc(sizeof(unsigned int));\
- *width = 1;\
- point->x = xx;\
- point->y = yy;\
- MI_PAINT_SPANS(paintedSet, pixel, 1, point, width)\
- }
- /* Macro for generating a list of spans, used when the successive points on
- a Bresenham line are generated. Assumes the availability of working
- storage, accessed via pointers `ppt' and `pwidths', and also variables
- numSpans (initted to 0), firstspan (initted to true), and ycurr. The
- arrays should be at least as large as the longest generated Bresenham
- line segment. */
-
- #define MI_ADD_POINT(xx, yy, ppt, pwidth, numSpans, ycurr, firstspan, signdy) \
- {\
- if (!firstspan && yy == ycurr)\
- {\
- int xdelta = xx - ppt->x;\
- if (xdelta < 0)\
- {\
- (*pwidth) -= xdelta;\
- ppt->x = xx;\
- }\
- else if (xdelta > 0)\
- { \
- unsigned int widthcurr = *pwidth; \
- (*pwidth) = UMAX(widthcurr, (unsigned int)(1 + xdelta));\
- } \
- }\
- else\
- {\
- if (!firstspan)\
- {\
- ppt += signdy;\
- pwidth += signdy;\
- }\
- else\
- firstspan = false;\
- ppt->x = xx;\
- ppt->y = yy;\
- *pwidth = 1;\
- ycurr = yy;\
- ++numSpans;\
- }\
- }
- /*
- * Draw a solid Bresenham polyline, i.e. a `zero-width' solid polyline,
- * in paint type #1.
- */
- /* ARGS: mode = Origin or Previous
- npt = number of points
- pPts = point array */
- void
- miZeroLine (miPaintedSet *paintedSet, const miGC *pGC, miCoordMode mode, int npt, const miPoint *pPts)
- {
- const miPoint *ppt; /* pointer to point within array */
- /* temporaries */
- int xstart, ystart;
- int x1, x2;
- int y1, y2;
- /* ensure we have >=1 points */
- if (npt <= 0)
- return;
- /* loop through points, drawing a solid Bresenham segment for each line
- segment */
- ppt = pPts;
- xstart = ppt->x;
- ystart = ppt->y;
- x2 = xstart;
- y2 = ystart;
- while (--npt)
- {
- x1 = x2;
- y1 = y2;
- ++ppt;
- x2 = ppt->x;
- y2 = ppt->y;
- if (mode == MI_COORD_MODE_PREVIOUS)
- /* convert from relative coordinates */
- {
- x2 += x1;
- y2 += y1;
- }
- if (x1 == x2) /* vertical line */
- {
- if (y1 > y2)
- /* make line go top to bottom, keeping endpoint semantics */
- {
- int tmp;
- tmp = y2;
- y2 = y1 + 1;
- y1 = tmp + 1;
- }
- /* draw line */
- if (y1 != y2)
- cfbVertS (paintedSet, pGC, x1, y1, y2 - y1);
- /* restore final point */
- y2 = ppt->y;
- }
- else if (y1 == y2) /* horizontal line */
- {
- if (x1 > x2)
- /* force line from left to right, keeping endpoint semantics */
- {
- int tmp;
- tmp = x2;
- x2 = x1 + 1;
- x1 = tmp + 1;
- }
-
- /* draw line */
- if (x1 != x2)
- cfbHorzS (paintedSet, pGC, x1, y1, x2 - x1);
- /* restore final point */
- x2 = ppt->x;
- }
- else /* sloped line */
- {
- int adx; /* abs values of dx and dy */
- int ady;
- int signdx; /* sign of dx and dy */
- int signdy;
- int e, e1, e2; /* Bresenham error and increments */
- int axis; /* major axis */
- int len; /* length of segment */
- AbsDeltaAndSign(x2, x1, adx, signdx);
- AbsDeltaAndSign(y2, y1, ady, signdy);
- if (adx > ady)
- {
- axis = X_AXIS;
- e1 = ady << 1;
- e2 = e1 - (adx << 1);
- e = e1 - adx;
- FIXUP_X_MAJOR_ERROR(e, signdx, signdy);
- }
- else
- {
- axis = Y_AXIS;
- e1 = adx << 1;
- e2 = e1 - (ady << 1);
- e = e1 - ady;
- FIXUP_Y_MAJOR_ERROR(e, signdx, signdy);
- }
- /* we have Bresenham parameters and two points, so all we need to
- do now is draw */
- if (axis == X_AXIS)
- len = adx;
- else
- len = ady;
- cfbBresS (paintedSet, pGC,
- signdx, signdy, axis, x1, y1,
- e, e1, e2, len);
- } /* sloped line */
- } /* while (--npt) */
-
- /* Paint the last point if the end style isn't CapNotLast. (I.e. assume
- that a round/butt/projecting/triangular cap that is one pixel wide is
- the same as the single pixel of the endpoint.) */
- if (pGC->capStyle != (int)MI_CAP_NOT_LAST
- &&
- (xstart != x2 || ystart != y2 || ppt == pPts + 1))
- MI_PAINT_POINT(paintedSet, pGC->pixels[1], x2, y2)
- }
- /*
- * Draw a dashed Bresenham polyline, i.e. a `zero-width' dashed polyline.
- */
- /* ARGS: mode = Origin or Previous
- npt = number of points
- pPts = point array */
- void
- miZeroDash (miPaintedSet *paintedSet, const miGC *pGC, miCoordMode mode, int npt, const miPoint *pPts)
- {
- const miPoint *ppt; /* pointer to current point */
- /* temporaries */
- int xstart, ystart;
- int x1, x2, y1, y2;
- const unsigned int *pDash;
- int dashNum, dashIndex;
- int dashOffset;
- int numInDashList;
- bool isDoubleDash;
- /* ensure we have >=1 points */
- if (npt <= 0)
- return;
- /* perform initial offsetting into the dash array; compute dash values */
- pDash = pGC->dash;
- numInDashList = pGC->numInDashList;
- isDoubleDash = (pGC->lineStyle == (int)MI_LINE_DOUBLE_DASH ? true : false);
- dashNum = 0;
- dashIndex = 0;
- dashOffset = 0;
- miStepDash (pGC->dashOffset, &dashNum, &dashIndex,
- pDash, numInDashList, &dashOffset);
- /* loop through points, drawing a dashed Bresenham segment for each line
- segment of nonzero length */
- ppt = pPts;
- xstart = ppt->x;
- ystart = ppt->y;
- x2 = xstart;
- y2 = ystart;
- while (--npt)
- {
- x1 = x2;
- y1 = y2;
- ++ppt;
- x2 = ppt->x;
- y2 = ppt->y;
- if (mode == MI_COORD_MODE_PREVIOUS)
- /* convert from relative coordinates */
- {
- x2 += x1;
- y2 += y1;
- }
-
- /* use Bresenham algorithm for sloped lines (no special treatment for
- horizontal or vertical lines, unlike the undashed case) */
- {
- int adx; /* abs values of dx and dy */
- int ady;
- int signdx; /* sign of dx and dy */
- int signdy;
- int e, e1, e2; /* Bresenham error and increments */
- int axis; /* major axis */
- int len;
- AbsDeltaAndSign(x2, x1, adx, signdx);
- AbsDeltaAndSign(y2, y1, ady, signdy);
- if (adx > ady)
- {
- axis = X_AXIS;
- e1 = ady << 1;
- e2 = e1 - (adx << 1);
- e = e1 - adx;
- len = adx;
- FIXUP_X_MAJOR_ERROR(e, signdx, signdy);
- }
- else
- {
- axis = Y_AXIS;
- e1 = adx << 1;
- e2 = e1 - (ady << 1);
- e = e1 - ady;
- len = ady;
- FIXUP_Y_MAJOR_ERROR(e, signdx, signdy);
- }
-
- /* we have Bresenham parameters and two points, so all we need to
- do now is draw (updating dashNum, dashIndex and dashOffset) */
- cfbBresD (paintedSet, pGC,
- &dashNum, &dashIndex, pDash, numInDashList,
- &dashOffset, isDoubleDash,
- signdx, signdy, axis, x1, y1,
- e, e1, e2, len);
- }
- } /* while (nline--) */
- /* paint the last point if the end style isn't CapNotLast.
- (Assume that a projecting, butt, or round cap that is one
- pixel wide is the same as the single pixel of the endpoint.) */
- if (pGC->capStyle != (int)MI_CAP_NOT_LAST
- &&
- (xstart != x2 || ystart != y2 || ppt == pPts + 1))
- {
- if (dashNum & 1)
- {
- /* background dash */
- if (isDoubleDash)
- /* paint, in paint type #0 */
- MI_PAINT_POINT(paintedSet, pGC->pixels[0], x2, y2);
- }
- else
- /* foreground dash */
- {
- /* use a paint type that cycles through 1..(numPixels-1) */
- int numPixels = pGC->numPixels;
- int paintType = 1 + ((dashNum / 2) % (numPixels - 1));
-
- MI_PAINT_POINT(paintedSet, pGC->pixels[paintType], x2, y2);
- }
- }
- }
- /* Internal: draw solid Bresenham line segment, in paint type #1. Called
- by miZeroLine(). Endpoint semantics are used, i.e. we paint only len
- pixels (i.e. |dx| or |dy| pixels), not including the endpoint. */
- /* ARGS: signdx,signdy = signs of directions
- axis = major axis (Y_AXIS or X_AXIS)
- x1,y1 = initial point
- e = error accumulator
- e1,e2 = Bresenham increments
- len = length of line in pixels */
- static void
- cfbBresS (miPaintedSet *paintedSet, const miGC *pGC, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e2, int len)
- {
- miPoint *pptInit, *pptLast;
- unsigned int *pwidthInit, *pwidthLast;
- int x, y;
- int e3;
- /* variables in span generation code, i.e. in MI_ADD_POINT() */
- int numSpans;
- int ycurr;
- miPoint *ppt;
- unsigned int *pwidth;
- bool firstspan;
- if (len == 0)
- return;
- /* set up work arrays */
- pptInit = (miPoint *)mi_xmalloc(len * sizeof(miPoint));
- pwidthInit = (unsigned int *)mi_xmalloc(len * sizeof(unsigned int));
- pptLast = pptInit + (len - 1);
- pwidthLast = pwidthInit + (len - 1);
- /* reset variables used in MI_ADD_POINT() */
- numSpans = 0;
- ycurr = 0;
- firstspan = true;
- if (signdy >= 0)
- {
- ppt = pptInit;
- pwidth = pwidthInit;
- }
- else
- {
- ppt = pptLast;
- pwidth = pwidthLast;
- }
-
- e3 = e2 - e1;
- e = e - e1; /* make looping easier */
- #define BresStep(minor,major) \
- {if ((e += e1) >= 0) { e += e3; minor; } major;}
- #define Loop_x(counter,store) while (counter--) \
- {store; BresStep(y+=signdy,x+=signdx) }
- #define Loop_y(counter,store) while (counter--) \
- {store; BresStep(x+=signdx, y+=signdy) }
- /* point to first point, and generate len pixels */
- x = x1;
- y = y1;
- switch (axis)
- {
- case X_AXIS:
- default:
- Loop_x(len, MI_ADD_POINT(x, y, ppt, pwidth, numSpans, ycurr, firstspan, signdy))
- break;
- case Y_AXIS:
- Loop_y(len, MI_ADD_POINT(x, y, ppt, pwidth, numSpans, ycurr, firstspan, signdy))
- break;
- }
- if (numSpans > 0)
- {
- if (signdy < 0)
- /* spans are offset, so shift downward */
- {
- miPoint *ppt_src = pptLast - (numSpans - 1);
- miPoint *ppt_dst = pptInit;
- unsigned int *pwidth_src = pwidthLast - (numSpans - 1);
- unsigned int *pwidth_dst = pwidthInit;
- int count = numSpans;
- while (count--)
- {
- *ppt_dst++ = *ppt_src++;
- *pwidth_dst++ = *pwidth_src++;
- }
- }
- MI_PAINT_SPANS(paintedSet, pGC->pixels[1], numSpans, pptInit, pwidthInit)
- }
- }
- /* Internal: draw dashed Bresenham line segment. Called by miZeroDash().
- Endpoint semantics are used. */
- /* ARGS: pdashNum = absolute dash number
- pdashIndx = index into dash array
- pDash = dash array
- numInDashList = length of dash array
- pdashOffset = offset into current dash
- signdx,signdy = signs of directions
- axis = major axis (Y_AXIS or X_AXIS)
- x1,y1 = initial point
- e = error accumulator
- e1,e2 = Bresenham increments
- len = length of line in pixels */
- static void
- cfbBresD (miPaintedSet *paintedSet, const miGC *pGC, int *pdashNum, int *pdashIndex, const unsigned int *pDash, int numInDashList, int *pdashOffset, bool isDoubleDash, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e2, int len)
- {
- miPoint *pptInit_fg, *pptInit_bg = (miPoint *)NULL;
- miPoint *pptLast_fg, *pptLast_bg = (miPoint *)NULL;
- unsigned int *pwidthInit_fg, *pwidthInit_bg = (unsigned int *)NULL;
- unsigned int *pwidthLast_fg, *pwidthLast_bg = (unsigned int *)NULL;
- int x, y;
- int e3;
- int dashNum, dashIndex;
- int dashOffset;
- int dashRemaining;
- int thisDash;
- /* variables in span generation code, i.e. in MI_ADD_POINT() */
- int numSpans_fg, numSpans_bg = 0;
- int ycurr_fg, ycurr_bg = 0;
- miPoint *ppt_fg, *ppt_bg = (miPoint *)NULL;
- unsigned int *pwidth_fg, *pwidth_bg = (unsigned int *)NULL;
- bool firstspan_fg, firstspan_bg = false;
- /* set up work arrays */
- pptInit_fg = (miPoint *)mi_xmalloc(len * sizeof(miPoint));
- pwidthInit_fg = (unsigned int *)mi_xmalloc(len * sizeof(unsigned int));
- pptLast_fg = pptInit_fg + (len - 1);
- pwidthLast_fg = pwidthInit_fg + (len - 1);
- if (isDoubleDash)
- {
- pptInit_bg = (miPoint *)mi_xmalloc(len * sizeof(miPoint));
- pwidthInit_bg = (unsigned int *)mi_xmalloc(len * sizeof(unsigned int));
- pptLast_bg = pptInit_bg + (len - 1);
- pwidthLast_bg = pwidthInit_bg + (len - 1);
- }
- dashNum = *pdashNum; /* absolute number of current dash */
- dashIndex = *pdashIndex; /* index of current dash */
- dashOffset = *pdashOffset; /* offset into current dash */
- dashRemaining = (int)(pDash[dashIndex]) - dashOffset; /* how much is left */
- if (len <= (thisDash = dashRemaining))
- /* line segment will be solid, not dashed */
- {
- thisDash = len;
- dashRemaining -= len;
- }
- #define NextDash {\
- dashNum++; \
- dashIndex++; \
- if (dashIndex == numInDashList) \
- dashIndex = 0; \
- dashRemaining = (int)(pDash[dashIndex]); \
- if ((thisDash = dashRemaining) >= len) \
- { \
- dashRemaining -= len; \
- thisDash = len; \
- } \
- }
- e3 = e2-e1;
- e = e - e1; /* make looping easier */
- /* point to first point */
- x = x1;
- y = y1;
- /* loop, generating dashes (in the absence of dashing, would
- generate len pixels in all) */
- for ( ; ; )
- {
- len -= thisDash;
- /* reset variables used in MI_ADD_POINT() */
- numSpans_fg = 0;
- ycurr_fg = 0;
- firstspan_fg = true;
- if (signdy >= 0)
- {
- ppt_fg = pptInit_fg;
- pwidth_fg = pwidthInit_fg;
- }
- else
- {
- ppt_fg = pptLast_fg;
- pwidth_fg = pwidthLast_fg;
- }
- if (isDoubleDash)
- {
- numSpans_bg = 0;
- ycurr_bg = 0;
- firstspan_bg = true;
- ppt_bg = pptInit_bg;
- pwidth_bg = pwidthInit_bg;
- if (signdy >= 0)
- {
- ppt_bg = pptInit_bg;
- pwidth_bg = pwidthInit_bg;
- }
- else
- {
- ppt_bg = pptLast_bg;
- pwidth_bg = pwidthLast_bg;
- }
- }
- switch (axis)
- {
- case X_AXIS:
- default:
- if (dashIndex & 1)
- {
- if (isDoubleDash)
- {
- /* create background dash */
- Loop_x(thisDash, MI_ADD_POINT(x, y, ppt_bg, pwidth_bg, numSpans_bg, ycurr_bg, firstspan_bg, signdy))
- }
- else
- /* not double dashing; no background dash */
- Loop_x(thisDash, ;);
- }
- else
- /* create foreground dash */
- Loop_x(thisDash, MI_ADD_POINT(x, y, ppt_fg, pwidth_fg, numSpans_fg, ycurr_fg, firstspan_fg, signdy))
- break;
- case Y_AXIS:
- if (dashIndex & 1)
- {
- if (isDoubleDash)
- {
- /* create background dash */
- Loop_y(thisDash, MI_ADD_POINT(x, y, ppt_bg, pwidth_bg, numSpans_bg, ycurr_bg, firstspan_bg, signdy))
- }
- else
- /* not double dashing; no background dash */
- Loop_y(thisDash, ;);
- }
- else
- /* create foreground dash */
- Loop_y(thisDash, MI_ADD_POINT(x, y, ppt_fg, pwidth_fg, numSpans_fg, ycurr_fg, firstspan_fg, signdy))
- break;
- } /* end switch */
-
- if (numSpans_fg > 0)
- /* have a foreground dash to paint */
- {
- miPoint *pptStart_fg;
- unsigned int *pwidthStart_fg;
-
- if (signdy >= 0)
- {
- pptStart_fg = pptInit_fg;
- pwidthStart_fg = pwidthInit_fg;
- }
- else
- {
- pptStart_fg = pptLast_fg - (numSpans_fg - 1);
- pwidthStart_fg = pwidthLast_fg - (numSpans_fg - 1);
- }
- /* for foreground dash, use a paint type that cycles through
- 1..(numPixels-1) */
- {
- int numPixels = pGC->numPixels;
- int paintType = 1 + ((dashNum / 2) % (numPixels - 1));
- MI_COPY_AND_PAINT_SPANS(paintedSet, pGC->pixels[paintType], numSpans_fg, pptStart_fg, pwidthStart_fg)
- }
- }
- if (isDoubleDash && numSpans_bg > 0)
- /* have a background dash to paint */
- {
- miPoint *pptStart_bg;
- unsigned int *pwidthStart_bg;
-
- if (signdy >= 0)
- {
- pptStart_bg = pptInit_bg;
- pwidthStart_bg = pwidthInit_bg;
- }
- else
- {
- pptStart_bg = pptLast_bg - (numSpans_bg - 1);
- pwidthStart_bg = pwidthLast_bg - (numSpans_bg - 1);
- }
- /* for background dash, use paint type #0 */
- MI_COPY_AND_PAINT_SPANS(paintedSet, pGC->pixels[0], numSpans_bg, pptStart_bg, pwidthStart_bg)
- }
- if (len == 0)
- break; /* break out of dash-generating loop */
- NextDash /* update dashNum, dashIndex, thisDash, dashRemaining */
- } /* end infinite dash-generating loop */
- *pdashNum = dashNum;
- *pdashIndex = dashIndex;
- *pdashOffset = (int)(pDash[dashIndex]) - dashRemaining;
- free (pwidthInit_fg);
- free (pptInit_fg);
- if (isDoubleDash)
- {
- free (pwidthInit_bg);
- free (pptInit_bg);
- }
- }
- /* Internal: draw horizontal zero-width solid line segment, in paint type #1.
- Called by miZeroLine().
- Called with len >= 1, and len=x2-x1. Endpoint semantics
- are used, so we paint only len pixels, i.e. x1..x2-1. */
- /* ARGS: x1,y1 = initial point, len = length of line */
- static void
- cfbHorzS (miPaintedSet *paintedSet, const miGC *pGC, int x1, int y1, int len)
- {
- miPoint *ppt;
- unsigned int *pwidth;
- ppt = (miPoint *)mi_xmalloc(sizeof(miPoint));
- pwidth = (unsigned int *)mi_xmalloc(sizeof(unsigned int));
- ppt->x = x1;
- ppt->y = y1;
- *pwidth = (unsigned int)len;
- MI_PAINT_SPANS(paintedSet, pGC->pixels[1], 1, ppt, pwidth)
- }
- /* Internal: draw vertical zero-width solid line segment, in paint type #1.
- Called by miZeroLine().
- Called with len >= 1, and len=y2-y1. Endpoint semantics
- are used, so we paint only len pixels, i.e. y1..y2-1. */
- /* ARGS: x1,y1 = initial point, len = length of line */
- static void
- cfbVertS (miPaintedSet *paintedSet, const miGC *pGC, int x1, int y1, int len)
- {
- miPoint *ppt, *pptInit;
- unsigned int *pwidth, *pwidthInit;
- int i;
- ppt = pptInit = (miPoint *)mi_xmalloc(len * sizeof(miPoint));
- pwidth = pwidthInit = (unsigned int *)mi_xmalloc(len * sizeof(unsigned int));
- for (i = 0; i < len; i++)
- {
- ppt->x = x1;
- ppt->y = y1 + i;
- ppt++;
- *pwidth++ = (unsigned int)1;
- }
- MI_PAINT_SPANS(paintedSet, pGC->pixels[1], len, pptInit, pwidthInit)
- }
|