diff options
Diffstat (limited to 'contrib/groff/src/xditview/draw.c')
-rw-r--r-- | contrib/groff/src/xditview/draw.c | 725 |
1 files changed, 0 insertions, 725 deletions
diff --git a/contrib/groff/src/xditview/draw.c b/contrib/groff/src/xditview/draw.c deleted file mode 100644 index fe7c80f..0000000 --- a/contrib/groff/src/xditview/draw.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * 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" - -#define DeviceToX(dw, n) ((int)((n) * (dw)->dvi.scale_factor + .5)) -#define XPos(dw) (DeviceToX((dw), (dw)->dvi.state->x - \ - (dw)->dvi.text_device_width) + (dw)->dvi.text_x_width) -#define YPos(dw) (DeviceToX((dw), (dw)->dvi.state->y)) - -static int FakeCharacter(); - -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; -} - -AdjustCacheDeltas (dw) - DviWidget dw; -{ - int extra; - int nadj; - int i; - - nadj = 0; - extra = DeviceToX(dw, dw->dvi.text_device_width) - - dw->dvi.text_x_width; - if (extra == 0) - return; - for (i = 0; i <= dw->dvi.cache.index; i++) - if (dw->dvi.cache.adjustable[i]) - ++nadj; - dw->dvi.text_x_width += extra; - if (nadj <= 1) - return; - for (i = 0; i <= dw->dvi.cache.index; i++) - if (dw->dvi.cache.adjustable[i]) { - int x; - int *deltap; - - x = extra/nadj; - deltap = &dw->dvi.cache.cache[i].delta; -#define MIN_DELTA 2 - if (*deltap > 0 && x + *deltap < MIN_DELTA) { - x = MIN_DELTA - *deltap; - if (x <= 0) - *deltap = MIN_DELTA; - else - x = 0; - } - else - *deltap += x; - extra -= x; - --nadj; - dw->dvi.cache.adjustable[i] = 0; - } -} - -FlushCharCache (dw) - DviWidget dw; -{ - if (dw->dvi.cache.char_index != 0) { - AdjustCacheDeltas (dw); - 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 0 - if (dw->dvi.noPolyText) - dw->dvi.cache.max = 1; -#endif - dw->dvi.cache.char_index = 0; - dw->dvi.cache.cache[0].nchars = 0; - dw->dvi.cache.start_x = dw->dvi.cache.x = XPos (dw); - dw->dvi.cache.start_y = dw->dvi.cache.y = YPos (dw); -} - -Newline (dw) - DviWidget dw; -{ - FlushCharCache (dw); - dw->dvi.text_x_width = dw->dvi.text_device_width = 0; - dw->dvi.word_flag = 0; -} - -Word (dw) - DviWidget dw; -{ - dw->dvi.word_flag = 1; -} - -#define charWidth(fi,c) (\ - (fi)->per_char ?\ - (fi)->per_char[(c) - (fi)->min_char_or_byte2].width\ - :\ - (fi)->max_bounds.width\ -) - - -static -int charExists (fi, c) - XFontStruct *fi; - int c; -{ - XCharStruct *p; - - if (fi->per_char == NULL || - c < fi->min_char_or_byte2 || c > fi->max_char_or_byte2) - return 0; - p = fi->per_char + (c - fi->min_char_or_byte2); - return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0 - || p->ascent != 0 || p->descent != 0 || p->attributes != 0); -} - -static -DoCharacter (dw, c, wid) - DviWidget dw; - int c; - int wid; /* width in device units */ -{ - register XFontStruct *font; - register XTextItem *text; - int x, y; - - x = XPos(dw); - y = YPos(dw); - - /* - * quick and dirty extents calculation: - */ - if (!(y + 24 >= dw->dvi.extents.y1 - && y - 24 <= dw->dvi.extents.y2 -#if 0 - && x + 24 >= dw->dvi.extents.x1 - && x - 24 <= dw->dvi.extents.x2 -#endif - )) - return; - - if (y != dw->dvi.cache.y - || dw->dvi.cache.char_index >= DVI_CHAR_CACHE_SIZE) { - FlushCharCache (dw); - x = dw->dvi.cache.x; - dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; - } - /* - * load a new font, if the current block is not empty, - * step to the next. - */ - if (dw->dvi.cache.font_size != dw->dvi.state->font_size || - dw->dvi.cache.font_number != dw->dvi.state->font_number) - { - FlushCharCache (dw); - x = dw->dvi.cache.x; - dw->dvi.cache.font_size = dw->dvi.state->font_size; - dw->dvi.cache.font_number = dw->dvi.state->font_number; - dw->dvi.cache.font = QueryFont (dw, - dw->dvi.cache.font_number, - dw->dvi.cache.font_size); - if (dw->dvi.cache.cache[dw->dvi.cache.index].nchars != 0) { - ++dw->dvi.cache.index; - if (dw->dvi.cache.index >= dw->dvi.cache.max) - FlushCharCache (dw); - dw->dvi.cache.cache[dw->dvi.cache.index].nchars = 0; - dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; - } - } - if (x != dw->dvi.cache.x || dw->dvi.word_flag) { - if (dw->dvi.cache.cache[dw->dvi.cache.index].nchars != 0) { - ++dw->dvi.cache.index; - if (dw->dvi.cache.index >= dw->dvi.cache.max) - FlushCharCache (dw); - dw->dvi.cache.cache[dw->dvi.cache.index].nchars = 0; - dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; - } - dw->dvi.cache.adjustable[dw->dvi.cache.index] - = dw->dvi.word_flag; - dw->dvi.word_flag = 0; - } - font = dw->dvi.cache.font; - text = &dw->dvi.cache.cache[dw->dvi.cache.index]; - if (text->nchars == 0) { - text->chars = &dw->dvi.cache.char_cache[dw->dvi.cache.char_index]; - text->delta = x - dw->dvi.cache.x; - if (font != dw->dvi.font) { - text->font = font->fid; - dw->dvi.font = font; - } else - text->font = None; - dw->dvi.cache.x += text->delta; - } - if (charExists(font, c)) { - int w; - dw->dvi.cache.char_cache[dw->dvi.cache.char_index++] = (char) c; - ++text->nchars; - w = charWidth(font, c); - dw->dvi.cache.x += w; - if (wid != 0) { - dw->dvi.text_x_width += w; - dw->dvi.text_device_width += wid; - } - } -} - -static -int FindCharWidth (dw, buf, widp) - DviWidget dw; - char *buf; - int *widp; -{ - int maxpos; - int i; - - if (dw->dvi.device_font == 0 - || dw->dvi.state->font_number != dw->dvi.device_font_number) { - dw->dvi.device_font_number = dw->dvi.state->font_number; - dw->dvi.device_font - = QueryDeviceFont (dw, dw->dvi.device_font_number); - } - if (dw->dvi.device_font - && device_char_width (dw->dvi.device_font, - dw->dvi.state->font_size, buf, widp)) - return 1; - - maxpos = MaxFontPosition (dw); - for (i = 1; i <= maxpos; i++) { - DeviceFont *f = QueryDeviceFont (dw, i); - if (f && device_font_special (f) - && device_char_width (f, dw->dvi.state->font_size, - buf, widp)) { - dw->dvi.state->font_number = i; - return 1; - } - } - return 0; -} - -/* Return the width of the character in device units. */ - -int PutCharacter (dw, buf) - DviWidget dw; - char *buf; -{ - int prevFont; - int c = -1; - int wid = 0; - DviCharNameMap *map; - - if (!dw->dvi.display_enable) - return 0; /* The width doesn't matter in this case. */ - prevFont = dw->dvi.state->font_number; - if (!FindCharWidth (dw, buf, &wid)) - return 0; - map = QueryFontMap (dw, dw->dvi.state->font_number); - if (map) - c = DviCharIndex (map, buf); - if (c >= 0) - DoCharacter (dw, c, wid); - else - (void) FakeCharacter (dw, buf, wid); - dw->dvi.state->font_number = prevFont; - return wid; -} - -/* Return 1 if we can fake it; 0 otherwise. */ - -static -int FakeCharacter (dw, buf, wid) - DviWidget dw; - char *buf; - int wid; -{ - int oldx, oldw; - char ch[2]; - char *chars = 0; - - if (buf[0] == '\0' || buf[1] == '\0' || buf[2] != '\0') - return 0; -#define pack2(c1, c2) (((c1) << 8) | (c2)) - - switch (pack2(buf[0], buf[1])) { - case pack2('f', 'i'): - chars = "fi"; - break; - case pack2('f', 'l'): - chars = "fl"; - break; - case pack2('f', 'f'): - chars = "ff"; - break; - case pack2('F', 'i'): - chars = "ffi"; - break; - case pack2('F', 'l'): - chars = "ffl"; - break; - } - if (!chars) - return 0; - oldx = dw->dvi.state->x; - oldw = dw->dvi.text_device_width; - ch[1] = '\0'; - for (; *chars; chars++) { - ch[0] = *chars; - dw->dvi.state->x += PutCharacter (dw, ch); - } - dw->dvi.state->x = oldx; - dw->dvi.text_device_width = oldw + wid; - return 1; -} - -PutNumberedCharacter (dw, c) - DviWidget dw; - int c; -{ - char *name; - int wid; - DviCharNameMap *map; - - if (!dw->dvi.display_enable) - return; - - if (dw->dvi.device_font == 0 - || dw->dvi.state->font_number != dw->dvi.device_font_number) { - dw->dvi.device_font_number = dw->dvi.state->font_number; - dw->dvi.device_font - = QueryDeviceFont (dw, dw->dvi.device_font_number); - } - - if (dw->dvi.device_font == 0 - || !device_code_width (dw->dvi.device_font, - dw->dvi.state->font_size, c, &wid)) - return; - if (dw->dvi.native) { - DoCharacter (dw, c, wid); - return; - } - map = QueryFontMap (dw, dw->dvi.state->font_number); - if (!map) - return; - for (name = device_name_for_code (dw->dvi.device_font, c); - name; - name = device_name_for_code ((DeviceFont *)0, c)) { - int code = DviCharIndex (map, name); - if (code >= 0) { - DoCharacter (dw, code, wid); - break; - } - if (FakeCharacter (dw, name, wid)) - break; - } -} - -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 = (int)(((double)dw->dvi.device_resolution - * dw->dvi.state->font_size) - / (10.0*72.0*dw->dvi.sizescale)); - else - desired_line_width = dw->dvi.line_thickness; - - if (desired_line_width != dw->dvi.line_width) { - XGCValues values; - values.line_width = DeviceToX(dw, desired_line_width); - if (values.line_width == 0) - values.line_width = 1; - XChangeGC(XtDisplay (dw), dw->dvi.normal_GC, - GCLineWidth, &values); - dw->dvi.line_width = desired_line_width; - } -} - -static -setFillGC (dw) - DviWidget dw; -{ - int fill_type; - unsigned long mask = GCFillStyle | GCForeground; - - fill_type = (dw->dvi.fill * 10) / (DVI_FILL_MAX + 1); - if (dw->dvi.fill_type != fill_type) { - XGCValues values; - if (fill_type <= 0) { - values.foreground = dw->dvi.background; - values.fill_style = FillSolid; - } else if (fill_type >= 9) { - values.foreground = dw->dvi.foreground; - values.fill_style = FillSolid; - } else { - values.foreground = dw->dvi.foreground; - values.fill_style = FillOpaqueStippled; - values.stipple = dw->dvi.gray[fill_type - 1]; - mask |= GCStipple; - } - XChangeGC(XtDisplay (dw), dw->dvi.fill_GC, mask, &values); - dw->dvi.fill_type = fill_type; - } -} - -DrawLine (dw, x, y) - DviWidget dw; - int x, y; -{ - int xp, yp; - - AdjustCacheDeltas (dw); - setGC (dw); - xp = XPos (dw); - yp = YPos (dw); - XDrawLine (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, - xp, yp, - xp + DeviceToX (dw, x), yp + DeviceToX (dw, y)); -} - -DrawCircle (dw, diam) - DviWidget dw; - int diam; -{ - int d; - - AdjustCacheDeltas (dw); - setGC (dw); - d = DeviceToX (dw, diam); - XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, - XPos (dw), YPos (dw) - d/2, - d, d, 0, 64*360); -} - -DrawFilledCircle (dw, diam) - DviWidget dw; - int diam; -{ - int d; - - AdjustCacheDeltas (dw); - setFillGC (dw); - d = DeviceToX (dw, diam); - XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - XPos (dw), YPos (dw) - d/2, - d, d, 0, 64*360); - XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - XPos (dw), YPos (dw) - d/2, - d, d, 0, 64*360); -} - -DrawEllipse (dw, a, b) - DviWidget dw; - int a, b; -{ - AdjustCacheDeltas (dw); - setGC (dw); - XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, - XPos (dw), YPos (dw) - DeviceToX (dw, b/2), - DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); -} - -DrawFilledEllipse (dw, a, b) - DviWidget dw; - int a, b; -{ - AdjustCacheDeltas (dw); - setFillGC (dw); - XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - XPos (dw), YPos (dw) - DeviceToX (dw, b/2), - DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); - XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - XPos (dw), YPos (dw) - DeviceToX (dw, b/2), - DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); -} - -DrawArc (dw, x0, y0, x1, y1) - DviWidget dw; - int x0, y0, x1, y1; -{ - 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; - - AdjustCacheDeltas (dw); - setGC (dw); - - rad = DeviceToX (dw, rad); - XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, - XPos (dw) + DeviceToX (dw, x0) - rad, - YPos (dw) + DeviceToX (dw, y0) - rad, - rad*2, rad*2, angle1, angle2); -} - -DrawPolygon (dw, v, n) - DviWidget dw; - int *v; - int n; -{ - XPoint *p; - int i; - int dx, dy; - - n /= 2; - - AdjustCacheDeltas (dw); - setGC (dw); - p = (XPoint *)XtMalloc((n + 2)*sizeof(XPoint)); - p[0].x = XPos (dw); - p[0].y = YPos (dw); - dx = 0; - dy = 0; - for (i = 0; i < n; i++) { - dx += v[2*i]; - p[i + 1].x = DeviceToX (dw, dx) + p[0].x; - dy += v[2*i + 1]; - p[i + 1].y = DeviceToX (dw, dy) + p[0].y; - } - p[n+1].x = p[0].x; - p[n+1].y = p[0].y; - XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, - p, n + 2, CoordModeOrigin); - XtFree((char *)p); -} - - -DrawFilledPolygon (dw, v, n) - DviWidget dw; - int *v; - int n; -{ - XPoint *p; - int i; - int dx, dy; - - n /= 2; - if (n < 2) - return; - - AdjustCacheDeltas (dw); - setFillGC (dw); - p = (XPoint *)XtMalloc((n + 2)*sizeof(XPoint)); - p[0].x = p[n+1].x = XPos (dw); - p[0].y = p[n+1].y = YPos (dw); - dx = 0; - dy = 0; - for (i = 0; i < n; i++) { - dx += v[2*i]; - p[i + 1].x = DeviceToX (dw, dx) + p[0].x; - dy += v[2*i + 1]; - p[i + 1].y = DeviceToX (dw, dy) + p[0].y; - } - XFillPolygon (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - p, n + 1, Complex, CoordModeOrigin); - XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, - p, n + 2, CoordModeOrigin); - XtFree((char *)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; - int ox, oy, dx, dy; - int i; - int pointi; - XPoint points[POINTS_MAX]; - - if (n == 0 || (n & 1) != 0) - return; - AdjustCacheDeltas (dw); - setGC (dw); - ox = XPos (dw); - oy = YPos (dw); - dx = v[0]; - dy = v[1]; - sx = ox; - sy = oy; - tx = sx + DeviceToX (dw, dx); - ty = sy + DeviceToX (dw, dy); - - 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 = ox + DeviceToX (dw, dx += v[i]); - int uy = oy + DeviceToX (dw, dy += 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: -*/ |