Bug Summary

File:draw.c
Location:line 440, column 5
Description:Value stored to 'dx' is never read

Annotated Source Code

1/*
2 *
3Copyright (c) 1991 X Consortium
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of the X Consortium shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from the X Consortium.
25 *
26 */
27
28/*
29 * draw.c
30 *
31 * accept dvi function calls and translate to X
32 */
33
34/*
35 Support for ditroff drawing commands added: lines, circles, ellipses,
36 arcs and splines. Splines are approximated as short lines by iterating
37 a simple approximation algorithm. This seems good enough for previewing.
38
39 David Evans <dre@cs.nott.ac.uk>, 14th March, 1990
40*/
41
42#include <X11/Xos.h>
43#include <X11/IntrinsicP.h>
44#include <X11/StringDefs.h>
45#include <stdio.h>
46#include <ctype.h>
47#include <math.h>
48#include "DviP.h"
49#include <stdlib.h>
50
51#ifndef M_PI3.14159265358979323846264338327950288
52#define M_PI3.14159265358979323846264338327950288 3.14159265358979323846264338327950
53#endif
54
55/* the following are for use in the spline approximation algorithm */
56
57typedef struct Point {
58 double x;
59 double y;
60 struct Point *next;
61} Point;
62
63#define ITERATIONS10 10 /* iterations to approximate spline */
64
65#define midx(p,q)((p->x + q->x) / 2) ((p->x + q->x) / 2) /* mid x point on pq */
66#define midy(p,q)((p->y + q->y) / 2) ((p->y + q->y) / 2) /* mid y point on pq */
67
68#define length(p,q)sqrt(((q->x - p->x)*(q->x - p->x)) + ((q->y - p
->y)*(q->y - p->y)))
sqrt(((q->x - p->x)*(q->x - p->x)) \
69 + ((q->y - p->y)*(q->y - p->y))) /* length of pq */
70
71static Point *spline = (Point *)NULL((void*)0); /* head of spline linked list */
72
73static void ApproxSpline(int n);
74static void DeletePoint(Point *p);
75static void DrawSplineSegments(DviWidget dw);
76static int GetSpline(const char *s);
77static void InsertPoint(Point *p, Point *q);
78static void LineApprox(Point *p1, Point *p2, Point *p3);
79static Point * MakePoint(double x, double y);
80
81void
82HorizontalMove(DviWidget dw, int delta)
83{
84 dw->dvi.state->x += delta;
85}
86
87void
88HorizontalGoto(DviWidget dw, int NewPosition)
89{
90 dw->dvi.state->x = NewPosition;
91}
92
93void
94VerticalMove(DviWidget dw, int delta)
95{
96 dw->dvi.state->y += delta;
97}
98
99void
100VerticalGoto(DviWidget dw, int NewPosition)
101{
102 dw->dvi.state->y = NewPosition;
103}
104
105#ifdef USE_XFT
106static void
107DrawText (DviWidget dw)
108{
109 int i;
110 XftFont *font;
111
112 font = dw->dvi.cache.font;
113 for (i = 0; i <= dw->dvi.cache.index; i++)
114 {
115 if (dw->dvi.cache.cache[i].font)
116 font = dw->dvi.cache.cache[i].font;
117 XftDrawString8 (dw->dvi.draw, &dw->dvi.black,
118 font,
119 dw->dvi.cache.cache[i].x,
120 dw->dvi.cache.start_y,
121 (unsigned char *) dw->dvi.cache.cache[i].chars,
122 dw->dvi.cache.cache[i].nchars);
123 }
124}
125#endif
126
127void
128FlushCharCache (DviWidget dw)
129{
130 int xx, yx;
131
132 xx = ToX(dw, dw->dvi.state->x)((int) ((dw->dvi.state->x) * (dw)->dvi.scale + 0.5));
133 yx = ToX(dw, dw->dvi.state->y)((int) ((dw->dvi.state->y) * (dw)->dvi.scale + 0.5));
134 if (dw->dvi.cache.char_index != 0)
135 {
136#ifdef USE_XFT
137 DrawText (dw);
138#else
139 XDrawText (XtDisplay (dw)(((dw)->core.screen)->display), XtWindow (dw)((dw)->core.window), dw->dvi.normal_GC,
140 dw->dvi.cache.start_x, dw->dvi.cache.start_y,
141 dw->dvi.cache.cache, dw->dvi.cache.index + 1);
142#endif
143 }
144 dw->dvi.cache.index = 0;
145 dw->dvi.cache.max = DVI_TEXT_CACHE_SIZE256;
146 if (dw->dvi.noPolyText)
147 dw->dvi.cache.max = 1;
148 dw->dvi.cache.char_index = 0;
149 dw->dvi.cache.cache[0].nchars = 0;
150 dw->dvi.cache.start_x = dw->dvi.cache.x = xx;
151 dw->dvi.cache.start_y = dw->dvi.cache.y = yx;
152}
153
154void
155SetGCForDraw (DviWidget dw)
156{
157 int lw;
158 if (dw->dvi.state->line_style != dw->dvi.line_style ||
159 dw->dvi.state->line_width != dw->dvi.line_width)
160 {
161 lw = ToX(dw, dw->dvi.state->line_width)((int) ((dw->dvi.state->line_width) * (dw)->dvi.scale
+ 0.5))
;
162 if (lw <= 1)
163 lw = 0;
164 XSetLineAttributes (XtDisplay (dw)(((dw)->core.screen)->display), dw->dvi.normal_GC,
165 lw, LineSolid0, CapButt1, JoinMiter0);
166 dw->dvi.line_style = dw->dvi.state->line_style;
167 dw->dvi.line_width = dw->dvi.state->line_width;
168 }
169}
170
171void
172DrawLine (DviWidget dw, int x, int y)
173{
174 if (dw->dvi.display_enable)
175 XDrawLine (XtDisplay (dw)(((dw)->core.screen)->display), XtWindow (dw)((dw)->core.window), dw->dvi.normal_GC,
176 ToX(dw, dw->dvi.state->x)((int) ((dw->dvi.state->x) * (dw)->dvi.scale + 0.5)), ToX(dw, dw->dvi.state->y)((int) ((dw->dvi.state->y) * (dw)->dvi.scale + 0.5)),
177 ToX(dw, dw->dvi.state->x + x)((int) ((dw->dvi.state->x + x) * (dw)->dvi.scale + 0.5
))
, ToX(dw,dw->dvi.state->y + y)((int) ((dw->dvi.state->y + y) * (dw)->dvi.scale + 0.5
))
);
178 dw->dvi.state->x += x;
179 dw->dvi.state->y += y;
180}
181
182void
183DrawCircle (DviWidget dw, int diameter)
184{
185 if (dw->dvi.display_enable)
186 XDrawArc (XtDisplay (dw)(((dw)->core.screen)->display), XtWindow (dw)((dw)->core.window), dw->dvi.normal_GC,
187 ToX(dw, dw->dvi.state->x)((int) ((dw->dvi.state->x) * (dw)->dvi.scale + 0.5)),
188 ToX(dw, dw->dvi.state->y - (diameter / 2))((int) ((dw->dvi.state->y - (diameter / 2)) * (dw)->
dvi.scale + 0.5))
,
189 ToX(dw, diameter)((int) ((diameter) * (dw)->dvi.scale + 0.5)), ToX(dw, diameter)((int) ((diameter) * (dw)->dvi.scale + 0.5)), 0, 360 * 64);
190 dw->dvi.state->x += diameter;
191}
192
193void
194DrawEllipse (DviWidget dw, int a, int b)
195{
196 if (dw->dvi.display_enable)
197 XDrawArc (XtDisplay (dw)(((dw)->core.screen)->display), XtWindow (dw)((dw)->core.window), dw->dvi.normal_GC,
198 ToX(dw, dw->dvi.state->x)((int) ((dw->dvi.state->x) * (dw)->dvi.scale + 0.5)), ToX(dw, dw->dvi.state->y - (b / 2))((int) ((dw->dvi.state->y - (b / 2)) * (dw)->dvi.scale
+ 0.5))
,
199 ToX(dw,a)((int) ((a) * (dw)->dvi.scale + 0.5)), ToX(dw,b)((int) ((b) * (dw)->dvi.scale + 0.5)), 0, 360 * 64);
200 dw->dvi.state->x += a;
201}
202
203
204/* Convert angle in degrees to 64ths of a degree */
205
206static int
207ConvertAngle(int theta)
208{
209 return(theta * 64);
210}
211
212void
213DrawArc (DviWidget dw, int x0, int y0, int x1, int y1)
214{
215 int xc, yc, x2, y2, r;
216 int angle1, angle2;
217
218 /* centre */
219 xc = dw->dvi.state->x + x0;
220 yc = dw->dvi.state->y + y0;
221
222 /* to */
223 x2 = xc + x1;
224 y2 = yc + y1;
225
226 dw->dvi.state->x = x2;
227 dw->dvi.state->y = y2;
228
229 if (dw->dvi.display_enable) {
230
231 /* radius */
232 r = (int)sqrt((float) x1 * x1 + (float) y1 * y1);
233
234 /* start and finish angles */
235 if (x0 == 0) {
236 if (y0 >= 0)
237 angle1 = 90;
238 else
239 angle1 = 270;
240 }
241 else {
242 angle1 = (int) (atan((double)(y0) / (double)(x0)) * 180 / M_PI3.14159265358979323846264338327950288);
243 if (x0 > 0)
244 angle1 = 180 - angle1;
245 else
246 angle1 = -angle1;
247 }
248
249 if (x1 == 0) {
250 if (y1 <= 0)
251 angle2 = 90;
252 else
253 angle2 = 270;
254 }
255 else {
256 angle2 = (int) (atan((double)(y1) / (double)(x1)) * 180 / M_PI3.14159265358979323846264338327950288);
257 if (x1 < 0)
258 angle2 = 180 - angle2;
259 else
260 angle2 = -angle2;
261 }
262
263 if (angle1 < 0)
264 angle1 += 360;
265 if (angle2 < 0)
266 angle2 += 360;
267
268 if (angle2 < angle1)
269 angle1 -= 360;
270 angle2 = angle2 - angle1;
271
272 angle1 = ConvertAngle(angle1);
273 angle2 = ConvertAngle(angle2);
274
275 XDrawArc (XtDisplay (dw)(((dw)->core.screen)->display), XtWindow (dw)((dw)->core.window), dw->dvi.normal_GC,
276 ToX(dw, xc - r)((int) ((xc - r) * (dw)->dvi.scale + 0.5)), ToX(dw, yc - r)((int) ((yc - r) * (dw)->dvi.scale + 0.5)),
277 ToX(dw, 2 * r)((int) ((2 * r) * (dw)->dvi.scale + 0.5)), ToX(dw, 2 * r)((int) ((2 * r) * (dw)->dvi.scale + 0.5)),
278 angle1, angle2);
279 }
280}
281
282/* copy next non-blank string from p to temp, update p */
283
284static const char *
285getstr(const char *p, char *temp)
286{
287 while (*p == ' ' || *p == '\t' || *p == '\n')
288 p++;
289 if (*p == '\0') {
290 temp[0] = 0;
291 return((char *)NULL((void*)0));
292 }
293 while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
294 *temp++ = *p++;
295 *temp = '\0';
296 return(p);
297}
298
299
300/* Draw a spline by approximating with short lines. */
301
302/*ARGSUSED*/
303void
304DrawSpline (DviWidget dw, const char *s, int len)
305{
306 int n;
307
308 /* get coordinate pairs into spline linked list */
309 if ((n = GetSpline(s)) <= 0)
310 return;
311
312 ApproxSpline(n);
313
314 DrawSplineSegments(dw);
315}
316
317
318/* Parse string s to create a linked list of Point's with spline */
319/* as its head. Return the number of coordinate pairs found. */
320
321static int
322GetSpline(const char *s)
323{
324 double x, y, x1, y1;
325 int n = 0;
326 Point *pt;
327 const char *p = s;
328 char d[10];
329
330 if (!*p)
331 return(n);
332
333 pt = spline = MakePoint(0.0, 0.0);
334 n = 1;
335 x = y = 0.0;
336 p = s;
337 while (p && *p) {
338 if ((p = getstr(p, d)) == (const char *)NULL((void*)0))
339 break;
340 x1 = x + atof(d);
341 if ((p = getstr(p, d)) == (const char *)NULL((void*)0))
342 break;
343 y1 = y + atof(d);
344 pt->next = MakePoint(x1, y1);
345 pt = pt->next;
346 x = pt->x;
347 y = pt->y;
348 n++;
349 }
350
351 /* number of pairs of points */
352
353 return(n);
354}
355
356/* Approximate a spline by lines generated by iterations of the */
357/* approximation algorithm from the original n points in the spline. */
358
359static void
360ApproxSpline(int n)
361{
362 int mid, j;
363 Point *p1, *p2, *p3, *p;
364
365 if (n < 3)
366 return;
367
368 /* number of mid-points to calculate */
369 mid = n - 3;
370
371 /* remember original points are stored as an array of n points */
372 /* so I can index it directly to calculate mid-points only. */
373 if (mid > 0) {
374 p = spline->next;
375 j = 1;
376 while (j < n-2) {
377 p1 = p;
378 p = p->next;
379 p2 = p;
380 InsertPoint(p1, MakePoint(midx(p1, p2)((p1->x + p2->x) / 2), midy(p1, p2)((p1->y + p2->y) / 2)));
381 j++;
382 }
383 }
384
385 /* Now approximate curve by line segments. */
386 /* There *should* be the correct number of points now! */
387
388 p = spline;
389 while (p != (Point *)NULL((void*)0)) {
390 p1 = p;
391 if ((p = p->next) == (Point *)NULL((void*)0))
392 break;
393 p2 = p;
394 if ((p = p->next) == (Point *)NULL((void*)0))
395 break;
396 p3 = p; /* This point becomes first point of next curve */
397
398 LineApprox(p1, p2, p3);
399 }
400}
401
402
403/* p1, p2, and p3 are initially 3 *consecutive* points on the curve. */
404/* For each adjacent pair of points find the mid-point, insert this */
405/* in the linked list, delete the first of the two used (unless it */
406/* is the first for this curve). Repeat this ITERATIONS times. */
407
408/*ARGSUSED*/
409static void
410LineApprox(Point *p1, Point *p2, Point *p3)
411{
412 Point *p4, *p;
413 int reps = ITERATIONS10;
414
415 while (reps) {
416 for (p = p1; p != (Point *)NULL((void*)0) && p != p3; ) {
417 InsertPoint(p, p4 = MakePoint( midx(p,p->next)((p->x + p->next->x) / 2), midy(p,p->next)((p->y + p->next->y) / 2) ));
418 if (p != p1)
419 DeletePoint(p);
420 p = p4->next; /* skip inserted point! */
421 }
422 reps--;
423 }
424}
425
426
427/* Traverse the linked list, calling DrawLine to approximate the */
428/* spline curve. Rounding errors are taken into account so that */
429/* the "curve" is continuous, and ends up where expected. */
430
431static void
432DrawSplineSegments(DviWidget dw)
433{
434 Point *p, *q;
435 double x1, y1;
436 int dx, dy;
437 double xpos, ypos;
438
439 p = spline;
440 dx = dy = 0;
Value stored to 'dx' is never read
441
442 /* save the start position */
443
444 xpos = dw->dvi.state->x;
445 ypos = dw->dvi.state->y;
446
447 x1 = y1 = 0.0;
448
449 while (p != (Point *)NULL((void*)0)) {
450 dx = p->x - x1 + 0.5;
451 dy = p->y - y1 + 0.5;
452 DrawLine (dw, dx, dy);
453
454 x1 = p->x;
455 y1 = p->y;
456 dw->dvi.state->x = xpos + x1;
457 dw->dvi.state->y = ypos + y1;
458
459 q = p;
460 p = p->next;
461 XtFree((char *)q);
462 }
463 spline = (Point *)NULL((void*)0);
464}
465
466
467/* Malloc memory for a Point, and initialise the elements to x, y, NULL */
468/* Return a pointer to the new Point. */
469
470static Point *
471MakePoint(double x, double y)
472{
473 Point *p;
474
475 p = (Point *) XtMalloc (sizeof (Point));
476 p->x = x;
477 p->y = y;
478 p->next = (Point *)NULL((void*)0);
479
480 return(p);
481}
482
483
484/* Insert point q in linked list after point p. */
485
486static void
487InsertPoint(Point *p, Point *q)
488{
489 /* point q to the next point */
490 q->next = p->next;
491
492 /* point p to new inserted one */
493 p->next = q;
494}
495
496/* Delete point p from the linked list. */
497
498static void
499DeletePoint(Point *p)
500{
501 Point *tmp;
502
503 tmp = p->next;
504 p->x = p->next->x;
505 p->y = p->next->y;
506 p->next = p->next->next;
507 XtFree((char *)tmp);
508}