1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design Systems
4 *
5 * File: graphqt.cpp
6 * Qt Window System interface
7 * Written by: Dmitry Nadezhin, Instutute for Design Problems in Microelectronics, Russian Academy of Sciences
8 *
9 * Copyright (c) 2001 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * info@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "graphqt.h"
34 #include "egraphics.h"
35
36 #define FLUSHTICKS 60 /* ticks between display flushes */
37
38 /****** fonts ******/
39
40 #define MAXCACHEDFONTS 200
41 #define FONTHASHSIZE 211 /* must be prime */
42 #define MAXFONTCHAR 128
43 #define MAXCHARBITS 32 /* maximum height of cached characters */
44
45 class EFont;
46
47 class EFontChar
48 {
49 public:
50 EFontChar( EFont *font, QChar aCh );
51 QChar ch;
52 QRect bounding;
53 QImage glyphImage;
54 int width;
55 EFontChar *next;
56 };
57
58 class EFont
59 {
60 public:
61 EFont( QFont fnt );
62 ~EFont();
63 QFont font;
64 QFontMetrics fontMetrics;
65 EFontChar *getFontChar(QChar ch);
66 private:
67 EFontChar *chars[MAXFONTCHAR];
68 };
69
70 static EFont *gra_fixedfont = 0, *gra_menufont = 0, *gra_tmpfont = 0;
71 static EFont *gra_fontcache[MAXCACHEDFONTS];
72 static INTBIG gra_numallfaces = 0, gra_numusedfaces = 0;
73 static char **gra_allfacelist, **gra_usedfacelist;
74
75 typedef struct
76 {
77 EFont *font;
78 INTBIG face;
79 INTBIG italic;
80 INTBIG bold;
81 INTBIG underline;
82 INTBIG size;
83 } FONTHASH;
84
85 static FONTHASH gra_fonthash[FONTHASHSIZE];
86
87 static INTBIG gra_textrotation = 0;
88 static char *gra_textbitsdata; /* buffer for converting text to bits */
89 static INTBIG gra_textbitsdatasize = 0; /* size of "gra_textbitsdata" */
90 static char **gra_textbitsrowstart; /* pointers to "gra_textbitsdata" */
91 static INTBIG gra_textbitsrowstartsize = 0; /* size of "gra_textbitsrowstart" */
92 static BOOLEAN gra_texttoosmall = FALSE; /* TRUE if text too small to draw */
93
94 static EFont *gra_createtextfont(INTBIG fontSize, QString face, INTBIG italic, INTBIG bold,
95 INTBIG underline);
96 static EFont *gra_gettextfont(WINDOWPART *win, TECHNOLOGY *tech, UINTBIG *descript);
97
98 /****** EFont ******/
EFontChar(EFont * font,QChar aCh)99 EFontChar::EFontChar( EFont *font, QChar aCh )
100 {
101 ch = aCh;
102 bounding = font->fontMetrics.boundingRect( ch );
103 width = font->fontMetrics.width( ch );
104
105 /* load the image array */
106 if (bounding.width() > gra->charbits.width() || bounding.height() > gra->charbits.height()) {
107 gra->charbits.resize( QMAX( bounding.width(), gra->charbits.width() ), QMAX( bounding.height(), gra->charbits.height() ) );
108 }
109
110 QPainter p( &gra->charbits );
111 p.eraseRect( 0, 0, bounding.width(), bounding.height() );
112 p.setFont( font->font );
113 p.drawText( -bounding.left(), -bounding.top(), ch );
114 p.end();
115
116 QImage image = gra->charbits.convertToImage();
117 #ifdef CHARPIXMAP
118 if (!bounding.isEmpty())
119 {
120 QImage boundImage = image.copy( 0, 0, bounding.width(), bounding.height() );
121 glyphImage = boundImage.convertDepth( 1, Qt::ThresholdDither );
122 }
123 #if 0
124 if (aCh == 'N')
125 {
126 QCString fam = font->font.family().latin1();
127 QCString raw = font->font.rawName().latin1();
128 printf("Char <%c>%o Font %s(%s) depth=%d(%d)\n",
129 aCh.latin1(), aCh.latin1(), (const char*)fam, (const char*)raw, image.depth(), glyphImage.depth());
130 for (int i = 0; i < bounding.height(); i++)
131 {
132 printf("\t");
133 for (int j = 0; j < bounding.width(); j++) printf(" %d", qGray( image.pixel(j, i) ) );
134 printf("\n");
135 }
136 for (int i = 0; i < bounding.height(); i++)
137 {
138 printf("\t");
139 for (int j = 0; j < bounding.width(); j++) printf("%c", (glyphImage.pixelIndex(j, i) ? 'X' : ' '));
140 printf("\n");
141 }
142 }
143 #endif
144 #else
145 glyphImage = image.copy( 0, 0, bounding.width(), bounding.height() );
146 #endif
147 }
148
EFont(QFont fnt)149 EFont::EFont( QFont fnt )
150 : font( fnt ), fontMetrics( fnt )
151 {
152 for (int i = 0; i < MAXFONTCHAR; i++) chars[i] = 0;
153 }
154
~EFont()155 EFont::~EFont()
156 {
157 for (int i = 0; i < MAXFONTCHAR; i++)
158 {
159 while (chars[i])
160 {
161 EFontChar *e = chars[i];
162 chars[i] = e->next;
163 delete e;
164 }
165 }
166 }
167
getFontChar(QChar ch)168 EFontChar *EFont::getFontChar(QChar ch)
169 {
170 int index = ch % MAXFONTCHAR;
171 EFontChar *e;
172 for (e = chars[index]; e; e = e->next)
173 {
174 if (e->ch == ch) return e;
175 }
176 e = new EFontChar( this, ch );
177 e->next = chars[index];
178 chars[index] = e;
179 return e;
180 }
181
182 /****** rectangle saving ******/
183 #define NOSAVEDBOX ((SAVEDBOX *)-1)
184 typedef struct Isavedbox
185 {
186 QPixmap pix;
187 GraphicsDraw *draw;
188 QPoint orig;
189 } SAVEDBOX;
190
191 /******************** GRAPHICS LINES ********************/
192
193 /*
194 * Routine to draw a line in the graphics window.
195 */
screendrawline(WINDOWPART * win,INTBIG x1,INTBIG y1,INTBIG x2,INTBIG y2,GRAPHICS * desc,INTBIG texture)196 void screendrawline(WINDOWPART *win, INTBIG x1, INTBIG y1, INTBIG x2, INTBIG y2, GRAPHICS *desc,
197 INTBIG texture)
198 {
199 gra_drawline( win, x1, y1, x2, y2, desc, texture );
200 }
201
202 /*
203 * Routine to invert bits of the line in the graphics window
204 */
screeninvertline(WINDOWPART * win,INTBIG x1,INTBIG y1,INTBIG x2,INTBIG y2)205 void screeninvertline(WINDOWPART *win, INTBIG x1, INTBIG y1, INTBIG x2, INTBIG y2)
206 {
207 gra_invertline( win, x1, y1, x2, y2 );
208 }
209
210 /******************** GRAPHICS POLYGONS ********************/
211
212 /*
213 * Routine to draw a polygon in the graphics window.
214 */
screendrawpolygon(WINDOWPART * win,INTBIG * x,INTBIG * y,INTBIG count,GRAPHICS * desc)215 void screendrawpolygon(WINDOWPART *win, INTBIG *x, INTBIG *y, INTBIG count, GRAPHICS *desc)
216 {
217 gra_drawpolygon( win, x, y, count, desc );
218 }
219
220 /******************** GRAPHICS BOXES ********************/
221
222 /*
223 * Routine to draw a box in the graphics window.
224 */
screendrawbox(WINDOWPART * win,INTBIG lowx,INTBIG highx,INTBIG lowy,INTBIG highy,GRAPHICS * desc)225 void screendrawbox(WINDOWPART *win, INTBIG lowx, INTBIG highx, INTBIG lowy, INTBIG highy,
226 GRAPHICS *desc)
227 {
228 gra_drawbox( win, lowx, highx, lowy, highy, desc );
229 }
230
231 /*
232 * routine to invert the bits in the box from (lowx, lowy) to (highx, highy)
233 */
screeninvertbox(WINDOWPART * win,INTBIG lowx,INTBIG highx,INTBIG lowy,INTBIG highy)234 void screeninvertbox(WINDOWPART *win, INTBIG lowx, INTBIG highx, INTBIG lowy, INTBIG highy)
235 {
236 gra_invertbox( win, lowx, highx, lowy, highy );
237 }
238
239 /*
240 * routine to move bits on the display starting with the area at
241 * (sx,sy) and ending at (dx,dy). The size of the area to be
242 * moved is "wid" by "hei".
243 */
screenmovebox(WINDOWPART * win,INTBIG sx,INTBIG sy,INTBIG wid,INTBIG hei,INTBIG dx,INTBIG dy)244 void screenmovebox(WINDOWPART *win, INTBIG sx, INTBIG sy, INTBIG wid, INTBIG hei,
245 INTBIG dx, INTBIG dy)
246 {
247 gra_movebox( win, sx, sy, wid, hei, dx, dy );
248 }
249
250 /*
251 * routine to save the contents of the box from "lx" to "hx" in X and from
252 * "ly" to "hy" in Y. A code is returned that identifies this box for
253 * overwriting and restoring. The routine returns negative if there is a error.
254 */
screensavebox(WINDOWPART * win,INTBIG lx,INTBIG hx,INTBIG ly,INTBIG hy)255 INTBIG screensavebox(WINDOWPART *win, INTBIG lx, INTBIG hx, INTBIG ly, INTBIG hy)
256 {
257 return gra_savebox( win, lx, hx, ly, hy );
258 }
259
260 /*
261 * routine to shift the saved box "code" so that it is restored in a different
262 * lcoation, offset by (dx,dy)
263 */
screenmovesavedbox(INTBIG code,INTBIG dx,INTBIG dy)264 void screenmovesavedbox(INTBIG code, INTBIG dx, INTBIG dy)
265 {
266 gra_movesavedbox( code, dx, dy );
267 }
268
269 /*
270 * routine to restore saved box "code" to the screen. "destroy" is:
271 * 0 restore box, do not free memory
272 * 1 restore box, free memory
273 * -1 free memory
274 */
screenrestorebox(INTBIG code,INTBIG destroy)275 void screenrestorebox(INTBIG code, INTBIG destroy)
276 {
277 gra_restorebox( code, destroy );
278 }
279
280 /******************** GRAPHICS TEXT ********************/
281
282 /*
283 * Routine to find face with name "facename" and to return
284 * its index in list of used fonts. If font was not used before,
285 * then it is appended to list of used fonts.
286 * If font "facename" is not available on the system, -1 is returned.
287 */
screenfindface(char * facename)288 INTBIG screenfindface(char *facename)
289 {
290 int i;
291
292 for (i = 1; i < gra_numusedfaces; i++)
293 if (namesame(facename, gra_usedfacelist[i]) == 0) return i;
294 if (gra_numusedfaces >= VTMAXFACE) return(-1);
295 for (i = 1; i < gra_numallfaces; i++)
296 if (namesame(facename, gra_allfacelist[i]) == 0) break;
297 if (i >= gra_numallfaces) return(-1);
298 gra_usedfacelist[gra_numusedfaces] = gra_allfacelist[i];
299 return(gra_numusedfaces++);
300 }
301
302 /*
303 * Routine to return the number of typefaces used (when "all" is FALSE)
304 * or available on the system (when "all" is TRUE)
305 * and to return their names in the array "list".
306 * "screenfindface
307 */
screengetfacelist(char *** list,BOOLEAN all)308 INTBIG screengetfacelist(char ***list, BOOLEAN all)
309 {
310 if (all)
311 {
312 *list = gra_allfacelist;
313 return(gra_numallfaces);
314 } else
315 {
316 *list = gra_usedfacelist;
317 return(gra_numusedfaces);
318 }
319 }
320
321 /*
322 * Routine to return the default typeface used on the screen.
323 */
screengetdefaultfacename(void)324 char *screengetdefaultfacename(void)
325 {
326 return(EApplication::localize(gra->defface));
327 }
328
screensettextinfo(WINDOWPART * win,TECHNOLOGY * tech,UINTBIG * descript)329 void screensettextinfo(WINDOWPART *win, TECHNOLOGY *tech, UINTBIG *descript)
330 {
331 gra_textrotation = TDGETROTATION(descript);
332 gra->curfont = gra_gettextfont(win, tech, descript);
333 }
334
gra_gettextfont(WINDOWPART * win,TECHNOLOGY * tech,UINTBIG * descript)335 static EFont *gra_gettextfont(WINDOWPART *win, TECHNOLOGY *tech, UINTBIG *descript)
336 {
337 gra_texttoosmall = FALSE;
338 int font = TDGETSIZE(descript);
339 if (font == TXTEDITOR)
340 {
341 if (gra_fixedfont == 0) gra_fixedfont = new EFont( gra->fixedfont );
342 return gra_fixedfont;
343 }
344 if (gra_menufont == 0) gra_menufont = new EFont( gra->font() );
345 if (font == TXTMENU) return gra_menufont;
346 /*
347 GraphicsMainWindow *qwin = (GraphicsMainWindow*)win->frame->qt;
348 gra->curfont = qwin->menuBar()->font();
349 */
350
351 int size = truefontsize(font, win, tech);
352 if (size < 1)
353 {
354 gra_texttoosmall = TRUE;
355 return(0);
356 }
357 if (size < MINIMUMTEXTSIZE) size = MINIMUMTEXTSIZE;
358 #if 0
359 /* Increase font size to match Unix X11 port */
360 size += 4;
361 #endif
362 int face = TDGETFACE(descript);
363 int italic = TDGETITALIC(descript);
364 int bold = TDGETBOLD(descript);
365 int underline = TDGETUNDERLINE(descript);
366 gra_textrotation = TDGETROTATION(descript);
367 if (face == 0 && italic == 0 && bold == 0 && underline == 0)
368 {
369 if (size >= MAXCACHEDFONTS) size = MAXCACHEDFONTS-1;
370 if (gra_fontcache[size] == 0) {
371 gra_fontcache[size] = gra_createtextfont(size, gra->defface, 0, 0, 0);
372 if (gra_fontcache[size] == 0) return gra_menufont;
373 }
374 return(gra_fontcache[size]);
375 } else
376 {
377 UINTBIG hash = size + 3*italic + 5*bold + 7*underline + 11*face;
378 hash %= FONTHASHSIZE;
379 for(int i=0; i<FONTHASHSIZE; i++)
380 {
381 if (gra_fonthash[hash].font == 0) break;
382 if (gra_fonthash[hash].face == face && gra_fonthash[hash].size == size &&
383 gra_fonthash[hash].italic == italic && gra_fonthash[hash].bold == bold &&
384 gra_fonthash[hash].underline == underline)
385 return(gra_fonthash[hash].font);
386 hash++;
387 if (hash >= FONTHASHSIZE) hash = 0;
388 }
389 QString facename = gra->defface;
390 if (face > 0 || face < gra_numusedfaces) facename = QString::fromLocal8Bit( gra_usedfacelist[face] );
391 EFont *theFont = gra_createtextfont(size, facename, italic, bold, underline);
392 if (theFont == 0) return gra_menufont;
393 if (gra_fonthash[hash].font == 0)
394 {
395 gra_fonthash[hash].font = theFont;
396 gra_fonthash[hash].face = face;
397 gra_fonthash[hash].size = size;
398 gra_fonthash[hash].italic = italic;
399 gra_fonthash[hash].bold = bold;
400 gra_fonthash[hash].underline = underline;
401 } else
402 {
403 delete gra_tmpfont;
404 gra_tmpfont = theFont;
405 }
406 return(theFont);
407 }
408 }
409
gra_createtextfont(INTBIG fontSize,QString face,INTBIG italic,INTBIG bold,INTBIG underline)410 static EFont *gra_createtextfont(INTBIG fontSize, QString face, INTBIG italic, INTBIG bold,
411 INTBIG underline)
412 {
413 QFont font( face, fontSize );
414 font.setStyleStrategy( QFont::NoAntialias );
415 font.setItalic( italic );
416 font.setBold( bold );
417 font.setUnderline( underline );
418 return new EFont( font );
419 }
420
screengettextsize(WINDOWPART * win,char * str,INTBIG * x,INTBIG * y)421 void screengettextsize(WINDOWPART *win, char *str, INTBIG *x, INTBIG *y)
422 {
423 Q_UNUSED( win );
424
425 INTBIG len, wid, hei;
426
427 len = strlen(str);
428 if (len == 0 || gra_texttoosmall)
429 {
430 *x = *y = 0;
431 return;
432 }
433
434 /* determine the size of the text */
435 QFontMetrics fontMetrics = gra->curfont->fontMetrics;
436 QString qstr = QString::fromLocal8Bit( str );
437 QRect bounding = fontMetrics.boundingRect( qstr );
438
439 /* fixing qt bug */
440 QRect bounding1 = fontMetrics.boundingRect( qstr[0] );
441 if (bounding1.left() < bounding.left() )
442 bounding.setLeft( bounding1.left() );
443
444 wid = bounding.width();
445 hei = QMAX(bounding.bottom(), fontMetrics.descent()) - bounding.top() + 1;
446
447 switch (gra_textrotation)
448 {
449 case 0: /* normal */
450 *x = wid;
451 *y = hei;
452 break;
453 case 1: /* 90 degrees counterclockwise */
454 *x = -hei;
455 *y = wid;
456 break;
457 case 2: /* 180 degrees */
458 *x = -wid;
459 *y = -hei;
460 break;
461 case 3: /* 90 degrees clockwise */
462 *x = hei;
463 *y = -wid;
464 break;
465 }
466 }
467
screendrawtext(WINDOWPART * win,INTBIG atx,INTBIG aty,char * s,GRAPHICS * desc)468 void screendrawtext(WINDOWPART *win, INTBIG atx, INTBIG aty, char *s, GRAPHICS *desc)
469 {
470 if (gra_texttoosmall) return;
471 gra_drawtext( win, atx, aty, gra_textrotation, s, desc );
472 }
473
474 /*
475 * Routine to convert the string "msg" (to be drawn into window "win") into an
476 * array of pixels. The size of the array is returned in "wid" and "hei", and
477 * the pixels are returned in an array of character vectors "rowstart".
478 * The routine returns nonzero if the operation cannot be done.
479 */
gettextbits(WINDOWPART * win,char * msg,INTBIG * wid,INTBIG * hei,UCHAR1 *** rowstart)480 BOOLEAN gettextbits(WINDOWPART *win, char *msg, INTBIG *wid, INTBIG *hei, UCHAR1 ***rowstart)
481 {
482 Q_UNUSED( win );
483
484 REGISTER INTBIG len, datasize;
485
486 /* quit if string is null */
487 *wid = *hei = 0;
488 len = strlen(msg);
489 if (len == 0 || gra_texttoosmall) return(FALSE);
490
491 /* determine the size of the text */
492 QFontMetrics fontMetrics = gra->curfont->fontMetrics;
493 QString qstr = QString::fromLocal8Bit( msg );
494 QRect bounding = fontMetrics.boundingRect( qstr );
495
496 #if QT_VERSION < 0x030005
497 /* fixing qt bug */
498 QRect bounding1 = fontMetrics.boundingRect( qstr[0] );
499 if (bounding1.left() < bounding.left() )
500 bounding.setLeft( bounding1.left() );
501 #endif
502
503 *wid = bounding.width();
504 *hei = QMAX(bounding.bottom(), fontMetrics.descent()) - bounding.top() + 1;
505
506 /* allocate space for this */
507 datasize = *wid * *hei;
508 if (datasize > gra_textbitsdatasize)
509 {
510 if (gra_textbitsdatasize > 0) efree((char *)gra_textbitsdata);
511 gra_textbitsdatasize = 0;
512
513 gra_textbitsdata = (char *)emalloc(datasize, us_tool->cluster);
514 if (gra_textbitsdata == 0) return(TRUE);
515 gra_textbitsdatasize = datasize;
516 }
517 if (*hei > gra_textbitsrowstartsize)
518 {
519 if (gra_textbitsrowstartsize > 0) efree((char *)gra_textbitsrowstart);
520 gra_textbitsrowstartsize = 0;
521 gra_textbitsrowstart = (char **)emalloc(*hei * (sizeof (UCHAR1 *)), us_tool->cluster);
522 if (gra_textbitsrowstart == 0) return(TRUE);
523 gra_textbitsrowstartsize = *hei;
524 }
525
526 /* load the row start array */
527 for(int y=0; y < *hei; y++)
528 {
529 gra_textbitsrowstart[y] = &gra_textbitsdata[*wid * y];
530 }
531 *rowstart = (UCHAR1 **)gra_textbitsrowstart;
532
533 if (*hei > MAXCHARBITS)
534 {
535 /* load the image array */
536 if (*wid > gra->textbits.width() || *hei > gra->textbits.height()) {
537 gra->textbits.resize( QMAX( *wid, gra->textbits.width() ), QMAX( *hei, gra->textbits.height() ) );
538 }
539
540 QPainter p( &gra->textbits );
541 p.eraseRect( 0, 0, *wid, *hei );
542 p.setFont( gra->curfont->font );
543 p.drawText( -bounding.left(), -bounding.top(), qstr );
544 p.end();
545
546 QImage image = gra->textbits.convertToImage();
547 for (int i=0; i<*hei; i++) {
548 for (int j=0; j < *wid; j++) gra_textbitsrowstart[i][j] = image.pixelIndex( j, i );
549 }
550 } else
551 {
552 int i, j;
553 int x = -bounding.left();
554
555 for (i = 0; i < *hei; i++) {
556 if (gra->curfont->font.underline() &&
557 i + bounding.top() >= gra->curfont->fontMetrics.underlinePos() &&
558 i + bounding.top() < gra->curfont->fontMetrics.underlinePos() + gra->curfont->fontMetrics.lineWidth())
559 {
560 for (int j=0; j < *wid; j++) gra_textbitsrowstart[i][j] = 1;
561 } else
562 {
563 for (int j=0; j < *wid; j++) gra_textbitsrowstart[i][j] = 0;
564 }
565 }
566 for (uint k = 0; k < qstr.length(); k++) {
567 EFontChar *efc = gra->curfont->getFontChar( qstr[k] );
568 int xl = x + efc->bounding.left();
569 int jmin = (xl >= 0 ? 0 : -xl);
570 int jmax = efc->glyphImage.width();
571 if (xl + jmax > *wid) jmax = *wid - xl;
572 for (i = 0; i < efc->glyphImage.height(); i++) {
573 int y = efc->bounding.top() + i - bounding.top();
574 if (y < 0 || y >= *hei) continue;
575 for (j = jmin; j < jmax; j++) {
576 if (efc->glyphImage.pixelIndex( j, i )) {
577 gra_textbitsrowstart[y][xl + j] = 1;
578 }
579 }
580 }
581 x += efc->width;
582 }
583 }
584
585 return(FALSE);
586 }
587
588 /******************** CIRCLE DRAWING ********************/
screendrawcircle(WINDOWPART * win,INTBIG atx,INTBIG aty,INTBIG radius,GRAPHICS * desc)589 void screendrawcircle(WINDOWPART *win, INTBIG atx, INTBIG aty, INTBIG radius, GRAPHICS *desc)
590 {
591 gra_drawcircle( win, atx, aty, radius, desc );
592 }
593
screendrawthickcircle(WINDOWPART * win,INTBIG atx,INTBIG aty,INTBIG radius,GRAPHICS * desc)594 void screendrawthickcircle(WINDOWPART *win, INTBIG atx, INTBIG aty, INTBIG radius,
595 GRAPHICS *desc)
596 {
597 gra_drawthickcircle( win, atx, aty, radius, desc );
598 }
599
600 /******************** DISC DRAWING ********************/
601
602 /*
603 * routine to draw a filled-in circle of radius "radius"
604 */
screendrawdisc(WINDOWPART * win,INTBIG atx,INTBIG aty,INTBIG radius,GRAPHICS * desc)605 void screendrawdisc(WINDOWPART *win, INTBIG atx, INTBIG aty, INTBIG radius, GRAPHICS *desc)
606 {
607 gra_drawdisc( win, atx, aty, radius, desc );
608 }
609
610 /******************** ARC DRAWING ********************/
611
612 /*
613 * draws a thin arc centered at (centerx, centery), clockwise,
614 * passing by (x1,y1) and (x2,y2)
615 */
screendrawcirclearc(WINDOWPART * win,INTBIG centerx,INTBIG centery,INTBIG p1_x,INTBIG p1_y,INTBIG p2_x,INTBIG p2_y,GRAPHICS * desc)616 void screendrawcirclearc(WINDOWPART *win, INTBIG centerx, INTBIG centery, INTBIG p1_x, INTBIG p1_y,
617 INTBIG p2_x, INTBIG p2_y, GRAPHICS *desc)
618 {
619 gra_drawcirclearc( win, centerx, centery, p1_x, p1_y, p2_x, p2_y, FALSE, desc );
620 }
621
622 /*
623 * draws a thick arc centered at (centerx, centery), clockwise,
624 * passing by (x1,y1) and (x2,y2)
625 */
screendrawthickcirclearc(WINDOWPART * win,INTBIG centerx,INTBIG centery,INTBIG p1_x,INTBIG p1_y,INTBIG p2_x,INTBIG p2_y,GRAPHICS * desc)626 void screendrawthickcirclearc(WINDOWPART *win, INTBIG centerx, INTBIG centery, INTBIG p1_x, INTBIG p1_y,
627 INTBIG p2_x, INTBIG p2_y, GRAPHICS *desc)
628 {
629 gra_drawcirclearc( win, centerx, centery, p1_x, p1_y, p2_x, p2_y, TRUE, desc );
630 }
631
632 /******************** GRID CONTROL ********************/
633
634 /*
635 * fast grid drawing routine
636 */
screendrawgrid(WINDOWPART * win,POLYGON * obj)637 void screendrawgrid(WINDOWPART *win, POLYGON *obj)
638 {
639 gra_drawgrid( win, obj );
640 }
641
gra_initfaces(QStringList & facelist)642 void gra_initfaces( QStringList &facelist )
643 {
644 uint i;
645
646 for(i=0; i<MAXCACHEDFONTS; i++) gra_fontcache[i] = 0;
647 for(i=0; i<FONTHASHSIZE; i++) gra_fonthash[i].font = 0;
648
649 gra_numallfaces = facelist.count() + 1;
650 gra_allfacelist = (char **)emalloc(gra_numallfaces * (sizeof (char *)), us_tool->cluster);
651 Q_CHECK_PTR( gra_allfacelist );
652 (void)allocstring(&gra_allfacelist[0], _("DEFAULT FACE"), us_tool->cluster);
653 for(i=0; i<facelist.count(); i++) {
654 char *facename = gra->localize( facelist[i] );
655 (void)allocstring(&gra_allfacelist[i+1], facename, us_tool->cluster);
656 }
657 gra_usedfacelist = (char **)emalloc(VTMAXFACE * (sizeof (char *)), us_tool->cluster);
658 Q_CHECK_PTR( gra_usedfacelist );
659 gra_numusedfaces = 1;
660 gra_usedfacelist[0] = gra_allfacelist[0];
661 }
662
gra_termfaces()663 void gra_termfaces()
664 {
665 int i;
666
667 for(i=0; i<MAXCACHEDFONTS; i++) {
668 if(gra_fontcache[i]) delete gra_fontcache[i];
669 }
670 for(i=0; i<FONTHASHSIZE; i++) {
671 if(gra_fonthash[i].font) delete gra_fonthash[i].font;
672 }
673
674 for(i=0; i<gra_numallfaces; i++) efree((char *)gra_allfacelist[i]);
675 if (gra_numallfaces > 0) efree((char *)gra_allfacelist);
676 if (gra_numusedfaces > 0) efree((char *)gra_usedfacelist);
677
678 if (gra_textbitsdatasize > 0) efree((char *)gra_textbitsdata);
679 if (gra_textbitsrowstartsize > 0) efree((char *)gra_textbitsrowstart);
680 }
681
682