miwideline.h revision 05b261ec
105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1988, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included
1205b261ecSmrgin all copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1505b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1605b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1705b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrgOTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg
2205b261ecSmrgExcept as contained in this notice, the name of The Open Group shall
2305b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or
2405b261ecSmrgother dealings in this Software without prior written authorization
2505b261ecSmrgfrom The Open Group.
2605b261ecSmrg
2705b261ecSmrg*/
2805b261ecSmrg
2905b261ecSmrg/* Author:  Keith Packard, MIT X Consortium */
3005b261ecSmrg
3105b261ecSmrg#include "mispans.h"
3205b261ecSmrg#include "mifpoly.h" /* for ICEIL */
3305b261ecSmrg
3405b261ecSmrg/*
3505b261ecSmrg * interface data to span-merging polygon filler
3605b261ecSmrg */
3705b261ecSmrg
3805b261ecSmrgtypedef struct _SpanData {
3905b261ecSmrg    SpanGroup	fgGroup, bgGroup;
4005b261ecSmrg} SpanDataRec, *SpanDataPtr;
4105b261ecSmrg
4205b261ecSmrg#define AppendSpanGroup(pGC, pixel, spanPtr, spanData) { \
4305b261ecSmrg	SpanGroup   *group, *othergroup = NULL; \
4405b261ecSmrg	if (pixel == pGC->fgPixel) \
4505b261ecSmrg	{ \
4605b261ecSmrg	    group = &spanData->fgGroup; \
4705b261ecSmrg	    if (pGC->lineStyle == LineDoubleDash) \
4805b261ecSmrg		othergroup = &spanData->bgGroup; \
4905b261ecSmrg	} \
5005b261ecSmrg	else \
5105b261ecSmrg	{ \
5205b261ecSmrg	    group = &spanData->bgGroup; \
5305b261ecSmrg	    othergroup = &spanData->fgGroup; \
5405b261ecSmrg	} \
5505b261ecSmrg	miAppendSpans (group, othergroup, spanPtr); \
5605b261ecSmrg}
5705b261ecSmrg
5805b261ecSmrg/*
5905b261ecSmrg * Polygon edge description for integer wide-line routines
6005b261ecSmrg */
6105b261ecSmrg
6205b261ecSmrgtypedef struct _PolyEdge {
6305b261ecSmrg    int	    height;	/* number of scanlines to process */
6405b261ecSmrg    int	    x;		/* starting x coordinate */
6505b261ecSmrg    int	    stepx;	/* fixed integral dx */
6605b261ecSmrg    int	    signdx;	/* variable dx sign */
6705b261ecSmrg    int	    e;		/* initial error term */
6805b261ecSmrg    int	    dy;
6905b261ecSmrg    int	    dx;
7005b261ecSmrg} PolyEdgeRec, *PolyEdgePtr;
7105b261ecSmrg
7205b261ecSmrg#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
7305b261ecSmrg
7405b261ecSmrg/*
7505b261ecSmrg * types for general polygon routines
7605b261ecSmrg */
7705b261ecSmrg
7805b261ecSmrgtypedef struct _PolyVertex {
7905b261ecSmrg    double  x, y;
8005b261ecSmrg} PolyVertexRec, *PolyVertexPtr;
8105b261ecSmrg
8205b261ecSmrgtypedef struct _PolySlope {
8305b261ecSmrg    int	    dx, dy;
8405b261ecSmrg    double  k;	    /* x0 * dy - y0 * dx */
8505b261ecSmrg} PolySlopeRec, *PolySlopePtr;
8605b261ecSmrg
8705b261ecSmrg/*
8805b261ecSmrg * Line face description for caps/joins
8905b261ecSmrg */
9005b261ecSmrg
9105b261ecSmrgtypedef struct _LineFace {
9205b261ecSmrg    double  xa, ya;
9305b261ecSmrg    int	    dx, dy;
9405b261ecSmrg    int	    x, y;
9505b261ecSmrg    double  k;
9605b261ecSmrg} LineFaceRec, *LineFacePtr;
9705b261ecSmrg
9805b261ecSmrg/*
9905b261ecSmrg * macros for polygon fillers
10005b261ecSmrg */
10105b261ecSmrg
10205b261ecSmrg#define MIPOLYRELOADLEFT    if (!left_height && left_count) { \
10305b261ecSmrg	    	    	    	left_height = left->height; \
10405b261ecSmrg	    	    	    	left_x = left->x; \
10505b261ecSmrg	    	    	    	left_stepx = left->stepx; \
10605b261ecSmrg	    	    	    	left_signdx = left->signdx; \
10705b261ecSmrg	    	    	    	left_e = left->e; \
10805b261ecSmrg	    	    	    	left_dy = left->dy; \
10905b261ecSmrg	    	    	    	left_dx = left->dx; \
11005b261ecSmrg	    	    	    	--left_count; \
11105b261ecSmrg	    	    	    	++left; \
11205b261ecSmrg			    }
11305b261ecSmrg
11405b261ecSmrg#define MIPOLYRELOADRIGHT   if (!right_height && right_count) { \
11505b261ecSmrg	    	    	    	right_height = right->height; \
11605b261ecSmrg	    	    	    	right_x = right->x; \
11705b261ecSmrg	    	    	    	right_stepx = right->stepx; \
11805b261ecSmrg	    	    	    	right_signdx = right->signdx; \
11905b261ecSmrg	    	    	    	right_e = right->e; \
12005b261ecSmrg	    	    	    	right_dy = right->dy; \
12105b261ecSmrg	    	    	    	right_dx = right->dx; \
12205b261ecSmrg	    	    	    	--right_count; \
12305b261ecSmrg	    	    	    	++right; \
12405b261ecSmrg			}
12505b261ecSmrg
12605b261ecSmrg#define MIPOLYSTEPLEFT  left_x += left_stepx; \
12705b261ecSmrg    	    	    	left_e += left_dx; \
12805b261ecSmrg    	    	    	if (left_e > 0) \
12905b261ecSmrg    	    	    	{ \
13005b261ecSmrg	    	    	    left_x += left_signdx; \
13105b261ecSmrg	    	    	    left_e -= left_dy; \
13205b261ecSmrg    	    	    	}
13305b261ecSmrg
13405b261ecSmrg#define MIPOLYSTEPRIGHT right_x += right_stepx; \
13505b261ecSmrg    	    	    	right_e += right_dx; \
13605b261ecSmrg    	    	    	if (right_e > 0) \
13705b261ecSmrg    	    	    	{ \
13805b261ecSmrg	    	    	    right_x += right_signdx; \
13905b261ecSmrg	    	    	    right_e -= right_dy; \
14005b261ecSmrg    	    	    	}
14105b261ecSmrg
14205b261ecSmrg#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
14305b261ecSmrg    oldPixel = pGC->fgPixel; \
14405b261ecSmrg    if (pixel != oldPixel) { \
14505b261ecSmrg	DoChangeGC (pGC, GCForeground, (XID *) &pixel, FALSE); \
14605b261ecSmrg	ValidateGC (pDrawable, pGC); \
14705b261ecSmrg    } \
14805b261ecSmrg}
14905b261ecSmrg#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
15005b261ecSmrg    if (pixel != oldPixel) { \
15105b261ecSmrg	DoChangeGC (pGC, GCForeground, (XID *) &oldPixel, FALSE); \
15205b261ecSmrg	ValidateGC (pDrawable, pGC); \
15305b261ecSmrg    } \
15405b261ecSmrg}
15505b261ecSmrg
15605b261ecSmrgextern void miRoundJoinClip(
15705b261ecSmrg    LineFacePtr /*pLeft*/,
15805b261ecSmrg    LineFacePtr /*pRight*/,
15905b261ecSmrg    PolyEdgePtr /*edge1*/,
16005b261ecSmrg    PolyEdgePtr /*edge2*/,
16105b261ecSmrg    int * /*y1*/,
16205b261ecSmrg    int * /*y2*/,
16305b261ecSmrg    Bool * /*left1*/,
16405b261ecSmrg    Bool * /*left2*/
16505b261ecSmrg);
16605b261ecSmrg
16705b261ecSmrgextern int miRoundCapClip(
16805b261ecSmrg    LineFacePtr /*face*/,
16905b261ecSmrg    Bool /*isInt*/,
17005b261ecSmrg    PolyEdgePtr /*edge*/,
17105b261ecSmrg    Bool * /*leftEdge*/
17205b261ecSmrg);
17305b261ecSmrg
17405b261ecSmrgextern int miPolyBuildEdge(double x0, double y0, double k, int dx, int dy,
17505b261ecSmrg				int xi, int yi, int left, PolyEdgePtr edge);
17605b261ecSmrgextern int miPolyBuildPoly(PolyVertexPtr vertices, PolySlopePtr slopes,
17705b261ecSmrg				int count, int xi, int yi, PolyEdgePtr left,
17805b261ecSmrg				PolyEdgePtr right, int *pnleft, int *pnright,
17905b261ecSmrg				int *h);
18005b261ecSmrg
181