home *** CD-ROM | disk | FTP | other *** search
- /*
- * draw.c
- *
- * accept dvi function calls and translate to X
- */
-
- #include <X11/Xos.h>
- #include <X11/IntrinsicP.h>
- #include <X11/StringDefs.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
-
- /* math.h on a Sequent doesn't define M_PI, apparently */
- #ifndef M_PI
- #define M_PI 3.14159265358979323846
- #endif
-
- #include "DviP.h"
-
- HorizontalMove(dw, delta)
- DviWidget dw;
- int delta;
- {
- dw->dvi.state->x += delta;
- }
-
- HorizontalGoto(dw, NewPosition)
- DviWidget dw;
- int NewPosition;
- {
- dw->dvi.state->x = NewPosition;
- }
-
- VerticalMove(dw, delta)
- DviWidget dw;
- int delta;
- {
- dw->dvi.state->y += delta;
- }
-
- VerticalGoto(dw, NewPosition)
- DviWidget dw;
- int NewPosition;
- {
- dw->dvi.state->y = NewPosition;
- }
-
- FlushCharCache (dw)
- DviWidget dw;
- {
- if (dw->dvi.cache.char_index != 0)
- XDrawText (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- dw->dvi.cache.start_x, dw->dvi.cache.start_y,
- dw->dvi.cache.cache, dw->dvi.cache.index + 1);
- dw->dvi.cache.index = 0;
- dw->dvi.cache.max = DVI_TEXT_CACHE_SIZE;
- if (dw->dvi.noPolyText)
- dw->dvi.cache.max = 1;
- dw->dvi.cache.char_index = 0;
- dw->dvi.cache.cache[0].nchars = 0;
- dw->dvi.cache.start_x = dw->dvi.cache.x = dw->dvi.state->x;
- dw->dvi.cache.start_y = dw->dvi.cache.y = dw->dvi.state->y;
- }
-
- ClearPage (dw)
- DviWidget dw;
- {
- XClearWindow (XtDisplay (dw), XtWindow (dw));
- }
-
- static
- setGC (dw)
- DviWidget dw;
- {
- int desired_line_width;
-
- if (dw->dvi.line_thickness < 0) {
- desired_line_width = (((dw->dvi.device_resolution
- * dw->dvi.state->font_size) + 5*72)
- / (10*72));
- if (desired_line_width == 0)
- desired_line_width = 1;
- }
- else
- desired_line_width = dw->dvi.line_thickness;
-
- if (desired_line_width != dw->dvi.line_width) {
- XGCValues values;
- values.line_width = desired_line_width;
- XChangeGC(XtDisplay (dw), dw->dvi.normal_GC,
- GCLineWidth, &values);
- dw->dvi.line_width = desired_line_width;
- }
- }
-
- static
- setFillGC (dw)
- DviWidget dw;
- {
- int fill_type;
-
- if (dw->dvi.fill == DVI_FILL_MAX)
- fill_type = DVI_FILL_BLACK;
- else if (dw->dvi.fill == 0)
- fill_type = DVI_FILL_WHITE;
- else
- fill_type = DVI_FILL_GRAY;
- if (dw->dvi.fill_type != fill_type) {
- XGCValues values;
- switch (fill_type) {
- case DVI_FILL_WHITE:
- values.foreground = dw->dvi.background;
- values.fill_style = FillSolid;
- break;
- case DVI_FILL_BLACK:
- values.foreground = dw->dvi.foreground;
- values.fill_style = FillSolid;
- break;
- case DVI_FILL_GRAY:
- values.foreground = dw->dvi.foreground;
- values.fill_style = FillOpaqueStippled;
- break;
- }
- XChangeGC(XtDisplay (dw), dw->dvi.fill_GC,
- GCFillStyle|GCForeground,
- &values);
- dw->dvi.fill_type = fill_type;
- }
- }
-
- DrawLine (dw, x, y)
- DviWidget dw;
- int x, y;
- {
- setGC (dw);
- XDrawLine (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- dw->dvi.state->x, dw->dvi.state->y,
- dw->dvi.state->x + x, dw->dvi.state->y + y);
- }
-
- DrawCircle (dw, diam)
- DviWidget dw;
- int diam;
- {
- setGC (dw);
- XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- dw->dvi.state->x, dw->dvi.state->y - diam/2,
- diam, diam, 0, 64*360);
- }
-
- DrawFilledCircle (dw, diam)
- DviWidget dw;
- int diam;
- {
- setFillGC (dw);
- XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC,
- dw->dvi.state->x, dw->dvi.state->y - diam/2,
- diam, diam, 0, 64*360);
- }
-
- DrawEllipse (dw, a, b)
- DviWidget dw;
- int a, b;
- {
- setGC (dw);
- XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- dw->dvi.state->x, dw->dvi.state->y - b/2,
- a, b, 0, 64*360);
- }
-
- DrawFilledEllipse (dw, a, b)
- DviWidget dw;
- int a, b;
- {
- setFillGC (dw);
- XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC,
- dw->dvi.state->x, dw->dvi.state->y - b/2,
- a, b, 0, 64*360);
- }
-
- DrawArc (dw, x0, y0, x1, y1)
- DviWidget dw;
- int x0, y0, x1, y1;
- {
- int x, y;
- int angle1, angle2;
- int rad = (int)((sqrt ((double)x0*x0 + (double)y0*y0)
- + sqrt ((double)x1*x1 + (double)y1*y1) + 1.0)/2.0);
- if ((x0 == 0 && y0 == 0) || (x1 == 0 && y1 == 0))
- return;
- angle1 = (int)(atan2 ((double)y0, (double)-x0)*180.0*64.0/M_PI);
- angle2 = (int)(atan2 ((double)-y1, (double)x1)*180.0*64.0/M_PI);
-
- angle2 -= angle1;
- if (angle2 < 0)
- angle2 += 64*360;
-
- setGC (dw);
- XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- dw->dvi.state->x + x0 - rad, dw->dvi.state->y + y0 - rad,
- rad*2, rad*2, angle1, angle2);
- }
-
- DrawPolygon (dw, v, n)
- DviWidget dw;
- int *v;
- int n;
- {
- extern char *malloc();
- XPoint *p;
- int i;
-
- n /= 2;
-
- setGC (dw);
- p = (XPoint *)malloc((n + 2)*sizeof(XPoint));
- if (p == NULL)
- return;
- p[0].x = dw->dvi.state->x;
- p[0].y = dw->dvi.state->y;
- for (i = 0; i < n; i++) {
- p[i + 1].x = v[2*i] + p[i].x;
- p[i + 1].y = v[2*i + 1] + p[i].y;
- }
- p[n+1].x = dw->dvi.state->x;
- p[n+1].y = dw->dvi.state->y;
- XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- p, n + 2, CoordModeOrigin);
- free(p);
- }
-
-
- DrawFilledPolygon (dw, v, n)
- DviWidget dw;
- int *v;
- int n;
- {
- extern char *malloc();
- XPoint *p;
- int i;
-
- n /= 2;
- if (n < 2)
- return;
-
- setFillGC (dw);
- p = (XPoint *)malloc((n + 1)*sizeof(XPoint));
- if (p == NULL)
- return;
- p[0].x = dw->dvi.state->x;
- p[0].y = dw->dvi.state->y;
- for (i = 0; i < n; i++) {
- p[i + 1].x = v[2*i];
- p[i + 1].y = v[2*i + 1];
- }
- XFillPolygon (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC,
- p, n + 1, Complex, CoordModePrevious);
- free(p);
- }
-
- #define POINTS_MAX 10000
-
- static
- appendPoint(points, pointi, x, y)
- XPoint *points;
- int *pointi;
- int x, y;
- {
- if (*pointi < POINTS_MAX) {
- points[*pointi].x = x;
- points[*pointi].y = y;
- *pointi += 1;
- }
- }
-
- #define FLATNESS 1
-
- static
- flattenCurve(points, pointi, x2, y2, x3, y3, x4, y4)
- XPoint *points;
- int *pointi;
- int x2, y2, x3, y3, x4, y4;
- {
- int x1, y1, dx, dy, n1, n2, n;
-
- x1 = points[*pointi - 1].x;
- y1 = points[*pointi - 1].y;
-
- dx = x4 - x1;
- dy = y4 - y1;
-
- n1 = dy*(x2 - x1) - dx*(y2 - y1);
- n2 = dy*(x3 - x1) - dx*(y3 - y1);
- if (n1 < 0)
- n1 = -n1;
- if (n2 < 0)
- n2 = -n2;
- n = n1 > n2 ? n1 : n2;
-
- if (n*n / (dy*dy + dx*dx) <= FLATNESS*FLATNESS)
- appendPoint (points, pointi, x4, y4);
- else {
- flattenCurve (points, pointi,
- (x1 + x2)/2, (y1 + y2)/2,
- (x1 + x2*2 + x3)/4, (y1 + y2*2 + y3)/4,
- (x1 +3*x2 + 3*x3 + x4)/8, (y1 +3*y2 + 3*y3 + y4)/8);
- flattenCurve (points, pointi,
- (x2 + x3*2 + x4)/4, (y2 + y3*2 + y4)/4,
- (x3 + x4)/2, (y3 + y4)/2,
- x4, y4);
- }
- }
-
-
- DrawSpline (dw, v, n)
- DviWidget dw;
- int *v;
- int n;
- {
- int sx, sy, tx, ty, ux, uy;
- int i;
- int pointi;
- XPoint points[POINTS_MAX];
-
- if (n == 0 || (n & 1) != 0)
- return;
- setGC (dw);
- sx = dw->dvi.state->x;
- sy = dw->dvi.state->y;
- tx = sx + v[0];
- ty = sy + v[1];
-
- pointi = 0;
-
- appendPoint (points, &pointi, sx, sy);
- appendPoint (points, &pointi, (sx + tx)/2, (sy + ty)/2);
-
- for (i = 2; i < n; i += 2) {
- int ux = tx + v[i];
- int uy = ty + v[i+1];
- flattenCurve (points, &pointi,
- (sx + tx*5)/6, (sy + ty*5)/6,
- (tx*5 + ux)/6, (ty*5 + uy)/6,
- (tx + ux)/2, (ty + uy)/2);
- sx = tx;
- sy = ty;
- tx = ux;
- ty = uy;
- }
-
- appendPoint (points, &pointi, tx, ty);
-
- XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
- points, pointi, CoordModeOrigin);
- }
-
-
- /*
- Local Variables:
- c-indent-level: 8
- c-continued-statement-offset: 8
- c-brace-offset: -8
- c-argdecl-indent: 8
- c-label-offset: -8
- c-tab-always-indent: nil
- End:
- */
-