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