void _L1TXX( short xpos, short ypos, char _WCI86FAR * str, /*========*/ struct xycoord _WCI86FAR * concat, struct xycoord _WCI86FAR * extent ) /* Inquire the extents of the character drawing parallelogram and return the concatenation point. The concatenation point is the same as the drawing point if it cannot be calculated exactly. */ { short hor; /* horizontal alignment */ short vert; /* vertical alignment */ struct xycoord up; /* character up vector */ struct xycoord base; /* character base line vector */ struct xycoord space; /* spacing between characters */ struct xycoord length; /* horizontal side of parallelogram */ struct xycoord height; /* vertical side of parallelogram */ struct xycoord trans; /* translation for parallelogram */ GetVectors( &base, &up ); GetAlignment( &hor, &vert ); CalcSpacing( &base, &up, &space ); CalcSides( &length, &height, &base, &up, &space, str ); CalcTranslation( &trans, &length, &height, &up, hor, vert ); CalcCorners( extent, &length, &height, &trans, xpos, ypos ); if( _TextSettings.txpath == _PATH_RIGHT || _TextSettings.txpath == _PATH_LEFT ) { CalcConcat( concat, &length, &space, xpos, ypos, hor, vert ); } else { CalcConcat( concat, &height, &space, xpos, ypos, hor, vert ); } }
void _L1Text( short xpos, short ypos, char _WCI86FAR * str ) /*===================================================== Draw the character string pointed to by "str" at the position (xpos, ypos) using the current graphics text settings. */ { short hor; /* horizontal alignment */ short vert; /* vertical alignment */ struct xycoord up; /* character up vector */ struct xycoord base; /* character base line vector */ struct xycoord prop; /* adjustment vector for prop. font */ struct xycoord nommove; /* nominal displacement vector */ struct xycoord space; /* spacing between characters */ struct xycoord length; /* horizontal side of parallelogram */ struct xycoord height; /* vertical side of parallelogram */ struct xycoord trans; /* translation for parallelogram */ struct xycoord corner[4]; /* 0 - lower left */ /* 1 - lower right */ /* 2 - upper right */ /* 3 - upper left */ if( *str == '\0' ) { _ErrorStatus = _GRNOOUTPUT; return; } if( _TextSettings.height == 0 || _TextSettings.width == 0 ) { _ErrorStatus = _GRNOOUTPUT; return; } GetVectors( &base, &up ); GetAlignment( &hor, &vert ); CalcSpacing( &base, &up, &space ); CalcSides( &length, &height, &base, &up, &space, str ); CalcTranslation( &trans, &length, &height, &up, hor, vert ); CalcCorners( &corner, &length, &height, &trans, xpos, ypos ); if( _TextSettings.txpath == _PATH_UP ) { /* select proper corner for */ xpos = corner[ 0 ].xcoord; /* text starting position */ ypos = corner[ 0 ].ycoord; } else { xpos = corner[ _TextSettings.txpath ].xcoord; ypos = corner[ _TextSettings.txpath ].ycoord; } if( _TextSettings.txpath == _PATH_RIGHT || _TextSettings.txpath == _PATH_LEFT ) { while( *str != '\0' ) { CalcNominal( &base, &up, &prop, &nommove, &space, *str ); if( _TextSettings.txpath == _PATH_RIGHT ) { _HershDraw( *str, up.xcoord, -up.ycoord, prop.xcoord, -prop.ycoord, xpos, ypos ); } else { _HershDraw( *str, up.xcoord, -up.ycoord, prop.xcoord, -prop.ycoord, xpos-prop.xcoord, ypos+prop.ycoord ); } xpos += nommove.xcoord; ypos -= nommove.ycoord; str++; } } else { /* path is Up or DOWN */ if( _TextSettings.txpath == _PATH_DOWN ) { xpos -= up.xcoord; /* special increment*/ ypos += up.ycoord; /* for path down */ } while( *str != '\0' ) { CalcNominal( &base, &up, &prop, &nommove, &space, *str ); _HershDraw( *str, up.xcoord, -up.ycoord, prop.xcoord, -prop.ycoord, xpos + ( length.xcoord-prop.xcoord ) / 2, ypos - ( length.ycoord-prop.ycoord ) / 2 ); xpos += nommove.xcoord; ypos -= nommove.ycoord; str++; } } _RefreshWindow(); }
/* ================== SplitFace ================== */ void SplitFace(face_t *in, plane_t *split, face_t **front, face_t **back) { vec_t dists[MAXEDGES + 1]; int sides[MAXEDGES + 1]; int counts[3]; vec_t dot; int i, j; face_t *newf, *new2; vec_t *p1, *p2; vec3_t mid; if (in->w.numpoints < 0) Message(msgError, errFreedFace); /* Fast test */ dot = DotProduct(in->origin, split->normal) - split->dist; if (dot > in->radius) { counts[SIDE_FRONT] = 1; counts[SIDE_BACK] = 0; } else if (dot < -in->radius) { counts[SIDE_FRONT] = 0; counts[SIDE_BACK] = 1; } else { CalcSides(&in->w, split, sides, dists, counts); } // Plane doesn't split this face after all if (!counts[SIDE_FRONT]) { *front = NULL; *back = in; return; } if (!counts[SIDE_BACK]) { *front = in; *back = NULL; return; } *back = newf = NewFaceFromFace(in); *front = new2 = NewFaceFromFace(in); // distribute the points and generate splits for (i = 0; i < in->w.numpoints; i++) { // Note: Possible for numpoints on newf or new2 to exceed MAXEDGES if // in->w.numpoints == MAXEDGES and it is a really devious split. p1 = in->w.points[i]; if (sides[i] == SIDE_ON) { VectorCopy(p1, newf->w.points[newf->w.numpoints]); newf->w.numpoints++; VectorCopy(p1, new2->w.points[new2->w.numpoints]); new2->w.numpoints++; continue; } if (sides[i] == SIDE_FRONT) { VectorCopy(p1, new2->w.points[new2->w.numpoints]); new2->w.numpoints++; } else { VectorCopy(p1, newf->w.points[newf->w.numpoints]); newf->w.numpoints++; } if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i]) continue; // generate a split point p2 = in->w.points[(i + 1) % in->w.numpoints]; dot = dists[i] / (dists[i] - dists[i + 1]); for (j = 0; j < 3; j++) { // avoid round off error when possible if (split->normal[j] == 1) mid[j] = split->dist; else if (split->normal[j] == -1) mid[j] = -split->dist; else mid[j] = p1[j] + dot * (p2[j] - p1[j]); } VectorCopy(mid, newf->w.points[newf->w.numpoints]); newf->w.numpoints++; VectorCopy(mid, new2->w.points[new2->w.numpoints]); new2->w.numpoints++; } if (newf->w.numpoints > MAXEDGES || new2->w.numpoints > MAXEDGES) Message(msgError, errLowSplitPointCount); // free the original face now that it is represented by the fragments FreeMem(in, FACE, 1); }