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