1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/oval.c,v 1.11 2011/06/09 16:11:42 cvsps Exp $
19 */
20
21 #define _INCLUDE_FROM_OVAL_C_
22
23 #include "tgifdefs.h"
24
25 #include "attr.e"
26 #include "auxtext.e"
27 #include "choice.e"
28 #include "cmd.e"
29 #include "color.e"
30 #include "cursor.e"
31 #include "cutpaste.e"
32 #include "dialog.e"
33 #include "drawing.e"
34 #include "dup.e"
35 #include "file.e"
36 #include "grid.e"
37 #include "mainloop.e"
38 #include "mark.e"
39 #include "msg.e"
40 #include "obj.e"
41 #include "oval.e"
42 #include "pattern.e"
43 #include "poly.e"
44 #include "ps.e"
45 #include "raster.e"
46 #include "rect.e"
47 #include "ruler.e"
48 #include "select.e"
49 #include "setup.e"
50 #include "spline.e"
51 #include "strtbl.e"
52 #include "util.e"
53 #include "xpixmap.e"
54
55 int ovalDrawn=FALSE;
56
57 static
GetPSEllipseStr(xc,yc,a,b,s)58 void GetPSEllipseStr(xc, yc, a, b, s)
59 int xc, yc, a, b;
60 char *s;
61 {
62 if (preDumpSetup) PSUseEllipse();
63 #ifdef INVERT_CTM_BUG
64 if (preDumpSetup) PSUseMinRadius();
65 sprintf(s, "%s %1d %1d %1d %s %1d %s TGEL",
66 gPsCmd[PS_NEWPATH], xc, yc, a, "tgif_min_radius",
67 b, "tgif_min_radius");
68 #else
69 sprintf(s, "%s %1d %1d %1d %1d TGEL",
70 gPsCmd[PS_NEWPATH], xc, yc, a, b);
71 #endif
72 }
73
MyOval(window,gc,bbox)74 void MyOval(window, gc, bbox)
75 Window window;
76 GC gc;
77 struct BBRec bbox;
78 {
79 int ltx, lty, w, h;
80
81 if (bbox.ltx > bbox.rbx) {
82 ltx = bbox.rbx; w = bbox.ltx - ltx;
83 } else {
84 ltx = bbox.ltx; w = bbox.rbx - ltx;
85 }
86 if (bbox.lty > bbox.rby) {
87 lty = bbox.rby; h = bbox.lty - lty;
88 } else {
89 lty = bbox.lty; h = bbox.rby - lty;
90 }
91 XDrawArc(mainDisplay, window, gc, ltx, lty, w, h, 0, (360<<6));
92 }
93
94 static
DumpOvalPath(FP,ObjPtr,Xc,Yc,A,B,Width,Pen,Dash,TransPat)95 void DumpOvalPath(FP, ObjPtr, Xc, Yc, A, B, Width, Pen, Dash, TransPat)
96 FILE *FP;
97 struct ObjRec *ObjPtr;
98 int Xc, Yc, A, B, Width, Pen, Dash, TransPat;
99 {
100 register int i;
101 int w_is_int=TRUE;
102 char *width_spec=ObjPtr->detail.o->width_spec;
103 double dw=GetWidthInDouble(Width, width_spec, &w_is_int);
104 char s[MAXSTRING];
105
106 fprintf(FP, " %s\n", gPsCmd[PS_GSAVE]);
107 if (!colorDump && useGray && Pen > BACKPAT) {
108 GrayCheck(Pen);
109 fprintf(FP, " %s %s\n", GrayStr(Pen), gPsCmd[PS_SETGRAY]);
110 }
111 GetPSEllipseStr(Xc, Yc, A, B, s);
112 fprintf(FP, " %s\n", s);
113
114 if (ObjPtr->ctm != NULL) {
115 fprintf(FP, " %s\n", &(gPsCmd[PS_TGIFSETMATRIX])[1]);
116 }
117 if (w_is_int) {
118 if (Width != 1) {
119 fprintf(FP, " %1d %s\n", Width, gPsCmd[PS_SETLINEWIDTH]);
120 }
121 } else {
122 fprintf(FP, " %.3f %s\n", dw, gPsCmd[PS_SETLINEWIDTH]);
123 }
124 if (Dash != 0) {
125 fprintf(FP, " [");
126 for (i = 0; i < dashListLength[Dash]-1; i++) {
127 fprintf(FP, "%1d ", (int)(dashList[Dash][i]));
128 }
129 fprintf(FP, "%1d] 0 %s\n",
130 (int)(dashList[Dash][dashListLength[Dash]-1]), gPsCmd[PS_SETDASH]);
131 }
132 switch (Pen) {
133 case SOLIDPAT: fprintf(FP, " %s\n", gPsCmd[PS_STROKE]); break;
134 case BACKPAT:
135 if (!TransPat) {
136 fprintf(FP, " 1 %s %s 0 %s\n",
137 gPsCmd[PS_SETGRAY], gPsCmd[PS_STROKE], gPsCmd[PS_SETGRAY]);
138 }
139 break;
140 default:
141 if (colorDump || !useGray) {
142 if (preDumpSetup) PSUseColorPattern();
143 fprintf(FP, " %s\n", gPsCmd[PS_FLATTENPATH]);
144 DumpPatFill(FP, Pen, ObjPtr->bbox, 6, TRUE);
145 } else {
146 fprintf(FP, " %s\n", gPsCmd[PS_STROKE]);
147 }
148 break;
149 }
150 fprintf(FP, " %s\n", gPsCmd[PS_GRESTORE]);
151 }
152
DumpOvalObj(FP,ObjPtr)153 void DumpOvalObj(FP, ObjPtr)
154 FILE *FP;
155 struct ObjRec *ObjPtr;
156 {
157 int ltx, lty, rbx, rby, xc, yc, a, b;
158 int trans_pat, fill, width, pen, dash, color_index;
159 char s[MAXSTRING];
160 struct OvalRec *oval_ptr=ObjPtr->detail.o;
161
162 if (ObjPtr->ctm == NULL) {
163 ltx = ObjPtr->obbox.ltx; lty = ObjPtr->obbox.lty;
164 rbx = ObjPtr->obbox.rbx; rby = ObjPtr->obbox.rby;
165 } else {
166 ltx = ObjPtr->orig_obbox.ltx; lty = ObjPtr->orig_obbox.lty;
167 rbx = ObjPtr->orig_obbox.rbx; rby = ObjPtr->orig_obbox.rby;
168 }
169 a = (rbx - ltx) / 2; xc = ltx + a;
170 b = (rby - lty) / 2; yc = lty + b;
171
172 trans_pat = ObjPtr->trans_pat;
173 fill = oval_ptr->fill;
174 width = oval_ptr->width;
175 pen = oval_ptr->pen;
176 dash = oval_ptr->dash;
177
178 if ((fill == NONEPAT || (trans_pat && fill == BACKPAT)) &&
179 (pen == NONEPAT || (trans_pat && pen == BACKPAT))) {
180 return;
181 }
182 fprintf(FP, "%% OVAL\n");
183 if (ObjPtr->ctm != NULL) {
184 float m[6];
185
186 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
187 m[CTM_SX] = ((float)ObjPtr->ctm->m[CTM_SX])/((float)1000.0);
188 m[CTM_SY] = ((float)ObjPtr->ctm->m[CTM_SY])/((float)1000.0);
189 m[CTM_SIN] = ((float)ObjPtr->ctm->m[CTM_SIN])/((float)1000.0);
190 m[CTM_MSIN] = ((float)ObjPtr->ctm->m[CTM_MSIN])/((float)1000.0);
191 fprintf(FP, " %1d %1d %s\n", ObjPtr->x, ObjPtr->y,
192 gPsCmd[PS_TRANSLATE]);
193 fprintf(FP, " [%.3f %.3f %.3f %.3f %1d %1d] %s\n",
194 m[CTM_SX], m[CTM_SIN], m[CTM_MSIN], m[CTM_SY],
195 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY], gPsCmd[PS_CONCAT]);
196 fprintf(FP, " %1d %s %1d %s %s\n", ObjPtr->x, gPsCmd[PS_NEG],
197 ObjPtr->y, gPsCmd[PS_NEG], gPsCmd[PS_TRANSLATE]);
198 }
199 color_index = ObjPtr->color;
200 DumpRGBColorLine(FP, color_index, 0, TRUE);
201
202 GetPSEllipseStr(xc, yc, a, b, s);
203 switch (fill) {
204 case NONEPAT: break;
205 case SOLIDPAT:
206 /* solid black oval */
207 fprintf(FP, "%s %s\n", s, gPsCmd[PS_FILL]);
208 break;
209 case BACKPAT:
210 /* solid white oval */
211 if (!trans_pat) {
212 fprintf(FP, "%s\n", s);
213 fprintf(FP, "%s 1 %s %s\n",
214 gPsCmd[PS_CLOSEPATH], gPsCmd[PS_SETGRAY], gPsCmd[PS_FILL]);
215 DumpRGBColorLine(FP, color_index, 3, TRUE);
216 }
217 break;
218 default:
219 /* patterned */
220 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
221 if (colorDump || !useGray) {
222 if (preDumpSetup) PSUseColorPattern();
223 if (!trans_pat) {
224 fprintf(FP, " %s\n", s);
225 fprintf(FP, " %s 1 %s %s\n",
226 gPsCmd[PS_CLOSEPATH], gPsCmd[PS_SETGRAY], gPsCmd[PS_FILL]);
227 DumpRGBColorLine(FP, color_index, 3, TRUE);
228 }
229 fprintf(FP, " %s\n", s);
230 fprintf(FP, " %s %s %s\n",
231 gPsCmd[PS_CLOSEPATH], gPsCmd[PS_EOCLIP], gPsCmd[PS_NEWPATH]);
232 DumpPatFill(FP, fill, ObjPtr->bbox, 3, TRUE);
233 } else {
234 GrayCheck(fill);
235 fprintf(FP, " %s %s\n", GrayStr(fill), gPsCmd[PS_SETGRAY]);
236 fprintf(FP, " %s %s\n", s, gPsCmd[PS_FILL]);
237 }
238 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
239 break;
240 }
241 if (pen == NONEPAT) {
242 if (ObjPtr->ctm != NULL) fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
243 fprintf(FP, "\n");
244 return;
245 }
246
247 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
248
249 if ((colorDump || !useGray) && pen > BACKPAT) {
250 if (!trans_pat) {
251 DumpOvalPath(FP, ObjPtr, xc, yc, a, b, width, BACKPAT, 0, trans_pat);
252 DumpRGBColorLine(FP, color_index, 3, TRUE);
253 }
254 }
255 DumpOvalPath(FP, ObjPtr, xc, yc, a, b, width, pen, dash, trans_pat);
256
257 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
258 if (ObjPtr->ctm != NULL) fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
259 fprintf(FP, "\n");
260 }
261
NeedsToCacheOvalObj(ObjPtr)262 int NeedsToCacheOvalObj(ObjPtr)
263 struct ObjRec *ObjPtr;
264 {
265 return (ObjPtr->ctm != NULL);
266 }
267
268 static double ovalXMag1=(double)0.0, ovalYMag1=(double)0.0;
269 static double ovalXMag2=(double)0.0, ovalYMag2=(double)0.0;
270
271 static
MakeCachedOval(ObjPtr)272 void MakeCachedOval(ObjPtr)
273 struct ObjRec *ObjPtr;
274 {
275 register int i;
276 int sn, cntrln, saved_zoomedin, saved_zoomscale, saved_x, saved_y;
277 struct OvalRec *oval_ptr=ObjPtr->detail.o;
278 XPoint *sv=NULL;
279 DoublePoint *tmp_sv=NULL, *pv=NULL, *cntrlv=NULL;
280 struct BBRec obbox;
281 double w, h, cx, cy;
282
283 if (ovalXMag1 == (double)0.0) {
284 ovalXMag1 = (double)cos((double)(28.6*M_PI/180.0));
285 ovalYMag1 = (double)sin((double)(28.6*M_PI/180.0));
286 ovalXMag2 = (double)cos((double)(61.4*M_PI/180.0));
287 ovalYMag2 = (double)sin((double)(61.4*M_PI/180.0));
288 }
289 if (ObjPtr->ctm == NULL) return;
290
291 if (oval_ptr->rotated_vlist != NULL) free(oval_ptr->rotated_vlist);
292 oval_ptr->rotated_n = 0;
293 oval_ptr->rotated_vlist = NULL;
294 tmp_sv = (DoublePoint*)malloc((13+1)*sizeof(DoublePoint));
295 pv = (DoublePoint*)malloc((13+1)*sizeof(DoublePoint));
296 if (tmp_sv == NULL || pv == NULL) FailAllocMessage();
297
298 obbox.ltx = ObjPtr->orig_obbox.ltx - ObjPtr->x;
299 obbox.lty = ObjPtr->orig_obbox.lty - ObjPtr->y;
300 obbox.rbx = ObjPtr->orig_obbox.rbx - ObjPtr->x;
301 obbox.rby = ObjPtr->orig_obbox.rby - ObjPtr->y;
302 cx = (((double)(obbox.ltx+obbox.rbx))/2.0);
303 cy = (((double)(obbox.lty+obbox.rby))/2.0);
304 w = (((double)(obbox.rbx-obbox.ltx))/2.0);
305 h = (((double)(obbox.rby-obbox.lty))/2.0);
306
307 tmp_sv[0].x = (double)obbox.rbx; tmp_sv[0].y = (double)cy;
308 tmp_sv[1].x = ((double)cx)+(w*ovalXMag1); tmp_sv[1].y = ((double)cy)-(h*ovalYMag1);
309 tmp_sv[2].x = ((double)cx)+(w*ovalXMag2); tmp_sv[2].y = ((double)cy)-(h*ovalYMag2);
310 tmp_sv[3].x = (double)cx; tmp_sv[3].y = (double)obbox.lty;
311 tmp_sv[4].x = ((double)cx)-(w*ovalXMag2); tmp_sv[4].y = ((double)cy)-(h*ovalYMag2);
312 tmp_sv[5].x = ((double)cx)-(w*ovalXMag1); tmp_sv[5].y = ((double)cy)-(h*ovalYMag1);
313 tmp_sv[6].x = (double)obbox.ltx; tmp_sv[6].y = (double)cy;
314 tmp_sv[7].x = ((double)cx)-(w*ovalXMag1); tmp_sv[7].y = ((double)cy)+(h*ovalYMag1);
315 tmp_sv[8].x = ((double)cx)-(w*ovalXMag2); tmp_sv[8].y = ((double)cy)+(h*ovalYMag2);
316 tmp_sv[9].x = (double)cx; tmp_sv[9].y = (double)obbox.rby;
317 tmp_sv[10].x = ((double)cx)+(w*ovalXMag2); tmp_sv[10].y = ((double)cy)+(h*ovalYMag2);
318 tmp_sv[11].x = ((double)cx)+(w*ovalXMag1); tmp_sv[11].y = ((double)cy)+(h*ovalYMag1);
319 tmp_sv[12].x = tmp_sv[0].x; tmp_sv[12].y = tmp_sv[0].y;
320 for (i=0; i < 13; i++) {
321 double x, y;
322
323 TransformDoublePointThroughCTM(tmp_sv[i].x, tmp_sv[i].y, ObjPtr->ctm,
324 &x, &y);
325 tmp_sv[i].x = pv[i].x = OFFSET_DOUBLE_X(x + (double)ObjPtr->x);
326 tmp_sv[i].y = pv[i].y = OFFSET_DOUBLE_Y(y + (double)ObjPtr->y);
327 }
328 saved_zoomedin = zoomedIn;
329 saved_zoomscale = zoomScale;
330 saved_x = drawOrigX;
331 saved_y = drawOrigY;
332 zoomedIn = FALSE;
333 zoomScale = 0;
334 drawOrigX = drawOrigY = 0;
335 sv = MakeDoubleIntSplinePolygonVertex(&sn, &cntrln, &cntrlv,
336 drawOrigX, drawOrigY, 13, pv);
337 zoomedIn = saved_zoomedin;
338 zoomScale = saved_zoomscale;
339 drawOrigX = saved_x;
340 drawOrigY = saved_y;
341 free(pv);
342 if (sv != NULL) {
343 free(tmp_sv);
344 oval_ptr->rotated_n = sn;
345 oval_ptr->rotated_vlist = sv;
346 } else {
347 oval_ptr->rotated_n = 13;
348 }
349
350 if (cntrlv != NULL) free(cntrlv);
351 }
352
DrawOvalObj(window,XOff,YOff,ObjPtr)353 void DrawOvalObj(window, XOff, YOff, ObjPtr)
354 Window window;
355 int XOff, YOff;
356 struct ObjRec *ObjPtr;
357 {
358 int trans_pat, fill, width, pen, dash, pixel, real_x_off, real_y_off;
359 struct BBRec bbox;
360 XGCValues values;
361 struct OvalRec *oval_ptr=ObjPtr->detail.o;
362
363 real_x_off = (zoomedIn ? XOff : (XOff>>zoomScale)<<zoomScale);
364 real_y_off = (zoomedIn ? YOff : (YOff>>zoomScale)<<zoomScale);
365 bbox.ltx = ZOOMED_SIZE(ObjPtr->obbox.ltx - real_x_off);
366 bbox.lty = ZOOMED_SIZE(ObjPtr->obbox.lty - real_y_off);
367 bbox.rbx = ZOOMED_SIZE(ObjPtr->obbox.rbx - real_x_off);
368 bbox.rby = ZOOMED_SIZE(ObjPtr->obbox.rby - real_y_off);
369
370 trans_pat = ObjPtr->trans_pat;
371 fill = oval_ptr->fill;
372 width = oval_ptr->width;
373 pen = oval_ptr->pen;
374 dash = oval_ptr->dash;
375 pixel = colorPixels[ObjPtr->color];
376
377 if (NeedsToCacheOvalObj(ObjPtr) && oval_ptr->rotated_vlist==NULL) {
378 MakeCachedOval(ObjPtr);
379 }
380 if (userDisableRedraw) return;
381
382 if (fill != NONEPAT) {
383 values.foreground = GetDrawingBgPixel(fill, pixel);
384 values.function = GXcopy;
385 values.fill_style = (trans_pat ? FillStippled : FillOpaqueStippled);
386 values.stipple = patPixmap[fill];
387 XChangeGC(mainDisplay, drawGC,
388 GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
389 if (ObjPtr->ctm != NULL) {
390 XFillPolygon(mainDisplay, window, drawGC,
391 oval_ptr->rotated_vlist, oval_ptr->rotated_n,
392 Convex, CoordModeOrigin);
393 } else {
394 XFillArc(mainDisplay, window, drawGC, bbox.ltx, bbox.lty,
395 bbox.rbx-bbox.ltx, bbox.rby-bbox.lty, 0, (360<<6));
396 }
397 }
398 if (pen != NONEPAT) {
399 values.foreground = GetDrawingBgPixel(pen, pixel);
400 values.function = GXcopy;
401 values.fill_style = (trans_pat ? FillStippled : FillOpaqueStippled);
402 values.stipple = patPixmap[pen];
403 values.line_width = ZOOMED_SIZE(width);
404 #ifdef NO_THIN_LINE
405 if (values.line_width < 1) values.line_width = 1;
406 #else
407 #ifdef THIN_OVAL_AND_ARC
408 if (values.line_width <= 1) values.line_width = 0;
409 #endif
410 #endif
411 if (dash != 0) {
412 XSetDashes(mainDisplay, drawGC, 0, dashList[dash],
413 dashListLength[dash]);
414 values.line_style = LineOnOffDash;
415 } else {
416 values.line_style = LineSolid;
417 }
418 XChangeGC(mainDisplay, drawGC,
419 GCForeground | GCFunction | GCFillStyle | GCStipple | GCLineWidth |
420 GCLineStyle, &values);
421 if (ObjPtr->ctm != NULL) {
422 XDrawLines(mainDisplay, window, drawGC,
423 oval_ptr->rotated_vlist, oval_ptr->rotated_n,
424 CoordModeOrigin);
425 } else {
426 XDrawArc(mainDisplay, window, drawGC, bbox.ltx, bbox.lty,
427 bbox.rbx-bbox.ltx, bbox.rby-bbox.lty, 0, (360<<6));
428 }
429 }
430 }
431
CreateOvalObj(BBox,CreateAbsolute)432 void CreateOvalObj(BBox, CreateAbsolute)
433 struct BBRec *BBox;
434 int CreateAbsolute;
435 {
436 struct OvalRec *oval_ptr;
437 struct ObjRec *obj_ptr;
438 int width, w;
439
440 oval_ptr = (struct OvalRec *)malloc(sizeof(struct OvalRec));
441 if (oval_ptr == NULL) FailAllocMessage();
442 memset(oval_ptr, 0, sizeof(struct OvalRec));
443 oval_ptr->fill = objFill;
444 oval_ptr->width = width = curWidthOfLine[lineWidth];
445 UtilStrCpyN(oval_ptr->width_spec, sizeof(oval_ptr->width_spec),
446 curWidthOfLineSpec[lineWidth]);
447 oval_ptr->pen = penPat;
448 oval_ptr->dash = curDash;
449 oval_ptr->rotated_n = 0;
450 oval_ptr->rotated_vlist = NULL;
451
452 obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
453 if (obj_ptr == NULL) FailAllocMessage();
454 memset(obj_ptr, 0, sizeof(struct ObjRec));
455
456 if (CreateAbsolute) {
457 obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = BBox->ltx;
458 obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = BBox->lty;
459 obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = BBox->rbx;
460 obj_ptr->bbox.rby = obj_ptr->obbox.rby = BBox->rby;
461 } else {
462 obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = ABS_X(BBox->ltx);
463 obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = ABS_Y(BBox->lty);
464 obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = ABS_X(BBox->rbx);
465 obj_ptr->bbox.rby = obj_ptr->obbox.rby = ABS_Y(BBox->rby);
466 }
467 w = HALF_W(width);
468 obj_ptr->bbox.ltx -= w;
469 obj_ptr->bbox.lty -= w;
470 obj_ptr->bbox.rbx += w;
471 obj_ptr->bbox.rby += w;
472 obj_ptr->type = OBJ_OVAL;
473 obj_ptr->color = colorIndex;
474 if (mainDisplay != NULL) {
475 UtilStrCpyN(obj_ptr->color_str, sizeof(obj_ptr->color_str),
476 colorMenuItems[colorIndex]);
477 }
478 obj_ptr->id = objId++;
479 obj_ptr->dirty = FALSE;
480 obj_ptr->rotation = 0;
481 obj_ptr->locked = FALSE;
482 obj_ptr->detail.o = oval_ptr;
483 obj_ptr->fattr = obj_ptr->lattr = NULL;
484 obj_ptr->ctm = NULL;
485 obj_ptr->invisible = FALSE;
486 obj_ptr->trans_pat = transPat;
487
488 AddObj(NULL, topObj, obj_ptr);
489 }
490
491 static
AdjContinueOvalBBox(pBBoxIn,pBBoxOut)492 void AdjContinueOvalBBox(pBBoxIn, pBBoxOut)
493 struct BBRec *pBBoxIn, *pBBoxOut;
494 {
495 int w, h, cx, cy;
496 double dx, dy, r;
497
498 switch (curChoice) {
499 case DRAWCORNEROVAL:
500 memcpy(pBBoxOut, pBBoxIn, sizeof(struct BBRec));
501 break;
502 case DRAWCENTEROVAL:
503 w = pBBoxIn->rbx - pBBoxIn->ltx;
504 h = pBBoxIn->rby - pBBoxIn->lty;
505 pBBoxOut->ltx = pBBoxIn->rbx - (w<<1);
506 pBBoxOut->lty = pBBoxIn->rby - (h<<1);
507 pBBoxOut->rbx = pBBoxIn->rbx;
508 pBBoxOut->rby = pBBoxIn->rby;
509 break;
510 case DRAWEDGECIRCLE:
511 cx = ((pBBoxIn->rbx + pBBoxIn->ltx) >> 1);
512 cy = ((pBBoxIn->rby + pBBoxIn->lty) >> 1);
513 dx = (double)(cx - pBBoxIn->ltx);
514 dy = (double)(cy - pBBoxIn->lty);
515 r = (double)sqrt(dx*dx+dy*dy);
516 w = round(r);
517 pBBoxOut->ltx = cx-w;
518 pBBoxOut->lty = cy-w;
519 pBBoxOut->rbx = cx+w;
520 pBBoxOut->rby = cy+w;
521 break;
522 }
523 }
524
525 static
MyContinueOval(d,gc,pBBox)526 void MyContinueOval(d, gc, pBBox)
527 Drawable d;
528 GC gc;
529 struct BBRec *pBBox;
530 {
531 struct BBRec bbox;
532
533 AdjContinueOvalBBox(pBBox, &bbox);
534 MyOval(d, gc, bbox);
535 }
536
537 static
ContinueOval(OrigX,OrigY)538 void ContinueOval(OrigX, OrigY)
539 int OrigX, OrigY;
540 {
541 int end_x, end_y, grid_x, grid_y, done=FALSE, abort=FALSE;
542 char buf[80], w_buf[80], h_buf[80], x_buf[80], y_buf[80];
543 struct BBRec bbox;
544 XEvent input, ev;
545 XMotionEvent *motion_ev=NULL;
546
547 bbox.ltx = bbox.rbx = OrigX;
548 bbox.lty = bbox.rby = OrigY;
549
550 SetXorDrawGC(xorColorPixels[colorIndex]);
551
552 grid_x = end_x = OrigX;
553 grid_y = end_y = OrigY;
554 PixelToMeasurementUnit(w_buf, 0);
555 PixelToMeasurementUnit(h_buf, 0);
556 PixelToMeasurementUnit(x_buf, ABS_X(grid_x));
557 PixelToMeasurementUnit(y_buf, ABS_Y(grid_y));
558 sprintf(buf, "w=%s\nh=%s\nx=%s\ny=%s", w_buf, h_buf, x_buf, y_buf);
559 StartShowMeasureCursor(grid_x, grid_y, buf, TRUE);
560 BeginIntervalRulers(grid_x, grid_y, grid_x, grid_y);
561 if (!debugNoPointerGrab) {
562 XGrabPointer(mainDisplay, drawWindow, FALSE,
563 PointerMotionMask | ButtonReleaseMask,
564 GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
565 }
566 while (!done) {
567 XNextEvent(mainDisplay, &input);
568
569 if (input.type == Expose || input.type == VisibilityNotify) {
570 ExposeEventHandler(&input, TRUE);
571 SetXorDrawGC(xorColorPixels[colorIndex]);
572 } else if (input.type == ButtonRelease) {
573 XUngrabPointer(mainDisplay, CurrentTime);
574 MyContinueOval(drawWindow, drawGC, &bbox);
575 EndIntervalRulers(grid_x, grid_y);
576 PixelToMeasurementUnit(w_buf, ABS_SIZE(abs(bbox.rbx-OrigX)));
577 PixelToMeasurementUnit(h_buf, ABS_SIZE(abs(bbox.rby-OrigY)));
578 PixelToMeasurementUnit(x_buf, ABS_X(bbox.rbx));
579 PixelToMeasurementUnit(y_buf, ABS_Y(bbox.rby));
580 sprintf(buf, "w=%s\nh=%s\nx=%s\ny=%s", w_buf, h_buf, x_buf, y_buf);
581 EndShowMeasureCursor(bbox.rbx, bbox.rby, buf, TRUE);
582 done = TRUE;
583 } else if (input.type == MotionNotify || input.type == KeyPress ||
584 input.type == KeyRelease) {
585 if (input.type == KeyPress) {
586 if (KeyPressEventIsEscape(&input.xkey)) {
587 XUngrabPointer(mainDisplay, CurrentTime);
588 MyContinueOval(drawWindow, drawGC, &bbox);
589 EndIntervalRulers(grid_x, grid_y);
590 PixelToMeasurementUnit(w_buf, ABS_SIZE(abs(bbox.rbx-OrigX)));
591 PixelToMeasurementUnit(h_buf, ABS_SIZE(abs(bbox.rby-OrigY)));
592 PixelToMeasurementUnit(x_buf, ABS_X(bbox.rbx));
593 PixelToMeasurementUnit(y_buf, ABS_Y(bbox.rby));
594 sprintf(buf, "w=%s\nh=%s\nx=%s\ny=%s",
595 w_buf, h_buf, x_buf, y_buf);
596 EndShowMeasureCursor(bbox.rbx, bbox.rby, buf, TRUE);
597 abort = TRUE;
598 done = TRUE;
599 }
600 }
601 if (done) {
602 break;
603 }
604 motion_ev = (&(input.xmotion));
605 if (input.type == KeyPress || input.type == KeyRelease) {
606 end_x = grid_x;
607 end_y = grid_y;
608 } else {
609 end_x = motion_ev->x;
610 end_y = motion_ev->y;
611 }
612 if (curChoice == DRAWEDGECIRCLE &&
613 shiftForDiagMouseMove && DiagEventCheck(&input)) {
614 if (input.type == KeyRelease) {
615 end_x = input.xkey.x;
616 end_y = input.xkey.y;
617 } else {
618 DiagGridXY(OrigX, OrigY, &end_x, &end_y);
619 }
620 }
621 GridXY(end_x, end_y, &grid_x, &grid_y);
622 if (input.type == MotionNotify && curChoice != DRAWEDGECIRCLE &&
623 (motion_ev->state & (ShiftMask | ControlMask)) != 0) {
624 int w, h, pos_w=TRUE, pos_h=TRUE;
625
626 w = grid_x - bbox.ltx;
627 h = grid_y - bbox.lty;
628 if (w < 0) {
629 w = (-w);
630 pos_w = FALSE;
631 }
632 if (h < 0) {
633 h = (-h);
634 pos_h = FALSE;
635 }
636 if (w > h) {
637 grid_x = (pos_w ? (bbox.ltx+h) : (bbox.ltx-h));
638 } else {
639 grid_y = (pos_h ? (bbox.lty+w) : (bbox.lty-w));
640 }
641 }
642 if (grid_x != bbox.rbx || grid_y != bbox.rby) {
643 PixelToMeasurementUnit(w_buf, ABS_SIZE(abs(bbox.rbx-OrigX)));
644 PixelToMeasurementUnit(h_buf, ABS_SIZE(abs(bbox.rby-OrigY)));
645 PixelToMeasurementUnit(x_buf, ABS_X(bbox.rbx));
646 PixelToMeasurementUnit(y_buf, ABS_Y(bbox.rby));
647 sprintf(buf, "w=%s\nh=%s\nx=%s\ny=%s", w_buf, h_buf, x_buf, y_buf);
648 ShowMeasureCursor(bbox.rbx, bbox.rby, buf, TRUE);
649 MyContinueOval(drawWindow, drawGC, &bbox);
650 bbox.rbx = grid_x;
651 bbox.rby = grid_y;
652 MyContinueOval(drawWindow, drawGC, &bbox);
653 PixelToMeasurementUnit(w_buf, ABS_SIZE(abs(bbox.rbx-OrigX)));
654 PixelToMeasurementUnit(h_buf, ABS_SIZE(abs(bbox.rby-OrigY)));
655 PixelToMeasurementUnit(x_buf, ABS_X(bbox.rbx));
656 PixelToMeasurementUnit(y_buf, ABS_Y(bbox.rby));
657 sprintf(buf, "w=%s\nh=%s\nx=%s\ny=%s", w_buf, h_buf, x_buf, y_buf);
658 ShowMeasureCursor(bbox.rbx, bbox.rby, buf, TRUE);
659 }
660 DrawIntervalRulers(OrigX, OrigY, grid_x, grid_y, NULL);
661 while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ;
662 }
663 }
664 if (!abort &&
665 ((curChoice!=DRAWEDGECIRCLE && OrigX!=grid_x && OrigY!=grid_y) ||
666 (curChoice==DRAWEDGECIRCLE && !(OrigX==grid_x && OrigY==grid_y)))) {
667 struct BBRec final_bbox;
668
669 AdjContinueOvalBBox(&bbox, &final_bbox);
670 if (final_bbox.ltx > final_bbox.rbx) {
671 /* swap final_bbox.ltx & final_bbox.rbx */
672 end_x = final_bbox.ltx;
673 final_bbox.ltx = final_bbox.rbx;
674 final_bbox.rbx = end_x;
675 }
676 if (final_bbox.lty > final_bbox.rby) {
677 /* swap final_bbox.lty & final_bbox.rby */
678 end_y = final_bbox.lty;
679 final_bbox.lty = final_bbox.rby;
680 final_bbox.rby = end_y;
681 }
682 CreateOvalObj(&final_bbox, FALSE);
683 RecordNewObjCmd();
684 DrawOvalObj(drawWindow, drawOrigX, drawOrigY, topObj);
685 ovalDrawn = TRUE;
686 SetFileModified(TRUE);
687 }
688 XSync(mainDisplay, False);
689 }
690
DrawOval(input)691 void DrawOval(input)
692 XEvent *input;
693 {
694 XButtonEvent *button_ev;
695 int mouse_x, mouse_y, grid_x, grid_y;
696
697 if (input->type != ButtonPress) return;
698
699 button_ev = &(input->xbutton);
700 if (button_ev->button == Button1) {
701 mouse_x = button_ev->x;
702 mouse_y = button_ev->y;
703 GridXY(mouse_x, mouse_y, &grid_x, &grid_y);
704 ContinueOval(grid_x, grid_y);
705 }
706 }
707
MakeOvalObjFromBoundingBox()708 void MakeOvalObjFromBoundingBox()
709 {
710 struct BBRec obbox;
711
712 if (topSel == NULL) {
713 MsgBox(TgLoadCachedString(CSTID_NO_OBJ_SELECTED), TOOL_NAME, INFO_MB);
714 return;
715 }
716 if (curChoice == VERTEXMODE) SetCurChoice(NOTHING);
717
718 HighLightReverse();
719 obbox.ltx = selObjLtX;
720 obbox.lty = selObjLtY;
721 obbox.rbx = selObjRbX;
722 obbox.rby = selObjRbY;
723 CreateOvalObj(&obbox, TRUE);
724 SelectTopObj();
725 RecordNewObjCmd();
726 RedrawAnArea(botObj, selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
727 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
728 HighLightForward();
729 justDupped = FALSE;
730 SetFileModified(TRUE);
731 }
732
SaveOvalObj(FP,ObjPtr)733 void SaveOvalObj(FP, ObjPtr)
734 FILE *FP;
735 struct ObjRec *ObjPtr;
736 {
737 struct OvalRec *oval_ptr=ObjPtr->detail.o;
738
739 if (fprintf(FP, "oval('%s','',", colorMenuItems[ObjPtr->color]) == EOF) {
740 writeFileFailed = TRUE;
741 }
742 if (fprintf(FP,
743 "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,'%s',%1d,",
744 ObjPtr->obbox.ltx, ObjPtr->obbox.lty, ObjPtr->obbox.rbx,
745 ObjPtr->obbox.rby, oval_ptr->fill, oval_ptr->width,
746 oval_ptr->pen, ObjPtr->id, oval_ptr->dash,
747 ObjPtr->rotation, ObjPtr->locked, ObjPtr->ctm!=NULL,
748 ObjPtr->invisible, oval_ptr->width_spec, ObjPtr->trans_pat) == EOF) {
749 writeFileFailed = TRUE;
750 }
751 if (ObjPtr->ctm != NULL && fprintf(FP,
752 "[\n %1d,%1d,%1d,%1d,%1d,%1d,%g,%g,%g,%g,%1d,%1d],",
753 ObjPtr->x, ObjPtr->y,
754 ObjPtr->orig_obbox.ltx, ObjPtr->orig_obbox.lty,
755 ObjPtr->orig_obbox.rbx, ObjPtr->orig_obbox.rby,
756 ObjPtr->ctm->m[CTM_SX], ObjPtr->ctm->m[CTM_SIN],
757 ObjPtr->ctm->m[CTM_MSIN], ObjPtr->ctm->m[CTM_SY],
758 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY]) == EOF) {
759 writeFileFailed = TRUE;
760 }
761 if (serializingFile) SaveCreatorID(FP, ObjPtr, " ");
762 SaveAttrs(FP, ObjPtr->lattr);
763 if (fprintf(FP, ")") == EOF) writeFileFailed = TRUE;
764 }
765
ReadOvalObj(FP,Inbuf,ObjPtr)766 void ReadOvalObj(FP, Inbuf, ObjPtr)
767 FILE *FP;
768 char *Inbuf;
769 struct ObjRec **ObjPtr;
770 {
771 struct OvalRec *oval_ptr;
772 char color_str[40], bg_color_str[40], *s, width_spec[40];
773 int ltx, lty, rbx, rby, trans_pat=FALSE, fill, width, pen, dash, w, id=0;
774 int new_alloc, rotation, locked=FALSE, transformed=FALSE, invisible=FALSE;
775
776 *ObjPtr = NULL;
777
778 s = FindChar((int)'(', Inbuf);
779 s = ParseStr(s, (int)',', color_str, sizeof(color_str));
780 if (fileVersion >= 37) {
781 s = ParseStr(s, (int)',', bg_color_str, sizeof(bg_color_str));
782 }
783 InitScan(s, "\n\t, ");
784
785 dash = 0;
786 rotation = 0;
787 *width_spec = '\0';
788 if (fileVersion <= 5) {
789 if (GETINT("oval", ltx, "ltx") == INVALID ||
790 GETINT("oval", lty, "lty") == INVALID ||
791 GETINT("oval", rbx, "rbx") == INVALID ||
792 GETINT("oval", rby, "rby") == INVALID ||
793 GETINT("oval", fill, "fill") == INVALID ||
794 GETINT("oval", width, "width") == INVALID ||
795 GETINT("oval", pen, "pen") == INVALID) {
796 return;
797 }
798 switch (width) {
799 case 1: width = 3; break;
800 case 2: width = 6; break;
801 }
802 id = objId++;
803 } else if (fileVersion <= 7) {
804 if (GETINT("oval", ltx, "ltx") == INVALID ||
805 GETINT("oval", lty, "lty") == INVALID ||
806 GETINT("oval", rbx, "rbx") == INVALID ||
807 GETINT("oval", rby, "rby") == INVALID ||
808 GETINT("oval", fill, "fill") == INVALID ||
809 GETINT("oval", width, "width") == INVALID ||
810 GETINT("oval", pen, "pen") == INVALID) {
811 return;
812 }
813 id = objId++;
814 } else if (fileVersion <= 8) {
815 if (GETINT("oval", ltx, "ltx") == INVALID ||
816 GETINT("oval", lty, "lty") == INVALID ||
817 GETINT("oval", rbx, "rbx") == INVALID ||
818 GETINT("oval", rby, "rby") == INVALID ||
819 GETINT("oval", fill, "fill") == INVALID ||
820 GETINT("oval", width, "width") == INVALID ||
821 GETINT("oval", pen, "pen") == INVALID ||
822 GETINT("oval", id, "id") == INVALID) {
823 return;
824 }
825 if (id >= objId) objId = id+1;
826 } else if (fileVersion <= 13) {
827 if (GETINT("oval", ltx, "ltx") == INVALID ||
828 GETINT("oval", lty, "lty") == INVALID ||
829 GETINT("oval", rbx, "rbx") == INVALID ||
830 GETINT("oval", rby, "rby") == INVALID ||
831 GETINT("oval", fill, "fill") == INVALID ||
832 GETINT("oval", width, "width") == INVALID ||
833 GETINT("oval", pen, "pen") == INVALID ||
834 GETINT("oval", id, "id") == INVALID ||
835 GETINT("oval", dash, "dash") == INVALID) {
836 return;
837 }
838 if (id >= objId) objId = id+1;
839 } else if (fileVersion <= 25) {
840 if (GETINT("oval", ltx, "ltx") == INVALID ||
841 GETINT("oval", lty, "lty") == INVALID ||
842 GETINT("oval", rbx, "rbx") == INVALID ||
843 GETINT("oval", rby, "rby") == INVALID ||
844 GETINT("oval", fill, "fill") == INVALID ||
845 GETINT("oval", width, "width") == INVALID ||
846 GETINT("oval", pen, "pen") == INVALID ||
847 GETINT("oval", id, "id") == INVALID ||
848 GETINT("oval", dash, "dash") == INVALID ||
849 GETINT("oval", rotation, "rotation") == INVALID) {
850 return;
851 }
852 if (id >= objId) objId = id+1;
853 } else if (fileVersion <= 32) {
854 if (GETINT("oval", ltx, "ltx") == INVALID ||
855 GETINT("oval", lty, "lty") == INVALID ||
856 GETINT("oval", rbx, "rbx") == INVALID ||
857 GETINT("oval", rby, "rby") == INVALID ||
858 GETINT("oval", fill, "fill") == INVALID ||
859 GETINT("oval", width, "width") == INVALID ||
860 GETINT("oval", pen, "pen") == INVALID ||
861 GETINT("oval", id, "id") == INVALID ||
862 GETINT("oval", dash, "dash") == INVALID ||
863 GETINT("oval", rotation, "rotation") == INVALID ||
864 GETINT("oval", locked, "locked") == INVALID) {
865 return;
866 }
867 if (id >= objId) objId = id+1;
868 } else if (fileVersion <= 34) {
869 if (GETINT("oval", ltx, "ltx") == INVALID ||
870 GETINT("oval", lty, "lty") == INVALID ||
871 GETINT("oval", rbx, "rbx") == INVALID ||
872 GETINT("oval", rby, "rby") == INVALID ||
873 GETINT("oval", fill, "fill") == INVALID ||
874 GETINT("oval", width, "width") == INVALID ||
875 GETINT("oval", pen, "pen") == INVALID ||
876 GETINT("oval", id, "id") == INVALID ||
877 GETINT("oval", dash, "dash") == INVALID ||
878 GETINT("oval", rotation, "rotation") == INVALID ||
879 GETINT("oval", locked, "locked") == INVALID ||
880 GETINT("oval", transformed, "transformed") == INVALID ||
881 GETINT("oval", invisible, "invisible") == INVALID ||
882 GETSTR("oval", width_spec, "width_spec") == INVALID) {
883 return;
884 }
885 if (id >= objId) objId = id+1;
886 UtilRemoveQuotes(width_spec);
887 } else {
888 if (GETINT("oval", ltx, "ltx") == INVALID ||
889 GETINT("oval", lty, "lty") == INVALID ||
890 GETINT("oval", rbx, "rbx") == INVALID ||
891 GETINT("oval", rby, "rby") == INVALID ||
892 GETINT("oval", fill, "fill") == INVALID ||
893 GETINT("oval", width, "width") == INVALID ||
894 GETINT("oval", pen, "pen") == INVALID ||
895 GETINT("oval", id, "id") == INVALID ||
896 GETINT("oval", dash, "dash") == INVALID ||
897 GETINT("oval", rotation, "rotation") == INVALID ||
898 GETINT("oval", locked, "locked") == INVALID ||
899 GETINT("oval", transformed, "transformed") == INVALID ||
900 GETINT("oval", invisible, "invisible") == INVALID ||
901 GETSTR("oval", width_spec, "width_spec") == INVALID ||
902 GETINT("oval", trans_pat, "trans_pat") == INVALID) {
903 return;
904 }
905 if (id >= objId) objId = id+1;
906 UtilRemoveQuotes(width_spec);
907 }
908
909 if (ltx > rbx || lty > rby) {
910 int tmp_ltx, tmp_lty, tmp_rbx, tmp_rby;
911
912 if (!PRTGIF) Msg(TgLoadCachedString(CSTID_BAD_OVAL_BBOX_ADJ));
913 CalcBBox(ltx, lty, rbx, rby, &tmp_ltx, &tmp_lty, &tmp_rbx, &tmp_rby);
914 ltx = tmp_ltx; lty = tmp_lty; rbx = tmp_rbx; rby = tmp_rby;
915 }
916
917 if (fileVersion <= 16 && width <= 6) width = origWidthOfLine[width];
918 if (fileVersion <= 32) {
919 sprintf(width_spec, "%1d", width);
920 }
921 fill = UpgradePenFill(fill);
922 pen = UpgradePenFill(pen);
923
924 *ObjPtr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
925 if (*ObjPtr == NULL) FailAllocMessage();
926 memset(*ObjPtr, 0, sizeof(struct ObjRec));
927 oval_ptr = (struct OvalRec *)malloc(sizeof(struct OvalRec));
928 if (oval_ptr == NULL) FailAllocMessage();
929 memset(oval_ptr, 0, sizeof(struct OvalRec));
930
931 oval_ptr->fill = fill;
932 oval_ptr->width = width;
933 UtilStrCpyN(oval_ptr->width_spec, sizeof(oval_ptr->width_spec), width_spec);
934 oval_ptr->pen = pen;
935 oval_ptr->dash = dash;
936
937 oval_ptr->rotated_n = 0;
938 oval_ptr->rotated_vlist = NULL;
939
940 (*ObjPtr)->x = ltx;
941 (*ObjPtr)->y = lty;
942 (*ObjPtr)->color = QuickFindColorIndex(*ObjPtr, color_str, &new_alloc, TRUE);
943 UtilStrCpyN((*ObjPtr)->color_str, sizeof((*ObjPtr)->color_str), color_str);
944 (*ObjPtr)->dirty = FALSE;
945 (*ObjPtr)->id = id;
946 (*ObjPtr)->rotation = rotation;
947 (*ObjPtr)->locked = locked;
948 (*ObjPtr)->type = OBJ_OVAL;
949 (*ObjPtr)->obbox.ltx = ltx;
950 (*ObjPtr)->obbox.lty = lty;
951 (*ObjPtr)->obbox.rbx = rbx;
952 (*ObjPtr)->obbox.rby = rby;
953 w = HALF_W(width);
954 (*ObjPtr)->bbox.ltx = ltx - w;
955 (*ObjPtr)->bbox.lty = lty - w;
956 (*ObjPtr)->bbox.rbx = rbx + w;
957 (*ObjPtr)->bbox.rby = rby + w;
958 (*ObjPtr)->detail.o = oval_ptr;
959 (*ObjPtr)->ctm = NULL;
960 (*ObjPtr)->invisible = invisible;
961 (*ObjPtr)->trans_pat = trans_pat;
962
963 if (fileVersion >= 33 && transformed) {
964 int real_x=0, real_y=0;
965 struct BBRec orig_obbox;
966 char inbuf[MAXSTRING+1];
967 struct XfrmMtrxRec *ctm;
968
969 (void)fgets(inbuf, MAXSTRING, FP);
970 scanLineNum++;
971 InitScan(inbuf, "\t\n, ");
972
973 ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
974 if (ctm == NULL) FailAllocMessage();
975 if (GETINT("oval", real_x, "real_x") == INVALID ||
976 GETINT("oval", real_y, "real_y") == INVALID ||
977 GETINT("oval", orig_obbox.ltx, "orig_obbox.ltx") == INVALID ||
978 GETINT("oval", orig_obbox.lty, "orig_obbox.lty") == INVALID ||
979 GETINT("oval", orig_obbox.rbx, "orig_obbox.rbx") == INVALID ||
980 GETINT("oval", orig_obbox.rby, "orig_obbox.rby") == INVALID ||
981 GETDBL("oval", ctm->m[CTM_SX], "CTM_SX") == INVALID ||
982 GETDBL("oval", ctm->m[CTM_SIN], "CTM_SIN") == INVALID ||
983 GETDBL("oval", ctm->m[CTM_MSIN], "CTM_MSIN") == INVALID ||
984 GETDBL("oval", ctm->m[CTM_SY], "CTM_SY") == INVALID ||
985 GETINT("oval", ctm->t[CTM_TX], "CTM_TX") == INVALID ||
986 GETINT("oval", ctm->t[CTM_TY], "CTM_TY") == INVALID) {
987 return;
988 }
989 (*ObjPtr)->ctm = ctm;
990 if (ctm != NULL) {
991 memcpy(&(*ObjPtr)->orig_obbox, &orig_obbox, sizeof(struct BBRec));
992 (*ObjPtr)->x = real_x;
993 (*ObjPtr)->y = real_y;
994 GetTransformedOBBoxOffsetVs(*ObjPtr, (*ObjPtr)->rotated_obbox);
995 }
996 }
997 }
998
SetOvalPropMask(ObjPtr,plMask,plSkip,pProp)999 void SetOvalPropMask(ObjPtr, plMask, plSkip, pProp)
1000 struct ObjRec *ObjPtr;
1001 long *plMask, *plSkip;
1002 struct PropertiesRec *pProp;
1003 {
1004 struct OvalRec *oval_ptr=ObjPtr->detail.o;
1005
1006 SetCTMPropertyMask(ObjPtr->ctm, plMask, plSkip, pProp);
1007
1008 SetIntPropertyMask(PROP_MASK_COLOR, ObjPtr->color,
1009 colorMenuItems[ObjPtr->color], plMask, plSkip, pProp);
1010 SetIntPropertyMask(PROP_MASK_WIDTH, oval_ptr->width, oval_ptr->width_spec,
1011 plMask, plSkip, pProp);
1012
1013 SetIntPropertyMask(PROP_MASK_TRANSPAT, ObjPtr->trans_pat, NULL,
1014 plMask, plSkip, pProp);
1015 SetIntPropertyMask(PROP_MASK_FILL, oval_ptr->fill, NULL,
1016 plMask, plSkip, pProp);
1017 SetIntPropertyMask(PROP_MASK_PEN, oval_ptr->pen, NULL,
1018 plMask, plSkip, pProp);
1019 SetIntPropertyMask(PROP_MASK_DASH, oval_ptr->dash, NULL,
1020 plMask, plSkip, pProp);
1021 }
1022
FreeOvalObj(ObjPtr)1023 void FreeOvalObj(ObjPtr)
1024 struct ObjRec *ObjPtr;
1025 {
1026 if (ObjPtr->detail.o->rotated_vlist != NULL) {
1027 free(ObjPtr->detail.o->rotated_vlist);
1028 }
1029 free(ObjPtr->detail.o);
1030 free(ObjPtr);
1031 }
1032