|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/vibrant/ncbidraw.c |
source navigation diff markup identifier search freetext search file search |
1 /* ncbidraw.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: ncbidraw.c
27 *
28 * Author: Jonathan Kans, Denis Vakatov
29 *
30 * Version Creation Date: 1/1/91
31 *
32 * $Revision: 6.45 $
33 *
34 * File Description:
35 * Vibrant drawing functions.
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 *
40 * ==========================================================================
41 */
42
43 #include <vibtypes.h>
44 #include <vibincld.h>
45
46 #ifdef VAR_ARGS
47 # include <varargs.h>
48 #else
49 # include <stdarg.h>
50 #endif
51
52 #ifdef WIN_GIF
53 # include <gifgen.h>
54 # ifdef Nlm_RgnTool
55 # undef Nlm_RgnTool
56 # endif
57 # ifdef Nlm_RectTool
58 # undef Nlm_RectTool
59 # endif
60 # define Nlm_RectTool Nlm_RecT
61 # ifdef WIN_MOTIF
62 # undef WIN_MOTIF
63 # ifdef WIN_X
64 # undef WIN_X
65 # endif
66 # define Nlm_RgnTool Nlm_VoidPtr
67 # endif
68 # ifdef WIN_MAC
69 # undef WIN_MAC
70 # define Nlm_RgnTool Handle
71 # endif
72 # ifdef WIN_MSWIN
73 # undef WIN_MSWIN
74 # define Nlm_RgnTool HANDLE
75 # endif
76 #else /* WIN_GIF */
77 typedef struct gdImageStruct { void* dummy; } gdImage;
78 #endif /* WIN_GIF */
79
80 #if defined(WIN_X) && !defined(__hpux)
81 #include <X11/Xmu/Drawing.h>
82 #endif
83
84 Nlm_Boolean Nlm_nowPrinting = FALSE;
85
86 #ifdef WIN_MAC
87 #ifdef __MWERKS__
88 #include "MoreCarbonAccessors.h"
89 #else
90 #define GetPortAndCall_(function, arg) \
91 do { \
92 GrafPtr port_; \
93 GetPort(&port_); \
94 function(GetWindowFromPort(port_), (arg)); \
95 } while (0)
96 #define InvalRect(rect) GetPortAndCall_(InvalWindowRect, (rect))
97 #define InvalRgn(rgn) GetPortAndCall_(InvalWindowRgn, (rgn ))
98 #define ValidRect(rect) GetPortAndCall_(ValidWindowRect, (rect))
99 #define ValidRgn(rgn) GetPortAndCall_(ValidWindowRgn, (rgn ))
100 #endif
101 #endif
102
103 #ifdef WIN_MAC
104 #ifdef WIN_MAC_QUARTZ
105 CFMutableArrayRef Nlm_QContextStack = 0;
106 static void Nlm_PushQContext( CGContextRef ctx )
107 {
108 if (!Nlm_QContextStack)
109 Nlm_QContextStack = CFArrayCreateMutable (NULL, 0, NULL);
110 CFArrayAppendValue (Nlm_QContextStack, ctx);
111 }
112 static CGContextRef Nlm_PeekQContext (void)
113 {
114 if (!Nlm_QContextStack)
115 return NULL;
116
117 CFIndex count = CFArrayGetCount (Nlm_QContextStack);
118 return count ? (CGContextRef)CFArrayGetValueAtIndex (Nlm_QContextStack, count - 1) : NULL;
119 }
120 static CGContextRef Nlm_PopQContext (void)
121 {
122 if (!Nlm_QContextStack)
123 return NULL;
124
125 void *ret = Nlm_PeekQContext();
126 CFIndex count = CFArrayGetCount (Nlm_QContextStack);
127 if (count)
128 CFArrayRemoveValueAtIndex (Nlm_QContextStack, count - 1);
129 return ret;
130 }
131
132 WindowRef Nlm_QWindow = 0;
133 Nlm_QuartzColor Nlm_QuartzForeColor;
134 Nlm_QuartzColor Nlm_QuartzBackColor;
135 Nlm_Boolean Nlm_hasColorQD = TRUE;
136 #else
137 RGBColor Nlm_RGBforeColor;
138 RGBColor Nlm_RGBbackColor;
139 Nlm_Boolean Nlm_hasColorQD = FALSE;
140 #endif
141 #endif
142
143 #ifdef WIN_MSWIN
144 #define ATT_PENSTYLE 1
145 #define ATT_PENWIDTH 2
146 #define ATT_PATTERN 4
147 HWND Nlm_currentHWnd;
148 HDC Nlm_currentHDC;
149 #endif
150
151 #ifdef WIN_X
152 Display *Nlm_currentXDisplay;
153 int Nlm_currentXScreen;
154 Window Nlm_currentXWindow;
155 GC Nlm_currentXGC;
156 Nlm_Uint4 Nlm_XbackColor;
157 Nlm_Uint4 Nlm_XforeColor;
158 Nlm_Int2 Nlm_XOffset;
159 Nlm_Int2 Nlm_YOffset;
160 Nlm_RegioN Nlm_clpRgn;
161 Nlm_Boolean Nlm_hasColor = FALSE;
162 #endif
163
164 #ifdef WIN_GIF
165 #define GIF_SOLID 0
166 #define GIF_DASHED 1
167 static gdImagePtr Nlm_currentGIF = NULL;
168 static int Nlm_curGIFColor = 1;
169 static int Nlm_curGIFLType = GIF_SOLID;
170 static gdFontPtr Nlm_curGIFFont = NULL;
171 static Nlm_PoinT Nlm_curGIFPoint = {0,0};
172 #endif
173
174 Nlm_RegioN Nlm_updateRgn;
175 Nlm_RecT Nlm_updateRect;
176
177 Nlm_Int2 Nlm_stdAscent;
178 Nlm_Int2 Nlm_stdDescent;
179 Nlm_Int2 Nlm_stdLeading;
180 Nlm_Int2 Nlm_stdFontHeight;
181 Nlm_Int2 Nlm_stdLineHeight;
182 Nlm_Int2 Nlm_stdCharWidth;
183
184 Nlm_FonT Nlm_systemFont = NULL;
185 Nlm_FonT Nlm_programFont = NULL;
186
187 #define COPY_MODE 1
188 #define MERGE_MODE 2
189 #define INVERT_MODE 3
190 #define ERASE_MODE 4
191
192 static Nlm_Int2 currentMode = COPY_MODE;
193
194 static Nlm_FonT Nlm_fontList = NULL;
195 static Nlm_FonT Nlm_fontInUse = NULL;
196
197 #ifndef WIN_GIF
198 static Nlm_RegioN Nlm_scrollRgn;
199 #endif
200
201 #ifdef WIN_MAC
202 static Nlm_Byte whitePat [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
203 static Nlm_Byte ltGrayPat [] = {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22};
204 static Nlm_Byte grayPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
205 static Nlm_Byte dkGrayPat [] = {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD};
206 static Nlm_Byte blackPat [] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
207
208 static Nlm_Byte dotPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
209 static Nlm_Byte dashPat [] = {0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33};
210 #endif
211
212 #ifdef WIN_MSWIN
213 static DWORD dash_gap[2];
214 static Nlm_Int2 currentPenStyle = PS_SOLID;
215 static Nlm_Int2 currentPenWidth = 1;
216 static void *currentPattern = NULL;
217 static COLORREF prevColor = 12346;
218 static Nlm_Int2 prevPenStyle = -1;
219 static Nlm_Int2 prevPenWidth = -1;
220 static void *prevPattern = NULL;
221 static HDC prevPenHDC = NULL;
222
223 static COLORREF blackColor;
224 static COLORREF redColor;
225 static COLORREF greenColor;
226 static COLORREF blueColor;
227 static COLORREF cyanColor;
228 static COLORREF magentaColor;
229 static COLORREF yellowColor;
230 static COLORREF whiteColor;
231
232 static Nlm_Uint2 blackPat [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
233 static Nlm_Uint2 dkGrayPat [] = {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22};
234 static Nlm_Uint2 grayPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
235 static Nlm_Uint2 ltGrayPat [] = {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD};
236 static Nlm_Uint2 whitePat [] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
237
238 static Nlm_Uint2 dotPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
239 static Nlm_Uint2 dashPat [] = {0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33};
240
241 static HPEN hBlackPen;
242 static HPEN hNullPen;
243 static HPEN hWhitePen;
244 static HBRUSH hBlackBrush;
245 static HBRUSH hDkGrayBrush;
246 static HBRUSH hGrayBrush;
247 static HBRUSH hHollowBrush;
248 static HBRUSH hLtGrayBrush;
249 static HBRUSH hNullBrush;
250 static HBRUSH hWhiteBrush;
251 static HFONT hAnsiFixedFont;
252 static HFONT hAnsiVarFont;
253 static HFONT hDeviceDefaultFont;
254 static HFONT hOemFixedFont;
255 static HFONT hSystemFont;
256 static HFONT hSystemFixedFont;
257 static HFONT hDefaultGuiFont;
258
259 static TEXTMETRIC textMetrics;
260
261 static COLORREF winTextColor;
262 static COLORREF winBkColor;
263
264 #endif
265
266 #ifdef WIN_X
267 static XFontStruct *currentFont;
268 static Pixmap currentPixmap = 0;
269 static Nlm_PoinT currentPoint;
270 static Nlm_Uint4 currentBkColor;
271 static Nlm_Uint4 currentFgColor;
272 static int currentFunction = GXcopy;
273 static int currentFillStyle = FillOpaqueStippled;
274
275 static Nlm_Uint4 blackColor;
276 static Nlm_Uint4 redColor;
277 static Nlm_Uint4 greenColor;
278 static Nlm_Uint4 blueColor;
279 static Nlm_Uint4 cyanColor;
280 static Nlm_Uint4 magentaColor;
281 static Nlm_Uint4 yellowColor;
282 static Nlm_Uint4 whiteColor;
283
284 static XFontStruct fontInfo;
285 static Nlm_Uint1 flip [256];
286
287 static Nlm_RgnTool emptyRgn;
288
289 #define ULTRA_SPARC_X_SERVER_BUG
290 #ifdef ULTRA_SPARC_X_SERVER_BUG
291 /* Attention! This looks as an X-server(not X-client) bug; it means
292 * that all X applications intended to run on an Ultra-SPARC's X-server
293 * must be compiled with this option, no matter where the X-client
294 * was built and run on(e.g. SGI, Linux, etc.)
295 */
296 void Nlm_XSetForeground(Display *display, GC gc, unsigned long color) {
297 if (currentFillStyle == FillOpaqueStippled) {
298 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillSolid);
299 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillOpaqueStippled);
300 }
301 XSetForeground(display, gc, color);
302 }
303 #define XSetForeground Nlm_XSetForeground
304 #endif
305
306 #endif /* WIN_X */
307
308 #if defined(WIN_X) || defined(WIN_GIF)
309 static Nlm_Uint1 whitePat []= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
310 static Nlm_Uint1 ltGrayPat[]= {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22};
311 static Nlm_Uint1 grayPat []= {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
312 static Nlm_Uint1 dkGrayPat[]= {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD};
313 static Nlm_Uint1 blackPat []= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
314 #endif /* WIN_X | WIN_GIF */
315
316 #ifdef WIN_MAC
317 #ifdef WIN_MAC_QUARTZ
318 extern void Nlm_SetPort (CGContextRef ctx)
319 {
320 if (Nlm_PeekQContext()) {
321 CGContextSynchronize(Nlm_PeekQContext());
322 CGContextRelease(Nlm_PeekQContext());
323 Nlm_PopQContext();
324 }
325
326 if (ctx)
327 {
328 Nlm_PushQContext(ctx);
329 CGContextRetain(Nlm_PeekQContext());
330 }
331 // QUARTZ_FIXME: some of this might be useful, somehow
332 // if (grafptr != 0) {
333 // CGAffineTransform textTransform;
334 //
335 // GetPortBounds(grafptr, &pBounds);
336 // pHeight = pBounds.bottom - pBounds.top;
337 // QDBeginCGContext(grafptr, &Nlm_PeekQContext());
338 // CGContextTranslateCTM(Nlm_PeekQContext(), 0, pHeight);
339 // CGContextScaleCTM(Nlm_PeekQContext(), 1.0f, -1.0f);
340 //
341 // textTransform = CGAffineTransformMakeScale(1.0f, -1.0f);
342 // CGContextSetTextMatrix(Nlm_PeekQContext(), textTransform);
343 // } else {
344 // Nlm_PeekQContext() = 0;
345 // }
346 }
347
348 void Nlm_PushPort (CGContextRef ctx)
349 {
350 Nlm_PushQContext (ctx);
351 }
352
353 CGContextRef Nlm_PopPort (void)
354 {
355 return Nlm_PopQContext ();
356 }
357
358 #else
359 extern void Nlm_SetPort (GrafPtr grafptr)
360 {
361 SetPort (grafptr);
362 }
363 #endif
364
365 extern void Nlm_SetPortWindowPort(Nlm_WindowTool wptr)
366 {
367 #ifdef WIN_MAC_QUARTZ
368 Nlm_QWindow = wptr;
369 #else
370 SetPortWindowPort(wptr);
371 #endif
372 }
373
374 #ifdef WIN_MAC_QUARTZ
375 WindowRef Nlm_GetQuartzCurrentWindow (void)
376 {
377 return Nlm_QWindow;
378 }
379
380 void Nlm_SetGraphicNeedsDisplay (Nlm_GraphiC graphic)
381 {
382 HIViewSetNeedsDisplay (HIViewGetRoot (Nlm_ParentWindowPtr (graphic)), 1);
383 }
384 #endif
385
386 #endif
387
388 #ifdef WIN_MSWIN
389 extern void Nlm_SetPort (HWND hwnd, HDC hdc)
390 {
391 Nlm_currentHWnd = hwnd;
392 Nlm_currentHDC = hdc;
393 }
394
395 #endif
396
397 #ifdef WIN_X
398
399 /* for internal Vibrant use only */
400 extern XFontStruct * Nlm_XLoadQueryFont (Display *d, Nlm_CharPtr fDescr, Nlm_Boolean critical)
401 {
402 XFontStruct *f;
403
404 if ((f = XLoadQueryFont(d, fDescr)) == NULL && critical)
405 {
406 fprintf (stderr, "Vibrant: Unable to load critical font <%s>\n", fDescr);
407 exit (1);
408 }
409
410 return f;
411 }
412 #endif
413
414
415 extern Nlm_Boolean Nlm_CreateGIF(Nlm_Int2 width, Nlm_Int2 height, Nlm_Boolean transparent)
416 {
417 #ifdef WIN_GIF
418 gdImage* im = gdImageCreate((int)width, (int)height);
419 if ( im ) {
420 int white_color = gdImageColorAllocate(im, 255, 255, 255);
421 if ( transparent )
422 gdImageColorTransparent(im, white_color);
423 gdImageColorAllocate(im, 0, 0, 0);
424
425 Nlm_SetCurrentGIF(im);
426 return TRUE;
427 }
428 #endif /* WIN_GIF */
429 return FALSE;
430 }
431
432
433 extern Nlm_Boolean Nlm_SaveGIF(FILE* out)
434 {
435 #ifdef WIN_GIF
436 if (Nlm_currentGIF && out) {
437 gdImageGif(Nlm_currentGIF, out);
438 return TRUE;
439 }
440 #endif /* WIN_GIF */
441 return FALSE;
442 }
443
444
445 extern void Nlm_DestroyGIF(void)
446 {
447 #ifdef WIN_GIF
448 gdImage* im = Nlm_SetCurrentGIF(0);
449 if ( im )
450 gdImageDestroy(im);
451 #endif /* WIN_GIF */
452 }
453
454
455 extern struct gdImageStruct* Nlm_SetCurrentGIF(struct gdImageStruct* im)
456 {
457 #ifdef WIN_GIF
458 gdImage* im_prev = Nlm_currentGIF;
459 if (im == im_prev)
460 return im;
461
462 Nlm_curGIFColor = 1;
463 Nlm_curGIFLType = GIF_SOLID;
464 Nlm_curGIFFont = gdFont7X13b;
465 Nlm_curGIFPoint.x = 0;
466 Nlm_curGIFPoint.y = 0;
467 Nlm_currentGIF = im;
468 return im_prev;
469 #else
470 return 0;
471 #endif /* WIN_GIF */
472 }
473
474
475 static void Nlm_SetFontData (Nlm_FonT f, Nlm_FontData * fdata)
476
477 {
478 Nlm_FntPtr fp;
479
480 if (f != NULL && fdata != NULL) {
481 fp = (Nlm_FntPtr) Nlm_HandLock (f);
482 *fp = *fdata;
483 Nlm_HandUnlock (f);
484 }
485 }
486
487 static void Nlm_GetFontData (Nlm_FonT f, Nlm_FontData * fdata)
488
489 {
490 Nlm_FntPtr fp;
491
492 if (f != NULL && fdata != NULL) {
493 fp = (Nlm_FntPtr) Nlm_HandLock (f);
494 *fdata = *fp;
495 Nlm_HandUnlock (f);
496 }
497 }
498
499
500 #ifdef WIN_MSWIN
501 static Nlm_Boolean Nlm_NotAStockPen (HPEN pen)
502 {
503 return (Nlm_Boolean) (pen != hBlackPen && pen != hNullPen && pen != hWhitePen);
504 }
505
506 static Nlm_Boolean Nlm_NotAStockBrush (HBRUSH brush)
507 {
508 return (Nlm_Boolean) (brush != hBlackBrush && brush != hDkGrayBrush &&
509 brush != hGrayBrush && brush != hHollowBrush &&
510 brush != hLtGrayBrush && hNullBrush &&
511 brush != hWhiteBrush);
512 }
513
514 /*
515 static Nlm_Boolean Nlm_NotAStockFont (HFONT font)
516 {
517 return (Nlm_Boolean) (font != hAnsiFixedFont && font != hAnsiVarFont &&
518 font != hDeviceDefaultFont && font != hOemFixedFont &&
519 font != hSystemFont && font != hSystemFixedFont);
520 }
521 */
522 #endif
523
524
525 extern void Nlm_SetPenDash(Nlm_Uint1 offset, Nlm_Uint1 dash, Nlm_Uint1 gap)
526 {
527 if (dash == 0)
528 dash = 1;
529 if (gap == 0)
530 gap = 1;
531
532 #ifdef WIN_X
533 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL)
534 {
535 XGCValues gcv;
536 char dash_gap[2];
537 dash_gap[0] = dash;
538 dash_gap[1] = gap;
539 gcv.line_style = LineOnOffDash;
540 XChangeGC(Nlm_currentXDisplay, Nlm_currentXGC,
541 GCLineStyle, &gcv);
542 XSetDashes(Nlm_currentXDisplay, Nlm_currentXGC,
543 (int)offset, dash_gap, sizeof(dash_gap));
544 }
545
546 #elif defined(WIN32) && defined(WIN_MSWIN)
547 dash_gap[0] = dash;
548 dash_gap[1] = gap;
549
550 if ( Nlm_GetPicWinHDC() ) {
551 Nlm_Dashed(); /* metafile-dumping driver does not support ext.pens */
552 return;
553 }
554
555 {{
556 HPEN newPen, oldPen;
557 LOGBRUSH newBrush;
558
559 newBrush.lbStyle = BS_SOLID;
560 newBrush.lbColor = winTextColor;
561 newBrush.lbHatch = 0;
562 if ((newPen = ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE,
563 1, &newBrush, 2, dash_gap)) == NULL ||
564 (oldPen = SelectObject(Nlm_currentHDC, newPen)) == NULL)
565 {
566 if ( newPen )
567 DeleteObject( newPen );
568 Nlm_Dashed();
569 return;
570 }
571
572 prevColor = winTextColor;
573 if ( Nlm_NotAStockPen( oldPen ) )
574 DeleteObject( oldPen );
575 }}
576
577 #elif defined(WIN_MAC_QUARTZ)
578 {
579 float dashes[2];
580 dashes[0] = (float) dash;
581 dashes[1] = (float) gap;
582 CGContextSetLineDash(Nlm_PeekQContext(), (float) offset, dashes, 2);
583 }
584 #else
585 Nlm_Dashed();
586 #endif
587 }
588
589
590 #ifdef WIN_MAC
591 static void Nlm_ChooseColor (Nlm_Int4 color)
592 {
593 #ifdef WIN_MAC_QUARTZ
594 ASSERT(false);
595 #else
596 ForeColor (color);
597 #endif
598 }
599 #endif
600
601
602 #ifdef WIN_MSWIN
603 static void Nlm_RecreateBrushes (void)
604 {
605 COLORREF color;
606 HBITMAP hBitmap;
607 HBRUSH newBrush;
608 HPEN newPen;
609 HBRUSH oldBrush;
610 HPEN oldPen;
611
612 if (Nlm_currentHDC != NULL) {
613 color = winTextColor;
614 if ( (prevColor != color)||(prevPenStyle != currentPenStyle)||
615 (prevPenWidth != currentPenWidth) ||
616 (prevPenHDC != Nlm_currentHDC) ){
617
618 #ifdef WIN32
619 if (dash_gap[0] != 0) {
620 if (prevColor != winTextColor)
621 Nlm_SetPenDash(0, (Nlm_Uint1)dash_gap[0], (Nlm_Uint1)dash_gap[1]);
622 return;
623 }
624
625 if ( Nlm_GetPicWinHDC() ) /* metafile driver does not support ext.pens */
626 newPen = CreatePen(currentPenStyle, currentPenWidth, color);
627 else {
628 LOGBRUSH brush;
629 brush.lbStyle = BS_SOLID;
630 brush.lbColor = color;
631 brush.lbHatch = 0;
632 newPen = ExtCreatePen(currentPenStyle|PS_GEOMETRIC|PS_ENDCAP_SQUARE,
633 currentPenWidth, &brush, 0, NULL);
634 }
635 #else
636 newPen = CreatePen(currentPenStyle, currentPenWidth, color);
637 #endif /* else!WIN32 */
638
639 if (newPen != NULL) {
640 oldPen = SelectObject (Nlm_currentHDC, newPen);
641 if (oldPen == NULL) {
642 OutputDebugString ("Cannot select pen\n");
643 DeleteObject (newPen);
644 } else {
645 prevColor = color;
646 prevPenStyle = currentPenStyle;
647 prevPenWidth = currentPenWidth;
648 if (Nlm_NotAStockPen (oldPen)) DeleteObject (oldPen);
649 }
650 }
651 }
652 if (currentPattern == NULL) {
653 currentPattern = whitePat;
654 }
655 if ( (currentPattern != prevPattern) ||
656 (prevPenHDC != Nlm_currentHDC) ){
657 hBitmap = CreateBitmap (8, 8, 1, 1, (LPSTR) currentPattern);
658 newBrush = CreatePatternBrush (hBitmap);
659 if (newBrush != NULL) {
660 oldBrush = SelectObject (Nlm_currentHDC, newBrush);
661 if (oldBrush == NULL) {
662 OutputDebugString ("Cannot select brush\n");
663 DeleteObject (newBrush);
664 } else {
665 prevPenHDC = Nlm_currentHDC;
666 prevPattern = currentPattern;
667 if ( Nlm_NotAStockBrush(oldBrush) )
668 DeleteObject (oldBrush);
669 }
670 }
671 DeleteObject (hBitmap);
672 }
673 }
674 }
675
676 static void Nlm_SelectPattern (Nlm_Int2 style, Nlm_Int2 width, void * pat,
677 Nlm_Int1 flags )
678
679 {
680 if ( flags & ATT_PENSTYLE ) currentPenStyle = style;
681 if ( flags & ATT_PENWIDTH ) currentPenWidth = width;
682 if ( flags & ATT_PATTERN ) currentPattern = pat;
683 #ifdef WIN32
684 dash_gap[0] = 0;
685 #endif
686 Nlm_RecreateBrushes ();
687 }
688
689 static void Nlm_ChooseColor (Nlm_Int4 color)
690
691 {
692 if (Nlm_currentHDC != NULL) {
693 SetTextColor (Nlm_currentHDC, color);
694 winTextColor = color;
695 Nlm_RecreateBrushes ();
696 }
697 }
698
699 static Nlm_Boolean Nlm_GetTextMetrics (void)
700
701 {
702 HDC hDC;
703 Nlm_Boolean success;
704
705 success = FALSE;
706 if (Nlm_currentHDC != NULL) {
707 success = (Nlm_Boolean) GetTextMetrics (Nlm_currentHDC, &textMetrics);
708 } else {
709 hDC = CreateIC ("DISPLAY", NULL, NULL, NULL);
710 success = (Nlm_Boolean) GetTextMetrics (hDC, &textMetrics);
711 DeleteDC (hDC);
712 }
713 return success;
714 }
715
716
717 static HBRUSH GetBackgroundBrush (HWND hwnd)
718
719 {
720 #ifndef WIN32
721 return (HBRUSH) GetClassWord (hwnd, GCLP_HBRBACKGROUND);
722 #else
723 return (HBRUSH) GetClassLongPtr (hwnd, GCLP_HBRBACKGROUND);
724 #endif
725 }
726 #endif
727
728 #ifdef WIN_X
729 static void Nlm_SelectPattern (void * pat)
730
731 {
732 if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0) {
733 if (currentPixmap != 0) {
734 XFreePixmap (Nlm_currentXDisplay, currentPixmap);
735 }
736 currentPixmap = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow,
737 (char *) pat, 8, 8);
738 if (currentPixmap != 0 && Nlm_currentXGC != NULL) {
739 XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, currentPixmap);
740 }
741 }
742 }
743
744 static void Nlm_ChooseColor (Nlm_Uint4 color)
745
746 {
747 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
748 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, color);
749 currentFgColor = color;
750 }
751 }
752
753 static Nlm_Boolean Nlm_GetTextMetrics (void)
754
755 {
756 Nlm_Boolean success;
757
758 success = FALSE;
759 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
760 if (currentFont != NULL) {
761 fontInfo = *currentFont;
762 success = TRUE;
763 }
764 }
765 return success;
766 }
767 #endif
768
769
770 #ifdef WIN_MSWIN
771 extern BOOLEAN Nlm_hasBackColor;
772 extern COLORREF Nlm_crBackColor;
773 extern HBRUSH Nlm_hbrWindowBackground;
774 #endif
775
776 #ifdef WIN_MAC_QUARTZ
777 static void Nlm_SelectQuartzColor (Nlm_QuartzColor c)
778 {
779 CGContextSetRGBFillColor (Nlm_PeekQContext(), c.r, c.g, c.b, 1.0);
780 CGContextSetRGBStrokeColor(Nlm_PeekQContext(), c.r, c.g, c.b, 1.0);
781 }
782 #endif
783
784 extern void Nlm_ResetDrawingTools (void)
785 {
786 #ifdef WIN_MAC
787 #ifdef WIN_MAC_QUARTZ
788 if (Nlm_PeekQContext())
789 {
790 CGContextSetLineWidth(Nlm_PeekQContext(), 1.0);
791 CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0);
792 CGContextSetAlpha(Nlm_PeekQContext(), 1.0);
793 Nlm_SelectQuartzColor(Nlm_QuartzForeColor);
794 }
795 #else
796 PenNormal ();
797 PenMode (patCopy);
798 TextMode (srcOr);
799 if (Nlm_hasColorQD) {
800 RGBForeColor (&Nlm_RGBforeColor);
801 RGBBackColor (&Nlm_RGBbackColor);
802 } else {
803 ForeColor (blackColor);
804 BackColor (whiteColor);
805 }
806 #endif
807 #endif
808 #ifdef WIN_MSWIN
809 if (Nlm_currentHDC != NULL) {
810 SetROP2 (Nlm_currentHDC, R2_COPYPEN);
811 SelectObject(Nlm_currentHDC, GetStockObject(SYSTEM_FONT));
812 winTextColor = GetSysColor (COLOR_WINDOWTEXT);
813 winBkColor = Nlm_hasBackColor ?
814 Nlm_crBackColor :
815 GetSysColor (COLOR_WINDOW);
816 SetTextColor (Nlm_currentHDC, winTextColor);
817 SetBkColor (Nlm_currentHDC, winBkColor);
818 SetBkMode (Nlm_currentHDC, TRANSPARENT);
819 Nlm_SelectPattern (PS_SOLID, 1, blackPat,
820 ATT_PENSTYLE|ATT_PENWIDTH|ATT_PATTERN );
821 prevPenHDC = NULL;
822 }
823 #endif
824 #ifdef WIN_X
825 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
826 currentMode = COPY_MODE;
827 currentFunction = GXcopy;
828 currentFillStyle = FillOpaqueStippled;
829 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
830 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
831 if (Nlm_hasColor) {
832 XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, Nlm_XbackColor);
833 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, Nlm_XforeColor);
834 currentBkColor = Nlm_XbackColor;
835 currentFgColor = Nlm_XforeColor;
836 } else {
837 XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, whiteColor);
838 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, blackColor);
839 currentBkColor = whiteColor;
840 currentFgColor = blackColor;
841 }
842 XSetLineAttributes (Nlm_currentXDisplay, Nlm_currentXGC,
843 1, LineSolid, CapProjecting, JoinMiter);
844 Nlm_SelectPattern (blackPat);
845 }
846 #endif
847 #ifdef WIN_GIF
848 Nlm_SelectColor (0,0,0);
849 Nlm_curGIFLType = GIF_SOLID;
850 Nlm_curGIFFont = gdFont7X13b;
851 gdImageSelectPattern(Nlm_currentGIF, blackPat);
852 #endif
853 currentMode = COPY_MODE;
854 }
855
856 /* The following functions:
857 * Local__PointToolToPoinT
858 * Local__PoinTToPointTool
859 * Local__RectToolToRecT
860 * Local__RecTToRectTool
861 * are the local versions of relevant global Nlm_... functions
862 * declared in "vibincld.h" and defined in "vibutils.c"
863 */
864
865 #ifdef WIN_MAC
866 static void Local__PointToolToPoinT(Nlm_PointTool src, Nlm_PointPtr dst)
867 {
868 if ( !dst )
869 return;
870
871 dst->x = src.h;
872 dst->y = src.v;
873 }
874 #endif /* WIN_MAC */
875
876 #ifndef WIN_GIF
877 static void Local__PoinTToPointTool(Nlm_PoinT src, Nlm_PointTool PNTR dst)
878 {
879 if ( !dst )
880 return;
881
882 #ifdef WIN_MAC
883 dst->h = src.x;
884 dst->v = src.y;
885 #endif
886 #if defined(WIN_MSWIN) || defined(WIN_X)
887 dst->x = src.x;
888 dst->y = src.y;
889 #endif
890 }
891
892
893 static void Local__RectToolToRecT(Nlm_RectTool PNTR src, Nlm_RectPtr dst)
894 {
895 if (!dst || !src)
896 return;
897
898 #if defined(WIN_MAC) || defined(WIN_MSWIN)
899 dst->left = (Nlm_Int2)src->left;
900 dst->top = (Nlm_Int2)src->top;
901 dst->right = (Nlm_Int2)src->right;
902 dst->bottom = (Nlm_Int2)src->bottom;
903 #endif
904 #ifdef WIN_X
905 dst->left = src->x;
906 dst->top = src->y;
907 dst->right = src->x + src->width;
908 dst->bottom = src->y + src->height;
909 #endif
910 }
911 #endif /* !WIN_GIF */
912
913 static void Local__RecTToRectTool(Nlm_RectPtr src, Nlm_RectTool PNTR dst)
914 {
915 if (!dst || !src)
916 return;
917
918 #if defined(WIN_MAC) || defined(WIN_MSWIN) || defined(WIN_GIF)
919 dst->left = MIN(src->left, src->right );
920 dst->top = MIN(src->top, src->bottom);
921 dst->right = MAX(src->left, src->right );
922 dst->bottom = MAX(src->top, src->bottom);
923 #endif
924 #ifdef WIN_X
925 dst->x = MIN(src->left, src->right);
926 dst->y = MIN(src->top, src->bottom);
927 dst->width = ABS(src->right - src->left);
928 dst->height = ABS(src->bottom - src->top);
929 #endif
930 }
931
932
933 extern void Nlm_CopyMode (void)
934 {
935 #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)
936 PenMode (patCopy);
937 TextMode (srcOr);
938 #endif
939 #ifdef WIN_MSWIN
940 if (Nlm_currentHDC != NULL) {
941 SetROP2 (Nlm_currentHDC, R2_COPYPEN);
942 }
943 #endif
944 #ifdef WIN_X
945 currentFunction = GXcopy;
946 currentFillStyle = FillOpaqueStippled;
947 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
948 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
949 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
950 }
951 #endif
952 currentMode = COPY_MODE;
953 }
954
955 extern void Nlm_MergeMode (void)
956 {
957 #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)
958 PenMode (patOr);
959 TextMode (srcOr);
960 #endif
961 #ifdef WIN_MSWIN
962 if (Nlm_currentHDC != NULL) {
963 SetROP2 (Nlm_currentHDC, R2_MASKPEN);
964 }
965 #endif
966 #ifdef WIN_X
967 if (Nlm_hasColor) {
968 currentFunction = GXand;
969 } else {
970 currentFunction = GXor;
971 }
972 currentFillStyle = FillStippled;
973 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
974 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
975 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
976 }
977 #endif
978 currentMode = MERGE_MODE;
979 }
980
981 extern void Nlm_InvertMode (void)
982 {
983 #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)
984 PenMode (patXor);
985 TextMode (srcXor);
986 #endif
987 #ifdef WIN_MSWIN
988 if (Nlm_currentHDC != NULL) {
989 SetROP2 (Nlm_currentHDC, R2_NOTXORPEN);
990 }
991 #endif
992 #ifdef WIN_X
993 if (Nlm_hasColor) {
994 currentFunction = GXequiv;
995 } else {
996 currentFunction = GXinvert;
997 }
998 currentFillStyle = FillStippled;
999 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
1000 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
1001 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
1002 }
1003 #endif
1004 currentMode = INVERT_MODE;
1005 }
1006
1007 extern void Nlm_EraseMode (void)
1008 {
1009 #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)
1010 PenMode (patBic);
1011 TextMode (srcBic);
1012 #endif
1013 #ifdef WIN_MSWIN
1014 if (Nlm_currentHDC != NULL) {
1015 SetROP2 (Nlm_currentHDC, R2_MERGENOTPEN);
1016 }
1017 #endif
1018 #ifdef WIN_X
1019 if (Nlm_hasColor) {
1020 currentFunction = GXorInverted;
1021 } else {
1022 currentFunction = GXand;
1023 }
1024 currentFillStyle = FillStippled;
1025 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
1026 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
1027 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
1028 }
1029 #endif
1030 currentMode = ERASE_MODE;
1031 }
1032
1033 extern void Nlm_Black (void)
1034
1035 {
1036 #ifdef WIN_MAC
1037 if (Nlm_hasColorQD) {
1038 Nlm_SelectColor (0, 0, 0);
1039 } else {
1040 Nlm_ChooseColor (blackColor);
1041 }
1042 #endif
1043 #ifdef WIN_MSWIN
1044 Nlm_ChooseColor (blackColor);
1045 #endif
1046 #ifdef WIN_X
1047 Nlm_ChooseColor (blackColor);
1048 #endif
1049 #ifdef WIN_GIF
1050 Nlm_SelectColor (0, 0, 0);
1051 #endif
1052 }
1053
1054 extern void Nlm_Red (void)
1055
1056 {
1057 #ifdef WIN_MAC
1058 if (Nlm_hasColorQD) {
1059 Nlm_SelectColor (255, 0, 0);
1060 } else {
1061 Nlm_ChooseColor (redColor);
1062 }
1063 #endif
1064 #ifdef WIN_MSWIN
1065 Nlm_ChooseColor (redColor);
1066 #endif
1067 #ifdef WIN_X
1068 Nlm_ChooseColor (redColor);
1069 #endif
1070 #ifdef WIN_GIF
1071 Nlm_SelectColor (255, 0, 0);
1072 #endif
1073 }
1074
1075 extern void Nlm_Green (void)
1076
1077 {
1078 #ifdef WIN_MAC
1079 if (Nlm_hasColorQD) {
1080 Nlm_SelectColor (0, 255, 0);
1081 } else {
1082 Nlm_ChooseColor (greenColor);
1083 }
1084 #endif
1085 #ifdef WIN_MSWIN
1086 Nlm_ChooseColor (greenColor);
1087 #endif
1088 #ifdef WIN_X
1089 Nlm_ChooseColor (greenColor);
1090 #endif
1091 #ifdef WIN_GIF
1092 Nlm_SelectColor (0, 255, 0);
1093 #endif
1094 }
1095
1096 extern void Nlm_Blue (void)
1097
1098 {
1099 #ifdef WIN_MAC
1100 if (Nlm_hasColorQD) {
1101 Nlm_SelectColor (0, 0, 255);
1102 } else {
1103 Nlm_ChooseColor (blueColor);
1104 }
1105 #endif
1106 #ifdef WIN_MSWIN
1107 Nlm_ChooseColor (blueColor);
1108 #endif
1109 #ifdef WIN_X
1110 Nlm_ChooseColor (blueColor);
1111 #endif
1112 #ifdef WIN_GIF
1113 Nlm_SelectColor (0, 0, 255);
1114 #endif
1115 }
1116
1117 extern void Nlm_Cyan (void)
1118
1119 {
1120 #ifdef WIN_MAC
1121 if (Nlm_hasColorQD) {
1122 Nlm_SelectColor (0, 255, 255);
1123 } else {
1124 Nlm_ChooseColor (cyanColor);
1125 }
1126 #endif
1127 #ifdef WIN_MSWIN
1128 Nlm_ChooseColor (cyanColor);
1129 #endif
1130 #ifdef WIN_X
1131 Nlm_ChooseColor (cyanColor);
1132 #endif
1133 #ifdef WIN_GIF
1134 Nlm_SelectColor (0, 255, 255);
1135 #endif
1136 }
1137
1138 extern void Nlm_Magenta (void)
1139
1140 {
1141 #ifdef WIN_MAC
1142 if (Nlm_hasColorQD) {
1143 Nlm_SelectColor (255, 0, 255);
1144 } else {
1145 Nlm_ChooseColor (magentaColor);
1146 }
1147 #endif
1148 #ifdef WIN_MSWIN
1149 Nlm_ChooseColor (magentaColor);
1150 #endif
1151 #ifdef WIN_X
1152 Nlm_ChooseColor (magentaColor);
1153 #endif
1154 #ifdef WIN_GIF
1155 Nlm_SelectColor (255, 0, 255);
1156 #endif
1157 }
1158
1159 extern void Nlm_Yellow (void)
1160
1161 {
1162 #ifdef WIN_MAC
1163 if (Nlm_hasColorQD) {
1164 Nlm_SelectColor (255, 255, 0);
1165 } else {
1166 Nlm_ChooseColor (yellowColor);
1167 }
1168 #endif
1169 #ifdef WIN_MSWIN
1170 Nlm_ChooseColor (yellowColor);
1171 #endif
1172 #ifdef WIN_X
1173 Nlm_ChooseColor (yellowColor);
1174 #endif
1175 #ifdef WIN_GIF
1176 Nlm_SelectColor (255, 255, 0);
1177 #endif
1178 }
1179
1180 extern void Nlm_White (void)
1181
1182 {
1183 #ifdef WIN_MAC
1184 if (Nlm_hasColorQD) {
1185 Nlm_SelectColor (255, 255, 255);
1186 } else {
1187 Nlm_ChooseColor (whiteColor);
1188 }
1189 #endif
1190 #ifdef WIN_MSWIN
1191 Nlm_ChooseColor (whiteColor);
1192 #endif
1193 #ifdef WIN_X
1194 Nlm_ChooseColor (whiteColor);
1195 #endif
1196 #ifdef WIN_GIF
1197 Nlm_SelectColor (255, 255, 255);
1198 #endif
1199 }
1200
1201 extern void Nlm_Gray (void)
1202
1203 {
1204 Nlm_SelectColor (127, 127, 127);
1205 }
1206
1207 extern void Nlm_LtGray (void)
1208
1209 {
1210 Nlm_SelectColor (191, 191, 191);
1211 }
1212
1213 extern void Nlm_DkGray (void)
1214
1215 {
1216 Nlm_SelectColor (63, 63, 63);
1217 }
1218
1219
1220 #ifdef WIN_X
1221 #define COLOR_HASH(lrgb) (lrgb % 251) /* 251 is the largest prime less than 256 */
1222 #define RGB_2_LRGB(red, green, blue) ((red) | (green << 8) | (blue << 16))
1223 #define LRGB_RED(lrgb) ((lrgb) & 0xFF)
1224 #define LRGB_GREEN(lrgb) ((lrgb >> 8) & 0xFF)
1225 #define LRGB_BLUE(lrgb) (((lrgb >> 16) & 0xFF)
1226
1227 /* note: without a lock, the same color may appear multiple times in the hash table (not the end of the world) */
1228 typedef struct nlm_colorHashBucket {
1229 Nlm_Uint4 lrgb;
1230 XColor xcolor;
1231 struct nlm_colorHashBucket PNTR next;
1232 } Nlm_ColorHashBucket, PNTR Nlm_ColorHashBucketPtr;
1233 #endif
1234
1235 extern void Nlm_SelectColor (Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
1236 {
1237 #ifdef WIN_MAC
1238 #ifdef WIN_MAC_QUARTZ
1239 Nlm_QuartzForeColor.r = red/255.0;
1240 Nlm_QuartzForeColor.g = green/255.0;
1241 Nlm_QuartzForeColor.b = blue/255.0;
1242 Nlm_SelectQuartzColor (Nlm_QuartzForeColor);
1243 #else
1244 RGBColor color;
1245 Nlm_Uint2 bl;
1246 Nlm_Uint2 gn;
1247 Nlm_Uint2 rd;
1248
1249 if (Nlm_hasColorQD) {
1250 rd = (Nlm_Uint2) red;
1251 gn = (Nlm_Uint2) green;
1252 bl = (Nlm_Uint2) blue;
1253 color.red = rd << 8 | rd;
1254 color.green = gn << 8 | gn;
1255 color.blue = bl << 8 | bl;
1256 RGBForeColor (&color);
1257 } else if ((int) red + (int) green + (int) blue < 192) {
1258 Nlm_ChooseColor (blackColor);
1259 } else {
1260 Nlm_ChooseColor (whiteColor);
1261 }
1262 #endif
1263 #endif
1264 #ifdef WIN_MSWIN
1265 COLORREF color;
1266 Nlm_Uint2 bl;
1267 Nlm_Uint2 gn;
1268 Nlm_Uint2 rd;
1269
1270 rd = (Nlm_Uint2) red;
1271 gn = (Nlm_Uint2) green;
1272 bl = (Nlm_Uint2) blue;
1273 color = RGB (rd, gn, bl);
1274 Nlm_ChooseColor (color);
1275 #endif
1276 #ifdef WIN_X
1277 XColor xcolor;
1278 Nlm_Uint1 hash;
1279 Nlm_Uint4 lrgb;
1280 Nlm_ColorHashBucketPtr CHBP, tail;
1281 static Nlm_ColorHashBucketPtr ColorHashBuckets [256] = {NULL};
1282
1283 lrgb = RGB_2_LRGB (red, green, blue);
1284 hash = COLOR_HASH (lrgb);
1285 tail = NULL;
1286 if (ColorHashBuckets [hash] != NULL) {
1287 for (CHBP = ColorHashBuckets [hash]; CHBP != NULL; CHBP = CHBP->next) {
1288 if (CHBP->lrgb == lrgb) {
1289 xcolor = CHBP->xcolor;
1290 Nlm_ChooseColor (xcolor.pixel);
1291 return;
1292 }
1293 tail = CHBP;
1294 }
1295 }
1296
1297 Nlm_XAllocColor(&xcolor, Nlm_VibrantDefaultColormap(), red, green, blue);
1298 Nlm_ChooseColor(xcolor.pixel );
1299
1300 if (tail != NULL) {
1301 tail->next = MemNew (sizeof (Nlm_ColorHashBucket));
1302 tail = tail->next;
1303 } else {
1304 tail = ColorHashBuckets [hash] = MemNew (sizeof (Nlm_ColorHashBucket));
1305 }
1306 if (tail != NULL) {
1307 tail->lrgb = lrgb;
1308 tail->xcolor = xcolor;
1309 }
1310
1311 #endif
1312 #ifdef WIN_GIF
1313 Nlm_curGIFColor = (int)Nlm_GetColorRGB ( red, green, blue );
1314 #endif
1315 }
1316
1317 #ifdef WIN_X
1318 #undef COLOR_HASH
1319 #undef RGB_2_LRGB
1320 #undef LRGB_RED
1321 #undef LRGB_GREEN
1322 #undef LRGB_BLUE
1323 #endif
1324
1325
1326 extern Nlm_Uint4 Nlm_GetColorRGB (Nlm_Uint1 red, Nlm_Uint1 green,
1327 Nlm_Uint1 blue)
1328 {
1329 #ifdef WIN_MAC
1330 Nlm_Uint1 colors [4];
1331
1332 colors [0] = 0;
1333 colors [1] = red;
1334 colors [2] = green;
1335 colors [3] = blue;
1336 return *((Nlm_Int4Ptr) colors);
1337 #endif
1338 #ifdef WIN_MSWIN
1339 Nlm_Uint2 bl;
1340 Nlm_Uint2 gn;
1341 Nlm_Uint2 rd;
1342
1343 rd = (Nlm_Uint2) red;
1344 gn = (Nlm_Uint2) green;
1345 bl = (Nlm_Uint2) blue;
1346 return (Nlm_Uint4)(RGB(rd, gn, bl));
1347 #endif
1348 #ifdef WIN_X
1349 XColor xcolor;
1350 Nlm_XAllocColor(&xcolor, Nlm_VibrantDefaultColormap(), red, green, blue);
1351 return xcolor.pixel;
1352 #endif
1353 #ifdef WIN_GIF
1354 int i;
1355
1356 if ( Nlm_currentGIF != NULL ){
1357 i = gdImageColorExact ( Nlm_currentGIF, (int)red, (int)green, (int)blue );
1358 if ( i == -1 ){
1359 i = gdImageColorAllocate ( Nlm_currentGIF, (int)red, (int)green,
1360 (int)blue );
1361 if ( i == -1 ){
1362 i = gdImageColorClosest ( Nlm_currentGIF, (int)red, (int)green,
1363 (int)blue );
1364 }
1365 }
1366 }
1367 return (Nlm_Uint4)i;
1368 #endif
1369 }
1370
1371
1372 extern Nlm_Uint4 Nlm_GetColor (void)
1373 {
1374 #ifdef WIN_MAC
1375 Nlm_Uint1 colors [4] = { 0 };
1376 Nlm_Int4 fgColor;
1377 #ifdef WIN_MAC_QUARTZ
1378 colors[0] = 0;
1379 colors[1] = Nlm_QuartzForeColor.r * 255.0;
1380 colors[2] = Nlm_QuartzForeColor.g * 255.0;
1381 colors[3] = Nlm_QuartzForeColor.b * 255.0;
1382 #else
1383 RGBColor foreColor;
1384
1385 if (Nlm_hasColorQD) {
1386 GetForeColor (&foreColor);
1387 colors [0] = 0;
1388 colors [1] = (Nlm_Uint1) (foreColor.red >> 8);
1389 colors [2] = (Nlm_Uint1) (foreColor.green >> 8);
1390 colors [3] = (Nlm_Uint1) (foreColor.blue >> 8);
1391 fgColor = *((Nlm_Int4Ptr) colors);
1392 }
1393 #endif
1394 fgColor = (colors[0] << 24) | (colors[1] << 16) | (colors[2] << 8) | colors[3];
1395 #if !defined( WIN_MAC_QUARTZ ) && !defined( OPAQUE_TOOLBOX_STRUCTS )
1396 if (!Nlm_hasColorQD) {
1397 GrafPtr port;
1398 GetPort (&port);
1399 if (port != NULL) {
1400 fgColor = port->fgColor;
1401 }
1402 }
1403 #endif
1404 return (Nlm_Uint4) fgColor;
1405 #endif
1406 #ifdef WIN_MSWIN
1407 Nlm_Int4 fgColor;
1408
1409 fgColor = 0;
1410 if (Nlm_currentHDC != NULL) {
1411 fgColor = GetTextColor (Nlm_currentHDC);
1412 }
1413 return (Nlm_Uint4) fgColor;
1414 #endif
1415 #ifdef WIN_X
1416 return currentFgColor;
1417 #endif
1418 #ifdef WIN_GIF
1419 return (Nlm_Uint4)Nlm_curGIFColor;
1420 #endif
1421 }
1422
1423 /*
1424 Used to set the color of text or foreground color. This function is the same
1425 as Nlm_SetColor except on Windows, where it does not call the
1426 extremely expensive Nlm_RecreateBrushes()
1427 */
1428
1429 extern void Nlm_SetColorEx (Nlm_Uint4 color)
1430 {
1431 #ifdef WIN_MAC
1432 Nlm_SetColor (color);
1433 #endif
1434 #ifdef WIN_MSWIN
1435 if (Nlm_currentHDC != NULL) {
1436 SetTextColor (Nlm_currentHDC, (Nlm_Int4) color);
1437 winTextColor = color;
1438 }
1439 #endif
1440 #ifdef WIN_X
1441 Nlm_SetColor (color);
1442 #endif
1443 }
1444
1445
1446 extern void Nlm_SetColor (Nlm_Uint4 color)
1447
1448 {
1449 #ifdef WIN_MAC
1450 Nlm_Uint2 bl;
1451 Nlm_Uint2 gn;
1452 Nlm_Uint2 rd;
1453 Nlm_Uint1 colors [4];
1454 RGBColor foreColor;
1455 GrafPtr port;
1456
1457 if (Nlm_hasColorQD) {
1458 *((Nlm_Int4Ptr) colors) = color;
1459 rd = (Nlm_Uint2) colors [1];
1460 gn = (Nlm_Uint2) colors [2];
1461 bl = (Nlm_Uint2) colors [3];
1462 #ifdef WIN_MAC_QUARTZ
1463 Nlm_SelectColor(rd, gn, bl);
1464 #else
1465 foreColor.red = rd << 8 | rd;
1466 foreColor.green = gn << 8 | gn;
1467 foreColor.blue = bl << 8 | bl;
1468 RGBForeColor (&foreColor);
1469 } else {
1470 GetPort (&port);
1471 if (port != NULL) {
1472 ForeColor ((Nlm_Int4) color);
1473 }
1474 #endif
1475 }
1476 #endif
1477 #ifdef WIN_MSWIN
1478 if (Nlm_currentHDC != NULL) {
1479 SetTextColor (Nlm_currentHDC, (Nlm_Int4) color);
1480 winTextColor = color;
1481 Nlm_RecreateBrushes ();
1482 }
1483 #endif
1484 #ifdef WIN_X
1485 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, color);
1486 currentFgColor = color;
1487 #endif
1488 #ifdef WIN_GIF
1489 Nlm_curGIFColor = (int)color;
1490 #endif
1491 }
1492
1493 extern void Nlm_InvertColors (void)
1494
1495 {
1496 #ifdef WIN_MAC
1497 #ifdef WIN_MAC_QUARTZ
1498 Nlm_QuartzColor temp = Nlm_QuartzForeColor;
1499 Nlm_QuartzForeColor = Nlm_QuartzBackColor;
1500 Nlm_QuartzBackColor = temp;
1501
1502 Nlm_SelectQuartzColor (Nlm_QuartzForeColor);
1503 #else
1504 RGBColor backColor;
1505 RGBColor foreColor;
1506
1507 if (Nlm_hasColorQD) {
1508 GetForeColor (&foreColor);
1509 GetBackColor (&backColor);
1510 RGBForeColor (&backColor);
1511 RGBBackColor (&foreColor);
1512 #if !OPAQUE_TOOLBOX_STRUCTS
1513 } else {
1514 Nlm_Int4 bkColor;
1515 Nlm_Int4 fgColor;
1516 GrafPtr port;
1517 GetPort (&port);
1518 if (port != NULL) {
1519 fgColor = port->fgColor;
1520 bkColor = port->bkColor;
1521 ForeColor (bkColor);
1522 BackColor (fgColor);
1523 #endif
1524 }
1525 #endif
1526 #endif
1527 #ifdef WIN_MSWIN
1528 Nlm_Int4 bkColor;
1529 Nlm_Int4 fgColor;
1530
1531 if (Nlm_currentHDC != NULL) {
1532 fgColor = GetTextColor (Nlm_currentHDC);
1533 bkColor = GetBkColor (Nlm_currentHDC);
1534 SetTextColor (Nlm_currentHDC, bkColor);
1535 winTextColor = bkColor;
1536 SetBkColor (Nlm_currentHDC, fgColor);
1537 winBkColor = fgColor;
1538 Nlm_RecreateBrushes ();
1539 }
1540 #endif
1541 #ifdef WIN_X
1542 Nlm_Uint4 newBkColor;
1543 Nlm_Uint4 newFgColor;
1544
1545 newBkColor = currentFgColor;
1546 newFgColor = currentBkColor;
1547 XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, newBkColor);
1548 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, newFgColor);
1549 currentBkColor = newBkColor;
1550 currentFgColor = newFgColor;
1551 #endif
1552 #ifdef WIN_GIF
1553 #endif
1554 }
1555
1556 extern void Nlm_DecodeColor (Nlm_Uint4 color, Nlm_Uint1Ptr red,
1557 Nlm_Uint1Ptr green, Nlm_Uint1Ptr blue)
1558
1559 {
1560 #ifdef WIN_MAC
1561 Nlm_Uint1Ptr colors;
1562 Nlm_Uint1 bl;
1563 Nlm_Uint1 gn;
1564 Nlm_Uint1 rd;
1565
1566 rd = 0;
1567 gn = 0;
1568 bl = 0;
1569 if (Nlm_hasColorQD) {
1570 colors = (Nlm_Uint1Ptr) (&color);
1571 rd = (Nlm_Uint1) colors [1];
1572 gn = (Nlm_Uint1) colors [2];
1573 bl = (Nlm_Uint1) colors [3];
1574 } else if (color == whiteColor) {
1575 rd = 255;
1576 gn = 255;
1577 bl = 255;
1578 }
1579 if (red != NULL) {
1580 *red = (Nlm_Uint1) rd;
1581 }
1582 if (green != NULL) {
1583 *green = (Nlm_Uint1) gn;
1584 }
1585 if (blue != NULL) {
1586 *blue = (Nlm_Uint1) bl;
1587 }
1588 #endif
1589 #ifdef WIN_MSWIN
1590 Nlm_Uint1 bl;
1591 Nlm_Uint1 gn;
1592 Nlm_Uint1 rd;
1593
1594 rd = GetRValue (color);
1595 gn = GetGValue (color);
1596 bl = GetBValue (color);
1597 if (red != NULL) {
1598 *red = (Nlm_Uint1) rd;
1599 }
1600 if (green != NULL) {
1601 *green = (Nlm_Uint1) gn;
1602 }
1603 if (blue != NULL) {
1604 *blue = (Nlm_Uint1) bl;
1605 }
1606 #endif
1607 #ifdef WIN_X
1608 Nlm_Uint2 bl;
1609 Nlm_Uint2 gn;
1610 Nlm_Uint2 rd;
1611 XColor xcolor;
1612
1613 rd = 0;
1614 gn = 0;
1615 bl = 0;
1616 if (Nlm_hasColor) {
1617 xcolor.pixel = color;
1618 if (Nlm_currentXDisplay != NULL) {
1619 XQueryColor(Nlm_currentXDisplay, Nlm_VibrantDefaultColormap(), &xcolor);
1620 rd = xcolor.red >> 8;
1621 gn = xcolor.green >> 8;
1622 bl = xcolor.blue >> 8;
1623 }
1624 } else if (color == whiteColor) {
1625 rd = 255;
1626 gn = 255;
1627 bl = 255;
1628 }
1629 if (red != NULL) {
1630 *red = (Nlm_Uint1) rd;
1631 }
1632 if (green != NULL) {
1633 *green = (Nlm_Uint1) gn;
1634 }
1635 if (blue != NULL) {
1636 *blue = (Nlm_Uint1) bl;
1637 }
1638 #endif
1639 #ifdef WIN_GIF
1640 #endif
1641 }
1642
1643 extern void Nlm_Dark (void)
1644 {
1645 #ifdef WIN_MAC_QUARTZ
1646 CGContextSetGrayFillColor (Nlm_PeekQContext(), .25, 1.0);
1647 CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .25, 1.0);
1648 #elif defined(WIN_MAC)
1649 PenPat ((ConstPatternParam) dkGrayPat);
1650 #endif
1651 #ifdef WIN_MSWIN
1652 Nlm_SelectPattern (PS_SOLID, 1, dkGrayPat, ATT_PATTERN );
1653 #endif
1654 #ifdef WIN_X
1655 Nlm_SelectPattern (dkGrayPat);
1656 #endif
1657 #ifdef WIN_GIF
1658 gdImageSelectPattern(Nlm_currentGIF, dkGrayPat);
1659 #endif
1660 }
1661
1662 extern void Nlm_Medium (void)
1663 {
1664 #ifdef WIN_MAC_QUARTZ
1665 CGContextSetGrayFillColor (Nlm_PeekQContext(), .5, 1.0);
1666 CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .5, 1.0);
1667 #elif defined(WIN_MAC)
1668 PenPat ((ConstPatternParam) grayPat);
1669 #endif
1670 #ifdef WIN_MSWIN
1671 Nlm_SelectPattern (PS_SOLID, 1, grayPat, ATT_PATTERN );
1672 #endif
1673 #ifdef WIN_X
1674 Nlm_SelectPattern (grayPat);
1675 #endif
1676 #ifdef WIN_GIF
1677 gdImageSelectPattern(Nlm_currentGIF, grayPat);
1678 #endif
1679 }
1680
1681 extern void Nlm_Light (void)
1682 {
1683 #ifdef WIN_MAC_QUARTZ
1684 CGContextSetGrayFillColor (Nlm_PeekQContext(), .75, 1.0);
1685 CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .75, 1.0);
1686 #elif defined(WIN_MAC)
1687 PenPat ((ConstPatternParam) ltGrayPat);
1688 #endif
1689 #ifdef WIN_MSWIN
1690 Nlm_SelectPattern (PS_SOLID, 1, ltGrayPat, ATT_PATTERN);
1691 #endif
1692 #ifdef WIN_X
1693 Nlm_SelectPattern (ltGrayPat);
1694 #endif
1695 #ifdef WIN_GIF
1696 gdImageSelectPattern(Nlm_currentGIF, ltGrayPat);
1697 #endif
1698 }
1699
1700 extern void Nlm_Empty (void)
1701 {
1702 #ifdef WIN_MAC
1703 #ifdef WIN_MAC_QUARTZ
1704 CGContextSetGrayFillColor (Nlm_PeekQContext(), 1.0, 1.0);
1705 CGContextSetGrayStrokeColor(Nlm_PeekQContext(), 1.0, 1.0);
1706 #else
1707 PenPat ((ConstPatternParam) whitePat);
1708 #endif
1709 #endif
1710 #ifdef WIN_MSWIN
1711 Nlm_SelectPattern (PS_SOLID, 1, whitePat, ATT_PATTERN);
1712 #endif
1713 #ifdef WIN_X
1714 Nlm_SelectPattern (whitePat);
1715 #endif
1716 #ifdef WIN_GIF
1717 gdImageSelectPattern(Nlm_currentGIF, whitePat);
1718 #endif
1719 }
1720
1721 extern void Nlm_SetPenPattern (Nlm_VoidPtr pattern)
1722 {
1723 #ifdef WIN_MAC
1724 Nlm_Int2 i;
1725 #ifdef WIN_MAC_QUARTZ
1726 float pat[8];
1727 #else
1728 Nlm_Byte pat [8];
1729 #endif
1730 Nlm_BytePtr ptr;
1731 #endif
1732 #ifdef WIN_MSWIN
1733 Nlm_Int2 i;
1734 Nlm_Uint2 pat [8];
1735 Nlm_Uint1Ptr ptr;
1736 Nlm_Uint1Ptr q;
1737 #endif
1738 #ifdef WIN_X
1739 Nlm_Int2 i;
1740 Nlm_Uint1 pat [8];
1741 Nlm_Uint1Ptr ptr;
1742 Nlm_Uint1Ptr q;
1743 #endif
1744
1745 if (pattern != NULL) {
1746 #ifdef WIN_MAC
1747 ptr = (Nlm_BytePtr) pattern;
1748 for (i = 0; i < 8; i++) {
1749 pat [i] = *ptr;
1750 ptr++;
1751 }
1752 #ifdef WIN_MAC_QUARTZ
1753 CGContextSetLineDash(Nlm_PeekQContext(), 0, pat, 8);
1754 #else
1755 PenPat ((ConstPatternParam) pat);
1756 #endif
1757 #endif
1758 #ifdef WIN_MSWIN
1759 ptr = (Nlm_Uint1Ptr) pattern;
1760 q = (Nlm_Uint1Ptr) pat;
1761 for (i = 0; i < 8; i++) {
1762 *q = (Nlm_Uint1) ~(*ptr);
1763 ptr++;
1764 q++;
1765 *q = 0;
1766 q++;
1767 }
1768 Nlm_SelectPattern (PS_SOLID, 1, pat, ATT_PATTERN);
1769 #endif
1770 #ifdef WIN_X
1771 ptr = (Nlm_Uint1Ptr) pattern;
1772 q = (Nlm_Uint1Ptr) pat;
1773 for (i = 0; i < 8; i++) {
1774 *q = flip [*ptr];
1775 ptr++;
1776 q++;
1777 }
1778 Nlm_SelectPattern (pat);
1779 #endif
1780 #ifdef WIN_GIF
1781 gdImageSelectPattern(Nlm_currentGIF, (const unsigned char*)pattern);
1782 #endif
1783 }
1784 }
1785
1786 extern void Nlm_Solid (void)
1787 { /* Reset *both* line stile and drawing pattern to SOLID */
1788 #ifdef WIN_MAC_QUARTZ
1789 CGContextSetGrayFillColor (Nlm_PeekQContext(), 0.0, 1.0);
1790 CGContextSetGrayStrokeColor(Nlm_PeekQContext(), 0.0, 1.0);
1791 CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0);
1792 #elif defined(WIN_MAC)
1793 PenPat ((ConstPatternParam) blackPat);
1794 #endif
1795 #ifdef WIN_MSWIN
1796 Nlm_SelectPattern (PS_SOLID, 1, blackPat, ATT_PATTERN|ATT_PENSTYLE );
1797 #endif
1798 #ifdef WIN_X
1799 Nlm_SelectPattern( blackPat );
1800 if (Nlm_currentXDisplay && Nlm_currentXGC) {
1801 XGCValues values;
1802 values.line_style = LineSolid;
1803 XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values);
1804 }
1805 #endif
1806 #ifdef WIN_GIF
1807 Nlm_SetPenPattern( blackPat );
1808 Nlm_curGIFLType = GIF_SOLID;
1809 #endif
1810 }
1811
1812 extern void Nlm_Dotted (void)
1813 {
1814 #ifdef WIN_MAC_QUARTZ
1815 float dashes[] = { 1.0, 1.0 };
1816 CGContextSetLineDash(Nlm_PeekQContext(), 0, dashes, 2);
1817 #elif defined(WIN_MAC)
1818 PenPat ((ConstPatternParam) dotPat);
1819 #endif
1820 #ifdef WIN_MSWIN
1821 Nlm_SelectPattern (PS_DOT, 1, dotPat, ATT_PENSTYLE|ATT_PATTERN);
1822 #endif
1823 #ifdef WIN_X
1824 if (Nlm_currentXDisplay && Nlm_currentXGC) {
1825 XGCValues values;
1826 values.line_style = LineOnOffDash;
1827 XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values);
1828 }
1829 #endif
1830 #ifdef WIN_GIF
1831 Nlm_curGIFLType = GIF_DASHED;
1832 #endif
1833 }
1834
1835 extern void Nlm_Dashed (void)
1836 {
1837 #ifdef WIN_MAC_QUARTZ
1838 float dashes[] = { 3.0, 1.0 };
1839 CGContextSetLineDash(Nlm_PeekQContext(), 0, dashes, 2);
1840 #elif defined(WIN_MAC)
1841 PenPat ((ConstPatternParam) dashPat);
1842 #endif
1843 #ifdef WIN_MSWIN
1844 Nlm_SelectPattern (PS_DASH, 1, dashPat, ATT_PENSTYLE|ATT_PATTERN);
1845 #endif
1846 #ifdef WIN_X
1847 if (Nlm_currentXDisplay && Nlm_currentXGC) {
1848 XGCValues values;
1849 values.line_style = LineOnOffDash;
1850 XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values);
1851 }
1852 #endif
1853 #ifdef WIN_GIF
1854 Nlm_curGIFLType = GIF_DASHED;
1855 #endif
1856 }
1857
1858 extern void Nlm_WidePen (Nlm_Int2 width)
1859 {
1860 #ifdef WIN_MAC_QUARTZ
1861 CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0);
1862 CGContextSetLineWidth(Nlm_PeekQContext(), (float) width);
1863 #elif defined(WIN_MAC)
1864 PenPat ((ConstPatternParam) blackPat);
1865 PenSize (width, width);
1866 #endif
1867 #ifdef WIN_MSWIN
1868 Nlm_SelectPattern (PS_SOLID, width, blackPat, ATT_PENWIDTH);
1869 #endif
1870 #ifdef WIN_X
1871 XGCValues values;
1872
1873 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
1874 values.line_width = width;
1875 XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineWidth, &values);
1876 }
1877 #endif
1878 #ifdef WIN_GIF
1879 #endif
1880 }
1881
1882 /* esl: changed to work with new FontData format */
1883 static void Nlm_LoadFontData (Nlm_FonT font,
1884 Nlm_FonT next,
1885 Nlm_Int4 refcnt,
1886 Nlm_FontSpecPtr fsp,
1887 #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI)
1888 Nlm_Int2 num,
1889 Nlm_Int2 size,
1890 Nlm_Int2 styl,
1891 #else
1892 Nlm_FontTool hdl,
1893 #endif
1894 Nlm_FonT print)
1895 { /* load font data */
1896 Nlm_FontData fdata;
1897 if (font == NULL) return;
1898 fdata.next = next;
1899 fdata.refcnt = refcnt;
1900 if (fsp != NULL) fdata.fontspec = *fsp;
1901 else Nlm_MemSet (&fdata.fontspec, 0, sizeof (Nlm_FontSpec));
1902 #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI)
1903 fdata.number = num;
1904 fdata.size = size;
1905 fdata.style = styl;
1906 #elif defined(WIN_MSWIN) || defined(WIN_X) || defined(WIN_MAC_ATSUI)
1907 fdata.handle = hdl;
1908 #endif
1909 fdata.print = print;
1910 Nlm_SetFontData (font, &fdata);
1911 }
1912
1913 /* esl: public proc for Windows font mapping (used also in ChooseFont) */
1914 #ifdef WIN_MSWIN
1915 extern void Nlm_FontSpecToLOGFONT (Nlm_FontSpecPtr fsp, LOGFONT *lfp)
1916 {
1917 if (fsp == NULL || lfp == NULL) return;
1918
1919 memset (lfp, 0, sizeof (LOGFONT));
1920
1921 { /* height & width */
1922 HDC hDC = GetDC (NULL);
1923 lfp->lfHeight = - MulDiv (fsp->size, GetDeviceCaps (hDC, LOGPIXELSY), 72);
1924 ReleaseDC (NULL, hDC);
1925 lfp->lfWidth = 0;
1926 }
1927
1928 /* weight & style */
1929 lfp->lfWeight = ((fsp->style & STYLE_BOLD) != 0) ? FW_BOLD : FW_DONTCARE; /*FW_NORMAL?*/
1930 lfp->lfItalic = (BYTE)((fsp->style & STYLE_ITALIC) != 0);
1931 lfp->lfUnderline = (BYTE)((fsp->style & STYLE_UNDERLINE) != 0);
1932 lfp->lfStrikeOut = (BYTE)((fsp->style & 128) != 0); /* Windows specific */
1933
1934 /* character set */
1935 switch (fsp->charset) {
1936 case CHARSET_SYMBOL: lfp->lfCharSet = SYMBOL_CHARSET; break;
1937 case CHARSET_KANJI: lfp->lfCharSet = SHIFTJIS_CHARSET; break;
1938 default: lfp->lfCharSet = ANSI_CHARSET; break;
1939 }
1940
1941 /* precisions & quality */
1942 lfp->lfOutPrecision = OUT_DEFAULT_PRECIS;
1943 lfp->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1944 lfp->lfQuality = DEFAULT_QUALITY;
1945
1946 { /* pitch & family */
1947 BYTE pitch, family;
1948 switch (fsp->pitch) {
1949 case PITCH_FIXED: pitch = FIXED_PITCH; break;
1950 case PITCH_VARIABLE: pitch = VARIABLE_PITCH; break;
1951 default: pitch = DEFAULT_PITCH; break;
1952 }
1953 switch (fsp->family) {
1954 case FAMILY_ROMAN: family = FF_ROMAN; break;
1955 case FAMILY_SWISS: family = FF_SWISS; break;
1956 case FAMILY_MODERN: family = FF_MODERN; break;
1957 case FAMILY_SCRIPT: family = FF_SCRIPT; break;
1958 case FAMILY_DECORATIVE: family = FF_DECORATIVE; break;
1959 default: family = FF_DONTCARE; break;
1960 }
1961 lfp->lfPitchAndFamily = (BYTE)(pitch | family);
1962 }
1963
1964 /* face name */
1965 Nlm_StringNCpy_0 (lfp->lfFaceName, fsp->name, LF_FACESIZE - 1);
1966 }
1967 #endif /* WIN_MSWIN */
1968
1969 /* VL */
1970 #ifdef WIN_X
1971 static Nlm_CharPtr Xi[]={
1972 "times",
1973 "palatino",
1974 "utopia",
1975 "new century schoolbook",
1976 "lucidabright",
1977 "lucida",
1978 "charter"
1979 };
1980
1981 extern XFontStruct *Nlm_XLoadStandardFont(void)
1982 {
1983 static char* s_StdXFontName[] = {
1984 "-*-helvetica-bold-r-*--14-*",
1985 "-*-helvetica-bold-r-*--*-140-*",
1986 "-*-helvetica-bold-r-*-*-*-140-*",
1987 "-*-fixed-medium-r-*--*-120-*",
1988 "-*-courier-medium-r-*--*-120-*",
1989 "8x13",
1990 "9x15",
1991 "fixed"
1992 };
1993
1994 int i;
1995 for (i = 0; i < DIM(s_StdXFontName); i++) {
1996 XFontStruct* font = Nlm_XLoadQueryFont(Nlm_currentXDisplay,
1997 s_StdXFontName[i], FALSE);
1998 if ( font )
1999 return font;
2000 }
2001
2002 /* the last-chance font */
2003 return Nlm_XLoadQueryFont(Nlm_currentXDisplay, "fixed", TRUE);
2004 }
2005 #endif
2006
2007 #ifdef WIN_MAC_ATSUI
2008
2009 static Nlm_FontTool Nlm_FontToATSUStyle(Nlm_FonT f)
2010 {
2011 Nlm_FontData fontData;
2012 Nlm_GetFontData (f, &fontData);
2013 return fontData.handle;
2014 }
2015
2016
2017 static Nlm_FontTool Nlm_NewATSUStyle(Nlm_FontSpecPtr fsp)
2018 {
2019 OSErr err;
2020 Nlm_FontTool style = NULL; /* type ATSUStyle */
2021
2022 err = ATSUCreateStyle(&style);
2023 if (err == noErr) {
2024 ATSUFontID fontID;
2025 Fixed atsuSize;
2026 Boolean boldTag = FALSE;
2027 Boolean italicTag = FALSE;
2028
2029 ATSUAttributeTag theTags[] = {kATSUFontTag, kATSUSizeTag, kATSUQDBoldfaceTag, kATSUQDItalicTag};
2030 ByteCount theSizes[] = {sizeof(ATSUFontID), sizeof(Fixed), sizeof(Boolean), sizeof(Boolean)};
2031 ATSUAttributeValuePtr theValues[] = {&fontID, &atsuSize, &boldTag, &italicTag};
2032
2033 /* Get Font id from the name. */
2034 OSStatus err = ATSUFindFontFromName (
2035 fsp->name, strlen(fsp->name),
2036 kFontFullName, // kFontFamilyName,
2037 kFontMacintoshPlatform, // kFontUnicodePlatform for Unicode support.
2038 kFontNoScriptCode, kFontNoLanguageCode,
2039 &fontID
2040 );
2041 if (err == kATSUInvalidFontErr)
2042 {
2043 /* or can we do something more intelligent here? */
2044 return NULL;
2045 }
2046
2047 if ((fsp->style & STYLE_BOLD) != 0) boldTag = TRUE;
2048 if ((fsp->style & STYLE_ITALIC) != 0) italicTag = TRUE;
2049
2050 /* get the size ready */
2051 atsuSize = Long2Fix (fsp->size);
2052
2053 /* put the attributes in to the style. */
2054 err = ATSUSetAttributes (
2055 style,
2056 sizeof(theTags)/sizeof(ATSUAttributeTag),
2057 theTags,
2058 theSizes,
2059 theValues
2060 );
2061 }
2062
2063 return style;
2064 }
2065
2066
2067 #endif
2068
2069 /* esl: main internal procedure to create fonts */
2070 static Nlm_FonT Nlm_AddNewFont (Nlm_FontSpecPtr fsp, Nlm_Boolean residentp)
2071 {
2072 Nlm_FonT rsult;
2073 #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI)
2074 Nlm_Int2 num = 0;
2075 Nlm_Int2 styl = 0;
2076 #else /* WIN_MSWIN | WIN_X | WIN_GIF | WIN_MAC_ATSUI */
2077 Nlm_FontTool hdl = NULL;
2078 #endif
2079
2080 if (fsp == NULL)
2081 return NULL;
2082 if ( (rsult = (Nlm_FonT)Nlm_HandNew( sizeof(Nlm_FontRec) )) == NULL )
2083 return NULL;
2084
2085 #ifdef WIN_MAC
2086 #ifdef WIN_MAC_ATSUI
2087 hdl = Nlm_NewATSUStyle(fsp);
2088 #else
2089 {{
2090 Nlm_Char temp[256];
2091 if (fsp->name[0] != '\0') {
2092 Nlm_StringNCpy_0 (temp, fsp->name, sizeof (temp));
2093 Nlm_CtoPstr (temp);
2094 GetFNum ((StringPtr) temp, &num);
2095 }
2096 if (num == 0) { /* use standard fonts */
2097 if (fsp->charset == CHARSET_KANJI) {
2098 if (fsp->pitch == PITCH_FIXED) num = 0x4034; /* osaka(fixed) */
2099 else num = 0x4000; /* osaka */
2100 }
2101 else if (fsp->charset == CHARSET_SYMBOL) num = 23; /* symbol */
2102 else if (fsp->family == FAMILY_ROMAN) {
2103 if (fsp->pitch == PITCH_FIXED) num = 22; /* courier */
2104 else num = 2; /* new york */
2105 } else if (fsp->family == FAMILY_SWISS) {
2106 if (fsp->pitch == PITCH_FIXED) num = 4; /* monaco */
2107 else num = 3; /* geneva */
2108 } else if (fsp->family == FAMILY_MODERN) num = 22; /* courier */
2109 else if (fsp->family == FAMILY_SCRIPT) num = 12; /* los angeles */
2110 else if (fsp->pitch == PITCH_FIXED) num = 4; /* monaco */
2111 else num = 0; /* system */
2112 }
2113 if ((fsp->style & STYLE_BOLD) != 0) styl += bold;
2114 if ((fsp->style & STYLE_ITALIC) != 0) styl += italic;
2115 if ((fsp->style & STYLE_UNDERLINE) != 0) styl += underline;
2116 /* other Mac-specific styles??? */
2117 if ((fsp->style & 8) != 0) styl += outline;
2118 if ((fsp->style & 16) != 0) styl += shadow;
2119 if ((fsp->style & 32) != 0) styl += condense;
2120 if ((fsp->style & 64) != 0) styl += extend;
2121 }}
2122 #endif /* WIN_MAC_ATSUI */
2123 #endif /* WIN_MAC */
2124 #ifdef WIN_MSWIN
2125 {{
2126 LOGFONT lf;
2127 Nlm_FontSpecToLOGFONT (fsp, &lf);
2128 hdl = CreateFontIndirect (&lf);
2129 }}
2130 #endif /* WIN_MSWIN */
2131 #ifdef WIN_X
2132 if ( !Nlm_currentXDisplay )
2133 return (Nlm_FonT) Nlm_MemFree(rsult);
2134
2135 {{
2136 Nlm_Char fspec[256];
2137 Nlm_CharPtr bs = ((fsp->style & STYLE_BOLD) != 0) ? "bold" : "medium";
2138 Nlm_CharPtr is = "r";
2139 int sz = (int)fsp->size;
2140
2141 if (fsp->style & STYLE_ITALIC) {
2142 size_t i;
2143 is="o";
2144 for (i=0; i<DIM(Xi); i++)
2145 if ( !Nlm_StringICmp(fsp->name, Xi[i]) ) {
2146 is="i";
2147 break;
2148 }
2149 }
2150 if ( *fsp->name ) { /* try the whole data */
2151 sprintf (fspec, "-*-%s-%s-%s-*--*-%d-*-*-*-*-*-*",
2152 fsp->name, bs, is, sz*10);
2153 hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE);
2154 if ( ! hdl ) {
2155 sprintf (fspec, "-*-%s-%s-%s-*-*-*-%d-*-*-*-*-*-*",
2156 fsp->name, bs, is, sz*10);
2157 hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE);
2158 }
2159 }
2160 if (!hdl && *fsp->name) { /* try the name only */
2161 sprintf (fspec, "-*-%s-*", fsp->name);
2162 hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE);
2163 }
2164 if (hdl == NULL) { /* try charset/pitch/family */
2165 Nlm_CharPtr ns;
2166 if (fsp->charset == CHARSET_SYMBOL) ns = "symbol";
2167 else if (fsp->family == FAMILY_ROMAN ) ns = "times";
2168 else if (fsp->family == FAMILY_SWISS ) ns = "helvetica";
2169 else if (fsp->family == FAMILY_MODERN ) ns = "courier";
2170 else if (fsp->pitch == PITCH_FIXED ) ns = "fixed";
2171 else ns = "helvetica";
2172
2173 sprintf(fspec, "-*-%s-%s-%s-*--*-%d-*", ns, bs, is, sz*10);
2174 hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE);
2175 if ( !hdl ) {
2176 sprintf(fspec, "-*-%s-%s-%s-*-*-*-%d-*", ns, bs, is, sz*10);
2177 hdl = Nlm_XLoadQueryFont(Nlm_currentXDisplay, fspec, FALSE);
2178 }
2179 }
2180
2181 if ( !hdl ) /* last resort: try "standard" font */
2182 hdl = Nlm_XLoadStandardFont();
2183 }}
2184 #endif /* WIN_X */
2185
2186 Nlm_LoadFontData (rsult,
2187 Nlm_fontList,
2188 residentp ? -1 : 1,
2189 fsp,
2190 #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI)
2191 num,
2192 fsp->size,
2193 styl,
2194 #else /* WIN_MSWIN | WIN_X | WIN_GIF | WIN_MAC_ATSUI */
2195 hdl,
2196 #endif
2197 NULL);
2198
2199 Nlm_fontList = rsult;
2200 return rsult;
2201 }
2202
2203
2204 /* esl: public procedure to compare FontSpecs */
2205 extern Nlm_Boolean Nlm_EqualFontSpec (Nlm_FontSpecPtr fsp1,
2206 Nlm_FontSpecPtr fsp2)
2207 {
2208 if (fsp1 == NULL || fsp2 == NULL) return FALSE;
2209 return (Nlm_Boolean) (
2210 (Nlm_StrNICmp (fsp1->name, fsp2->name, FONT_NAME_SIZE) == 0) &&
2211 fsp1->size == fsp2->size &&
2212 fsp1->style == fsp2->style &&
2213 fsp1->charset == fsp2->charset &&
2214 fsp1->pitch == fsp2->pitch &&
2215 fsp1->family == fsp2->family
2216 );
2217 }
2218
2219 /* esl: internal procedure to find existing fonts */
2220 static Nlm_FonT Nlm_FindFont (Nlm_FontSpecPtr fsp)
2221 {
2222 if (fsp != NULL) {
2223 Nlm_FonT font = Nlm_fontList;
2224 while (font != NULL) {
2225 Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font);
2226 Nlm_Boolean found = Nlm_EqualFontSpec (fsp, &fp->fontspec);
2227 Nlm_FonT next = fp->next;
2228 Nlm_HandUnlock (font);
2229 if (found) return font;
2230 font = next;
2231 }
2232 }
2233 return NULL;
2234 }
2235
2236 /* esl: internal procedure to increase refcnt */
2237 static void Nlm_ReuseFont (Nlm_FonT font, Nlm_Boolean residentp)
2238 {
2239 if (font != NULL) {
2240 Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font);
2241 /* ASSERT (fp->refcnt != 0) */
2242 if (fp->refcnt > 0) {
2243 /* font is temporary: make it resident or increment refcnt */
2244 fp->refcnt = residentp ? -1 : fp->refcnt + 1;
2245 } /* else font is resident: just use it */
2246 Nlm_HandUnlock (font);
2247 }
2248 }
2249
2250 /* esl: internal procedure to create resident/temporary fonts */
2251 static Nlm_FonT Nlm_CreateFontIndirect (Nlm_FontSpecPtr fsp,
2252 Nlm_Boolean residentp)
2253 {
2254 if (fsp != NULL) {
2255 if (fsp->family == 255) { /* magic number! */
2256 /* conventional specification of the standard fonts */
2257 return (fsp->pitch == PITCH_FIXED) ? Nlm_programFont : Nlm_systemFont;
2258 } else {
2259 Nlm_FonT font = Nlm_FindFont (fsp);
2260 if (font == NULL) {
2261 /* create new font and add it to the font list */
2262 return Nlm_AddNewFont (fsp, residentp);
2263 } else {
2264 /* reuse existing font */
2265 Nlm_ReuseFont (font, residentp);
2266 return font;
2267 }
2268 }
2269 }
2270 return NULL;
2271 }
2272
2273 #ifdef WIN_MSWIN
2274 /* Creates(if yet no one) FonT based on the properties of "screen_font".
2275 * Use this function to choose a font corresponding to a stock font.
2276 */
2277 static Nlm_FonT HFONT2Font(HFONT screen_font)
2278 {
2279 HDC hDC;
2280 if ( !screen_font )
2281 return NULL;
2282
2283 hDC = GetDC( NULL ); /* CreateIC("DISPLAY", NULL, NULL, NULL); */
2284 if ( !hDC )
2285 return NULL;
2286
2287 {{
2288 TEXTMETRIC tMetrics;
2289
2290 BOOL ok = SelectObject(hDC, screen_font) &&
2291 GetTextMetrics(hDC, &tMetrics);
2292 int height = MulDiv(tMetrics.tmHeight, 72, GetDeviceCaps(hDC, LOGPIXELSY));
2293
2294 ReleaseDC(NULL, hDC); /* DeleteDC( hDC ); */
2295 if ( !ok )
2296 return NULL;
2297
2298 {{
2299 Nlm_FontSpec fs;
2300 fs.name[0] = '\0';
2301 fs.size = (Nlm_Int2)height;
2302 fs.style = 0;
2303 if (tMetrics.tmWeight == FW_BOLD)
2304 fs.style |= STYLE_BOLD;
2305 if ( tMetrics.tmItalic )
2306 fs.style |= STYLE_ITALIC;
2307 if ( tMetrics.tmUnderlined )
2308 fs.style |= STYLE_UNDERLINE;
2309 fs.charset = CHARSET_NULL;
2310 fs.pitch = (Nlm_Uint1)((tMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH) ?
2311 PITCH_VARIABLE : PITCH_FIXED);
2312 switch (tMetrics.tmPitchAndFamily & 0xF0)
2313 {
2314 case FF_DECORATIVE: fs.family = FAMILY_DECORATIVE; break;
2315 case FF_MODERN: fs.family = FAMILY_MODERN; break;
2316 case FF_ROMAN: fs.family = FAMILY_ROMAN; break;
2317 case FF_SCRIPT: fs.family = FAMILY_SCRIPT; break;
2318 case FF_SWISS: fs.family = FAMILY_SWISS; break;
2319 default:
2320 fs.family = FAMILY_NULL;
2321 }
2322
2323 return Nlm_CreateFontIndirect(&fs, TRUE);
2324 }}
2325 }}
2326 }
2327 #endif /* WIN_MSWIN */
2328
2329 /* esl: public procedures to create resident/temporary fonts */
2330 extern Nlm_FonT Nlm_CreateFont (Nlm_FontSpecPtr fsp)
2331 {
2332 return Nlm_CreateFontIndirect (fsp, FALSE);
2333 }
2334 extern Nlm_FonT Nlm_GetResidentFont (Nlm_FontSpecPtr fsp)
2335 {
2336 return Nlm_CreateFontIndirect (fsp, TRUE);
2337 }
2338
2339 /* esl: public procedure to "copy" font (actually to increment refcnt) */
2340 extern Nlm_FonT Nlm_CopyFont (Nlm_FonT font)
2341 {
2342 Nlm_ReuseFont (font, FALSE); /* do not make it resident */
2343 return font;
2344 }
2345
2346 /* esl: fonts created this way are resident for compatibility */
2347 extern Nlm_FonT Nlm_GetFont (Nlm_CharPtr name, Nlm_Int2 size,
2348 Nlm_Boolean bld, Nlm_Boolean itlc,
2349 Nlm_Boolean undrln, Nlm_CharPtr fmly)
2350 {
2351 Nlm_Uint1 style, charset, pitch, family;
2352
2353 /* style */
2354 style = 0;
2355 if (bld) style |= STYLE_BOLD;
2356 if (itlc) style |= STYLE_ITALIC;
2357 if (undrln) style |= STYLE_UNDERLINE;
2358
2359 /* charset */
2360 charset = CHARSET_NULL;
2361
2362 /* pitch */
2363 pitch = PITCH_NULL;
2364
2365 /* family */
2366 if (fmly == NULL || fmly [0] != '\0') family = FAMILY_NULL;
2367 else if (Nlm_StringICmp (fmly, "Roman") == 0) family = FAMILY_ROMAN;
2368 else if (Nlm_StringICmp (fmly, "Swiss") == 0) family = FAMILY_SWISS;
2369 else if (Nlm_StringICmp (fmly, "Modern") == 0) family = FAMILY_MODERN;
2370 else if (Nlm_StringICmp (fmly, "Script") == 0) family = FAMILY_SCRIPT;
2371 else if (Nlm_StringICmp (fmly, "Decorative") == 0) family = FAMILY_DECORATIVE;
2372 else family = FAMILY_NULL;
2373
2374 /* create resident font */
2375 { Nlm_FontSpec fs;
2376 Nlm_MemSet (fs.name, 0, FONT_NAME_SIZE);
2377 if (name != NULL) Nlm_StringNCpy_0 (fs.name, name, FONT_NAME_SIZE - 1);
2378 fs.size = size;
2379 fs.style = style;
2380 fs.charset = charset;
2381 fs.pitch = pitch;
2382 fs.family = family;
2383 return Nlm_CreateFontIndirect (&fs, TRUE);
2384 }
2385 }
2386
2387 static Nlm_FonT Nlm_ParseFontSpec (Nlm_CharPtr spec)
2388 {
2389 Nlm_Boolean bold;
2390 Nlm_CharPtr fmly;
2391 Nlm_Boolean ital;
2392 Nlm_Char name [128];
2393 Nlm_CharPtr p;
2394 Nlm_CharPtr q;
2395 Nlm_CharPtr r;
2396 Nlm_FonT rsult;
2397 Nlm_Int2 size;
2398 Nlm_Char temp [128];
2399 Nlm_Boolean undr;
2400 int val;
2401
2402 rsult = NULL;
2403 if (spec != NULL && spec [0] != '\0') {
2404 fmly = NULL;
2405 bold = FALSE;
2406 ital = FALSE;
2407 undr = FALSE;
2408 Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1);
2409 p = Nlm_StringChr (name, ',');
2410 if (p != NULL) {
2411 *p = '\0';
2412 p++;
2413 q = Nlm_StringChr (p, ',');
2414 if (q != NULL) {
2415 *q = '\0';
2416 q++;
2417 }
2418 r = Nlm_StringChr (q, 'B');
2419 if (r == NULL) {
2420 r = Nlm_StringChr (q, 'b');
2421 }
2422 if (r != NULL) {
2423 bold = TRUE;
2424 }
2425 r = Nlm_StringChr (q, 'I');
2426 if (r == NULL) {
2427 r = Nlm_StringChr (q, 'i');
2428 }
2429 if (r != NULL) {
2430 ital = TRUE;
2431 }
2432 r = Nlm_StringChr (q, 'U');
2433 if (r == NULL) {
2434 r = Nlm_StringChr (q, 'u');
2435 }
2436 if (r != NULL) {
2437 undr = TRUE;
2438 }
2439 Nlm_StringNCpy_0 (temp, p, sizeof (temp) - 1);
2440 if (sscanf (temp, "%d", &val) != EOF) {
2441 size = (Nlm_Int2) val;
2442 rsult = Nlm_GetFont (name, size, bold, ital, undr, fmly);
2443 }
2444 }
2445 }
2446 return rsult;
2447 }
2448
2449 /* esl: fonts created this way are resident for compatibility */
2450 extern Nlm_FonT Nlm_ParseFont (Nlm_CharPtr spec)
2451
2452 {
2453 Nlm_Char name [128];
2454 Nlm_CharPtr p;
2455 Nlm_FonT prtr;
2456 Nlm_CharPtr q;
2457 Nlm_FonT rsult;
2458
2459 rsult = NULL;
2460 if (spec != NULL && spec [0] != '\0') {
2461 Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1);
2462 p = Nlm_StringChr (name, '|');
2463 if (p != NULL) {
2464 *p = '\0';
2465 p++;
2466 while (*p == ' ') {
2467 p++;
2468 }
2469 q = name;
2470 while (*q == ' ') {
2471 q++;
2472 }
2473 rsult = Nlm_ParseFontSpec (q);
2474 prtr = Nlm_ParseFontSpec (p);
2475 Nlm_AssignPrinterFont (rsult, prtr);
2476 } else {
2477 q = name;
2478 while (*q == ' ') {
2479 q++;
2480 }
2481 rsult = Nlm_ParseFontSpec (q);
2482 }
2483 }
2484 return rsult;
2485 }
2486
2487 extern Nlm_FonT Nlm_GetFontEx (Nlm_CharPtr name, Nlm_Int2 size,
2488 Nlm_Boolean bld, Nlm_Boolean itlc,
2489 Nlm_Boolean undrln, Nlm_CharPtr fmly,
2490 Nlm_CharPtr chset, Nlm_Boolean fixed)
2491 {
2492 Nlm_Uint1 style, charset, pitch, family;
2493
2494 /* style */
2495 style = 0;
2496 if (bld) style |= STYLE_BOLD;
2497 if (itlc) style |= STYLE_ITALIC;
2498 if (undrln) style |= STYLE_UNDERLINE;
2499
2500 /* charset */
2501 if (chset == NULL || chset [0] == '\0') charset = CHARSET_NULL;
2502 else if (Nlm_StringICmp (chset, "Ansi") == 0) charset = CHARSET_ANSI;
2503 else if (Nlm_StringICmp (chset, "Symbol") == 0) charset = CHARSET_SYMBOL;
2504 else if (Nlm_StringICmp (chset, "Kanji") == 0) charset = CHARSET_KANJI;
2505 else if (Nlm_StringICmp (chset, "Hangul") == 0) charset = CHASET_HANGUL;
2506 else charset = CHARSET_NULL;
2507
2508 /* pitch */
2509 if (fixed) pitch = PITCH_FIXED;
2510 else pitch = PITCH_NULL;
2511
2512 /* family */
2513 if (fmly == NULL || fmly [0] == '\0') family = FAMILY_NULL;
2514 else if (Nlm_StringICmp (fmly, "Roman") == 0) family = FAMILY_ROMAN;
2515 else if (Nlm_StringICmp (fmly, "Swiss") == 0) family = FAMILY_SWISS;
2516 else if (Nlm_StringICmp (fmly, "Modern") == 0) family = FAMILY_MODERN;
2517 else if (Nlm_StringICmp (fmly, "Script") == 0) family = FAMILY_SCRIPT;
2518 else if (Nlm_StringICmp (fmly, "Decorative") == 0) family = FAMILY_DECORATIVE;
2519 else family = FAMILY_NULL;
2520
2521 /* create resident font */
2522 { Nlm_FontSpec fs;
2523 Nlm_MemSet (fs.name, 0, FONT_NAME_SIZE);
2524 if (name != NULL) Nlm_StringNCpy_0 (fs.name, name, FONT_NAME_SIZE - 1);
2525 fs.size = size;
2526 fs.style = style;
2527 fs.charset = charset;
2528 fs.pitch = pitch;
2529 fs.family = family;
2530 return Nlm_CreateFontIndirect (&fs, TRUE);
2531 }
2532 }
2533
2534 static Nlm_FonT Nlm_ParseFontSpecEx (Nlm_CharPtr spec)
2535 {
2536 Nlm_Boolean bold;
2537 Nlm_CharPtr fmly;
2538 Nlm_Boolean ital;
2539 Nlm_Char name [128];
2540 Nlm_CharPtr p;
2541 Nlm_CharPtr q;
2542 Nlm_CharPtr r;
2543 Nlm_CharPtr s;
2544 Nlm_FonT rsult;
2545 Nlm_Int2 size;
2546 Nlm_Char temp [128];
2547 Nlm_Boolean undr;
2548 int val;
2549 Nlm_Char chst [128];
2550 Nlm_Boolean fixd;
2551
2552 rsult = NULL;
2553 if (spec != NULL && spec [0] != '\0') {
2554 fmly = NULL;
2555 bold = FALSE;
2556 ital = FALSE;
2557 undr = FALSE;
2558 fixd = FALSE;
2559 chst [0] = '\0';
2560 Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1);
2561 p = Nlm_StringChr (name, ',');
2562 if (p != NULL) {
2563 *p = '\0';
2564 p++;
2565 q = Nlm_StringChr (p, ',');
2566 if (q != NULL) {
2567 *q = '\0';
2568 q++;
2569 }
2570 s = Nlm_StringChr (q, ',');
2571 if (s != NULL) {
2572 *s = '\0';
2573 s++;
2574 }
2575 r = Nlm_StringChr (q, 'B');
2576 if (r == NULL) {
2577 r = Nlm_StringChr (q, 'b');
2578 }
2579 if (r != NULL) {
2580 bold = TRUE;
2581 }
2582 r = Nlm_StringChr (q, 'I');
2583 if (r == NULL) {
2584 r = Nlm_StringChr (q, 'i');
2585 }
2586 if (r != NULL) {
2587 ital = TRUE;
2588 }
2589 r = Nlm_StringChr (q, 'U');
2590 if (r == NULL) {
2591 r = Nlm_StringChr (q, 'u');
2592 }
2593 if (r != NULL) {
2594 undr = TRUE;
2595 }
2596 r = Nlm_StringChr (q, 'F');
2597 if (r == NULL) {
2598 r = Nlm_StringChr (q, 'f');
2599 }
2600 if (r != NULL) {
2601 fixd = TRUE;
2602 }
2603 if (s != NULL) {
2604 Nlm_StringNCpy_0 (chst, s, sizeof (chst) - 1);
2605 }
2606 Nlm_StringNCpy_0 (temp, p, sizeof (temp) - 1);
2607 if (sscanf (temp, "%d", &val) != EOF) {
2608 size = (Nlm_Int2) val;
2609 rsult = Nlm_GetFontEx (name, size, bold, ital, undr, fmly, chst, fixd);
2610 }
2611 }
2612 }
2613 return rsult;
2614 }
2615
2616 extern Nlm_FonT Nlm_ParseFontEx (Nlm_CharPtr scrSpec, Nlm_CharPtr prtSpec)
2617 {
2618 Nlm_CharPtr p;
2619 Nlm_FonT prtr;
2620 Nlm_CharPtr q;
2621 Nlm_FonT rsult;
2622
2623 rsult = NULL;
2624 if (scrSpec != NULL && scrSpec [0] != '\0') {
2625 q = scrSpec;
2626 while (*q == ' ') {
2627 q++;
2628 }
2629 rsult = Nlm_ParseFontSpecEx(q);
2630 }
2631 prtr = NULL;
2632 if (prtSpec != NULL && prtSpec [0] != '\0') {
2633 p = prtSpec;
2634 while (*p == ' ') {
2635 p++;
2636 }
2637 prtr = Nlm_ParseFontSpecEx(p);
2638 Nlm_AssignPrinterFont (rsult, prtr);
2639 }
2640 return rsult;
2641 }
2642
2643 /* esl: public procedures to get specifications for common fonts */
2644 /* ToDo: add platform-dependent names? */
2645
2646 static Nlm_FontSpec Nlm_commonFontSpec;
2647 extern Nlm_FontSpecPtr Nlm_Helvetica (Nlm_Int2 size, Nlm_Uint1 style)
2648 {
2649 #ifdef WIN_MAC_QUARTZ
2650 strncpy(Nlm_commonFontSpec.name, "Helvetica", sizeof(Nlm_commonFontSpec.name));
2651 #else
2652 Nlm_commonFontSpec.name[0] = '\0';
2653 #endif
2654 Nlm_commonFontSpec.size = size;
2655 Nlm_commonFontSpec.style = style;
2656 Nlm_commonFontSpec.charset = CHARSET_ANSI;
2657 Nlm_commonFontSpec.pitch = PITCH_VARIABLE;
2658 Nlm_commonFontSpec.family = FAMILY_SWISS;
2659 return &Nlm_commonFontSpec;
2660 }
2661
2662 extern Nlm_FontSpecPtr Nlm_Times (Nlm_Int2 size, Nlm_Uint1 style)
2663 {
2664 #ifdef WIN_MAC_QUARTZ
2665 strncpy(Nlm_commonFontSpec.name, "Times", sizeof(Nlm_commonFontSpec.name));
2666 #else
2667 Nlm_commonFontSpec.name[0] = '\0';
2668 #endif
2669 Nlm_commonFontSpec.size = size;
2670 Nlm_commonFontSpec.style = style;
2671 Nlm_commonFontSpec.charset = CHARSET_ANSI;
2672 Nlm_commonFontSpec.pitch = PITCH_VARIABLE;
2673 Nlm_commonFontSpec.family = FAMILY_ROMAN;
2674 return &Nlm_commonFontSpec;
2675 }
2676
2677 extern Nlm_FontSpecPtr Nlm_Courier (Nlm_Int2 size, Nlm_Uint1 style)
2678 {
2679 #ifdef WIN_MAC_QUARTZ
2680 strncpy(Nlm_commonFontSpec.name, "Courier", sizeof(Nlm_commonFontSpec.name));
2681 #else
2682 Nlm_commonFontSpec.name[0] = '\0';
2683 #endif
2684 Nlm_commonFontSpec.size = size;
2685 Nlm_commonFontSpec.style = style;
2686 Nlm_commonFontSpec.charset = CHARSET_ANSI;
2687 Nlm_commonFontSpec.pitch = PITCH_FIXED;
2688 Nlm_commonFontSpec.family = FAMILY_MODERN;
2689 return &Nlm_commonFontSpec;
2690 }
2691
2692 extern Nlm_FontSpecPtr Nlm_Symbol (Nlm_Int2 size, Nlm_Uint1 style)
2693 {
2694 #ifdef WIN_MAC_QUARTZ
2695 strncpy(Nlm_commonFontSpec.name, "Symbol", sizeof(Nlm_commonFontSpec.name));
2696 #else
2697 Nlm_commonFontSpec.name[0] = '\0';
2698 #endif
2699 Nlm_commonFontSpec.size = size;
2700 Nlm_commonFontSpec.style = style;
2701 Nlm_commonFontSpec.charset = CHARSET_SYMBOL; /* should be enough */
2702 Nlm_commonFontSpec.pitch = PITCH_NULL;
2703 Nlm_commonFontSpec.family = FAMILY_NULL;
2704 return &Nlm_commonFontSpec;
2705 }
2706
2707 extern Nlm_FontSpecPtr Nlm_Gothic (Nlm_Int2 size, Nlm_Uint1 style)
2708
2709 {
2710 #ifdef WIN_MAC
2711 strncpy(Nlm_commonFontSpec.name, "Osaka", sizeof(Nlm_commonFontSpec.name));
2712 #endif
2713 #ifdef WIN_MSWIN
2714 strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e", sizeof(Nlm_commonFontSpec.name));
2715 #endif
2716 #ifdef WIN_MOTIF
2717 strncpy(Nlm_commonFontSpec.name, "gothic", sizeof(Nlm_commonFontSpec.name));
2718 #endif
2719 Nlm_commonFontSpec.size = size;
2720 Nlm_commonFontSpec.style = style;
2721 Nlm_commonFontSpec.charset = CHARSET_KANJI;
2722 Nlm_commonFontSpec.pitch = PITCH_NULL;
2723 Nlm_commonFontSpec.family = FAMILY_GOTHIC;
2724 return &Nlm_commonFontSpec;
2725 }
2726
2727 extern Nlm_FontSpecPtr Nlm_Minchou (Nlm_Int2 size, Nlm_Uint1 style)
2728
2729 {
2730 #ifdef WIN_MAC
2731 strncpy(Nlm_commonFontSpec.name, "Osaka", sizeof(Nlm_commonFontSpec.name));
2732 #endif
2733 #ifdef WIN_MSWIN
2734 strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x82\x6f\x96\xbe\x92\xa9", sizeof(Nlm_commonFontSpec.name));
2735 #endif
2736 #ifdef WIN_MOTIF
2737 strncpy(Nlm_commonFontSpec.name, "minchou", sizeof(Nlm_commonFontSpec.name));
2738 #endif
2739 Nlm_commonFontSpec.size = size;
2740 Nlm_commonFontSpec.style = style;
2741 Nlm_commonFontSpec.charset = CHARSET_KANJI;
2742 Nlm_commonFontSpec.pitch = PITCH_NULL;
2743 Nlm_commonFontSpec.family = FAMILY_MINCHOU;
2744 return &Nlm_commonFontSpec;
2745 }
2746
2747 extern Nlm_FontSpecPtr Nlm_GothicFixed (Nlm_Int2 size, Nlm_Uint1 style)
2748
2749 {
2750 Nlm_Gothic(size, style);
2751 #ifdef WIN_MAC
2752 strncpy(Nlm_commonFontSpec.name, "Osaka\x81\x7c\x93\x99\x95\x9d", sizeof(Nlm_commonFontSpec.name));
2753 #endif
2754 #ifdef WIN_MSWIN
2755 strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x83\x53\x83\x56\x83\x62\x83\x4e", sizeof(Nlm_commonFontSpec.name));
2756 #endif
2757 Nlm_commonFontSpec.pitch = PITCH_FIXED;
2758 return &Nlm_commonFontSpec;
2759 }
2760 extern Nlm_FontSpecPtr Nlm_MinchouFixed (Nlm_Int2 size, Nlm_Uint1 style)
2761 {
2762 Nlm_Minchou(size, style);
2763 #ifdef WIN_MAC
2764 strncpy(Nlm_commonFontSpec.name, "Osaka\x81\x7c\x93\x99\x95\x9d", sizeof(Nlm_commonFontSpec.name));
2765 #endif
2766 #ifdef WIN_MSWIN
2767 strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x96\xbe\x92\xa9", sizeof(Nlm_commonFontSpec.name));
2768 #endif
2769 Nlm_commonFontSpec.pitch = PITCH_FIXED;
2770 return &Nlm_commonFontSpec;
2771 }
2772
2773
2774 /* esl: public procedure to delete temporary fonts */
2775 /* ToDo: track associated fdata.print font! */
2776 extern Nlm_FonT Nlm_DeleteFont (Nlm_FonT font)
2777 {
2778 if (font != NULL) {
2779 Nlm_FontData fdata;
2780 Nlm_GetFontData (font, &fdata);
2781 /* ASSERT(fdata.refcnt != 0) */
2782 if (fdata.refcnt > 0) {
2783 if (fdata.refcnt > 1) {
2784 /* still in use somewhere else: decrement refcnt */
2785 fdata.refcnt--;
2786 Nlm_SetFontData (font, &fdata);
2787 } else {
2788 /* last reference should be lost: remove from the list and delete */
2789 Nlm_FonT prev = NULL;
2790 Nlm_FonT curr = Nlm_fontList;
2791 while (curr != NULL) {
2792 if (curr == font) { /* font is found! */
2793 Nlm_GetFontData (curr, &fdata);
2794 curr = fdata.next;
2795 if (prev != NULL) { /* remove in the middle */
2796 Nlm_GetFontData (prev, &fdata);
2797 fdata.next = curr;
2798 Nlm_SetFontData (prev, &fdata);
2799 } else { /* remove first */
2800 Nlm_fontList = curr;
2801 }
2802 } else { /* check next! */
2803 prev = curr;
2804 Nlm_GetFontData (curr, &fdata);
2805 curr = fdata.next;
2806 }
2807 }
2808 /* if font is selected, unselect it before deletion! */
2809 if (font == Nlm_fontInUse) Nlm_SelectFont (Nlm_systemFont);
2810 /* delete it! */
2811 Nlm_GetFontData (font, &fdata);
2812 #ifdef WIN_MSWIN
2813 if (fdata.handle != NULL)
2814 DeleteObject (fdata.handle);
2815 #endif
2816 #ifdef WIN_MOTIF
2817 if (fdata.handle != NULL)
2818 XFreeFont (Nlm_currentXDisplay, fdata.handle);
2819 #endif
2820 Nlm_HandFree (font);
2821 }
2822 } /* else font is resident: leave it as it is */
2823 }
2824 return NULL;
2825 }
2826
2827 /* esl: procedure to enumerate resident fonts */
2828 extern Nlm_FonT Nlm_FindNextResidentFont (Nlm_FonT font)
2829 {
2830 Nlm_FonT curr;
2831 Nlm_FontData fdata;
2832 if (font == NULL) {
2833 curr = Nlm_fontList;
2834 } else {
2835 Nlm_GetFontData (font, &fdata);
2836 curr = fdata.next;
2837 }
2838 while (curr != NULL) { /* skip temporary fonts */
2839 Nlm_GetFontData (curr, &fdata);
2840 if (fdata.refcnt < 0) return curr; else curr = fdata.next;
2841 }
2842 return NULL;
2843 }
2844
2845 /* esl: procedure to extract specification from font */
2846 extern Nlm_Boolean Nlm_GetFontSpec (Nlm_FonT font, Nlm_FontSpecPtr fsp)
2847 {
2848 if (font == NULL || fsp == NULL) return FALSE;
2849 /* use conventional specification for system/program fonts */
2850 if (font == Nlm_systemFont || font == Nlm_programFont) {
2851 /*alexs: copy fontspec for System and Program font */
2852 Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font);
2853 *fsp = fp->fontspec;
2854 Nlm_HandUnlock (font);
2855 fsp->family = 255; /* magic number! */
2856 fsp->pitch = (Nlm_Uint1)((font == Nlm_programFont) ?
2857 PITCH_FIXED : PITCH_NULL);
2858 } else {
2859 Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font);
2860 *fsp = fp->fontspec;
2861 Nlm_HandUnlock (font);
2862 }
2863 return TRUE;
2864 }
2865
2866 extern void Nlm_SelectFont (Nlm_FonT f)
2867
2868 {
2869 Nlm_FontData fdata;
2870
2871 if (f != NULL) {
2872 Nlm_GetFontData (f, &fdata);
2873 if (fdata.print != NULL && Nlm_nowPrinting) {
2874 f = fdata.print;
2875 Nlm_GetFontData (f, &fdata);
2876 }
2877 #ifdef WIN_MAC
2878 #ifdef WIN_MAC_ATSUI
2879 Nlm_fontInUse = f;
2880 #else
2881 TextFont (fdata.number);
2882 TextSize (fdata.size);
2883 TextFace (fdata.style);
2884 #endif
2885 #endif
2886 #ifdef WIN_MSWIN
2887 if (Nlm_currentHDC != NULL) {
2888 SelectObject (Nlm_currentHDC, fdata.handle);
2889 }
2890 #endif
2891 #ifdef WIN_X
2892 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
2893 if (fdata.handle != NULL) {
2894 XSetFont (Nlm_currentXDisplay, Nlm_currentXGC, fdata.handle->fid);
2895 currentFont = fdata.handle;
2896 }
2897 }
2898 #endif
2899 #ifdef WIN_GIF
2900 if (fdata.fontspec.size >= 16) {
2901 Nlm_curGIFFont = gdFont8X16;
2902 } else if (fdata.fontspec.size >= 15) {
2903 Nlm_curGIFFont = gdFont9X15b;
2904 } else if (fdata.fontspec.size >= 13) {
2905 Nlm_curGIFFont = gdFont7X13b;
2906 } else if (fdata.fontspec.size >= 10) {
2907 Nlm_curGIFFont = gdFont6X12;
2908 } else {
2909 Nlm_curGIFFont = gdFont5X8;
2910 }
2911 #endif
2912 Nlm_fontInUse = f;
2913 }
2914 }
2915
2916 /* esl ToDo: increment refcnt for fdata.print font? */
2917 extern void Nlm_AssignPrinterFont (Nlm_FonT scrnFont, Nlm_FonT prtrFont)
2918 {
2919 if (scrnFont != NULL) {
2920 Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (scrnFont);
2921 fp->print = prtrFont;
2922 Nlm_HandUnlock (scrnFont);
2923 }
2924 }
2925
2926 extern Nlm_Int2 Nlm_CharWidth (Nlm_Char ch)
2927
2928 {
2929 #ifdef WIN_MAC
2930 #ifdef WIN_MAC_QUARTZ
2931 return Nlm_TextWidth (&ch, 1);
2932 #else
2933 return (CharWidth (ch));
2934 #endif
2935 #endif
2936 #ifdef WIN_MSWIN
2937 Nlm_Char str [4];
2938
2939 str [0] = ch;
2940 str [1] = '\0';
2941 return (Nlm_TextWidth (str, 1));
2942 #endif
2943 #ifdef WIN_X
2944 Nlm_Char str [4];
2945
2946 str [0] = ch;
2947 str [1] = '\0';
2948 return (Nlm_TextWidth (str, 1));
2949 #endif
2950 #ifdef WIN_GIF
2951 return (Nlm_Int2)Nlm_curGIFFont->w;
2952 #endif
2953 }
2954
2955 extern Nlm_Int2 Nlm_StringWidth(const Nlm_Char* text)
2956 {
2957 return Nlm_TextWidth(text, Nlm_StringLen(text));
2958 }
2959
2960 extern Nlm_Int2 Nlm_TextWidth(const Nlm_Char* text, size_t len)
2961 {
2962 if (text && len) {
2963 #if defined(WIN_MAC)
2964 #if defined(WIN_MAC_ATSUI)
2965 OSErr err;
2966 Nlm_PoinT pt;
2967 CFStringRef cfString;
2968 CFIndex cfsLen;
2969 const UniChar * unicodeString;
2970 ATSUTextLayout layout;
2971 Nlm_FontTool curStyle;
2972 Rect tr;
2973
2974 /* convert the string to Unicode */
2975 cfString = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingMacRoman);
2976 if (cfString == NULL)
2977 return 0;
2978 cfsLen = CFStringGetLength(cfString);
2979 unicodeString = CFStringGetCharactersPtr(cfString);
2980 if (unicodeString == NULL) {
2981 CFRange range;
2982 static UniChar ucbuf[1024];
2983
2984 range.location = 0;
2985 range.length = MIN(cfsLen, 1024);
2986 CFStringGetCharacters (cfString, range, ucbuf);
2987 unicodeString = ucbuf;
2988 }
2989
2990 /* get the current style */
2991 curStyle = Nlm_FontToATSUStyle(Nlm_fontInUse);
2992
2993 /* create the layout */
2994 err = ATSUCreateTextLayoutWithTextPtr (
2995 unicodeString,
2996 0,
2997 cfsLen,
2998 cfsLen,
2999 1,
3000 (unsigned long *)&cfsLen,
3001 &curStyle,
3002 &layout
3003 );
3004 /* how big is the text. */
3005 err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd,
3006 0, 0, &tr);
3007
3008 if (err == noErr)
3009 return (tr.right - tr.left) + 3;
3010 #else
3011 return TextWidth(text, 0, (Nlm_Int2)len);
3012 #endif
3013 #elif defined(WIN_MSWIN)
3014 SIZE tag;
3015 if ( Nlm_currentHDC )
3016 GetTextExtentPoint(Nlm_currentHDC, text, (int)len, &tag);
3017 else {
3018 HDC hDC = CreateIC("DISPLAY", NULL, NULL, NULL);
3019 GetTextExtentPoint (hDC, text, (int)len, &tag);
3020 DeleteDC(hDC);
3021 }
3022 return (Nlm_Int2)tag.cx;
3023
3024 #elif defined(WIN_X)
3025 if ( Nlm_GetTextMetrics() )
3026 return (Nlm_Int2)XTextWidth(&fontInfo, text, (int)len);
3027
3028 #elif defined(WIN_GIF)
3029 return (Nlm_Int2)(Nlm_curGIFFont->w * len);
3030 #endif
3031 }
3032
3033 return 0;
3034 }
3035
3036 #if defined(WIN_MAC) && defined(WIN_MAC_ATSUI)
3037 static ATSFontMetrics Nlm_CurrentATSUFontMetrics(void)
3038 {
3039 Nlm_FontTool curStyle = Nlm_FontToATSUStyle (Nlm_fontInUse);
3040 ATSUFontID fontID = 0;
3041 ByteCount ignoredCount;
3042
3043 ATSUGetAttribute (curStyle, kATSUFontTag, sizeof (fontID), &fontID, &ignoredCount);
3044
3045 ATSFontRef font = FMGetATSFontRefFromFont (fontID);
3046
3047 ATSFontMetrics metrics;
3048 memset (&metrics, 0, sizeof (metrics));
3049 ATSFontGetHorizontalMetrics (font, kATSOptionFlagsDefault, &metrics);
3050
3051 return metrics;
3052 }
3053
3054 static Fixed Nlm_CurrentATSUFontSize(void)
3055 {
3056 Nlm_FontTool curStyle = Nlm_FontToATSUStyle (Nlm_fontInUse);
3057 Fixed size = 0;
3058 ByteCount ignoredCount;
3059
3060 ATSUGetAttribute (curStyle, kATSUSizeTag, sizeof (size), &size, &ignoredCount);
3061
3062 return size;
3063 }
3064 #endif
3065
3066 extern Nlm_Int2 Nlm_Ascent (void)
3067
3068 {
3069 #ifdef WIN_MAC
3070 #ifdef WIN_MAC_ATSUI
3071 return ceilf (Nlm_CurrentATSUFontMetrics().ascent * Nlm_CurrentATSUFontSize() / 65536.0);
3072 #else
3073 FontInfo fontinfo;
3074
3075 GetFontInfo (&fontinfo);
3076 return (fontinfo.ascent);
3077 #endif
3078 #endif
3079 #ifdef WIN_MSWIN
3080 Nlm_Int2 rsult;
3081
3082 rsult = 0;
3083 if (Nlm_GetTextMetrics ()) {
3084 rsult = (Nlm_Int2) textMetrics.tmAscent;
3085 }
3086 return rsult;
3087 #endif
3088 #ifdef WIN_X
3089 Nlm_Int2 rsult;
3090
3091 rsult = 0;
3092 if (Nlm_GetTextMetrics ()) {
3093 rsult = MAX (fontInfo.ascent, fontInfo.max_bounds.ascent);
3094 }
3095 return rsult;
3096 #endif
3097 #ifdef WIN_GIF
3098 return (Nlm_Int2)Nlm_curGIFFont->h - (Nlm_Int2)Nlm_curGIFFont->d;
3099 #endif
3100 }
3101
3102 extern Nlm_Int2 Nlm_Descent (void)
3103
3104 {
3105 #ifdef WIN_MAC
3106 #ifdef WIN_MAC_ATSUI
3107 return ceilf (-Nlm_CurrentATSUFontMetrics().descent * Nlm_CurrentATSUFontSize() / 65536.0);
3108 #else
3109 FontInfo fontinfo;
3110
3111 GetFontInfo (&fontinfo);
3112 return (fontinfo.descent);
3113 #endif
3114 #endif
3115 #ifdef WIN_MSWIN
3116 Nlm_Int2 rsult;
3117
3118 rsult = 0;
3119 if (Nlm_GetTextMetrics ()) {
3120 rsult = (Nlm_Int2) textMetrics.tmDescent;
3121 }
3122 return rsult;
3123 #endif
3124 #ifdef WIN_X
3125 Nlm_Int2 rsult;
3126
3127 rsult = 0;
3128 if (Nlm_GetTextMetrics ()) {
3129 rsult = MAX (fontInfo.descent, fontInfo.max_bounds.descent);
3130 }
3131 return rsult;
3132 #endif
3133 #ifdef WIN_GIF
3134 return (Nlm_Int2)Nlm_curGIFFont->d;
3135 #endif
3136 }
3137
3138 extern Nlm_Int2 Nlm_Leading (void)
3139
3140 {
3141 #ifdef WIN_MAC
3142 #ifdef WIN_MAC_ATSUI
3143 return ceilf (Nlm_CurrentATSUFontMetrics().leading * Nlm_CurrentATSUFontSize() / 65536.0);
3144 #else
3145 FontInfo fontinfo;
3146
3147 GetFontInfo (&fontinfo);
3148 return (fontinfo.leading);
3149 #endif
3150 #endif
3151 #ifdef WIN_MSWIN
3152 Nlm_Int2 rsult;
3153
3154 rsult = 0;
3155 if (Nlm_GetTextMetrics ()) {
3156 rsult = (Nlm_Int2) textMetrics.tmExternalLeading;
3157 }
3158 return rsult;
3159 #endif
3160 #ifdef WIN_X
3161 return 0;
3162 #endif
3163 #ifdef WIN_GIF
3164 return 0;
3165 #endif
3166 }
3167
3168 extern Nlm_Int2 Nlm_FontHeight (void)
3169
3170 {
3171 #ifdef WIN_MAC
3172 #ifdef WIN_MAC_ATSUI
3173 return Nlm_Ascent() + Nlm_Descent();
3174 #else
3175 FontInfo fontinfo;
3176
3177 GetFontInfo (&fontinfo);
3178 return (fontinfo.ascent + fontinfo.descent);
3179 #endif
3180 #endif
3181 #ifdef WIN_MSWIN
3182 Nlm_Int2 rsult;
3183
3184 rsult = 0;
3185 if (Nlm_GetTextMetrics ()) {
3186 rsult = (Nlm_Int2) textMetrics.tmHeight;
3187 }
3188 return rsult;
3189 #endif
3190 #ifdef WIN_X
3191 Nlm_Int2 rsult;
3192
3193 rsult = 0;
3194 if (Nlm_GetTextMetrics ()) {
3195 rsult = (MAX (fontInfo.ascent, fontInfo.max_bounds.ascent) +
3196 MAX (fontInfo.descent, fontInfo.max_bounds.descent));
3197 }
3198 return rsult;
3199 #endif
3200 #ifdef WIN_GIF
3201 return (Nlm_Int2)Nlm_curGIFFont->h;
3202 #endif
3203 }
3204
3205 extern Nlm_Int2 Nlm_LineHeight (void)
3206
3207 {
3208 #ifdef WIN_MAC
3209 #ifdef WIN_MAC_ATSUI
3210 return Nlm_Ascent() + Nlm_Descent() + Nlm_Leading();
3211 #else
3212 FontInfo fontinfo;
3213
3214 GetFontInfo (&fontinfo);
3215 return (fontinfo.ascent + fontinfo.descent + fontinfo.leading);
3216 #endif
3217 #endif
3218 #ifdef WIN_MSWIN
3219 Nlm_Int2 rsult;
3220
3221 rsult = 0;
3222 if (Nlm_GetTextMetrics ()) {
3223 rsult = (Nlm_Int2) (textMetrics.tmHeight + textMetrics.tmExternalLeading);
3224 }
3225 return rsult;
3226 #endif
3227 #ifdef WIN_X
3228 Nlm_Int2 rsult;
3229
3230 rsult = 0;
3231 if (Nlm_GetTextMetrics ()) {
3232 rsult = (MAX (fontInfo.ascent, fontInfo.max_bounds.ascent) +
3233 MAX (fontInfo.descent, fontInfo.max_bounds.descent));
3234 }
3235 return rsult;
3236 #endif
3237 #ifdef WIN_GIF
3238 return (Nlm_Int2)(Nlm_curGIFFont->h + 1);
3239 #endif
3240 }
3241
3242 extern Nlm_Int2 Nlm_MaxCharWidth (void)
3243
3244 {
3245 #ifdef WIN_MAC
3246 #ifdef WIN_MAC_ATSUI
3247 return ceilf (Nlm_CurrentATSUFontMetrics().maxAdvanceWidth * Nlm_CurrentATSUFontSize() / 65536.0);
3248 #else
3249 FontInfo fontinfo;
3250
3251 GetFontInfo (&fontinfo);
3252 return (fontinfo.widMax);
3253 #endif
3254 #endif
3255 #ifdef WIN_MSWIN
3256 Nlm_Int2 rsult;
3257
3258 rsult = 0;
3259 if (Nlm_GetTextMetrics ()) {
3260 rsult = (Nlm_Int2) textMetrics.tmMaxCharWidth;
3261 }
3262 return rsult;
3263 #endif
3264 #ifdef WIN_X
3265 Nlm_Int2 rsult;
3266
3267 rsult = 0;
3268 if (Nlm_GetTextMetrics ()) {
3269 rsult = fontInfo.max_bounds.width;
3270 }
3271 return rsult;
3272 #endif
3273 #ifdef WIN_GIF
3274 return (Nlm_Int2)Nlm_curGIFFont->w;
3275 #endif
3276 }
3277
3278
3279 size_t Nlm_FitStringWidth(const Nlm_Char PNTR str, Nlm_Int4 max_width)
3280 {
3281 size_t len;
3282 if (!str || !*str || max_width < 1)
3283 return 0;
3284
3285 #if defined(WIN_X)
3286 {{
3287 if ( !Nlm_GetTextMetrics() )
3288 return 0;
3289
3290 if (fontInfo.min_byte1 || fontInfo.max_byte1)
3291 return 0; /* two-byte font */
3292
3293 if ( !fontInfo.per_char ) /* non-proportional font */
3294 return (fontInfo.max_bounds.width > 0 ?
3295 max_width / fontInfo.max_bounds.width : 0);
3296
3297 {{
3298 Nlm_Int4 width = 0;
3299 unsigned min_char = fontInfo.min_char_or_byte2;
3300 unsigned max_char = fontInfo.max_char_or_byte2;
3301 XCharStruct *per_char = fontInfo.per_char;
3302 int def_char_width =
3303 (min_char <= fontInfo.default_char &&
3304 fontInfo.default_char <= max_char) ?
3305 per_char[fontInfo.default_char - min_char].width : 0;
3306 const unsigned char *ustr = (const unsigned char *) str;
3307
3308 for (len = 0; width <= max_width && *ustr; len++, ustr++)
3309 {
3310 if (min_char <= *ustr && *ustr <= max_char) {
3311 int w = per_char[*ustr - min_char].width;
3312 width += w ? w : def_char_width;
3313 }
3314 else
3315 width += def_char_width;
3316 }
3317
3318 return (width > max_width ? len-1 : len);
3319 }}
3320 }}
3321 #else
3322 {{ /* platform-independent algorithm */
3323 Nlm_Int2 max_char_width = Nlm_MaxCharWidth();
3324 if (max_char_width < 1)
3325 return 0;
3326
3327 ASSERT ( max_width > 0 );
3328 if (Nlm_StringWidth( (Nlm_CharPtr)str ) <= max_width)
3329 return Nlm_StringLen( str );
3330
3331 len = (size_t)(max_width / max_char_width);
3332 ASSERT ( len < StringLen( str ) );
3333
3334 while (str[len] != '\0' &&
3335 Nlm_TextWidth((Nlm_CharPtr)str, len) <= max_width)
3336 len++;
3337
3338 return (len ? len-1 : 0);
3339 }}
3340 #endif
3341 }
3342
3343
3344 extern void Nlm_SetPen (Nlm_PoinT pt)
3345 {
3346 #ifdef WIN_MAC
3347 Nlm_MoveTo (pt.x, pt.y);
3348 #endif
3349 #ifdef WIN_MSWIN
3350 if (Nlm_currentHDC != NULL) {
3351 MoveToEx (Nlm_currentHDC, pt.x, pt.y, NULL);
3352 }
3353 #endif
3354 #ifdef WIN_X
3355 currentPoint = pt;
3356 #endif
3357 #ifdef WIN_GIF
3358 Nlm_curGIFPoint = pt;
3359 #endif
3360 }
3361
3362 extern void Nlm_GetPen (Nlm_PointPtr pt)
3363
3364 {
3365 #ifdef WIN_MAC_QUARTZ
3366 CGPoint cgp;
3367
3368 if (pt != NULL) {
3369 cgp = CGContextGetPathCurrentPoint(Nlm_PeekQContext());
3370 }
3371 pt->x = cgp.x;
3372 pt->y = cgp.y;
3373 #elif defined(WIN_MAC)
3374 Nlm_PointTool ptool;
3375
3376 if (pt != NULL) {
3377 GetPen (&ptool);
3378 Local__PointToolToPoinT (ptool, pt);
3379 }
3380 #endif
3381 #ifdef WIN_MSWIN
3382 POINT pos;
3383
3384 if (pt != NULL && Nlm_currentHDC != NULL) {
3385 GetCurrentPositionEx (Nlm_currentHDC, &pos);
3386 pt->x = (Nlm_Int2) pos.x;
3387 pt->y = (Nlm_Int2) pos.y;
3388 }
3389 #endif
3390 #ifdef WIN_X
3391 if (pt != NULL) {
3392 *pt = currentPoint;
3393 }
3394 #endif
3395 #ifdef WIN_GIF
3396 *pt = Nlm_curGIFPoint;
3397 #endif
3398 }
3399
3400 void Nlm_SetPenWidth(Nlm_Int2 width)
3401 {
3402 #ifdef WIN_MAC
3403 #ifdef WIN_MAC_QUARTZ
3404 CGContextSetLineWidth (Nlm_PeekQContext(), width);
3405 #else
3406 PenSize (width, width);
3407 #endif
3408 #endif
3409 }
3410
3411 extern void Nlm_PaintChar (Nlm_Char ch)
3412
3413 {
3414 #ifdef WIN_MAC
3415 #ifdef WIN_MAC_QUARTZ
3416 Nlm_PoinT pt;
3417 Nlm_GetPen (& pt);
3418 CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, & ch, 1);
3419 #else
3420 DrawChar (ch);
3421 #endif
3422 #endif
3423 #ifdef WIN_MSWIN
3424 Nlm_PoinT pt;
3425 Nlm_Char str [2];
3426
3427 if (Nlm_currentHDC != NULL) {
3428 str [0] = ch;
3429 str [1] = '\0';
3430 Nlm_GetPen (&pt);
3431 TextOut (Nlm_currentHDC, pt.x, pt.y - Nlm_Ascent (), str, 1);
3432 pt.x += Nlm_CharWidth (ch);
3433 Nlm_MoveTo (pt.x, pt.y);
3434 }
3435 #endif
3436 #ifdef WIN_X
3437 Nlm_PoinT pt;
3438 Nlm_Char str [2];
3439
3440 if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 &&
3441 Nlm_currentXGC != NULL) {
3442 str [0] = ch;
3443 str [1] = '\0';
3444 Nlm_GetPen (&pt);
3445 XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
3446 pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, str, 1);
3447 pt.x += Nlm_CharWidth (ch);
3448 Nlm_MoveTo (pt.x, pt.y);
3449 }
3450 #endif
3451 #ifdef WIN_GIF
3452 if ( Nlm_currentGIF != NULL ){
3453 gdImageChar ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x,
3454 Nlm_curGIFPoint.y - Nlm_Ascent(),
3455 (int)ch, Nlm_curGIFColor );
3456 Nlm_curGIFPoint.x += Nlm_CharWidth (ch);
3457 }
3458 #endif
3459 }
3460
3461
3462 extern void Nlm_PaintStringEx(Nlm_CharPtr text, Nlm_Int2 x, Nlm_Int2 y)
3463 {
3464 #ifdef WIN_MSWIN
3465 if (!text || !*text || !Nlm_currentHDC)
3466 return;
3467
3468 TextOut(Nlm_currentHDC, x, y - Nlm_Ascent(),
3469 text, (Nlm_Int2)Nlm_StringLen( text ));
3470 Nlm_MoveTo((Nlm_Int2)(x + Nlm_StringWidth(text)), y);
3471 #else
3472 Nlm_MoveTo(x, y);
3473 Nlm_PaintString( text );
3474 #endif
3475 }
3476
3477
3478 extern void Nlm_PaintString (Nlm_CharPtr text)
3479 {
3480 #ifdef WIN_MAC
3481 #ifdef WIN_MAC_ATSUI
3482 OSErr err;
3483 Nlm_PoinT pt;
3484 CFStringRef cfString;
3485 CFIndex cfsLen;
3486 const UniChar * unicodeString;
3487 ATSUTextLayout layout;
3488 Nlm_FontTool curStyle;
3489
3490 /* convert the string to Unicode */
3491 cfString = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingMacRoman);
3492 if (cfString == NULL)
3493 return;
3494 cfsLen = CFStringGetLength(cfString);
3495 unicodeString = CFStringGetCharactersPtr(cfString);
3496 if (unicodeString == NULL) {
3497 CFRange range;
3498 static UniChar ucbuf[1024];
3499
3500 range.location = 0;
3501 range.length = MIN(cfsLen, 1024);
3502 CFStringGetCharacters (cfString, range, ucbuf);
3503 unicodeString = ucbuf;
3504 }
3505
3506 /* get the current style */
3507 curStyle = Nlm_FontToATSUStyle(Nlm_fontInUse);
3508
3509 /* create the layout */
3510 err = ATSUCreateTextLayoutWithTextPtr (
3511 unicodeString,
3512 0,
3513 cfsLen,
3514 cfsLen,
3515 1,
3516 (unsigned long *)&cfsLen,
3517 &curStyle,
3518 &layout
3519 );
3520
3521 /* draw where? */
3522 Nlm_GetPen (&pt);
3523 /* CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, text, Nlm_StringLen (text)); */
3524 err = ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd,
3525 Long2Fix(pt.x), Long2Fix(pt.y));
3526
3527 #else
3528 Nlm_PoinT pt;
3529 Nlm_Char str [256];
3530
3531 if (text != NULL) {
3532 Nlm_GetPen (&pt);
3533 if (Nlm_StringLen (text) > 0) {
3534 Nlm_StringNCpy_0 (str, text, sizeof (str));
3535 Nlm_CtoPstr (str);
3536 DrawString ((StringPtr) str);
3537 }
3538 pt.x += Nlm_StringWidth (text);
3539 Nlm_MoveTo (pt.x, pt.y);
3540 }
3541 #endif
3542 #endif
3543 #ifdef WIN_MSWIN
3544 Nlm_PoinT pt;
3545 Nlm_GetPen( &pt );
3546 Nlm_PaintStringEx(text, pt.x, pt.y);
3547 #endif
3548 #ifdef WIN_X
3549 Nlm_Int2 len;
3550 Nlm_PoinT pt;
3551
3552 if (text != NULL && Nlm_currentXDisplay != NULL &&
3553 Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) {
3554 len = (Nlm_Int2) Nlm_StringLen (text);
3555 Nlm_GetPen (&pt);
3556 if (len > 0) {
3557 XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
3558 pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, text, len);
3559 }
3560 pt.x += Nlm_StringWidth (text);
3561 Nlm_MoveTo (pt.x, pt.y);
3562 }
3563 #endif
3564 #ifdef WIN_GIF
3565 if ( text != NULL && Nlm_currentGIF != NULL ){
3566 gdImageString ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x,
3567 Nlm_curGIFPoint.y - Nlm_Ascent(),
3568 text, Nlm_curGIFColor );
3569 Nlm_curGIFPoint.x += Nlm_StringWidth (text);
3570 }
3571 #endif
3572 }
3573
3574
3575 #ifdef VAR_ARGS
3576 void CDECL Nlm_PaintText (format, va_alist)
3577 char *format;
3578 va_dcl
3579 #else
3580 void CDECL Nlm_PaintText (char *format, ...)
3581 #endif
3582 {
3583 #ifdef WIN_MAC
3584 va_list args;
3585 Nlm_PoinT pt;
3586 Nlm_Char str [256];
3587
3588 if (format != NULL) {
3589 #ifdef VAR_ARGS
3590 va_start(args);
3591 #else
3592 va_start(args, format);
3593 #endif
3594 vsprintf(str, format, args);
3595 va_end(args);
3596 Nlm_GetPen (&pt);
3597 #ifdef WIN_MAC_QUARTZ
3598 CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, str, Nlm_StringLen (str));
3599 #else
3600 if (Nlm_StringLen (str) > 0) {
3601 Nlm_CtoPstr (str);
3602 DrawString ((StringPtr) str);
3603 }
3604 pt.y += Nlm_LineHeight ();
3605 Nlm_MoveTo (pt.x, pt.y);
3606 #endif
3607 }
3608 #endif
3609 #ifdef WIN_MSWIN
3610 va_list args;
3611 Nlm_Int2 len;
3612 Nlm_PoinT pt;
3613 Nlm_Char str [256];
3614
3615 if (format != NULL && Nlm_currentHDC != NULL) {
3616 #ifdef VAR_ARGS
3617 va_start(args);
3618 #else
3619 va_start(args, format);
3620 #endif
3621 vsprintf(str, format, args);
3622 va_end(args);
3623 len = (Nlm_Int2) Nlm_StringLen (str);
3624 Nlm_GetPen (&pt);
3625 if (len > 0) {
3626 TextOut (Nlm_currentHDC, pt.x, pt.y - Nlm_Ascent (), str, len);
3627 }
3628 pt.y += Nlm_LineHeight ();
3629 Nlm_MoveTo (pt.x, pt.y);
3630 }
3631 #endif
3632 #ifdef WIN_X
3633 va_list args;
3634 Nlm_Int2 len;
3635 Nlm_PoinT pt;
3636 Nlm_Char str [256];
3637
3638 if (format != NULL && Nlm_currentXDisplay != NULL &&
3639 Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) {
3640 #ifdef VAR_ARGS
3641 va_start(args);
3642 #else
3643 va_start(args, format);
3644 #endif
3645 vsprintf(str, format, args);
3646 va_end(args);
3647 len = (Nlm_Int2) Nlm_StringLen (str);
3648 Nlm_GetPen (&pt);
3649 if (len > 0) {
3650 XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
3651 pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, str, len);
3652 }
3653 pt.y += Nlm_LineHeight ();
3654 Nlm_MoveTo (pt.x, pt.y);
3655 }
3656 #endif
3657 #ifdef WIN_GIF
3658 va_list args;
3659 Nlm_Char str [256];
3660
3661 if ( format != NULL && Nlm_currentGIF != NULL ){
3662 #ifdef VAR_ARGS
3663 va_start(args);
3664 #else
3665 va_start(args, format);
3666 #endif
3667 vsprintf(str, format, args);
3668 va_end(args);
3669 gdImageString ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x,
3670 Nlm_curGIFPoint.y - Nlm_Ascent(),
3671 str, Nlm_curGIFColor );
3672 Nlm_curGIFPoint.x += Nlm_StringWidth (str);
3673 }
3674 #endif
3675 }
3676
3677 extern void Nlm_DrawString (Nlm_RectPtr r, Nlm_CharPtr text,
3678 Nlm_Char jst, Nlm_Boolean gray)
3679
3680 {
3681 Nlm_DrawText (r, text, Nlm_StringLen (text), jst, gray);
3682 }
3683
3684 extern void Nlm_DrawText (Nlm_RectPtr r, Nlm_CharPtr text,
3685 size_t len, Nlm_Char jst,
3686 Nlm_Boolean gray)
3687
3688 {
3689 #ifdef WIN_MAC
3690 #ifdef WIN_MAC_ATSUI
3691 CFStringRef cfString;
3692 CFIndex cfsLen;
3693 Nlm_RectTool rtool;
3694 OSStatus err;
3695 ATSUStyle aStyle;
3696 TXNTextBoxOptionsData boxOptions;
3697
3698 if (r != NULL) {
3699 Nlm_EraseRect (r);
3700 if (text != NULL && len > 0) {
3701 cfString = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)text, len, kCFStringEncodingMacRoman, false);
3702 if (cfString == NULL)
3703 return;
3704 cfsLen = CFStringGetLength(cfString);
3705
3706 Local__RecTToRectTool(r, &rtool);
3707
3708 boxOptions.optionTags = kTXNSetFlushnessMask;
3709 switch (jst) {
3710 case 'r':
3711 boxOptions.flushness = kATSUEndAlignment;
3712 break;
3713 case 'l':
3714 boxOptions.flushness = kATSUStartAlignment;
3715 break;
3716 case 'c':
3717 boxOptions.flushness = kATSUCenterAlignment;
3718 break;
3719 default:
3720 boxOptions.flushness = kATSUStartAlignment;
3721 break;
3722 }
3723 aStyle = Nlm_FontToATSUStyle(Nlm_fontInUse);
3724
3725 #ifdef WIN_MAC_QUARTZ
3726 // QUARTZ_FIXME: is this stuff necessary?
3727 // boxOptions.optionTags |= kTXNUseCGContextRefMask;
3728 // boxOptions.options = Nlm_PeekQContext();
3729 // CGContextSaveGState(Nlm_PeekQContext());
3730 // /* need to undo the coordinate transforms, otherwise the text comes out upside down. */
3731 // CGContextScaleCTM(Nlm_PeekQContext(), 1.0f, -1.0f);
3732 // {
3733 // Rect pBounds;
3734 // int pHeight;
3735 // GrafPtr grafptr;
3736 //
3737 // GetPort(&grafptr);
3738 // GetPortBounds(grafptr, &pBounds);
3739 // pHeight = pBounds.bottom - pBounds.top;
3740 // CGContextTranslateCTM(Nlm_PeekQContext(), 0, -pHeight);
3741 // }
3742 #endif
3743
3744 err = TXNDrawCFStringTextBox(cfString, &rtool, aStyle, &boxOptions);
3745 CFRelease(cfString);
3746
3747 //#ifdef WIN_MAC_QUARTZ
3748 // CGContextRestoreGState(Nlm_PeekQContext());
3749 //#endif
3750 }
3751 }
3752
3753 #else
3754 Nlm_Int2 delta;
3755 Nlm_Int2 height;
3756 Nlm_Int2 just;
3757 Nlm_Int2 limit;
3758 PenState pnState;
3759 Nlm_RectTool rtool;
3760
3761 if (r != NULL) {
3762 Nlm_EraseRect (r);
3763 if (text != NULL && len > 0) {
3764 Local__RecTToRectTool (r, &rtool);
3765 limit = ABS (r->bottom - r->top);
3766 height = Nlm_LineHeight ();
3767 delta = limit - height;
3768 if (delta > 0) {
3769 rtool.top += delta / 2;
3770 rtool.bottom = rtool.top + height;
3771 }
3772 switch (jst) {
3773 case 'r':
3774 just = -1;
3775 break;
3776 case 'l':
3777 just = 0;
3778 break;
3779 case 'c':
3780 just = 1;
3781 break;
3782 default:
3783 just = 0;
3784 break;
3785 }
3786 TETextBox (text, len, &rtool, just);
3787 if (gray) {
3788 GetPenState (&pnState);
3789 PenMode (patBic);
3790 PenPat ((ConstPatternParam) grayPat);
3791 PaintRect (&rtool);
3792 SetPenState (&pnState);
3793 }
3794 }
3795 }
3796 #endif
3797 #endif
3798 #ifdef WIN_MSWIN
3799 Nlm_Int2 format;
3800 Nlm_Int4 oldcolor = 0;
3801 Nlm_RectTool rtool;
3802 Nlm_FontData fdata;
3803 SIZE tsize;
3804 HDC hdc;
3805
3806 if (r != NULL && Nlm_currentHDC != NULL) {
3807 Local__RecTToRectTool (r, &rtool);
3808 if (Nlm_currentHWnd != NULL) {
3809 Nlm_EraseRect (r);
3810 } else {
3811 FillRect (Nlm_currentHDC, &rtool, hWhiteBrush);
3812 }
3813 if (text != NULL && len > 0) {
3814 switch (jst) {
3815 case 'r':
3816 format = DT_RIGHT;
3817 break;
3818 case 'l':
3819 format = DT_LEFT;
3820 break;
3821 case 'c':
3822 format = DT_CENTER;
3823 break;
3824 default:
3825 format = DT_LEFT;
3826 break;
3827 }
3828 if (gray) {
3829 winTextColor = GetSysColor (COLOR_GRAYTEXT);
3830 oldcolor = SetTextColor (Nlm_currentHDC, winTextColor);
3831 }
3832 hdc = Nlm_GetPicWinHDC();
3833 if ( hdc == NULL ){
3834 /* esl: DT_VCENTER must be combined with DT_SINGLELINE! */
3835 DrawText (Nlm_currentHDC, text, (Nlm_Int2) len, &rtool,
3836 format | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
3837 } else {
3838 if ( Nlm_fontInUse != NULL ){
3839 Nlm_GetFontData (Nlm_fontInUse, &fdata);
3840 SelectObject (hdc, fdata.handle);
3841 }
3842 GetTextExtentPoint ( hdc, text, len, &tsize );
3843 tsize.cy = (r->top + r->bottom)/2 - tsize.cy/2;
3844 switch ( format ){
3845 case DT_LEFT:
3846 tsize.cx = r->left; break;
3847 case DT_RIGHT:
3848 tsize.cx = r->right - tsize.cx; break;
3849 default:
3850 tsize.cx = (r->left + r->right)/2 - tsize.cx/2;
3851 }
3852 Nlm_PaintStringEx(text, (Nlm_Int2)tsize.cx, (Nlm_Int2)tsize.cy);
3853 }
3854 if (gray) {
3855 SetTextColor (Nlm_currentHDC, oldcolor);
3856 winTextColor = oldcolor;
3857 }
3858 }
3859 }
3860 #endif
3861 #ifdef WIN_X
3862 Nlm_Int2 delta;
3863 Nlm_Int2 height;
3864 Nlm_Int2 limit;
3865 Pixmap pix = 0;
3866 Nlm_PoinT pt;
3867 Nlm_Int2 width;
3868
3869 if (r != NULL && Nlm_currentXDisplay != NULL &&
3870 Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) {
3871 Nlm_EraseRect (r);
3872 if (text != NULL && len > 0) {
3873 pt.x = r->left;
3874 pt.y = r->top;
3875 limit = ABS (r->right - r->left);
3876 width = Nlm_TextWidth (text, len);
3877 while (len > 0 && width > limit) {
3878 len--;
3879 width = Nlm_TextWidth (text, len);
3880 }
3881 delta = limit - width;
3882 switch (jst) {
3883 case 'r':
3884 pt.x += delta;
3885 break;
3886 case 'l':
3887 break;
3888 case 'c':
3889 pt.x += delta / 2;
3890 break;
3891 default:
3892 break;
3893 }
3894 limit = ABS (r->bottom - r->top);
3895 height = Nlm_LineHeight ();
3896 delta = limit - height;
3897 if (delta > 0) {
3898 pt.y += delta / 2;
3899 }
3900 if (limit >= height) {
3901 if (gray) {
3902 pix = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow,
3903 (char *) grayPat, 8, 8);
3904 if (pix != 0 && Nlm_currentXGC != NULL) {
3905 XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, pix);
3906 }
3907 }
3908 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled);
3909 XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
3910 pt.x - Nlm_XOffset, pt.y + Nlm_Ascent () - Nlm_YOffset,
3911 text, (int) len);
3912 if (gray && pix != 0) {
3913 XFreePixmap (Nlm_currentXDisplay, pix);
3914 if (Nlm_currentXGC != NULL) {
3915 XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, currentPixmap);
3916 }
3917 }
3918 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
3919 }
3920 }
3921 }
3922 #endif
3923 #ifdef WIN_GIF
3924 Nlm_Int2 delta;
3925 Nlm_Int2 height;
3926 Nlm_Int2 limit;
3927 Nlm_PoinT pt;
3928 Nlm_Int2 width;
3929
3930 if (r != NULL && Nlm_currentGIF != NULL ) {
3931 Nlm_EraseRect (r);
3932 if (text != NULL && len > 0) {
3933 pt.x = r->left;
3934 pt.y = r->top;
3935 limit = ABS (r->right - r->left);
3936 width = Nlm_TextWidth (text, len);
3937 while (len > 0 && width > limit) {
3938 len--;
3939 width = Nlm_TextWidth (text, len);
3940 }
3941 delta = limit - width;
3942 switch (jst) {
3943 case 'r':
3944 pt.x += delta;
3945 break;
3946 case 'l':
3947 break;
3948 case 'c':
3949 pt.x += delta / 2;
3950 break;
3951 default:
3952 break;
3953 }
3954 limit = ABS (r->bottom - r->top);
3955 height = Nlm_LineHeight ();
3956 delta = limit - height;
3957 if (delta > 0) {
3958 pt.y += delta / 2;
3959 }
3960 if (limit >= height) {
3961 char save;
3962 save = text[len];
3963 text[len] = 0;
3964 gdImageString ( Nlm_currentGIF, Nlm_curGIFFont,
3965 pt.x, pt.y,
3966 text, Nlm_curGIFColor );
3967 text[len] = save;
3968 }
3969 }
3970 }
3971 #endif
3972 }
3973
3974 extern void Nlm_MoveTo (Nlm_Int2 x, Nlm_Int2 y)
3975
3976 {
3977 #ifdef WIN_MAC
3978 #ifdef WIN_MAC_QUARTZ
3979 CGContextMoveToPoint(Nlm_PeekQContext(), x, y);
3980 #else
3981 MoveTo (x, y);
3982 #endif
3983 #endif
3984 #ifdef WIN_MSWIN
3985 if (Nlm_currentHDC != NULL) {
3986 MoveToEx (Nlm_currentHDC, x, y, NULL);
3987 }
3988 #endif
3989 #ifdef WIN_X
3990 currentPoint.x = x;
3991 currentPoint.y = y;
3992 #endif
3993 #ifdef WIN_GIF
3994 Nlm_curGIFPoint.x = x;
3995 Nlm_curGIFPoint.y = y;
3996 #endif
3997 }
3998
3999
4000 extern void Nlm_LineTo (Nlm_Int2 x, Nlm_Int2 y)
4001
4002 {
4003 #ifdef WIN_MAC
4004 #ifdef WIN_MAC_QUARTZ
4005 CGContextAddLineToPoint(Nlm_PeekQContext(), x, y);
4006 CGContextStrokePath(Nlm_PeekQContext());
4007 CGContextMoveToPoint(Nlm_PeekQContext(), x, y);
4008 #else
4009 LineTo (x, y);
4010 #endif
4011 #endif
4012 #ifdef WIN_MSWIN
4013 if (Nlm_currentHDC != NULL) {
4014 LineTo (Nlm_currentHDC, x, y);
4015 }
4016 #endif
4017 #ifdef WIN_X
4018 Nlm_PoinT to_point;
4019 to_point.x = x;
4020 to_point.y = y;
4021 Nlm_DrawLine(currentPoint, to_point);
4022 #endif
4023 #ifdef WIN_GIF
4024 if ( Nlm_currentGIF != NULL ){
4025 if ( Nlm_curGIFLType == GIF_DASHED ) {
4026 gdImageDashedLine ( Nlm_currentGIF, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y,
4027 x, y, Nlm_curGIFColor );
4028 } else {
4029 gdImageLine ( Nlm_currentGIF, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y,
4030 x, y, Nlm_curGIFColor );
4031 }
4032 Nlm_MoveTo ( x,y );
4033 }
4034 #endif
4035 }
4036
4037 extern void Nlm_DrawLine (Nlm_PoinT pt1, Nlm_PoinT pt2)
4038 {
4039 #ifdef WIN_MAC
4040 #ifdef WIN_MAC_QUARTZ
4041 CGContextMoveToPoint(Nlm_PeekQContext(), pt1.x, pt1.y);
4042 CGContextAddLineToPoint(Nlm_PeekQContext(), pt2.x, pt2.y);
4043 CGContextStrokePath(Nlm_PeekQContext());
4044 #else
4045 MoveTo (pt1.x, pt1.y);
4046 LineTo (pt2.x, pt2.y);
4047 #endif
4048 #endif
4049 #ifdef WIN_MSWIN
4050 if (Nlm_currentHDC != NULL) {
4051 if (pt1.x == pt2.x && pt1.y == pt2.y) {
4052 SetPixel(Nlm_currentHDC, pt1.x, pt1.y, winTextColor); /* just a dot */
4053 } else {
4054 MoveToEx(Nlm_currentHDC, pt1.x, pt1.y, NULL);
4055 LineTo (Nlm_currentHDC, pt2.x, pt2.y);
4056 }
4057 }
4058 #endif
4059 #ifdef WIN_X
4060 if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 &&
4061 Nlm_currentXGC != NULL)
4062 {
4063 XDrawLine(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4064 pt1.x - Nlm_XOffset, pt1.y - Nlm_YOffset,
4065 pt2.x - Nlm_XOffset, pt2.y - Nlm_YOffset);
4066 currentPoint.x = pt2.x;
4067 currentPoint.y = pt2.y;
4068 }
4069 #endif
4070 #ifdef WIN_GIF
4071 if ( Nlm_currentGIF != NULL ){
4072 if ( Nlm_curGIFLType == GIF_DASHED ) {
4073 gdImageDashedLine ( Nlm_currentGIF, pt1.x, pt1.y, pt2.x, pt2.y,
4074 Nlm_curGIFColor );
4075 } else {
4076 gdImageLine ( Nlm_currentGIF, pt1.x, pt1.y, pt2.x, pt2.y,
4077 Nlm_curGIFColor );
4078 }
4079 Nlm_MoveTo ( pt2.x, pt2.y );
4080 }
4081 #endif
4082 }
4083
4084 #ifdef WIN_GIF
4085 static void Nlm_GIFRgnToRect ( Nlm_RgnTool t, Nlm_RectPtr r )
4086 {
4087 Nlm_RectPtr rTool;
4088
4089 if ( t != NULL && r != NULL ){
4090 rTool = (Nlm_RectPtr)HandLock(t);
4091 *r = *rTool;
4092 HandUnlock(rTool);
4093 }
4094 }
4095
4096 static void Nlm_RectToGIFRgn ( Nlm_RectPtr r, Nlm_RgnTool t )
4097 {
4098 Nlm_RectPtr rTool;
4099
4100 if ( t != NULL && r != NULL ){
4101 rTool = (Nlm_RectPtr)HandLock(t);
4102 *rTool = *r;
4103 HandUnlock(rTool);
4104 }
4105 }
4106 #endif
4107
4108 extern void Nlm_LoadPt (Nlm_PointPtr pt, Nlm_Int2 x, Nlm_Int2 y)
4109
4110 {
4111 if (pt != NULL) {
4112 pt->x = x;
4113 pt->y = y;
4114 }
4115 }
4116
4117 extern void Nlm_AddPt (Nlm_PoinT src, Nlm_PointPtr dst)
4118
4119 {
4120 if (dst != NULL) {
4121 dst->x += src.x;
4122 dst->y += src.y;
4123 }
4124 }
4125
4126 extern void Nlm_SubPt (Nlm_PoinT src, Nlm_PointPtr dst)
4127
4128 {
4129 if (dst != NULL) {
4130 dst->x -= src.x;
4131 dst->y -= src.y;
4132 }
4133 }
4134
4135 extern Nlm_Boolean Nlm_EqualPt (Nlm_PoinT p1, Nlm_PoinT p2)
4136
4137 {
4138 return (Nlm_Boolean) (p1.x == p2.x && p1.y == p2.y);
4139 }
4140
4141 extern Nlm_Boolean Nlm_PtInRect (Nlm_PoinT pt, Nlm_RectPtr r)
4142
4143 {
4144 return (Nlm_Boolean) (r != NULL && pt.x >= r->left && pt.x < r->right &&
4145 pt.y >= r->top && pt.y < r->bottom);
4146 }
4147
4148 extern Nlm_Boolean Nlm_PtInRgn (Nlm_PoinT pt, Nlm_RegioN rgn)
4149
4150 {
4151 Nlm_RgnTool ntool;
4152 Nlm_Boolean rsult;
4153 #ifdef WIN_MAC
4154 #ifdef WIN_MAC_QUARTZ
4155 CGPoint ptool;
4156 #else
4157 Nlm_PointTool ptool;
4158 #endif
4159 #endif
4160 #ifdef WIN_GIF
4161 Nlm_RecT r;
4162 #endif
4163
4164 rsult = FALSE;
4165 if (rgn != NULL) {
4166 ntool = (Nlm_RgnTool) rgn;
4167 #ifdef WIN_MAC
4168 #ifdef WIN_MAC_QUARTZ
4169 ptool = Nlm_PoinTToCGPoint (pt);
4170 rsult = HIShapeContainsPoint (ntool, &ptool);
4171 #else
4172 Local__PoinTToPointTool (pt, &ptool);
4173 rsult = PtInRgn (ptool, ntool);
4174 #endif
4175 #endif
4176 #ifdef WIN_MSWIN
4177 rsult = (Nlm_Boolean) PtInRegion (ntool, pt.x, pt.y);
4178 #endif
4179 #ifdef WIN_X
4180 rsult = (XPointInRegion (ntool, pt.x, pt.y) != 0);
4181 #endif
4182 #ifdef WIN_GIF
4183 Nlm_GIFRgnToRect ( ntool, &r );
4184 rsult = Nlm_PtInRect (pt, &r);
4185 #endif
4186 }
4187 return rsult;
4188 }
4189
4190 extern void Nlm_LoadRect (Nlm_RectPtr r, Nlm_Int2 lf,
4191 Nlm_Int2 tp, Nlm_Int2 rt,
4192 Nlm_Int2 bt)
4193
4194 {
4195 if (r != NULL) {
4196 r->left = lf;
4197 r->top = tp;
4198 r->right = rt;
4199 r->bottom = bt;
4200 }
4201 }
4202
4203 extern void Nlm_UpsetRect (Nlm_RectPtr r, Nlm_Int2 lf,
4204 Nlm_Int2 tp, Nlm_Int2 rt,
4205 Nlm_Int2 bt)
4206
4207 {
4208 if (r != NULL) {
4209 r->left += lf;
4210 r->top += tp;
4211 r->right -= rt;
4212 r->bottom -= bt;
4213 }
4214 }
4215
4216 extern void Nlm_OffsetRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy)
4217
4218 {
4219 if (r != NULL) {
4220 r->left += dx;
4221 r->top += dy;
4222 r->right += dx;
4223 r->bottom += dy;
4224 }
4225 }
4226
4227 extern void Nlm_InsetRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy)
4228
4229 {
4230 if (r != NULL) {
4231 r->left += dx;
4232 r->top += dy;
4233 r->right -= dx;
4234 r->bottom -= dy;
4235 }
4236 }
4237
4238
4239 static void Nlm_LoadNormalized (Nlm_RectPtr dst, Nlm_RectPtr src)
4240 {
4241 if (!src || !dst)
4242 return;
4243
4244 Nlm_LoadRect(dst,
4245 (Nlm_Int2)MIN(src->left, src->right),
4246 (Nlm_Int2)MIN(src->top, src->bottom),
4247 (Nlm_Int2)MAX(src->left, src->right),
4248 (Nlm_Int2)MAX(src->top, src->bottom));
4249 }
4250
4251
4252 extern Nlm_Boolean Nlm_SectRect(Nlm_RectPtr src1, Nlm_RectPtr src2,
4253 Nlm_RectPtr dst)
4254 {
4255 #ifdef WIN_MAC_QUARTZ
4256 CGRect r1 = Nlm_RecTToCGRect (*src1);
4257 CGRect r2 = Nlm_RecTToCGRect (*src2);
4258 CGRect d = CGRectIntersection (r1, r2);
4259 *dst = Nlm_CGRectToRecT (d);
4260 return !CGRectIsNull (d);
4261 #else
4262
4263 #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ))
4264 Nlm_Boolean rsult;
4265 Nlm_RectTool rtool1;
4266 Nlm_RectTool rtool2;
4267 Nlm_RectTool rtool3;
4268 #elif defined(WIN_X) || defined(WIN_GIF)
4269 Nlm_RecT rect1;
4270 Nlm_RecT rect2;
4271 #endif
4272
4273 if (!src1 || !src2 || !dst)
4274 return FALSE;
4275
4276 #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ))
4277 Local__RecTToRectTool(src1, &rtool1);
4278 Local__RecTToRectTool(src2, &rtool2);
4279 #ifdef WIN_MSWIN
4280 rsult = (Nlm_Boolean)IntersectRect(&rtool3, &rtool1, &rtool2);
4281 #else
4282 rsult = SectRect(&rtool1, &rtool2, &rtool3);
4283 #endif
4284 Local__RectToolToRecT(&rtool3, dst);
4285 return rsult;
4286
4287 #elif defined(WIN_X) || defined(WIN_GIF)
4288 Nlm_LoadNormalized(&rect1, src1);
4289 Nlm_LoadNormalized(&rect2, src2);
4290 dst->left = MAX(rect1.left, rect2.left );
4291 dst->right = MIN(rect1.right, rect2.right );
4292 dst->top = MAX(rect1.top, rect2.top );
4293 dst->bottom = MIN(rect1.bottom, rect2.bottom);
4294 if (dst->left > dst->right || dst->top > dst->bottom)
4295 {
4296 Nlm_LoadRect(dst, 0, 0, 0, 0);
4297 return FALSE;
4298 }
4299 return TRUE;
4300 #endif
4301 #endif
4302 }
4303
4304
4305 extern Nlm_Boolean Nlm_UnionRect(Nlm_RectPtr src1, Nlm_RectPtr src2,
4306 Nlm_RectPtr dst)
4307 {
4308 #ifdef WIN_MAC_QUARTZ
4309 CGRect r1 = Nlm_RecTToCGRect (*src1);
4310 CGRect r2 = Nlm_RecTToCGRect (*src2);
4311 CGRect d = CGRectUnion (r1, r2);
4312 *dst = Nlm_CGRectToRecT (d);
4313 return CGRectIsEmpty (d);
4314 #else
4315
4316 #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ))
4317 Nlm_Boolean rsult;
4318 Nlm_RectTool rtool1;
4319 Nlm_RectTool rtool2;
4320 Nlm_RectTool rtool3;
4321 #elif defined(WIN_X) || defined(WIN_GIF)
4322 Nlm_RecT rect1;
4323 Nlm_RecT rect2;
4324 #endif
4325
4326 if (!src1 || !src2 || !dst)
4327 return FALSE;
4328
4329 #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ))
4330 Local__RecTToRectTool(src1, &rtool1);
4331 Local__RecTToRectTool(src2, &rtool2);
4332 #ifdef WIN_MSWIN
4333 rsult = (Nlm_Boolean)UnionRect(&rtool3, &rtool1, &rtool2);
4334 #else
4335 UnionRect(&rtool1, &rtool2, &rtool3);
4336 rsult = EmptyRect(&rtool3);
4337 #endif
4338 Local__RectToolToRecT(&rtool3, dst);
4339 return rsult;
4340
4341 #elif defined(WIN_X) || defined(WIN_GIF)
4342 Nlm_LoadNormalized (&rect1, src1);
4343 Nlm_LoadNormalized (&rect2, src2);
4344 dst->left = MIN(rect1.left, rect2.left );
4345 dst->right = MAX(rect1.right, rect2.right );
4346 dst->top = MIN(rect1.top, rect2.top );
4347 dst->bottom = MAX(rect1.bottom, rect2.bottom);
4348 return TRUE;
4349 #endif
4350 #endif
4351 }
4352
4353
4354 extern Nlm_Boolean Nlm_EqualRect (Nlm_RectPtr r1, Nlm_RectPtr r2)
4355
4356 {
4357 return (Nlm_Boolean) (r1 != NULL && r2 != NULL && r1->left == r2->left &&
4358 r1->top == r2->top && r1->right == r2->right &&
4359 r1->bottom == r2->bottom);
4360 }
4361
4362 extern Nlm_Boolean Nlm_EmptyRect (Nlm_RectPtr r)
4363
4364 {
4365 return (Nlm_Boolean) ! (r != NULL && r->bottom > r->top && r->right > r->left);
4366 }
4367
4368 extern Nlm_Boolean Nlm_RectInRect (Nlm_RectPtr r1, Nlm_RectPtr r2)
4369
4370 {
4371 Nlm_Boolean rsult;
4372
4373 rsult = FALSE;
4374 if (r1 != NULL && r2 != NULL &&
4375 r1->top >= r2->top && r1->bottom <= r2->bottom &&
4376 r1->left >= r2->left && r1->right <= r2->right) {
4377 rsult = TRUE;
4378 }
4379 return rsult;
4380 }
4381
4382 extern Nlm_Boolean Nlm_RectInRgn (Nlm_RectPtr r, Nlm_RegioN rgn)
4383
4384 {
4385 Nlm_RgnTool ntool;
4386 Nlm_Boolean rsult;
4387 Nlm_RectTool rtool;
4388 #ifdef WIN_MAC_QUARTZ
4389 CGRect rect;
4390 #endif
4391 #ifdef WIN_GIF
4392 Nlm_RecT rect;
4393 #endif
4394
4395 rsult = FALSE;
4396 if (r != NULL && rgn != NULL) {
4397 Local__RecTToRectTool (r, &rtool);
4398 ntool = (Nlm_RgnTool) rgn;
4399 #ifdef WIN_MAC
4400 #ifdef WIN_MAC_QUARTZ
4401 rect = Nlm_RecTToCGRect (*r);
4402 rsult = HIShapeIntersectsRect (ntool, &rect);
4403 #else
4404 rsult = RectInRgn (&rtool, ntool);
4405 #endif
4406 #endif
4407 #ifdef WIN_MSWIN
4408 rsult = (Nlm_Boolean) RectInRegion (ntool, &rtool);
4409 #endif
4410 #ifdef WIN_X
4411 rsult = (XRectInRegion (ntool, rtool.x, rtool.y, rtool.width+1, rtool.height+1) != 0);
4412 #endif
4413 #ifdef WIN_GIF
4414 Nlm_GIFRgnToRect ( ntool, &rect );
4415 rsult = Nlm_RectInRect (r, &rect) ;
4416 #endif
4417 }
4418 return rsult;
4419 }
4420
4421
4422 extern void Nlm_EraseRect (Nlm_RectPtr r)
4423 {
4424 Nlm_RectTool rtool;
4425 if ( !r )
4426 return;
4427
4428 Local__RecTToRectTool(r, &rtool);
4429
4430 #ifdef WIN_MAC
4431 #ifdef WIN_MAC_QUARTZ
4432 CGRect cgr;
4433 cgr = Nlm_RecTToCGRect(*r);
4434 CGContextSaveGState(Nlm_PeekQContext());
4435 Nlm_White();
4436 CGContextFillRect(Nlm_PeekQContext(), cgr);
4437 CGContextRestoreGState(Nlm_PeekQContext());
4438 #else
4439 EraseRect (&rtool);
4440 #endif
4441 #endif
4442 #ifdef WIN_MSWIN
4443 if (Nlm_currentHDC && Nlm_currentHWnd) {
4444 Nlm_Int4 bkColor = GetBkColor (Nlm_currentHDC);
4445 HBRUSH hBackBrush = CreateSolidBrush (bkColor);
4446 FillRect (Nlm_currentHDC, &rtool, hBackBrush);
4447 DeleteObject (hBackBrush);
4448 }
4449 #endif
4450 #ifdef WIN_X
4451 if (Nlm_currentXDisplay && Nlm_currentXWindow) {
4452 XGCValues values;
4453 XGetGCValues(Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values);
4454 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor);
4455 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid);
4456 XFillRectangle (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4457 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4458 rtool.width+1, rtool.height+1);
4459 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style);
4460 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor);
4461 }
4462 #endif
4463 #ifdef WIN_GIF
4464 if ( Nlm_currentGIF )
4465 gdImageFilledRectangle(Nlm_currentGIF, rtool.left, rtool.top,
4466 rtool.right, rtool.bottom, 0);
4467 #endif
4468 }
4469
4470
4471 extern void Nlm_FrameRect (Nlm_RectPtr r)
4472
4473 {
4474 #ifdef WIN_MAC
4475 #ifdef WIN_MAC_QUARTZ
4476 CGRect rtool;
4477 rtool = Nlm_RecTToCGRect(*r);
4478 CGContextStrokeRect(Nlm_PeekQContext(), rtool);
4479 #else
4480 Nlm_RectTool rtool;
4481
4482 if (r != NULL) {
4483 Local__RecTToRectTool (r, &rtool);
4484 if (rtool.right == rtool.left) {
4485 rtool.right = rtool.left + 1;
4486 }
4487 if (rtool.bottom == rtool.top) {
4488 rtool.bottom = rtool.top + 1;
4489 }
4490 FrameRect (&rtool);
4491 }
4492 #endif
4493 #endif
4494 #ifdef WIN_MSWIN
4495 HBRUSH oldBrush;
4496 POINT pos;
4497 Nlm_RectTool rtool;
4498
4499 if (r != NULL && Nlm_currentHDC != NULL) {
4500 oldBrush = SelectObject (Nlm_currentHDC, GetStockObject (NULL_BRUSH));
4501 Local__RecTToRectTool (r, &rtool);
4502 if (rtool.right == rtool.left) {
4503 rtool.right = rtool.left + 1;
4504 }
4505 if (rtool.bottom == rtool.top) {
4506 rtool.bottom = rtool.top + 1;
4507 }
4508 if ( (rtool.bottom == (rtool.top+1)) &&
4509 (rtool.right == (rtool.left+1)) ){
4510 GetCurrentPositionEx (Nlm_currentHDC, &pos);
4511 MoveToEx (Nlm_currentHDC, rtool.left, rtool.top, NULL);
4512 LineTo (Nlm_currentHDC, rtool.left+1, rtool.top);
4513 MoveToEx (Nlm_currentHDC, pos.x, pos.y, NULL);
4514 } else {
4515 Rectangle (Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1);
4516 }
4517 if (oldBrush != NULL) {
4518 SelectObject (Nlm_currentHDC, oldBrush);
4519 }
4520 }
4521 #endif
4522 #ifdef WIN_X
4523 Nlm_RectTool rtool;
4524
4525 if (r != NULL && Nlm_currentXDisplay != NULL &&
4526 Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) {
4527 Local__RecTToRectTool (r, &rtool);
4528 if ( !rtool.width ) rtool.width++;
4529 if ( !rtool.height ) rtool.height++;
4530 XDrawRectangle (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4531 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4532 rtool.width, rtool.height);
4533 }
4534 #endif
4535 #ifdef WIN_GIF
4536 Nlm_RectTool rtool;
4537
4538 if ( r != NULL && Nlm_currentGIF != NULL ){
4539 Local__RecTToRectTool (r, &rtool);
4540 gdImageRectangle (Nlm_currentGIF, rtool.left, rtool.top,
4541 rtool.right, rtool.bottom, Nlm_curGIFColor );
4542 }
4543 #endif
4544 }
4545
4546 extern void Nlm_PaintRect(Nlm_RectPtr r)
4547
4548 {
4549 #ifndef WIN_MAC_QUARTZ
4550 Nlm_RectTool rtool;
4551 if ( !r )
4552 return;
4553 Local__RecTToRectTool(r, &rtool);
4554 #endif
4555
4556 #ifdef WIN_MAC_QUARTZ
4557 CGRect cgr;
4558 cgr = Nlm_RecTToCGRect(*r);
4559 CGContextFillRect(Nlm_PeekQContext(), cgr);
4560 #elif defined(WIN_MAC)
4561 if (rtool.right == rtool.left) {
4562 rtool.right = rtool.left + 1;
4563 }
4564 if (rtool.bottom == rtool.top) {
4565 rtool.bottom = rtool.top + 1;
4566 }
4567 PaintRect(&rtool);
4568
4569 #elif defined(WIN_MSWIN)
4570 if ( Nlm_currentHDC ) {
4571 HPEN oldPen = SelectObject (Nlm_currentHDC, GetStockObject (NULL_PEN));
4572 Rectangle(Nlm_currentHDC,
4573 rtool.left, rtool.top, rtool.right+2, rtool.bottom+2);
4574 if ( oldPen )
4575 SelectObject(Nlm_currentHDC, oldPen);
4576 }
4577
4578 #elif defined(WIN_X)
4579 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
4580 XFillRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4581 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4582 rtool.width + 1, rtool.height + 1);
4583 }
4584 #elif defined(WIN_GIF)
4585 if ( Nlm_currentGIF ) {
4586 gdImageFilledRectangle(Nlm_currentGIF, rtool.left, rtool.top,
4587 rtool.right, rtool.bottom, Nlm_curGIFColor);
4588 }
4589 #endif
4590 }
4591
4592 extern void Nlm_InvertRect (Nlm_RectPtr r)
4593 {
4594 #ifndef WIN_GIF
4595 Nlm_RectTool rtool;
4596 #endif
4597
4598 if (r == NULL)
4599 return;
4600
4601 #ifdef WIN_MAC
4602 #ifdef WIN_MAC_QUARTZ
4603 /* ASSERT(false); */ /* Can't invert rectangles in Quartz */
4604 #else
4605 Local__RecTToRectTool (r, &rtool);
4606 InvertRect (&rtool);
4607 #endif
4608 #endif
4609 #ifdef WIN_MSWIN
4610 if (Nlm_currentHDC == NULL)
4611 return;
4612
4613 Local__RecTToRectTool (r, &rtool);
4614 InvertRect (Nlm_currentHDC, &rtool);
4615 #endif
4616 #ifdef WIN_X
4617 if (Nlm_currentXDisplay == NULL ||
4618 Nlm_currentXWindow == 0 || Nlm_currentXGC == NULL)
4619 return;
4620
4621 Local__RecTToRectTool (r, &rtool);
4622 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert);
4623 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled);
4624 XFillRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4625 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4626 rtool.width + 1, rtool.height + 1);
4627 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
4628 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
4629 #endif
4630 }
4631
4632
4633 extern void Nlm_ScrollRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy)
4634
4635 {
4636 #ifdef WIN_MAC
4637 Nlm_RectTool rtool;
4638
4639 if (r != NULL) {
4640 Local__RecTToRectTool (r, &rtool);
4641 #ifdef WIN_MAC_QUARTZ
4642 // QUARTZ_FIXME: might want to do a little more than this
4643 HIViewSetNeedsDisplay (HIViewGetRoot (Nlm_QWindow), 1);
4644 #else
4645 ScrollRect (&rtool, dx, dy, (Nlm_RgnTool) Nlm_scrollRgn);
4646 InvalRgn ((Nlm_RgnTool) Nlm_scrollRgn);
4647 #endif
4648 }
4649 #endif
4650 #ifdef WIN_MSWIN
4651 Nlm_RectTool rtool;
4652
4653 if (r != NULL && Nlm_currentHDC != NULL) {
4654 SetRectRgn ((Nlm_RgnTool) Nlm_scrollRgn, 0, 0, 0, 0);
4655 Local__RecTToRectTool (r, &rtool);
4656 ScrollDC (Nlm_currentHDC, dx, dy, &rtool, &rtool,
4657 (Nlm_RgnTool) Nlm_scrollRgn, NULL);
4658 if (Nlm_currentHWnd != NULL && Nlm_scrollRgn != NULL) {
4659 FillRgn (Nlm_currentHDC, (Nlm_RgnTool) Nlm_scrollRgn,
4660 GetBackgroundBrush (Nlm_currentHWnd));
4661 }
4662 InvalidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) Nlm_scrollRgn, TRUE);
4663 }
4664 #endif
4665 #ifdef WIN_X
4666 XEvent event;
4667 unsigned int height;
4668 Nlm_RecT rct;
4669 Nlm_RectTool rtool;
4670 unsigned int width;
4671 unsigned int dstX;
4672 unsigned int dstY;
4673 unsigned int srcX;
4674 unsigned int srcY;
4675
4676 if (r != NULL) {
4677 if (ABS (dy) >= ABS (r->bottom - r->top) || ABS (dx) >= ABS (r->right - r->left)) {
4678 Nlm_InvalRect (r);
4679 return;
4680 }
4681 }
4682 if (r != NULL && Nlm_currentXDisplay != NULL &&
4683 Nlm_currentXGC != NULL && Nlm_currentXWindow != 0) {
4684 height = ABS (r->bottom - r->top) - ABS (dy);
4685 width = ABS (r->right - r->left) - ABS (dx);
4686 if (dx > 0) {
4687 srcX = r->left - Nlm_XOffset;
4688 dstX = r->left - Nlm_XOffset + dx;
4689 } else if (dx < 0) {
4690 srcX = r->left - Nlm_XOffset - dx;
4691 dstX = r->left - Nlm_XOffset;
4692 } else {
4693 srcX = r->left - Nlm_XOffset;
4694 dstX = r->left - Nlm_XOffset;
4695 }
4696 if (dy > 0) {
4697 srcY = r->top - Nlm_YOffset;
4698 dstY = r->top - Nlm_YOffset + dy;
4699 } else if (dy < 0) {
4700 srcY = r->top - Nlm_YOffset - dy;
4701 dstY = r->top - Nlm_YOffset;
4702 } else {
4703 srcY = r->top - Nlm_YOffset;
4704 dstY = r->top - Nlm_YOffset;
4705 }
4706 if (Nlm_hasColor) {
4707 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor);
4708 }
4709 XCopyArea (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXWindow,
4710 Nlm_currentXGC, srcX, srcY, width, height, dstX, dstY);
4711 XSync (Nlm_currentXDisplay, FALSE);
4712 if (! XCheckTypedWindowEvent (Nlm_currentXDisplay,
4713 Nlm_currentXWindow, NoExpose, &event)) {
4714 while (XCheckTypedWindowEvent (Nlm_currentXDisplay,
4715 Nlm_currentXWindow, GraphicsExpose, &event)) {
4716 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
4717 event.xgraphicsexpose.x, event.xgraphicsexpose.y,
4718 event.xgraphicsexpose.width, event.xgraphicsexpose.height,
4719 TRUE);
4720 }
4721 }
4722 if (dx > 0) {
4723 rct = *r;
4724 rct.right = rct.left + dx;
4725 Local__RecTToRectTool (&rct, &rtool);
4726 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
4727 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4728 rtool.width, rtool.height, TRUE);
4729 } else if (dx < 0) {
4730 rct = *r;
4731 rct.left = rct.right + dx;
4732 Local__RecTToRectTool (&rct, &rtool);
4733 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
4734 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4735 rtool.width, rtool.height, TRUE);
4736 }
4737 if (dy > 0) {
4738 rct = *r;
4739 rct.bottom = rct.top + dy;
4740 Local__RecTToRectTool (&rct, &rtool);
4741 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
4742 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4743 rtool.width, rtool.height, TRUE);
4744 } else if (dy < 0) {
4745 rct = *r;
4746 rct.top = rct.bottom + dy;
4747 Local__RecTToRectTool (&rct, &rtool);
4748 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
4749 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4750 rtool.width, rtool.height, TRUE);
4751 }
4752 if (Nlm_hasColor) {
4753 XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor);
4754 }
4755 }
4756 #endif
4757 #ifdef WIN_GIF
4758 #endif
4759 }
4760
4761 #ifdef WIN_MAC_QUARTZ
4762
4763 static void Nlm_addOvalToPath(CGContextRef context, CGRect r)
4764 {
4765 CGAffineTransform matrix;
4766 CGContextSaveGState(context);
4767 matrix = CGAffineTransformMake((r.size.width)/2, 0,
4768 0, (r.size.height)/2,
4769 r.origin.x + (r.size.width)/2,
4770 r.origin.y + (r.size.height)/2);
4771 CGContextConcatCTM(context, matrix);
4772 CGContextBeginPath(context);
4773 CGContextAddArc(context, 0, 0, 1, 0, 2*pi, true);
4774 CGContextRestoreGState(context);
4775 }
4776 #endif
4777
4778 extern void Nlm_EraseOval (Nlm_RectPtr r)
4779 {
4780 Nlm_RectTool rtool;
4781 if ( !r )
4782 return;
4783 Local__RecTToRectTool(r, &rtool);
4784
4785 #if defined(WIN_MAC)
4786 #if defined(WIN_MAC_QUARTZ)
4787 {
4788 CGRect cgr;
4789 cgr = Nlm_RecTToCGRect(*r);
4790 Nlm_addOvalToPath(Nlm_PeekQContext(), cgr);
4791 }
4792 CGContextSaveGState(Nlm_PeekQContext());
4793 Nlm_White();
4794 CGContextFillPath(Nlm_PeekQContext());
4795 CGContextRestoreGState(Nlm_PeekQContext());
4796 #else
4797 EraseOval(&rtool);
4798 #endif
4799 #elif defined(WIN_MSWIN)
4800 if (Nlm_currentHDC && Nlm_currentHWnd) {
4801 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
4802 HBRUSH xBrush = SelectObject(Nlm_currentHDC,
4803 GetBackgroundBrush(Nlm_currentHWnd));
4804 Ellipse(Nlm_currentHDC,
4805 rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2);
4806 if ( xPen )
4807 SelectObject(Nlm_currentHDC, xPen);
4808 if ( xBrush )
4809 SelectObject(Nlm_currentHDC, xBrush);
4810 }
4811
4812 #elif defined(WIN_X)
4813 if (Nlm_currentXDisplay && Nlm_currentXWindow) {
4814 XGCValues values;
4815 XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values);
4816 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor);
4817 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid);
4818 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4819 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4820 rtool.width, rtool.height, 0, 23040);
4821 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style);
4822 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor);
4823 }
4824
4825 #elif defined(WIN_GIF)
4826 gdImageEllipse(Nlm_currentGIF,
4827 (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2,
4828 (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2,
4829 0, TRUE);
4830 #endif
4831 }
4832
4833 extern void Nlm_FrameOval(Nlm_RectPtr r)
4834 {
4835 Nlm_RectTool rtool;
4836 if ( !r )
4837 return;
4838 Local__RecTToRectTool(r, &rtool);
4839
4840 #if defined(WIN_MAC)
4841 #if defined(WIN_MAC_QUARTZ)
4842 {
4843 CGRect cgr;
4844 cgr = Nlm_RecTToCGRect(*r);
4845 Nlm_addOvalToPath(Nlm_PeekQContext(), cgr);
4846 }
4847 CGContextStrokePath(Nlm_PeekQContext());
4848 #else
4849 FrameOval(&rtool);
4850 #endif
4851 #elif defined(WIN_MSWIN)
4852 if ( Nlm_currentHDC ) {
4853 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH));
4854 Ellipse(Nlm_currentHDC, rtool.left, rtool.top, rtool.right, rtool.bottom);
4855 if ( xBrush )
4856 SelectObject(Nlm_currentHDC, xBrush);
4857 }
4858
4859 #elif defined(WIN_X)
4860 if ( Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
4861 XDrawArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4862 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4863 rtool.width - 1, rtool.height - 1, 0, 23040);
4864 }
4865
4866 #elif defined(WIN_GIF)
4867 gdImageEllipse(Nlm_currentGIF,
4868 (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2,
4869 (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2,
4870 Nlm_curGIFColor, FALSE);
4871 #endif
4872 }
4873
4874 extern void Nlm_PaintOval(Nlm_RectPtr r)
4875 {
4876 Nlm_RectTool rtool;
4877 if ( !r )
4878 return;
4879 Local__RecTToRectTool(r, &rtool);
4880
4881 #if defined(WIN_MAC)
4882 #if defined(WIN_MAC_QUARTZ)
4883 {
4884 CGRect cgr;
4885 cgr = Nlm_RecTToCGRect(*r);
4886 Nlm_addOvalToPath(Nlm_PeekQContext(), cgr);
4887 }
4888 CGContextFillPath(Nlm_PeekQContext());
4889 #else
4890 PaintOval(&rtool);
4891
4892 #endif
4893 #elif defined(WIN_MSWIN)
4894 if ( Nlm_currentHDC ) {
4895 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
4896 Ellipse(Nlm_currentHDC,
4897 rtool.left, rtool.top, rtool.right+1, rtool.bottom+1);
4898 if ( xPen )
4899 SelectObject(Nlm_currentHDC, xPen);
4900 }
4901
4902 #elif defined(WIN_X)
4903 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
4904 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4905 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4906 rtool.width, rtool.height, 0, 23040);
4907 }
4908
4909 #elif defined(WIN_GIF)
4910 gdImageEllipse(Nlm_currentGIF,
4911 (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2,
4912 (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2,
4913 Nlm_curGIFColor, TRUE);
4914 #endif
4915 }
4916
4917
4918 extern void Nlm_InvertOval(Nlm_RectPtr r)
4919 {
4920 Nlm_RectTool rtool;
4921 if ( !r )
4922 return;
4923 Local__RecTToRectTool(r, &rtool);
4924
4925 #if defined(WIN_MAC)
4926 #ifdef WIN_MAC_QUARTZ
4927 /* QUART_FIXME: can't invert, what to do? */
4928 Nlm_PaintOval (r);
4929 #else
4930 InvertOval (&rtool);
4931 #endif
4932
4933 #elif defined(WIN_MSWIN)
4934 if ( Nlm_currentHDC ) {
4935 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN ));
4936 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH));
4937 int xMode = GetROP2(Nlm_currentHDC);
4938 SetROP2(Nlm_currentHDC, R2_NOTXORPEN);
4939 Ellipse(Nlm_currentHDC,
4940 rtool.left, rtool.top, rtool.right+1, rtool.bottom+1);
4941 if ( xPen )
4942 SelectObject(Nlm_currentHDC, xPen);
4943 if ( xBrush )
4944 SelectObject(Nlm_currentHDC, xBrush);
4945 SetROP2(Nlm_currentHDC, xMode);
4946 }
4947
4948 #elif defined(WIN_X)
4949 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
4950 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert);
4951 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillStippled);
4952 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
4953 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
4954 rtool.width, rtool.height, 0, 23040);
4955 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
4956 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
4957 }
4958 #elif defined(WIN_GIF)
4959 #endif
4960 }
4961
4962
4963 static void s_AdjustRoundRect(const Nlm_RecT* r, Nlm_Int2 *w, Nlm_Int2 *h)
4964 {
4965 Nlm_Int2 w2, h2;
4966
4967 w2 = r->right - r->left; w2 = ABS(w2) / 2;
4968 if (*w > w2)
4969 *w = w2;
4970
4971 h2 = r->bottom - r->top; h2 = ABS(h2) / 2;
4972 if (*h > h2)
4973 *h = h2;
4974 }
4975
4976
4977 #ifdef WIN_MAC_QUARTZ
4978 static void addRoundedRectToPath(CGContextRef context, CGRect rect,
4979 float ovalWidth,float ovalHeight)
4980 {
4981 float fw, fh;
4982 if (ovalWidth == 0 || ovalHeight == 0) {
4983 CGContextAddRect(context, rect);
4984 return;
4985 }
4986 CGContextSaveGState(context);
4987 CGContextTranslateCTM (context, CGRectGetMinX(rect),
4988 CGRectGetMinY(rect));
4989 CGContextScaleCTM (context, ovalWidth, ovalHeight);
4990 fw = CGRectGetWidth (rect) / ovalWidth;
4991 fh = CGRectGetHeight (rect) / ovalHeight;
4992 CGContextMoveToPoint(context, fw, fh/2);
4993 CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
4994 CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
4995 CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
4996 CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
4997 CGContextClosePath(context);
4998 CGContextRestoreGState(context);
4999 }
5000 #endif
5001
5002 extern void Nlm_EraseRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt)
5003 {
5004 Nlm_RectTool rtool;
5005 if ( !r )
5006 return;
5007 Local__RecTToRectTool(r, &rtool);
5008 s_AdjustRoundRect(r, &ovlWid, &ovlHgt);
5009
5010 #if defined(WIN_MAC)
5011 #if defined(WIN_MAC_QUARTZ)
5012 {
5013 CGRect cgr;
5014 cgr = Nlm_RecTToCGRect(*r);
5015 addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt);
5016 }
5017 CGContextSaveGState(Nlm_PeekQContext());
5018 Nlm_White();
5019 CGContextFillPath(Nlm_PeekQContext());
5020 CGContextRestoreGState(Nlm_PeekQContext());
5021 #else
5022 EraseRoundRect(&rtool, ovlWid, ovlHgt);
5023 #endif
5024 #elif defined(WIN_MSWIN)
5025 if (Nlm_currentHDC && Nlm_currentHWnd) {
5026 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
5027 HBRUSH xBrush = SelectObject(Nlm_currentHDC,
5028 GetBackgroundBrush(Nlm_currentHWnd));
5029 RoundRect(Nlm_currentHDC, rtool.left, rtool.top,
5030 rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt);
5031 if ( xPen )
5032 SelectObject(Nlm_currentHDC, xPen);
5033 if ( xBrush )
5034 SelectObject(Nlm_currentHDC, xBrush);
5035 }
5036
5037 #elif defined(WIN_X)
5038 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5039 XGCValues values;
5040 XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values);
5041 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor);
5042 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid);
5043 XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow,
5044 Nlm_currentXGC,
5045 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5046 rtool.width+1, rtool.height+1, ovlWid, ovlHgt);
5047 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style);
5048 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor);
5049 }
5050
5051 #elif defined(WIN_GIF)
5052 if ( Nlm_currentGIF ) {
5053 gdImageRoundRectangle(Nlm_currentGIF,
5054 rtool.left, rtool.top, rtool.right, rtool.bottom,
5055 ovlWid, ovlHgt, 0, TRUE);
5056 }
5057 #endif
5058 }
5059
5060
5061 extern void Nlm_FrameRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt)
5062 {
5063 Nlm_RectTool rtool;
5064 if ( !r )
5065 return;
5066 Local__RecTToRectTool(r, &rtool);
5067 s_AdjustRoundRect(r, &ovlWid, &ovlHgt);
5068
5069 #if defined(WIN_MAC)
5070 #if defined(WIN_MAC_QUARTZ)
5071 {
5072 CGRect cgr;
5073 cgr = Nlm_RecTToCGRect(*r);
5074 addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt);
5075 }
5076 CGContextStrokePath(Nlm_PeekQContext());
5077 #else
5078 FrameRoundRect(&rtool, ovlWid, ovlHgt);
5079 #endif
5080 #elif defined(WIN_MSWIN)
5081 if ( Nlm_currentHDC ) {
5082 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH));
5083 RoundRect(Nlm_currentHDC, rtool.left, rtool.top,
5084 rtool.right + 1, rtool.bottom + 1, ovlWid, ovlHgt);
5085 if ( xBrush )
5086 SelectObject(Nlm_currentHDC, xBrush);
5087 }
5088
5089 #elif defined(WIN_X)
5090 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5091 XmuDrawRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow,
5092 Nlm_currentXGC,
5093 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5094 rtool.width, rtool.height, ovlWid, ovlHgt);
5095 }
5096
5097 #elif defined(WIN_GIF)
5098 if ( Nlm_currentGIF ) {
5099 gdImageRoundRectangle(Nlm_currentGIF,
5100 rtool.left, rtool.top, rtool.right, rtool.bottom,
5101 ovlWid, ovlHgt, Nlm_curGIFColor, FALSE);
5102 }
5103 #endif
5104 }
5105
5106
5107 extern void Nlm_PaintRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt)
5108 {
5109 Nlm_RectTool rtool;
5110 if ( !r )
5111 return;
5112 Local__RecTToRectTool(r, &rtool);
5113 s_AdjustRoundRect(r, &ovlWid, &ovlHgt);
5114
5115 #if defined(WIN_MAC)
5116 #if defined(WIN_MAC_QUARTZ)
5117 {
5118 CGRect cgr;
5119 cgr = Nlm_RecTToCGRect(*r);
5120 addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt);
5121 }
5122 CGContextFillPath(Nlm_PeekQContext());
5123 #else
5124 PaintRoundRect(&rtool, ovlWid, ovlHgt);
5125 #endif
5126 #elif defined(WIN_MSWIN)
5127 if ( Nlm_currentHDC ) {
5128 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
5129 RoundRect(Nlm_currentHDC, rtool.left, rtool.top,
5130 rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt);
5131 if ( xPen )
5132 SelectObject(Nlm_currentHDC, xPen);
5133 }
5134
5135 #elif defined(WIN_X)
5136 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5137 XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow,
5138 Nlm_currentXGC,
5139 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5140 rtool.width+1, rtool.height+1, ovlWid, ovlHgt);
5141 }
5142
5143 #elif defined(WIN_GIF)
5144 if ( Nlm_currentGIF ) {
5145 gdImageRoundRectangle(Nlm_currentGIF,
5146 rtool.left, rtool.top, rtool.right, rtool.bottom,
5147 ovlWid, ovlHgt, Nlm_curGIFColor, TRUE);
5148 }
5149 #endif
5150 }
5151
5152
5153 extern void Nlm_InvertRoundRect(Nlm_RectPtr r,
5154 Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt)
5155 {
5156 Nlm_RectTool rtool;
5157 if ( !r )
5158 return;
5159 Local__RecTToRectTool(r, &rtool);
5160 s_AdjustRoundRect(r, &ovlWid, &ovlHgt);
5161
5162 #if defined(WIN_MAC)
5163 #ifdef WIN_MAC_QUARTZ
5164 /* QUARTZ_FIXME: can't invert, what to do? */
5165 Nlm_PaintRoundRect (r, ovlWid, ovlHgt);
5166 #else
5167 InvertRoundRect (&rtool, ovlWid, ovlHgt);
5168 #endif
5169
5170 #elif defined(WIN_MSWIN)
5171 if ( Nlm_currentHDC ) {
5172 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN ));
5173 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH));
5174 int xMode = GetROP2(Nlm_currentHDC);
5175 SetROP2(Nlm_currentHDC, R2_NOTXORPEN);
5176 RoundRect(Nlm_currentHDC, rtool.left, rtool.top,
5177 rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt);
5178 if ( xPen )
5179 SelectObject(Nlm_currentHDC, xPen);
5180 if ( xBrush )
5181 SelectObject(Nlm_currentHDC, xBrush);
5182 SetROP2(Nlm_currentHDC, xMode);
5183 }
5184
5185 #elif defined(WIN_X)
5186 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5187 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert);
5188 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled);
5189 XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow,
5190 Nlm_currentXGC,
5191 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5192 rtool.width+1, rtool.height+1, ovlWid, ovlHgt);
5193 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
5194 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
5195 }
5196 #elif defined(WIN_GIF)
5197 #endif
5198 }
5199
5200
5201 #ifdef WIN_X
5202 static int Nlm_PtToAngle (Nlm_RectPtr r, Nlm_PoinT pt)
5203
5204 {
5205 int rsult;
5206 double val;
5207 double x;
5208 double y;
5209
5210 x = pt.x - (r->right + r->left) / 2;
5211 y = (r->bottom + r->top) / 2 - pt.y;
5212 if (x == 0) {
5213 rsult = 5760;
5214 } else if (y == 0) {
5215 rsult = 0;
5216 } else {
5217 val = atan2 (ABS (y), ABS (x));
5218 rsult = (int)(val * 11520.0 / 3.14159);
5219 }
5220 if (x < 0) {
5221 if (y < 0) {
5222 rsult = 11520 + rsult;
5223 } else {
5224 rsult = 11520 - rsult;
5225 }
5226 } else if (y < 0) {
5227 rsult = 23040 - rsult;
5228 }
5229 return rsult;
5230 }
5231 #endif
5232
5233
5234 #ifdef WIN_MAC_QUARTZ
5235 /*
5236 static void pathForArc (CGContextRef context, CGRect r,
5237 int startAngle, int arcAngle)
5238 {
5239 float start, end;
5240 CGAffineTransform matrix;
5241 CGContextSaveGState(context);
5242 matrix = CGAffineTransformMake(r.size.width/2, 0,
5243 0, r.size.height/2,
5244 r.origin.x + r.size.width/2,
5245 r.origin.y + r.size.height/2);
5246 CGContextConcatCTM(context, matrix);
5247 if (arcAngle > 0) {
5248 start = (90 - startAngle - arcAngle) * M_PI / 180;
5249 end = (90 - startAngle) * M_PI / 180;
5250 } else {
5251 start = (90 - startAngle) * M_PI / 180;
5252 end = (90 - startAngle - arcAngle) * M_PI / 180;
5253 }
5254 CGContextAddArc (context, 0, 0, 1, start, end, false);
5255 CGContextRestoreGState(context);
5256 }
5257 */
5258
5259 static void pathForArc (CGContextRef context, CGRect r,
5260 CGPoint startPt, CGPoint endPt)
5261 {
5262 float start, end;
5263 CGAffineTransform matrix, invMatrix;
5264 CGContextSaveGState(context);
5265 matrix = CGAffineTransformMake(r.size.width/2, 0,
5266 0, r.size.height/2,
5267 r.origin.x + r.size.width/2,
5268 r.origin.y + r.size.height/2);
5269 CGContextConcatCTM(context, matrix);
5270
5271 invMatrix = CGAffineTransformInvert(matrix);
5272 startPt = CGPointApplyAffineTransform(startPt, invMatrix);
5273 endPt = CGPointApplyAffineTransform(endPt, invMatrix);
5274 start = atan2(startPt.y, startPt.x);
5275 end = atan2( endPt.y, endPt.x);
5276
5277
5278 CGContextAddArc (context, 0, 0, 1, start, end, 0);
5279 CGContextRestoreGState(context);
5280 }
5281
5282 #endif
5283
5284
5285 extern void Nlm_EraseArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end)
5286 {
5287 Nlm_RectTool rtool;
5288 if ( !r )
5289 return;
5290 Local__RecTToRectTool(r, &rtool);
5291
5292 #if defined(WIN_MAC)
5293 {{
5294 #if defined(WIN_MAC_QUARTZ)
5295 CGRect cgr;
5296 CGPoint startPt;
5297 CGPoint endPt;
5298
5299 cgr = Nlm_RecTToCGRect(*r);
5300 startPt = Nlm_PoinTToCGPoint(start);
5301 endPt = Nlm_PoinTToCGPoint(end);
5302 Nlm_MoveTo((r->right + r->left)/2, (r->top + r->bottom)/2);
5303 pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt);
5304
5305 CGContextSaveGState(Nlm_PeekQContext());
5306 Nlm_White();
5307 CGContextFillPath(Nlm_PeekQContext());
5308 CGContextRestoreGState(Nlm_PeekQContext());
5309 #else
5310 Nlm_Int2 angle1;
5311 Nlm_Int2 angle2;
5312 Nlm_Int2 arcAngle;
5313 Nlm_PointTool ptool1;
5314 Nlm_PointTool ptool2;
5315 Nlm_RectTool rtool;
5316
5317 Local__RecTToRectTool(r, &rtool);
5318 Local__PoinTToPointTool(start, &ptool1);
5319 Local__PoinTToPointTool( end, &ptool2);
5320 PtToAngle(&rtool, ptool1, &angle1);
5321 PtToAngle(&rtool, ptool2, &angle2);
5322 if (angle2 > angle1)
5323 arcAngle = angle2 - angle1;
5324 else
5325 arcAngle = 360 - angle1 + angle2;
5326
5327 EraseArc(&rtool, angle1, arcAngle);
5328 #endif
5329 }}
5330
5331 #elif defined(WIN_MSWIN)
5332 if (Nlm_currentHDC && Nlm_currentHWnd) {
5333 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
5334 HBRUSH xBrush = SelectObject(Nlm_currentHDC,
5335 GetBackgroundBrush(Nlm_currentHWnd));
5336 Pie(Nlm_currentHDC,
5337 rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2,
5338 end.x, end.y, start.x, start.y);
5339 if ( xPen )
5340 SelectObject(Nlm_currentHDC, xPen);
5341 if ( xBrush )
5342 SelectObject(Nlm_currentHDC, xBrush);
5343 }
5344
5345 #elif defined(WIN_X)
5346 if (Nlm_currentXDisplay && Nlm_currentXWindow) {
5347 XGCValues values;
5348 int angle1 = Nlm_PtToAngle(r, start);
5349 int angle2 = Nlm_PtToAngle(r, end);
5350 int arcAngle;
5351
5352 if (angle1 > angle2)
5353 arcAngle = angle1 - angle2;
5354 else
5355 arcAngle = 23040 - angle2 + angle1;
5356
5357 XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values);
5358 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor);
5359 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid);
5360 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5361 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5362 rtool.width, rtool.height, angle1, -arcAngle);
5363 XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style);
5364 XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor);
5365 }
5366 #elif defined(WIN_GIF)
5367 #endif
5368 }
5369
5370 extern void Nlm_FrameArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end)
5371 {
5372 Nlm_RectTool rtool;
5373 if ( !r )
5374 return;
5375 Local__RecTToRectTool(r, &rtool);
5376
5377 #if defined(WIN_MAC)
5378 {{
5379 #if defined(WIN_MAC_QUARTZ)
5380 CGRect cgr;
5381 CGPoint startPt;
5382 CGPoint endPt;
5383
5384 cgr = Nlm_RecTToCGRect(*r);
5385 startPt = Nlm_PoinTToCGPoint(start);
5386 endPt = Nlm_PoinTToCGPoint(end);
5387 pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt);
5388 CGContextStrokePath(Nlm_PeekQContext());
5389 #else
5390 Nlm_Int2 angle1;
5391 Nlm_Int2 angle2;
5392 Nlm_Int2 arcAngle;
5393 Nlm_PointTool ptool1;
5394 Nlm_PointTool ptool2;
5395
5396 Local__PoinTToPointTool(start, &ptool1);
5397 Local__PoinTToPointTool( end, &ptool2);
5398 PtToAngle(&rtool, ptool1, &angle1);
5399 PtToAngle(&rtool, ptool2, &angle2);
5400 if (angle2 > angle1) {
5401 arcAngle = angle2 - angle1;
5402 } else {
5403 arcAngle = 360 - angle1 + angle2;
5404 }
5405 FrameArc (&rtool, angle1, arcAngle);
5406 #endif
5407 }}
5408
5409 #elif defined(WIN_MSWIN)
5410 if ( Nlm_currentHDC ) {
5411 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH));
5412 Arc(Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1,
5413 end.x, end.y, start.x, start.y);
5414 if ( xBrush )
5415 SelectObject(Nlm_currentHDC, xBrush);
5416 }
5417
5418 #elif defined(WIN_X)
5419 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5420 int angle1 = Nlm_PtToAngle(r, start);
5421 int angle2 = Nlm_PtToAngle(r, end);
5422 int arcAngle = angle1 > angle2 ? angle1 - angle2 : 23040 - angle2 + angle1;
5423 XDrawArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5424 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5425 rtool.width - 1, rtool.height - 1, angle1, -arcAngle);
5426 }
5427
5428 #elif defined(WIN_GIF)
5429 {{
5430 int cx = (rtool.left + rtool.right) / 2;
5431 int cy = (rtool.top + rtool.bottom) / 2;
5432 double s_angle = atan2(start.x - cx, start.y - cy);
5433 double e_angle = atan2(end.x - cx, end.y - cy);
5434 gdImageArcEx(Nlm_currentGIF, cx, cy,
5435 (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2,
5436 s_angle, e_angle, Nlm_curGIFColor, FALSE);
5437 }}
5438 #endif
5439 }
5440
5441 extern void Nlm_PaintArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end)
5442 {
5443 Nlm_RectTool rtool;
5444 if ( !r )
5445 return;
5446 Local__RecTToRectTool(r, &rtool);
5447
5448 #if defined(WIN_MAC)
5449 {{
5450 #if defined(WIN_MAC_QUARTZ)
5451 CGRect cgr;
5452 CGPoint startPt;
5453 CGPoint endPt;
5454
5455 cgr = Nlm_RecTToCGRect(*r);
5456 startPt = Nlm_PoinTToCGPoint(start);
5457 endPt = Nlm_PoinTToCGPoint(end);
5458 Nlm_MoveTo((r->right + r->left)/2, (r->top + r->bottom)/2);
5459 pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt);
5460 CGContextFillPath(Nlm_PeekQContext());
5461 #else
5462 Nlm_Int2 angle1;
5463 Nlm_Int2 angle2;
5464 Nlm_Int2 arcAngle;
5465 Nlm_PointTool ptool1;
5466 Nlm_PointTool ptool2;
5467
5468 Local__PoinTToPointTool(start, &ptool1);
5469 Local__PoinTToPointTool(end, &ptool2);
5470 PtToAngle(&rtool, ptool1, &angle1);
5471 PtToAngle(&rtool, ptool2, &angle2);
5472 if (angle2 > angle1)
5473 arcAngle = angle2 - angle1;
5474 else
5475 arcAngle = 360 - angle1 + angle2;
5476
5477 PaintArc(&rtool, angle1, arcAngle);
5478 #endif
5479 }}
5480
5481 #elif defined(WIN_MSWIN)
5482 if ( Nlm_currentHDC ) {
5483 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN));
5484 Pie(Nlm_currentHDC,
5485 rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2,
5486 end.x, end.y, start.x, start.y);
5487 if ( xPen )
5488 SelectObject(Nlm_currentHDC, xPen);
5489 }
5490
5491 #elif defined(WIN_X)
5492 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5493 int angle1 = Nlm_PtToAngle(r, start);
5494 int angle2 = Nlm_PtToAngle(r, end);
5495 int arcAngle;
5496
5497 if (angle1 > angle2)
5498 arcAngle = angle1 - angle2;
5499 else
5500 arcAngle = 23040 - angle2 + angle1;
5501
5502 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5503 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5504 rtool.width, rtool.height, angle1, -arcAngle);
5505 }
5506
5507 #elif defined(WIN_GIF)
5508 {{
5509 int cx = (rtool.left + rtool.right) / 2;
5510 int cy = (rtool.top + rtool.bottom) / 2;
5511 double s_angle = atan2(start.x - cx, start.y - cy);
5512 double e_angle = atan2(end.x - cx, end.y - cy);
5513 gdImageArcEx(Nlm_currentGIF, cx, cy,
5514 (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2,
5515 s_angle, e_angle, Nlm_curGIFColor, TRUE);
5516 }}
5517 #endif
5518 }
5519
5520 extern void Nlm_InvertArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end)
5521 {
5522 Nlm_RectTool rtool;
5523 if ( !r )
5524 return;
5525 Local__RecTToRectTool(r, &rtool);
5526
5527 #if defined(WIN_MAC)
5528 #ifdef WIN_MAC_QUARTZ
5529 /* QUARTZ_FIXME: can't invert, what to do? */
5530 Nlm_PaintArc (r, start, end);
5531 #else
5532 {{
5533 Nlm_Int2 angle1;
5534 Nlm_Int2 angle2;
5535 Nlm_Int2 arcAngle;
5536 Nlm_PointTool ptool1;
5537 Nlm_PointTool ptool2;
5538 Nlm_RectTool rtool;
5539
5540 Local__RecTToRectTool(r, &rtool);
5541 Local__PoinTToPointTool(start, &ptool1);
5542 Local__PoinTToPointTool(end, &ptool2);
5543 PtToAngle(&rtool, ptool1, &angle1);
5544 PtToAngle(&rtool, ptool2, &angle2);
5545 if (angle2 > angle1)
5546 arcAngle = angle2 - angle1;
5547 else
5548 arcAngle = 360 - angle1 + angle2;
5549
5550 InvertArc(&rtool, angle1, arcAngle);
5551 }}
5552 #endif
5553
5554 #elif defined(WIN_MSWIN)
5555 if ( Nlm_currentHDC ) {
5556 HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN ));
5557 HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH));
5558 int xMode = GetROP2(Nlm_currentHDC);
5559 SetROP2(Nlm_currentHDC, R2_NOTXORPEN);
5560 Pie(Nlm_currentHDC,
5561 rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2,
5562 end.x, end.y, start.x, start.y);
5563 if ( xPen )
5564 SelectObject(Nlm_currentHDC, xPen);
5565 if ( xBrush )
5566 SelectObject(Nlm_currentHDC, xBrush);
5567 SetROP2(Nlm_currentHDC, xMode);
5568 }
5569
5570 #elif defined(WIN_X)
5571 if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) {
5572 int angle1 = Nlm_PtToAngle(r, start);
5573 int angle2 = Nlm_PtToAngle(r, end);
5574 int arcAngle;
5575
5576 if (angle1 > angle2)
5577 arcAngle = angle1 - angle2;
5578 else
5579 arcAngle = 23040 - angle2 + angle1;
5580
5581 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert);
5582 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillStippled);
5583 XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5584 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
5585 rtool.width, rtool.height, angle1, -arcAngle);
5586 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction);
5587 XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle);
5588 }
5589 #elif defined(WIN_GIF)
5590 #endif
5591 }
5592
5593 typedef enum {
5594 eDM_Erase = 0,
5595 eDM_Frame,
5596 eDM_Paint,
5597 eDM_Invert
5598 } EDrawMethod;
5599
5600
5601 /*********************************
5602 * QUADRANT
5603 */
5604
5605 static void s_DoQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant,
5606 EDrawMethod method)
5607 {
5608 Nlm_RecT rr;
5609 Nlm_Int2 rx, ry;
5610
5611 Nlm_LoadNormalized(&rr, r);
5612 rx = rr.right - rr.left;
5613 ry = rr.bottom - rr.top;
5614
5615 #ifdef WIN_GIF
5616 {{
5617 int cx = 0, cy = 0;
5618
5619 switch ( quadrant ) {
5620 case eQ_RightTop:
5621 cx = rr.left; cy = rr.bottom; break;
5622 case eQ_LeftTop:
5623 cx = rr.right; cy = rr.bottom; break;
5624 case eQ_LeftBottom:
5625 cx = rr.right; cy = rr.top; break;
5626 case eQ_RightBottom:
5627 cx = rr.left; cy = rr.top; break;
5628 }
5629
5630 gdImageQuadrant(Nlm_currentGIF, cx, cy, rx, ry,
5631 (method == eDM_Erase) ? 0 : Nlm_curGIFColor,
5632 (method != eDM_Frame), (int)quadrant);
5633 }}
5634 #else
5635 {{
5636 Nlm_PoinT start, stop;
5637 switch ( quadrant ) {
5638 case eQ_RightTop:
5639 start.x = rr.left; start.y = rr.top;
5640 stop.x = rr.right; stop.y = rr.bottom;
5641 rr.left -= rx; rr.bottom += ry;
5642 break;
5643 case eQ_LeftTop:
5644 start.x = rr.left; start.y = rr.bottom;
5645 stop.x = rr.right; stop.y = rr.top;
5646 rr.right += rx; rr.bottom += ry;
5647 break;
5648 case eQ_LeftBottom:
5649 start.x = rr.right; start.y = rr.bottom;
5650 stop.x = rr.left; stop.y = rr.top;
5651 rr.right += rx; rr.top -= ry;
5652 break;
5653 case eQ_RightBottom:
5654 start.x = rr.right; start.y = rr.top;
5655 stop.x = rr.left; stop.y = rr.bottom;
5656 rr.left -= rx; rr.top -= ry;
5657 break;
5658 }
5659
5660 switch ( method ) {
5661 case eDM_Erase:
5662 Nlm_EraseArc(&rr, start, stop); break;
5663 case eDM_Frame:
5664 Nlm_FrameArc(&rr, start, stop); break;
5665 case eDM_Paint:
5666 Nlm_PaintArc(&rr, start, stop); break;
5667 case eDM_Invert:
5668 Nlm_InvertArc(&rr, start, stop); break;
5669 }
5670 }}
5671 #endif
5672 }
5673
5674 void Nlm_EraseQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) {
5675 s_DoQuadrant(r, quadrant, eDM_Erase);
5676 }
5677 void Nlm_FrameQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) {
5678 s_DoQuadrant(r, quadrant, eDM_Frame);
5679 }
5680 void Nlm_PaintQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) {
5681 s_DoQuadrant(r, quadrant, eDM_Paint);
5682 }
5683 void Nlm_InvertQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) {
5684 s_DoQuadrant(r, quadrant, eDM_Invert);
5685 }
5686
5687
5688 /*********************************
5689 * POLYGON
5690 */
5691
5692 #ifdef WIN_MAC
5693 #ifdef WIN_MAC_QUARTZ
5694 static void Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts)
5695 {
5696 Nlm_PoinT firstPt;
5697 Nlm_Int2 i;
5698 Nlm_PoinT pt;
5699
5700 if (pts != NULL && num > 0) {
5701 firstPt = pts [0];
5702 CGContextMoveToPoint(Nlm_PeekQContext(), (float) firstPt.x, (float) firstPt.y);
5703 for (i = 1; i < num; i++) {
5704 pt = pts [i];
5705 CGContextAddLineToPoint(Nlm_PeekQContext(), (float) pt.x, (float) pt.y);
5706 }
5707 if (! Nlm_EqualPt (pt, firstPt)) {
5708 CGContextClosePath(Nlm_PeekQContext());
5709 }
5710 }
5711 }
5712
5713 #else
5714 static PolyHandle Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts)
5715
5716 {
5717 Nlm_PoinT firstPt;
5718 Nlm_Int2 i;
5719 Nlm_PoinT pt;
5720 PolyHandle rsult;
5721
5722 rsult = NULL;
5723 if (pts != NULL && num > 0) {
5724 rsult = OpenPoly ();
5725 firstPt = pts [0];
5726 MoveTo (firstPt.x, firstPt.y);
5727 for (i = 1; i < num; i++) {
5728 pt = pts [i];
5729 LineTo (pt.x, pt.y);
5730 }
5731 if (! Nlm_EqualPt (pt, firstPt)) {
5732 LineTo (firstPt.x, firstPt.y);
5733 }
5734 ClosePoly ();
5735 }
5736 return rsult;
5737 }
5738
5739 static void Nlm_DestroyPoly (PolyHandle ply)
5740
5741 {
5742 if (ply != NULL) {
5743 KillPoly (ply);
5744 }
5745 }
5746 #endif
5747 #endif
5748
5749 #ifdef WIN_MSWIN
5750 static LPPOINT Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts)
5751
5752 {
5753 Nlm_PoinT firstPt;
5754 Nlm_Int2 i;
5755 Nlm_PoinT pt;
5756 Nlm_PointTool ptool;
5757 LPPOINT rsult;
5758
5759 rsult = NULL;
5760 if (pts != NULL && num > 0) {
5761 rsult = (LPPOINT) Nlm_MemNew ((size_t) ((num + 1) * sizeof (POINT)));
5762 if (rsult != NULL) {
5763 firstPt = pts [0];
5764 for (i = 0; i < num; i++) {
5765 pt = pts [i];
5766 Local__PoinTToPointTool (pt, &ptool);
5767 rsult [i] = ptool;
5768 }
5769 if (! Nlm_EqualPt (pt, firstPt)) {
5770 Local__PoinTToPointTool (firstPt, &ptool);
5771 rsult [i] = ptool;
5772 }
5773 }
5774 }
5775 return rsult;
5776 }
5777
5778 static void Nlm_DestroyPoly (LPPOINT ply)
5779
5780 {
5781 if (ply != NULL) {
5782 Nlm_MemFree (ply);
5783 }
5784 }
5785 #endif
5786
5787 #ifdef WIN_X
5788 static XPoint *Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts)
5789
5790 {
5791 Nlm_PoinT firstPt;
5792 Nlm_Int2 i;
5793 Nlm_PoinT pt;
5794 Nlm_PointTool ptool;
5795 XPoint *rsult;
5796
5797 rsult = NULL;
5798 if (pts != NULL && num > 0) {
5799 rsult = (XPoint *) Nlm_MemNew ((size_t) ((num + 1) * sizeof (XPoint)));
5800 if (rsult != NULL) {
5801 firstPt = pts [0];
5802 firstPt.x -= Nlm_XOffset;
5803 firstPt.y -= Nlm_YOffset;
5804 for (i = 0; i < num; i++) {
5805 pt = pts [i];
5806 pt.x -= Nlm_XOffset;
5807 pt.y -= Nlm_YOffset;
5808 Local__PoinTToPointTool (pt, &ptool);
5809 rsult [i] = ptool;
5810 }
5811 if (! Nlm_EqualPt (pt, firstPt)) {
5812 Local__PoinTToPointTool (firstPt, &ptool);
5813 rsult [i] = ptool;
5814 }
5815 }
5816 }
5817 return rsult;
5818 }
5819
5820 static void Nlm_DestroyPoly (XPoint *ply)
5821
5822 {
5823 if (ply != NULL) {
5824 Nlm_MemFree (ply);
5825 }
5826 }
5827 #endif
5828
5829 extern void Nlm_ErasePoly (Nlm_Int2 num, Nlm_PointPtr pts)
5830
5831 {
5832 if (pts != NULL && num > 1) {
5833 #ifdef WIN_MAC
5834 #ifdef WIN_MAC_QUARTZ
5835 Nlm_CreatePoly (num, pts);
5836 CGContextSaveGState(Nlm_PeekQContext());
5837 Nlm_White();
5838 CGContextEOFillPath(Nlm_PeekQContext());
5839 CGContextRestoreGState(Nlm_PeekQContext());
5840 #else
5841 PolyHandle ply;
5842
5843 ply = Nlm_CreatePoly (num, pts);
5844 if (ply != NULL) {
5845 ErasePoly (ply);
5846 }
5847 Nlm_DestroyPoly (ply);
5848 #endif
5849 #endif
5850 #ifdef WIN_MSWIN
5851 #endif
5852 #ifdef WIN_X
5853 #endif
5854 #ifdef WIN_GIF
5855 #endif
5856 }
5857 }
5858
5859
5860 extern void Nlm_FramePoly(Nlm_Int2 num, Nlm_PointPtr pts)
5861 {
5862 if (pts != NULL && num > 1) {
5863 #ifdef WIN_MAC
5864 #ifdef WIN_MAC_QUARTZ
5865 Nlm_CreatePoly (num, pts);
5866 CGContextStrokePath(Nlm_PeekQContext());
5867 #else
5868 PolyHandle ply;
5869
5870 ply = Nlm_CreatePoly (num, pts);
5871 if (ply != NULL) {
5872 FramePoly (ply);
5873 }
5874 Nlm_DestroyPoly (ply);
5875 #endif
5876 #endif
5877 #ifdef WIN_MSWIN
5878 LPPOINT ply;
5879
5880 ply = Nlm_CreatePoly (num, pts);
5881 if (Nlm_currentHDC != NULL && ply != NULL) {
5882 if (! Nlm_EqualPt (pts [0], pts [num - 1])) {
5883 num++;
5884 }
5885 Polyline (Nlm_currentHDC, ply, num);
5886 }
5887 Nlm_DestroyPoly (ply);
5888 #endif
5889 #ifdef WIN_X
5890 XPoint *ply;
5891
5892 ply = Nlm_CreatePoly (num, pts);
5893 if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 &&
5894 Nlm_currentXGC != NULL && ply != NULL) {
5895 if (! Nlm_EqualPt (pts [0], pts [num - 1])) {
5896 num++;
5897 }
5898 XDrawLines (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5899 ply, num, CoordModeOrigin);
5900 }
5901 Nlm_DestroyPoly (ply);
5902 #endif
5903 #ifdef WIN_GIF
5904 gdPointPtr pPtr;
5905 int i;
5906
5907 if (Nlm_currentGIF != NULL && pts != NULL) {
5908 pPtr = (gdPointPtr)Nlm_MemNew(num * sizeof(gdPoint));
5909 for ( i=0; i<num; i++ ){
5910 pPtr[i].x = pts[i].x;
5911 pPtr[i].y = pts[i].y;
5912 }
5913 gdImagePolygon ( Nlm_currentGIF, pPtr, num, Nlm_curGIFColor );
5914 MemFree (pPtr);
5915 }
5916 #endif
5917 }
5918 }
5919
5920 extern void Nlm_PaintPoly (Nlm_Int2 num, Nlm_PointPtr pts)
5921
5922 {
5923 if (pts != NULL && num > 1) {
5924 #ifdef WIN_MAC
5925 #ifdef WIN_MAC_QUARTZ
5926 Nlm_CreatePoly (num, pts);
5927 CGContextEOFillPath(Nlm_PeekQContext());
5928 #else
5929 PolyHandle ply;
5930
5931 ply = Nlm_CreatePoly (num, pts);
5932 if (ply != NULL) {
5933 PaintPoly (ply);
5934 }
5935 Nlm_DestroyPoly (ply);
5936 #endif
5937 #endif
5938 #ifdef WIN_MSWIN
5939 LPPOINT ply;
5940
5941 ply = Nlm_CreatePoly (num, pts);
5942 if (Nlm_currentHDC != NULL && ply != NULL) {
5943 if (! Nlm_EqualPt (pts [0], pts [num - 1])) {
5944 num++;
5945 }
5946 SetPolyFillMode (Nlm_currentHDC, ALTERNATE);
5947 Polygon (Nlm_currentHDC, ply, num);
5948 }
5949 Nlm_DestroyPoly (ply);
5950 #endif
5951 #ifdef WIN_X
5952 XPoint *ply = Nlm_CreatePoly (num, pts);
5953 if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 &&
5954 Nlm_currentXGC != NULL && ply != NULL)
5955 {
5956 int i;
5957 short left=32767, top=32767;
5958 for (i = 0; i < num; i++)
5959 {
5960 if (ply[i].x < left)
5961 left = ply[i].x;
5962 if (ply[i].y < top)
5963 top = ply[i].y;
5964 }
5965 for (i = 0; i < num; i++)
5966 {
5967 if (ply[i].x != left)
5968 ply[i].x++;
5969 if (ply[i].y != top)
5970 ply[i].y++;
5971 }
5972
5973 XSetFillRule (Nlm_currentXDisplay, Nlm_currentXGC, EvenOddRule);
5974 XFillPolygon (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC,
5975 ply, num, Complex, CoordModeOrigin);
5976 }
5977 Nlm_DestroyPoly (ply);
5978 #endif
5979 #ifdef WIN_GIF
5980 gdPointPtr pPtr;
5981 int i;
5982
5983 if (Nlm_currentGIF != NULL && pts != NULL) {
5984 pPtr = (gdPointPtr)Nlm_MemNew(num * sizeof(gdPoint));
5985 for ( i=0; i<num; i++ ){
5986 pPtr[i].x = pts[i].x;
5987 pPtr[i].y = pts[i].y;
5988 }
5989 gdImageFilledPolygon ( Nlm_currentGIF, pPtr, num, Nlm_curGIFColor );
5990 MemFree (pPtr);
5991 }
5992 #endif
5993 }
5994 }
5995
5996 extern void Nlm_InvertPoly (Nlm_Int2 num, Nlm_PointPtr pts)
5997
5998 {
5999 if (pts != NULL && num > 1) {
6000 #ifdef WIN_MAC
6001 #ifdef WIN_MAC_QUARTZ
6002 #else
6003 PolyHandle ply;
6004
6005 ply = Nlm_CreatePoly (num, pts);
6006 if (ply != NULL) {
6007 InvertPoly (ply);
6008 }
6009 Nlm_DestroyPoly (ply);
6010 #endif
6011 #endif
6012 #ifdef WIN_MSWIN
6013 #endif
6014 #ifdef WIN_X
6015 #endif
6016 #ifdef WIN_GIF
6017 #endif
6018 }
6019 }
6020
6021 extern Nlm_RegioN Nlm_CreateRgn (void)
6022
6023 {
6024 Nlm_RgnTool ntool;
6025
6026 #ifdef WIN_MAC
6027 #ifdef WIN_MAC_QUARTZ
6028 ntool = HIShapeCreateMutable();
6029 #else
6030 ntool = NewRgn ();
6031 #endif
6032 #endif
6033 #ifdef WIN_MSWIN
6034 ntool = CreateRectRgn (0, 0, 0, 0);
6035 #endif
6036 #ifdef WIN_X
6037 ntool = XCreateRegion ();
6038 #endif
6039 #ifdef WIN_GIF
6040 ntool = HandNew ( sizeof(Nlm_RecT) );
6041 #endif
6042 return (Nlm_RegioN) ntool;
6043 }
6044
6045 extern Nlm_RegioN Nlm_DestroyRgn (Nlm_RegioN rgn)
6046
6047 {
6048 Nlm_RgnTool ntool;
6049
6050 if (rgn != NULL) {
6051 ntool = (Nlm_RgnTool) rgn;
6052 #ifdef WIN_MAC
6053 #ifdef WIN_MAC_QUARTZ
6054 CFRelease (ntool);
6055 #else
6056 DisposeRgn (ntool);
6057 #endif
6058 #endif
6059 #ifdef WIN_MSWIN
6060 DeleteObject (ntool);
6061 #endif
6062 #ifdef WIN_X
6063 XDestroyRegion (ntool);
6064 #endif
6065 #ifdef WIN_GIF
6066 HandFree ( ntool );
6067 #endif
6068 }
6069 return NULL;
6070 }
6071
6072 extern void Nlm_ClearRgn (Nlm_RegioN rgn)
6073
6074 {
6075 Nlm_RgnTool ntool;
6076 #ifdef WIN_MSWIN
6077 Nlm_RgnTool temp;
6078 #endif
6079
6080 if (rgn != NULL) {
6081 ntool = (Nlm_RgnTool) rgn;
6082 #ifdef WIN_MAC
6083 #ifdef WIN_MAC_QUARTZ
6084 HIShapeSetEmpty (ntool);
6085 #else
6086 SetEmptyRgn (ntool);
6087 #endif
6088 #endif
6089 #ifdef WIN_MSWIN
6090 temp = CreateRectRgn (0, 0, 0, 0);
6091 CombineRgn (ntool, temp, temp, RGN_COPY);
6092 DeleteObject (temp);
6093 #endif
6094 #ifdef WIN_X
6095 XUnionRegion (emptyRgn, emptyRgn, ntool);
6096 #endif
6097 }
6098 }
6099
6100 extern void Nlm_LoadRectRgn (Nlm_RegioN rgn, Nlm_Int2 lf,
6101 Nlm_Int2 tp, Nlm_Int2 rt,
6102 Nlm_Int2 bt)
6103
6104 {
6105 Nlm_RgnTool ntool;
6106 #ifdef WIN_X
6107 Nlm_RecT rct;
6108 Nlm_RectTool rtool;
6109 #endif
6110 #ifdef WIN_GIF
6111 Nlm_RecT rct;
6112 #endif
6113
6114 if (rgn != NULL) {
6115 ntool = (Nlm_RgnTool) rgn;
6116 #ifdef WIN_MAC
6117 #ifdef WIN_MAC_QUARTZ
6118 HIShapeSetEmpty (ntool);
6119
6120 CGRect r = CGRectMake (lf, tp, rt - lf, bt - tp);
6121 HIShapeRef tempShape = HIShapeCreateWithRect (&r);
6122 HIShapeUnion (tempShape, ntool, ntool);
6123 CFRelease (tempShape);
6124 #else
6125 SetRectRgn (ntool, lf, tp, rt, bt);
6126 #endif
6127 #endif
6128 #ifdef WIN_MSWIN
6129 SetRectRgn (ntool, lf, tp, rt, bt);
6130 #endif
6131 #ifdef WIN_X
6132 Nlm_LoadRect (&rct, lf, tp, rt, bt);
6133 Local__RecTToRectTool (&rct, &rtool);
6134 XUnionRectWithRegion (&rtool, emptyRgn, ntool);
6135 #endif
6136 #ifdef WIN_GIF
6137 Nlm_LoadRect (&rct, lf, tp, rt, bt);
6138 Nlm_RectToGIFRgn ( &rct, ntool );
6139 #endif
6140 }
6141 }
6142
6143 extern void Nlm_OffsetRgn (Nlm_RegioN rgn, Nlm_Int2 dx, Nlm_Int2 dy)
6144
6145 {
6146 Nlm_RgnTool ntool;
6147 #ifdef WIN_GIF
6148 Nlm_RecT rTool;
6149 #endif
6150
6151 if (rgn != NULL) {
6152 ntool = (Nlm_RgnTool) rgn;
6153 #ifdef WIN_MAC
6154 #ifdef WIN_MAC_QUARTZ
6155 HIShapeOffset (ntool, dx, dy);
6156 #else
6157 OffsetRgn (ntool, dx, dy);
6158 #endif
6159 #endif
6160 #ifdef WIN_MSWIN
6161 OffsetRgn (ntool, dx, dy);
6162 #endif
6163 #ifdef WIN_X
6164 XOffsetRegion (ntool, dx, dy);
6165 #endif
6166 #ifdef WIN_GIF
6167 Nlm_GIFRgnToRect ( ntool, &rTool );
6168 Nlm_OffsetRect ( &rTool, dx, dy );
6169 Nlm_RectToGIFRgn ( &rTool, ntool );
6170 #endif
6171 }
6172 }
6173
6174 extern void Nlm_SectRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst)
6175
6176 {
6177 Nlm_RgnTool ntool1;
6178 Nlm_RgnTool ntool2;
6179 Nlm_RgnTool ntool3;
6180 #ifdef WIN_X
6181 Nlm_RgnTool temp;
6182 #endif
6183 #ifdef WIN_GIF
6184 Nlm_RecT rsrc1;
6185 Nlm_RecT rsrc2;
6186 Nlm_RecT rdst;
6187 #endif
6188
6189 if (src1 != NULL && src2 != NULL && dst != NULL) {
6190 ntool1 = (Nlm_RgnTool) src1;
6191 ntool2 = (Nlm_RgnTool) src2;
6192 ntool3 = (Nlm_RgnTool) dst;
6193 #ifdef WIN_MAC
6194 #ifdef WIN_MAC_QUARTZ
6195 HIShapeIntersect (ntool1, ntool2, ntool3);
6196 #else
6197 SectRgn (ntool1, ntool2, ntool3);
6198 #endif
6199 #endif
6200 #ifdef WIN_MSWIN
6201 CombineRgn (ntool3, ntool1, ntool2, RGN_AND);
6202 #endif
6203 #ifdef WIN_X
6204 temp = XCreateRegion ();
6205 XIntersectRegion (ntool1, ntool2, temp);
6206 XUnionRegion (temp, emptyRgn, ntool3);
6207 XDestroyRegion (temp);
6208 #endif
6209 #ifdef WIN_GIF
6210 Nlm_GIFRgnToRect ( ntool1, &rsrc1 );
6211 Nlm_GIFRgnToRect ( ntool2, &rsrc2 );
6212 Nlm_SectRect ( &rsrc1, &rsrc2, &rdst );
6213 Nlm_RectToGIFRgn ( &rdst, ntool3 );
6214 #endif
6215 }
6216 }
6217
6218 extern void Nlm_UnionRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst)
6219
6220 {
6221 Nlm_RgnTool ntool1;
6222 Nlm_RgnTool ntool2;
6223 Nlm_RgnTool ntool3;
6224 #ifdef WIN_X
6225 Nlm_RgnTool temp;
6226 #endif
6227 #ifdef WIN_GIF
6228 Nlm_RecT rsrc1;
6229 Nlm_RecT rsrc2;
6230 Nlm_RecT rdst;
6231 #endif
6232
6233 if (src1 != NULL && src2 != NULL && dst != NULL) {
6234 ntool1 = (Nlm_RgnTool) src1;
6235 ntool2 = (Nlm_RgnTool) src2;
6236 ntool3 = (Nlm_RgnTool) dst;
6237 #ifdef WIN_MAC
6238 #ifdef WIN_MAC_QUARTZ
6239 HIShapeUnion( ntool1, ntool2, ntool3);
6240 #else
6241 UnionRgn (ntool1, ntool2, ntool3);
6242 #endif
6243 #endif
6244 #ifdef WIN_MSWIN
6245 CombineRgn (ntool3, ntool1, ntool2, RGN_OR);
6246 #endif
6247 #ifdef WIN_X
6248 temp = XCreateRegion ();
6249 XUnionRegion (ntool1, ntool2, temp);
6250 XUnionRegion (temp, emptyRgn, ntool3);
6251 XDestroyRegion (temp);
6252 #endif
6253 #ifdef WIN_GIF
6254 Nlm_GIFRgnToRect ( ntool1, &rsrc1 );
6255 Nlm_GIFRgnToRect ( ntool2, &rsrc2 );
6256 Nlm_UnionRect ( &rsrc1, &rsrc2, &rdst );
6257 Nlm_RectToGIFRgn ( &rdst, ntool3 );
6258 #endif
6259 }
6260 }
6261
6262 extern void Nlm_DiffRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst)
6263
6264 {
6265 Nlm_RgnTool ntool1;
6266 Nlm_RgnTool ntool2;
6267 Nlm_RgnTool ntool3;
6268 #ifdef WIN_X
6269 Nlm_RgnTool temp;
6270 #endif
6271
6272 if (src1 != NULL && src2 != NULL && dst != NULL) {
6273 ntool1 = (Nlm_RgnTool) src1;
6274 ntool2 = (Nlm_RgnTool) src2;
6275 ntool3 = (Nlm_RgnTool) dst;
6276 #ifdef WIN_MAC
6277 #ifdef WIN_MAC_QUARTZ
6278 HIShapeDifference (ntool1, ntool2, ntool3);
6279 #else
6280 DiffRgn (ntool1, ntool2, ntool3);
6281 #endif
6282 #endif
6283 #ifdef WIN_MSWIN
6284 CombineRgn (ntool3, ntool1, ntool2, RGN_DIFF);
6285 #endif
6286 #ifdef WIN_X
6287 temp = XCreateRegion ();
6288 XSubtractRegion (ntool1, ntool2, temp);
6289 XUnionRegion (temp, emptyRgn, ntool3);
6290 XDestroyRegion (temp);
6291 #endif
6292 }
6293 }
6294
6295 extern void Nlm_XorRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst)
6296
6297 {
6298 #ifdef WIN_MAC_QUARTZ
6299 /* this is actually a general solution, but less efficient
6300 Quartz has no choice but to use it since HIShape does not support
6301 the xor operation natively
6302
6303 xor is equivalent to the union minus the intersection, so we do that */
6304
6305 Nlm_RegioN sum = Nlm_CreateRgn();
6306 Nlm_RegioN intersection = Nlm_CreateRgn();
6307
6308 Nlm_UnionRgn (src1, src2, sum);
6309 Nlm_SectRgn (src1, src2, intersection);
6310 Nlm_DiffRgn (sum, intersection, dst);
6311
6312 Nlm_DestroyRgn (sum);
6313 Nlm_DestroyRgn (intersection);
6314 #else
6315
6316 Nlm_RgnTool ntool1;
6317 Nlm_RgnTool ntool2;
6318 Nlm_RgnTool ntool3;
6319 #ifdef WIN_X
6320 Nlm_RgnTool temp;
6321 #endif
6322
6323 if (src1 != NULL && src2 != NULL && dst != NULL) {
6324 ntool1 = (Nlm_RgnTool) src1;
6325 ntool2 = (Nlm_RgnTool) src2;
6326 ntool3 = (Nlm_RgnTool) dst;
6327 #ifdef WIN_MAC
6328 XorRgn (ntool1, ntool2, ntool3);
6329 #endif
6330 #ifdef WIN_MSWIN
6331 CombineRgn (ntool3, ntool1, ntool2, RGN_XOR);
6332 #endif
6333 #ifdef WIN_X
6334 temp = XCreateRegion ();
6335 XXorRegion (ntool1, ntool2, temp);
6336 XUnionRegion (temp, emptyRgn, ntool3);
6337 XDestroyRegion (temp);
6338 #endif
6339 }
6340 #endif
6341 }
6342
6343 extern Nlm_Boolean Nlm_EqualRgn (Nlm_RegioN rgn1, Nlm_RegioN rgn2)
6344
6345 {
6346 Nlm_RgnTool ntool1;
6347 Nlm_RgnTool ntool2;
6348 Nlm_Boolean rsult;
6349
6350 rsult = FALSE;
6351 if (rgn1 != NULL && rgn2 != NULL) {
6352 ntool1 = (Nlm_RgnTool) rgn1;
6353 ntool2 = (Nlm_RgnTool) rgn2;
6354 #ifdef WIN_MAC
6355 #ifdef WIN_MAC_QUARTZ
6356 /* HIShapeRefs are CFTypeRefs so we can use CFEqual */
6357 rsult = CFEqual (ntool1, ntool2);
6358 #else
6359 rsult = EqualRgn (ntool1, ntool2);
6360 #endif
6361 #endif
6362 #ifdef WIN_MSWIN
6363 rsult = (Nlm_Boolean) EqualRgn (ntool1, ntool2);
6364 #endif
6365 #ifdef WIN_X
6366 rsult = (XEqualRegion (ntool1, ntool2) != 0);
6367 #endif
6368 }
6369 return rsult;
6370 }
6371
6372 extern Nlm_Boolean Nlm_EmptyRgn (Nlm_RegioN rgn)
6373
6374 {
6375 Nlm_RgnTool ntool;
6376 Nlm_Boolean rsult;
6377 #ifdef WIN_MSWIN
6378 Nlm_RectTool rtool;
6379 #endif
6380
6381 rsult = FALSE;
6382 if (rgn != NULL) {
6383 ntool = (Nlm_RgnTool) rgn;
6384 #ifdef WIN_MAC
6385 #ifdef WIN_MAC_QUARTZ
6386 rsult = HIShapeIsEmpty (ntool);
6387 #else
6388 rsult = EmptyRgn (ntool);
6389 #endif
6390 #endif
6391 #ifdef WIN_MSWIN
6392 rsult = (Nlm_Boolean) (GetRgnBox (ntool, &rtool) == NULLREGION);
6393 #endif
6394 #ifdef WIN_X
6395 rsult = (XEmptyRegion (ntool) != 0);
6396 #endif
6397 }
6398 return rsult;
6399 }
6400
6401 extern void Nlm_EraseRgn (Nlm_RegioN rgn)
6402
6403 {
6404 #ifdef WIN_MAC
6405 Nlm_RgnTool ntool;
6406
6407 if (rgn != NULL) {
6408 ntool = (Nlm_RgnTool) rgn;
6409 #ifdef WIN_MAC_QUARTZ
6410 HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext());
6411
6412 Nlm_SelectQuartzColor (Nlm_QuartzBackColor);
6413 CGContextFillPath (Nlm_PeekQContext());
6414 Nlm_SelectQuartzColor (Nlm_QuartzForeColor);
6415 #else
6416 EraseRgn (ntool);
6417 #endif
6418 }
6419 #endif
6420 #ifdef WIN_MSWIN
6421 Nlm_RgnTool ntool;
6422
6423 if (rgn != NULL && Nlm_currentHDC != NULL && Nlm_currentHWnd != NULL) {
6424 ntool = (Nlm_RgnTool) rgn;
6425 FillRgn (Nlm_currentHDC, ntool, GetBackgroundBrush (Nlm_currentHWnd));
6426 }
6427 #endif
6428 #ifdef WIN_X
6429 #endif
6430 }
6431
6432 extern void Nlm_FrameRgn (Nlm_RegioN rgn)
6433
6434 {
6435 #ifdef WIN_MAC
6436 Nlm_RgnTool ntool;
6437
6438 if (rgn != NULL) {
6439 ntool = (Nlm_RgnTool) rgn;
6440 #ifdef WIN_MAC_QUARTZ
6441 HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext());
6442 CGContextStrokePath (Nlm_PeekQContext());
6443 #else
6444 FrameRgn (ntool);
6445 #endif
6446 }
6447 #endif
6448 #ifdef WIN_MSWIN
6449 Nlm_RgnTool ntool;
6450
6451 if (rgn != NULL && Nlm_currentHDC != NULL) {
6452 ntool = (Nlm_RgnTool) rgn;
6453 FrameRgn (Nlm_currentHDC, ntool, GetStockObject (BLACK_BRUSH), 1, 1);
6454 }
6455 #endif
6456 #ifdef WIN_X
6457 #endif
6458 }
6459
6460 extern void Nlm_PaintRgn (Nlm_RegioN rgn)
6461
6462 {
6463 #ifdef WIN_MAC
6464 Nlm_RgnTool ntool;
6465
6466 if (rgn != NULL) {
6467 ntool = (Nlm_RgnTool) rgn;
6468 #ifdef WIN_MAC_QUARTZ
6469 HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext());
6470 CGContextFillPath (Nlm_PeekQContext());
6471 #else
6472 PaintRgn (ntool);
6473 #endif
6474 }
6475 #endif
6476 #ifdef WIN_MSWIN
6477 Nlm_RgnTool ntool;
6478 HBRUSH oldBrush;
6479
6480 if (rgn != NULL && Nlm_currentHDC != NULL) {
6481 ntool = (Nlm_RgnTool) rgn;
6482 oldBrush = SelectObject (Nlm_currentHDC, GetStockObject (BLACK_BRUSH));
6483 if (oldBrush != NULL) {
6484 SelectObject (Nlm_currentHDC, oldBrush);
6485 FillRgn (Nlm_currentHDC, ntool, oldBrush);
6486 }
6487 }
6488 #endif
6489 #ifdef WIN_X
6490 #endif
6491 }
6492
6493 extern void Nlm_InvertRgn (Nlm_RegioN rgn)
6494
6495 {
6496 #ifdef WIN_MAC
6497 Nlm_RgnTool ntool;
6498
6499 if (rgn != NULL) {
6500 ntool = (Nlm_RgnTool) rgn;
6501 #ifdef WIN_MAC_QUARTZ
6502 // QUARTZ_FIXME: this operation does not make sense in quartz, what to do?
6503 #else
6504 InvertRgn (ntool);
6505 #endif
6506 }
6507 #endif
6508 #ifdef WIN_MSWIN
6509 Nlm_RgnTool ntool;
6510
6511 if (rgn != NULL && Nlm_currentHDC != NULL) {
6512 ntool = (Nlm_RgnTool) rgn;
6513 InvertRgn (Nlm_currentHDC, ntool);
6514 }
6515 #endif
6516 #ifdef WIN_X
6517 #endif
6518 }
6519
6520 extern void Nlm_ClipRect (Nlm_RectPtr r)
6521
6522 {
6523 #ifdef WIN_MAC
6524 Nlm_RectTool rtool;
6525
6526 if (r != NULL) {
6527 Local__RecTToRectTool (r, &rtool);
6528 #ifdef WIN_MAC_QUARTZ
6529 if (Nlm_PeekQContext())
6530 {
6531 CGRect cgr = Nlm_RecTToCGRect (*r);
6532
6533 CGContextClipToRect (Nlm_PeekQContext(), cgr);
6534 }
6535 #else
6536 ClipRect (&rtool);
6537 #endif
6538 }
6539 #endif
6540 #ifdef WIN_MSWIN
6541 HRGN hRgnClip;
6542
6543 if (r != NULL && Nlm_currentHDC != NULL) {
6544 hRgnClip = CreateRectRgn (r->left, r->top, r->right, r->bottom);
6545 SelectClipRgn (Nlm_currentHDC, hRgnClip);
6546 DeleteObject (hRgnClip);
6547 }
6548 #endif
6549 #ifdef WIN_X
6550 Nlm_RectTool rtool;
6551
6552 if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
6553 Local__RecTToRectTool (r, &rtool);
6554 rtool.x -= Nlm_XOffset;
6555 rtool.y -= Nlm_YOffset;
6556 XSetClipRectangles (Nlm_currentXDisplay, Nlm_currentXGC, 0, 0, &rtool, 1, Unsorted);
6557 if (Nlm_clpRgn != NULL) {
6558 XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn);
6559 Nlm_clpRgn = NULL;
6560 }
6561 Nlm_clpRgn = (Nlm_RegioN) XCreateRegion ();
6562 XUnionRectWithRegion (&rtool, (Nlm_RgnTool) Nlm_clpRgn, (Nlm_RgnTool) Nlm_clpRgn);
6563 XOffsetRegion ((Nlm_RgnTool) Nlm_clpRgn, Nlm_XOffset, Nlm_YOffset);
6564 }
6565 #endif
6566 }
6567
6568 extern void Nlm_ClipRgn (Nlm_RegioN rgn)
6569
6570 {
6571 #ifdef WIN_MAC
6572 Nlm_RgnTool ntool;
6573
6574 if (rgn != NULL) {
6575 ntool = (Nlm_RgnTool) rgn;
6576 #ifdef WIN_MAC_QUARTZ
6577 HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext());
6578 CGContextClip (Nlm_PeekQContext());
6579 #else
6580 SetClip (ntool);
6581 #endif
6582 }
6583 #endif
6584 #ifdef WIN_MSWIN
6585 Nlm_RgnTool ntool;
6586
6587 if (rgn != NULL && Nlm_currentHDC != NULL) {
6588 ntool = (Nlm_RgnTool) rgn;
6589 SelectClipRgn (Nlm_currentHDC, ntool);
6590 }
6591 #endif
6592 #ifdef WIN_X
6593 Nlm_RgnTool ntool1;
6594 Nlm_RgnTool ntool2;
6595
6596 if (rgn != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
6597 ntool1 = XCreateRegion ();
6598 ntool2 = XCreateRegion ();
6599 XUnionRegion ((Nlm_RgnTool) rgn, ntool1, ntool2);
6600 XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset);
6601 XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2);
6602 if (Nlm_clpRgn != NULL) {
6603 XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn);
6604 Nlm_clpRgn = NULL;
6605 }
6606 Nlm_clpRgn = (Nlm_RegioN) XCreateRegion ();
6607 XUnionRegion ((Nlm_RgnTool) rgn, ntool1, (Nlm_RgnTool) Nlm_clpRgn);
6608 XOffsetRegion ((Nlm_RgnTool) Nlm_clpRgn, -Nlm_XOffset, -Nlm_YOffset);
6609 XDestroyRegion (ntool1);
6610 XDestroyRegion (ntool2);
6611 }
6612 #endif
6613 }
6614
6615 extern void Nlm_ResetClip (void)
6616
6617 {
6618 #ifdef WIN_MAC
6619 #ifdef WIN_MAC_QUARTZ
6620 // QUARTZ_FIXME: CGContext clips can only contract, not expand, needs to be handled by popping the context, but callers don't know about that... maybe have the global context always be inherently pushed, and this can pop and immediately re-push?
6621 #else
6622 Nlm_RecT r;
6623 Nlm_RectTool rtool;
6624
6625 Nlm_LoadRect (&r, -32767, -32767, 32767, 32767);
6626 Local__RecTToRectTool (&r, &rtool);
6627 ClipRect (&rtool);
6628 #endif
6629 #endif
6630 #ifdef WIN_MSWIN
6631 if (Nlm_currentHDC != NULL) {
6632 SelectClipRgn (Nlm_currentHDC, NULL);
6633 }
6634 #endif
6635 #ifdef WIN_X
6636 if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) {
6637 XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None);
6638 if (Nlm_clpRgn != NULL) {
6639 XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn);
6640 Nlm_clpRgn = NULL;
6641 }
6642 }
6643 #endif
6644 }
6645
6646 extern void Nlm_ValidRect (Nlm_RectPtr r)
6647
6648 {
6649 #ifdef WIN_MAC
6650 #ifdef WIN_MAC_QUARTZ
6651 // QUARTZ_FIXME: do we care? just let it redraw
6652 #else
6653 Nlm_RectTool rtool;
6654
6655 if (r != NULL) {
6656 Local__RecTToRectTool (r, &rtool);
6657 ValidRect (&rtool);
6658 }
6659 #endif
6660 #endif
6661 #ifdef WIN_MSWIN
6662 Nlm_RectTool rtool;
6663
6664 if (r != NULL && Nlm_currentHWnd != NULL) {
6665 Local__RecTToRectTool (r, &rtool);
6666 ValidateRect (Nlm_currentHWnd, &rtool);
6667 }
6668 #endif
6669 #ifdef WIN_X
6670 #endif
6671 }
6672
6673 extern void Nlm_InvalRect (Nlm_RectPtr r)
6674
6675 {
6676 #ifdef WIN_MAC
6677 #ifdef WIN_MAC_QUARTZ
6678 // QUARTZ_FIXME: this could stand to be a little more fine-grained
6679 HIViewRef view = HIViewGetRoot (Nlm_QWindow);
6680 HIViewSetNeedsDisplay (view, 1);
6681 #else
6682 Nlm_RectTool rtool;
6683
6684 if (r != NULL) {
6685 Local__RecTToRectTool (r, &rtool);
6686 InvalRect (&rtool);
6687 }
6688 #endif
6689 #endif
6690 #ifdef WIN_MSWIN
6691 Nlm_RectTool rtool;
6692
6693 if (r != NULL && Nlm_currentHWnd != NULL) {
6694 Local__RecTToRectTool (r, &rtool);
6695 InvalidateRect (Nlm_currentHWnd, &rtool, TRUE);
6696 }
6697 #endif
6698 #ifdef WIN_X
6699 Nlm_RectTool rtool;
6700
6701 if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0) {
6702 Local__RecTToRectTool (r, &rtool);
6703 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow,
6704 rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset,
6705 rtool.width, rtool.height, TRUE);
6706 }
6707 #endif
6708 }
6709
6710 extern void Nlm_ValidRgn (Nlm_RegioN rgn)
6711
6712 {
6713 #ifdef WIN_MAC
6714 if (rgn != NULL) {
6715 #ifdef WIN_MAC_QUARTZ
6716 // QUARTZ_FIXME: do we care? just let it redraw
6717 #else
6718 ValidRgn ((Nlm_RgnTool) rgn);
6719 #endif
6720 }
6721 #endif
6722 #ifdef WIN_MSWIN
6723 if (rgn != NULL && Nlm_currentHWnd != NULL) {
6724 ValidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) rgn);
6725 }
6726 #endif
6727 #ifdef WIN_X
6728 #endif
6729 }
6730
6731 extern void Nlm_InvalRgn (Nlm_RegioN rgn)
6732
6733 {
6734 #ifdef WIN_MAC
6735 if (rgn != NULL) {
6736 #ifdef WIN_MAC_QUARTZ
6737 // QUARTZ_FIXME: this could stand to be a little more fine-grained
6738 HIViewRef view = HIViewGetRoot (Nlm_QWindow);
6739 HIViewSetNeedsDisplay (view, 1);
6740 #else
6741 InvalRgn ((Nlm_RgnTool) rgn);
6742 #endif
6743 }
6744 #endif
6745 #ifdef WIN_MSWIN
6746 if (rgn != NULL && Nlm_currentHWnd != NULL) {
6747 InvalidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) rgn, TRUE);
6748 }
6749 #endif
6750 #ifdef WIN_X
6751 Nlm_RgnTool ntool1;
6752 Nlm_RgnTool ntool2;
6753 Nlm_RectTool rtool;
6754
6755 if (rgn != NULL && Nlm_currentXDisplay != NULL &&
6756 Nlm_currentXGC != NULL && Nlm_currentXWindow != 0) {
6757 ntool1 = XCreateRegion ();
6758 ntool2 = XCreateRegion ();
6759 XUnionRegion ((Nlm_RgnTool) rgn, ntool1, ntool2);
6760 XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset);
6761 XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2);
6762 XClipBox (ntool2, &rtool);
6763 XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x,
6764 rtool.y, rtool.width, rtool.height, TRUE);
6765 XDestroyRegion (ntool1);
6766 XDestroyRegion (ntool2);
6767 if (Nlm_clpRgn != NULL) {
6768 ntool1 = XCreateRegion ();
6769 ntool2 = XCreateRegion ();
6770 XUnionRegion ((Nlm_RgnTool) Nlm_clpRgn, ntool1, ntool2);
6771 XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset);
6772 XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2);
6773 XDestroyRegion (ntool1);
6774 XDestroyRegion (ntool2);
6775 } else {
6776 XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None);
6777 }
6778 }
6779 #endif
6780 }
6781
6782 extern void Nlm_CopyBits (Nlm_RectPtr r, Nlm_VoidPtr source)
6783
6784 {
6785 #ifdef WIN_MAC
6786 #ifdef WIN_MAC_QUARTZ
6787 CGRect rect = Nlm_RecTToCGRect (*r);
6788
6789 int width = r->left - r->right;
6790 int height = r->bottom - r->top;
6791 int bytesPerRow = (width - 1) / 8 + 1;
6792
6793 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
6794 CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL, source, bytesPerRow * height, NULL);
6795
6796 CGImageRef image = CGImageCreate (
6797 width,
6798 height,
6799 1, /* bits per component */
6800 1, /* bits per pixel */
6801 bytesPerRow,
6802 colorSpace,
6803 0, /* bitmap info */
6804 dataProvider,
6805 NULL,
6806 1, /* should interpolate */
6807 kCGRenderingIntentDefault);
6808
6809 CGContextDrawImage (Nlm_PeekQContext(), rect, image);
6810
6811 CFRelease (image);
6812 CFRelease (dataProvider);
6813 CFRelease (colorSpace);
6814
6815 #else
6816 const BitMap *dstBitsPtr;
6817 Nlm_Int2 mode;
6818 PenState pnState;
6819 GrafPtr port;
6820 Rect rect;
6821 BitMap srcBits;
6822 Rect srcRect;
6823
6824 if (r != NULL && source != NULL) {
6825 GetPort (&port);
6826 GetPenState (&pnState);
6827 switch (pnState.pnMode) {
6828 case patCopy:
6829 mode = srcCopy;
6830 break;
6831 case patOr:
6832 mode = srcOr;
6833 break;
6834 case patXor:
6835 mode = srcXor;
6836 break;
6837 case patBic:
6838 mode = srcBic;
6839 break;
6840 default:
6841 mode = srcCopy;
6842 break;
6843 }
6844 Local__RecTToRectTool (r, &rect);
6845 srcRect = rect;
6846 OffsetRect (&srcRect, -rect.left, -rect.top);
6847 srcBits.baseAddr = (Ptr) source;
6848 srcBits.rowBytes = (rect.right - rect.left - 1) / 8 + 1;
6849 srcBits.bounds = srcRect;
6850 #if OPAQUE_TOOLBOX_STRUCTS
6851 dstBitsPtr = GetPortBitMapForCopyBits(port);
6852 #else
6853 dstBitsPtr = &port->portBits;
6854 #endif
6855 CopyBits (&srcBits, dstBitsPtr, &srcRect, &rect, mode, NULL);
6856 }
6857 #endif
6858 #endif
6859 #ifdef WIN_MSWIN
6860 Nlm_Int2 cols;
6861 HBITMAP hBitmap;
6862 HBITMAP hOldBitmap;
6863 HDC hMemoryDC;
6864 int rop2;
6865 Nlm_Int2 i;
6866 Nlm_Int2 j;
6867 Nlm_Int4 mode;
6868 Nlm_Int4 num;
6869 Nlm_Boolean odd;
6870 Nlm_Uint1Ptr p;
6871 Nlm_Uint1Ptr ptr;
6872 Nlm_Uint1Ptr q;
6873 Nlm_Int2 rows;
6874
6875 if (r != NULL && source != NULL && Nlm_currentHDC != NULL) {
6876 rows = (Nlm_Int2)((r->right - r->left - 1) / 8 + 1);
6877 odd = (Nlm_Boolean) ((rows & 1) != 0);
6878 cols = (Nlm_Int2)(r->bottom - r->top);
6879 num = rows * cols;
6880 if (odd) {
6881 num += cols;
6882 }
6883 ptr = (Nlm_Uint1Ptr) Nlm_MemNew ((size_t) num * sizeof (Nlm_Uint1));
6884 if (ptr != NULL) {
6885 p = source;
6886 q = ptr;
6887 for (i = 0; i < cols; i++) {
6888 j = 0;
6889 while (j < rows) {
6890 *q = *p;
6891 p++;
6892 q++;
6893 j++;
6894 }
6895 if (odd) {
6896 *q = 0;
6897 q++;
6898 }
6899 }
6900 q = ptr;
6901 while (num > 0) {
6902 *q = (Nlm_Uint1) ~(*q);
6903 q++;
6904 num--;
6905 }
6906 hBitmap = CreateBitmap (r->right - r->left, r->bottom - r->top,
6907 1, 1, (LPSTR) ptr);
6908 hMemoryDC = CreateCompatibleDC (Nlm_currentHDC);
6909 if ( hMemoryDC == NULL ) {
6910 hMemoryDC = CreateCompatibleDC (NULL);
6911 hOldBitmap = SelectObject (hMemoryDC, hBitmap);
6912 mode = SRCCOPY;
6913 BitBlt (Nlm_currentHDC, r->left, r->top,
6914 r->right - r->left, r->bottom - r->top,
6915 hMemoryDC, 0, 0, mode);
6916 SelectObject (hMemoryDC, hOldBitmap);
6917 } else {
6918 hOldBitmap = SelectObject (hMemoryDC, hBitmap);
6919 if (hOldBitmap != NULL) {
6920 rop2 = GetROP2( Nlm_currentHDC );
6921 switch (rop2) {
6922 case R2_COPYPEN:
6923 mode = SRCCOPY;
6924 break;
6925 case R2_MASKPEN:
6926 mode = SRCAND;
6927 break;
6928 case R2_NOTXORPEN:
6929 mode = 0x00990066;
6930 break;
6931 case R2_MERGENOTPEN:
6932 mode = MERGEPAINT;
6933 break;
6934 default:
6935 mode = WHITENESS;
6936 break;
6937 }
6938 BitBlt (Nlm_currentHDC, r->left, r->top,
6939 r->right - r->left, r->bottom - r->top,
6940 hMemoryDC, 0, 0, mode);
6941 SelectObject (hMemoryDC, hOldBitmap);
6942 }
6943 }
6944 Nlm_MemFree (ptr);
6945 DeleteDC (hMemoryDC);
6946 DeleteObject (hBitmap);
6947 }
6948 }
6949 #endif
6950 #ifdef WIN_X
6951 Nlm_Int2 cols;
6952 Nlm_Int2 height;
6953 Nlm_Int4 num;
6954 Pixmap pixmap;
6955 Nlm_Uint1Ptr ptr;
6956 Nlm_Uint1Ptr q;
6957 Nlm_Int2 rows;
6958 Nlm_Int2 width;
6959
6960 if (r != NULL && source != NULL && Nlm_currentXDisplay != NULL &&
6961 Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) {
6962 rows = (r->right - r->left - 1) / 8 + 1;
6963 cols = r->bottom - r->top;
6964 num = rows * cols;
6965 ptr = (Nlm_Uint1Ptr) Nlm_MemNew ((size_t) num * sizeof (Nlm_Uint1));
6966 if (ptr != NULL) {
6967 Nlm_MemCopy (ptr, source, (size_t) num);
6968 q = ptr;
6969 while (num > 0) {
6970 *q = flip [*q];
6971 q++;
6972 num--;
6973 }
6974 width = r->right - r->left;
6975 height = r->bottom - r->top;
6976 pixmap = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow,
6977 (char *) ptr, width, height);
6978 XSetGraphicsExposures (Nlm_currentXDisplay, Nlm_currentXGC, FALSE);
6979 if (currentMode != MERGE_MODE) {
6980 XCopyPlane (Nlm_currentXDisplay, pixmap, Nlm_currentXWindow,
6981 Nlm_currentXGC, 0, 0, width, height,
6982 r->left - Nlm_XOffset, r->top - Nlm_YOffset, 1);
6983 } else {
6984 XSetClipOrigin (Nlm_currentXDisplay, Nlm_currentXGC,
6985 r->left - Nlm_XOffset, r->top - Nlm_YOffset);
6986 XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, pixmap);
6987 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXcopy);
6988 XCopyPlane (Nlm_currentXDisplay, pixmap, Nlm_currentXWindow,
6989 Nlm_currentXGC, 0, 0, width, height,
6990 r->left - Nlm_XOffset, r->top - Nlm_YOffset, 1);
6991 XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXand);
6992 XSetClipOrigin (Nlm_currentXDisplay, Nlm_currentXGC, 0, 0);
6993 if (Nlm_clpRgn != NULL) {
6994 XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, (Nlm_RgnTool) Nlm_clpRgn);
6995 } else {
6996 XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None);
6997 }
6998 }
6999 XSetGraphicsExposures (Nlm_currentXDisplay, Nlm_currentXGC, TRUE);
7000 XFreePixmap (Nlm_currentXDisplay, pixmap);
7001 Nlm_MemFree (ptr);
7002 }
7003 }
7004 #endif
7005 #ifdef WIN_GIF
7006 if (r != NULL && source != NULL && Nlm_currentGIF != NULL ){
7007 gdImageCopyBits ( Nlm_currentGIF, r->left, r->top,
7008 r->right - r->left, r->bottom - r->top,
7009 (char*)source, Nlm_curGIFColor );
7010 }
7011 #endif
7012 }
7013
7014 extern void Nlm_CopyPixmap ( Nlm_RectPtr r, Nlm_Int1Ptr source,
7015 Nlm_Uint1 totalColors,
7016 Nlm_RGBColoRPtr colorTable )
7017 {
7018 #ifdef WIN_MSWIN
7019 BITMAPINFO PNTR bInfoPtr;
7020 RGBQUAD PNTR quadPtr;
7021 BITMAPINFOHEADER PNTR bmpHeader;
7022 HBITMAP pixMap;
7023 HDC hMemDC;
7024 #endif
7025 #ifdef WIN_MAC
7026 PixMap PNTR pixelMap;
7027 Rect rectSrc;
7028 Rect rectDst;
7029 GrafPtr port;
7030 CTabHandle tabHandle;
7031 CTabPtr tabPtr;
7032 #endif
7033 Nlm_Int2 width;
7034 Nlm_Int2 height;
7035 #ifndef WIN_GIF
7036 Nlm_Int2 i;
7037 #endif
7038
7039 if ( (r==NULL)||(source==NULL)||(totalColors==0)||
7040 (colorTable==NULL) ) return;
7041
7042 width = (Nlm_Int2)(r->right - r->left);
7043 height = (Nlm_Int2)(r->bottom - r->top);
7044
7045 #ifdef WIN_MSWIN
7046 bInfoPtr = (BITMAPINFO*)MemNew ( sizeof(BITMAPINFOHEADER) +
7047 totalColors*sizeof(RGBQUAD) );
7048 bInfoPtr->bmiHeader.biClrUsed = totalColors;
7049 for( i=0; i<(Nlm_Int2)totalColors; i++ ) {
7050 quadPtr = &(bInfoPtr->bmiColors[i]);
7051 quadPtr->rgbRed = colorTable[i].red;
7052 quadPtr->rgbGreen = colorTable[i].green;
7053 quadPtr->rgbBlue = colorTable[i].blue;
7054 quadPtr->rgbReserved = 0;
7055 }
7056 bmpHeader = &(bInfoPtr->bmiHeader);
7057 bmpHeader->biWidth = width;
7058 bmpHeader->biHeight = height;
7059 bmpHeader->biSize = sizeof(BITMAPINFOHEADER);
7060 bmpHeader->biCompression = BI_RGB;
7061 bmpHeader->biXPelsPerMeter = 2000;
7062 bmpHeader->biYPelsPerMeter = 2000;
7063 bmpHeader->biClrImportant = 0;
7064 bmpHeader->biSizeImage = 0;
7065 bmpHeader->biBitCount = 8;
7066 bmpHeader->biPlanes = 1;
7067 pixMap = CreateDIBitmap( Nlm_currentHDC,
7068 (BITMAPINFOHEADER*)bInfoPtr,
7069 CBM_INIT, source, bInfoPtr,
7070 DIB_RGB_COLORS );
7071 if ( pixMap != NULL ){
7072 hMemDC = CreateCompatibleDC ( Nlm_currentHDC );
7073 if ( hMemDC != NULL ){
7074 SelectObject( hMemDC, pixMap );
7075 StretchBlt ( Nlm_currentHDC, r->left, r->top+height, width, -height,
7076 hMemDC, 0, 0, width, height, SRCCOPY );
7077
7078 /* BitBlt( Nlm_currentHDC, r->left, r->top, width, height, hMemDC, 0, 0,
7079 SRCCOPY );*/
7080 DeleteDC( hMemDC );
7081 }
7082 DeleteObject( pixMap );
7083 }
7084 MemFree(bInfoPtr);
7085 #endif
7086 #ifdef WIN_MAC
7087 #ifdef WIN_MAC_QUARTZ
7088 CGRect rect = Nlm_RecTToCGRect (*r);
7089
7090 width = r->left - r->right;
7091 height = r->bottom - r->top;
7092
7093 CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB ();
7094
7095 /* we're going to pass the color table directly; it's an array of
7096 structs containing r, g, b, and the function wants an array
7097 of unsigned char containing r, g, b, so they all line up */
7098 CGColorSpaceRef colorSpace = CGColorSpaceCreateIndexed (baseSpace, totalColors - 1, (const unsigned char *)colorTable);
7099
7100 CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL, source, width * height, NULL);
7101
7102 CGImageRef image = CGImageCreate (
7103 width,
7104 height,
7105 8, /* bits per component */
7106 8, /* bits per pixel */
7107 width * height,
7108 colorSpace,
7109 0, /* bitmap info */
7110 dataProvider,
7111 NULL,
7112 1, /* should interpolate */
7113 kCGRenderingIntentDefault);
7114
7115 CGContextDrawImage (Nlm_PeekQContext(), rect, image);
7116
7117 CFRelease (image);
7118 CFRelease (dataProvider);
7119 CFRelease (colorSpace);
7120 CFRelease (baseSpace);
7121 #else
7122 pixelMap = (PixMap*)MemNew(sizeof(PixMap));
7123 pixelMap->hRes = 72;
7124 pixelMap->vRes = 72;
7125 pixelMap->bounds.left = 0;
7126 pixelMap->bounds.top = 0;
7127 pixelMap->cmpSize = 8;
7128 /* 2001-03-22: Joshua Juran */
7129 /* Evidently these two members don't exist in Carbon. So don't set them. */
7130 #if !TARGET_API_MAC_CARBON
7131 pixelMap->planeBytes = 0;
7132 pixelMap->pmReserved = 0;
7133 #endif
7134 pixelMap->pmVersion = 0;
7135 pixelMap->packType = 0;
7136 pixelMap->packSize = 0;
7137 pixelMap->pixelSize = 8;
7138 pixelMap->pixelType = 0;
7139 pixelMap->cmpCount = 1;
7140 pixelMap->rowBytes = width | 0x8000;
7141 pixelMap->bounds.right = width;
7142 pixelMap->bounds.bottom = height;
7143 pixelMap->pmTable = tabHandle = GetCTable(72);
7144 if ( tabHandle != NULL ) {
7145 HLock ( (Handle)tabHandle );
7146 tabPtr = *tabHandle;
7147 for ( i=0; i<(Nlm_Int2)totalColors; i++ ){
7148 tabPtr->ctTable[i].rgb.red = (Nlm_Uint2)colorTable[i].red<<8 |
7149 (Nlm_Uint2)colorTable[i].red;
7150 tabPtr->ctTable[i].rgb.green = (Nlm_Uint2)colorTable[i].green<<8 |
7151 (Nlm_Uint2)colorTable[i].green;
7152 tabPtr->ctTable[i].rgb.blue = (Nlm_Uint2)colorTable[i].blue<<8 |
7153 (Nlm_Uint2)colorTable[i].blue;
7154 if (i >= 254) break;
7155 }
7156 tabPtr->ctSeed = GetCTSeed();
7157 HUnlock((Handle)tabHandle );
7158 pixelMap->baseAddr = (Ptr)source;
7159 rectSrc.top = 0; rectSrc.bottom = height;
7160 rectSrc.left = 0; rectSrc.right = width;
7161 rectDst.top = r->top; rectDst.bottom = r->bottom;
7162 rectDst.left = r->left; rectDst.right = r->right;
7163 GetPort(&port);
7164 #ifdef CopyBits
7165 #undef CopyBits
7166 #endif
7167 CopyBits((BitMap*)pixelMap,
7168 GetPortBitMapForCopyBits(port),
7169 &rectSrc, &rectDst, srcCopy, NULL);
7170 DisposeCTable(tabHandle);
7171 }
7172 MemFree(pixelMap);
7173 #endif
7174 #endif
7175
7176 #ifdef WIN_MOTIF
7177 {{
7178 XVisualInfo visinfo;
7179 if (XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen,
7180 8, PseudoColor, &visinfo) ||
7181 XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen,
7182 8, GrayScale, &visinfo) )
7183 {
7184 Visual* vis = visinfo.visual;
7185 Nlm_Uint1Ptr nSource = (Nlm_Uint1Ptr)MemNew(width * height);
7186 Nlm_Uint1Ptr iMap = (Nlm_Uint1Ptr)MemNew( totalColors );
7187 XImage* imageX11;
7188 Nlm_Uint1Ptr curPtr;
7189 Nlm_Uint1Ptr endPtr;
7190
7191 for (i = 0; i < (Nlm_Int2)totalColors; i++)
7192 {
7193 XColor colorCell;
7194 Nlm_XAllocColor(&colorCell, Nlm_VibrantDefaultColormap(),
7195 colorTable[i].red, colorTable[i].green,
7196 colorTable[i].blue);
7197 iMap[i] = (Nlm_Uint1)colorCell.pixel;
7198 }
7199
7200 curPtr = (Nlm_Uint1Ptr)nSource;
7201 endPtr = curPtr + width * height;
7202 while ( curPtr != endPtr )
7203 *curPtr++ = iMap[*source++];
7204
7205 imageX11 = XCreateImage(Nlm_currentXDisplay, vis, 8, ZPixmap, 0,
7206 (char*)nSource, width, height, 8 , 0 );
7207 XPutImage(Nlm_currentXDisplay, Nlm_currentXWindow,
7208 Nlm_currentXGC, imageX11, 0, 0, r->left-Nlm_XOffset,
7209 r->top-Nlm_YOffset, width, height );
7210 XFlush ( Nlm_currentXDisplay );
7211 XDestroyImage( imageX11 );
7212 MemFree( nSource );
7213 MemFree( iMap );
7214 }
7215 }}
7216 #endif
7217 }
7218
7219
7220 extern void Nlm_SetUpDrawingTools (void)
7221 {
7222 #ifdef WIN_MAC
7223 Rect bounds;
7224 Nlm_FontSpec fsp;
7225 long gval;
7226 char tmpFontName[256];
7227
7228
7229 #ifdef WIN_MAC_QUARTZ
7230 CGRect r = CGRectMake (-32768, -32768, 65535, 65535);
7231 HIShapeRef rectShape = HIShapeCreateWithRect (&r);
7232 Nlm_scrollRgn = HIShapeCreateMutableCopy (rectShape);
7233 Nlm_updateRgn = HIShapeCreateMutableCopy (rectShape);
7234 CFRelease (rectShape);
7235
7236 /* can't use QuickDraw functions to get the system font,
7237 no replacemet available, so just hardcode it */
7238 memset ( &fsp, 0, sizeof(Nlm_FontSpec));
7239 Nlm_StrCpy (fsp.name, "Lucida Grande");
7240 fsp.size = 13;
7241 #else
7242 Nlm_scrollRgn = (Nlm_RegioN) (NewRgn ());
7243
7244 Nlm_updateRgn = (Nlm_RegioN) (NewRgn ());
7245 SetRectRgn ((Nlm_RgnTool) Nlm_updateRgn, -32768, -32768, 32767, 32767);
7246 /* HLock ((Handle) Nlm_updateRgn); */
7247 GetRegionBounds(Nlm_updateRgn, &bounds);
7248 Local__RectToolToRecT (&bounds, &Nlm_updateRect);
7249 /* HUnlock ((Handle) Nlm_updateRgn); */
7250
7251 /* esl: LoadFontData changed to work with new FontData format */
7252 /* alexs get font name */
7253 memset ( &fsp, 0, sizeof(Nlm_FontSpec));
7254 GetFontName ( GetSysFont(), (StringPtr) tmpFontName );
7255 Nlm_PtoCstr ( tmpFontName );
7256 Nlm_StringNCpy_0 (fsp.name, tmpFontName, FONT_NAME_SIZE - 1);
7257 fsp.name[FONT_NAME_SIZE - 1] = 0;
7258 fsp.size = GetDefFontSize ();
7259 #endif
7260
7261 Nlm_fontList = NULL;
7262 Nlm_fontInUse = NULL;
7263 Nlm_systemFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec));
7264
7265 #ifdef WIN_MAC_ATSUI
7266 Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, Nlm_NewATSUStyle(&fsp), NULL);
7267 #else
7268 Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, 0, fsp.size, 0, NULL);
7269 #endif
7270 Nlm_programFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec));
7271 /* esl: LoadFontData changed to work with new FontData format */
7272 Nlm_StrCpy (fsp.name, "Monaco");
7273 fsp.size = 9;
7274 #ifdef WIN_MAC_ATSUI
7275 Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, Nlm_NewATSUStyle(&fsp), NULL);
7276 #else
7277 Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, 4, 9, 0, NULL);
7278 #endif
7279 Nlm_fontList = NULL;
7280 Nlm_fontInUse = Nlm_systemFont;
7281
7282 Nlm_stdAscent = Nlm_Ascent ();
7283 Nlm_stdDescent = Nlm_Descent ();
7284 Nlm_stdLeading = Nlm_Leading ();
7285 Nlm_stdFontHeight = Nlm_FontHeight ();
7286 Nlm_stdLineHeight = Nlm_LineHeight ();
7287 Nlm_stdCharWidth = Nlm_MaxCharWidth ();
7288 /* gestalt for quickdraw features are defined as bits in a bitfield
7289 for example gestaltHasColor = 0, thus we need to test for lsb set
7290 */
7291 if( Gestalt( gestaltQuickdrawFeatures, &gval) == noErr){
7292 Nlm_hasColorQD = (gval && (1 << gestaltHasColor));
7293 }
7294 if (Nlm_hasColorQD) {
7295 #ifdef WIN_MAC_QUARTZ
7296 Nlm_QuartzForeColor.r = 0;
7297 Nlm_QuartzForeColor.g = 0;
7298 Nlm_QuartzForeColor.b = 0;
7299 Nlm_QuartzBackColor.r = 1.0;
7300 Nlm_QuartzBackColor.g = 1.0;
7301 Nlm_QuartzBackColor.b = 1.0;
7302 #else
7303 Nlm_RGBforeColor.red = 0;
7304 Nlm_RGBforeColor.green = 0;
7305 Nlm_RGBforeColor.blue = 0;
7306 Nlm_RGBbackColor.red = 65535;
7307 Nlm_RGBbackColor.green = 65535;
7308 Nlm_RGBbackColor.blue = 65535;
7309 #endif
7310 }
7311 #endif
7312 #ifdef WIN_MSWIN
7313 Nlm_scrollRgn = (Nlm_RegioN)CreateRectRgn(0, 0, 0, 0);
7314 Nlm_updateRgn = (Nlm_RegioN)CreateRectRgn(-32767, -32767, 32767, 32767);
7315
7316 {{
7317 Nlm_RectTool rtool;
7318 GetRgnBox((Nlm_RgnTool)Nlm_updateRgn, &rtool);
7319 Local__RectToolToRecT(&rtool, &Nlm_updateRect);
7320 }}
7321
7322 /* Stock fonts */
7323 hAnsiFixedFont = GetStockObject( ANSI_FIXED_FONT );
7324 hAnsiVarFont = GetStockObject( ANSI_VAR_FONT );
7325 hDeviceDefaultFont = GetStockObject( DEVICE_DEFAULT_FONT );
7326 hOemFixedFont = GetStockObject( OEM_FIXED_FONT );
7327 hSystemFont = GetStockObject( SYSTEM_FONT );
7328 hSystemFixedFont = GetStockObject( SYSTEM_FIXED_FONT );
7329 hDefaultGuiFont = GetStockObject( DEFAULT_GUI_FONT );
7330
7331 Nlm_systemFont = (Nlm_FonT) Nlm_HandNew( sizeof(Nlm_FontRec) );
7332 Nlm_LoadFontData(Nlm_systemFont, NULL, -1, NULL, hDefaultGuiFont,
7333 HFONT2Font( hDefaultGuiFont ));
7334
7335 Nlm_fontList = NULL;
7336 Nlm_fontInUse = Nlm_systemFont;
7337
7338 Nlm_stdAscent = Nlm_Ascent();
7339 Nlm_stdDescent = Nlm_Descent();
7340 Nlm_stdLeading = Nlm_Leading();
7341 Nlm_stdFontHeight = Nlm_FontHeight();
7342 Nlm_stdLineHeight = Nlm_LineHeight();
7343 Nlm_stdCharWidth = Nlm_MaxCharWidth();
7344
7345 Nlm_programFont = (Nlm_FonT) Nlm_HandNew( sizeof(Nlm_FontRec) );
7346 Nlm_LoadFontData(Nlm_programFont, NULL, -1, NULL, hAnsiFixedFont,
7347 HFONT2Font( hAnsiFixedFont ));
7348
7349 blackColor = RGB( 0, 0, 0);
7350 redColor = RGB(255, 0, 0);
7351 greenColor = RGB( 0, 255, 0);
7352 blueColor = RGB( 0, 0, 255);
7353 cyanColor = RGB( 0, 255, 255);
7354 magentaColor = RGB(255, 0, 255);
7355 yellowColor = RGB(255, 255, 0);
7356 whiteColor = RGB(255, 255, 255);
7357
7358 hBlackPen = GetStockObject( BLACK_PEN );
7359 hNullPen = GetStockObject( NULL_PEN );
7360 hWhitePen = GetStockObject( WHITE_PEN );
7361
7362 hBlackBrush = GetStockObject( BLACK_BRUSH );
7363 hDkGrayBrush = GetStockObject( DKGRAY_BRUSH );
7364 hGrayBrush = GetStockObject( GRAY_BRUSH );
7365 hHollowBrush = GetStockObject( HOLLOW_BRUSH );
7366 hLtGrayBrush = GetStockObject( LTGRAY_BRUSH );
7367 hNullBrush = GetStockObject( NULL_BRUSH );
7368 hWhiteBrush = GetStockObject( WHITE_BRUSH );
7369 #endif
7370 #ifdef WIN_X
7371 XFontStruct *f;
7372 Nlm_Int2 i;
7373 Nlm_Uint2 inv;
7374 Nlm_Int2 j;
7375 XFontStruct *p;
7376 Nlm_RecT r;
7377 Nlm_RectTool rtool;
7378 Nlm_Uint2 val;
7379 Nlm_FontSpec fsp;
7380 Nlm_Char fSpecName[64];
7381
7382
7383 Nlm_scrollRgn = (Nlm_RegioN) (XCreateRegion ());
7384
7385 Nlm_updateRgn = (Nlm_RegioN) (XCreateRegion ());
7386 Nlm_LoadRect (&r, -32767, -32767, 32767, 32767);
7387 Local__RecTToRectTool (&r, &rtool);
7388 XUnionRectWithRegion (&rtool, (Nlm_RgnTool) Nlm_updateRgn, (Nlm_RgnTool) Nlm_updateRgn);
7389 Local__RectToolToRecT (&rtool, &Nlm_updateRect);
7390
7391 emptyRgn = XCreateRegion ();
7392
7393 Nlm_fontList = NULL;
7394 Nlm_fontInUse = NULL;
7395 {{
7396 XFontStruct *F =XQueryFont(Nlm_currentXDisplay,
7397 XGContextFromGC(DefaultGC(Nlm_currentXDisplay,
7398 Nlm_currentXScreen)));
7399 i = F->ascent + F->descent;
7400 XFreeFontInfo(NULL, F, 1);
7401 }}
7402 sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i );
7403 f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE);
7404 if ( f == NULL ){
7405 i++;
7406 sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i );
7407 f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE);
7408 }
7409 if ( f == NULL ){
7410 i--; i--;
7411 sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i );
7412 f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE);
7413 }
7414 if ( f == NULL ){
7415 f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, "-*-helvetica-bold-r-*--*-140-*", FALSE);
7416 i = 14;
7417 }
7418
7419 memset(&fsp, 0, sizeof(Nlm_FontSpec));
7420 if ( f ) {
7421 Nlm_StrCpy(fsp.name, "helvetica");
7422 fsp.style = STYLE_BOLD;
7423 } else {
7424 f = Nlm_XLoadStandardFont();
7425 fsp.name[0] = '\0';
7426 fsp.style = STYLE_REGULAR;
7427 i = f->ascent + f->descent;
7428 }
7429 fsp.size = i;
7430
7431 Nlm_systemFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec));
7432 Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, f, NULL);
7433
7434 sprintf ( fSpecName, "-*-fixed-medium-r-*--%d-*-*", i );
7435 p = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE);
7436 Nlm_StrCpy ( fsp.name, "fixed" );
7437 fsp.size = i;
7438 fsp.style = STYLE_REGULAR;
7439 if (p == NULL) {
7440 p = Nlm_XLoadQueryFont (Nlm_currentXDisplay, "-*-fixed-medium-r-*--*-120-*", FALSE);
7441 Nlm_StrCpy ( fsp.name, "fixed" );
7442 fsp.size = 12;
7443 }
7444 if (p == NULL) {
7445 p = Nlm_XLoadQueryFont (Nlm_currentXDisplay,
7446 "-*-courier-medium-r-*--*-120-*", FALSE);
7447 Nlm_StrCpy ( fsp.name, "courier" );
7448 fsp.size = 12;
7449 }
7450 if ( !p ) {
7451 p = Nlm_XLoadStandardFont();
7452 fsp.name[0] = '\0';
7453 fsp.size = p->ascent + p->descent;
7454 }
7455 Nlm_programFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec));
7456 /* esl: LoadFontData changed to work with new FontData format */
7457 Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, p, NULL);
7458 Nlm_fontList = NULL;
7459 Nlm_fontInUse = Nlm_systemFont;
7460
7461 XSetFont (Nlm_currentXDisplay, Nlm_currentXGC, f->fid);
7462 currentFont = f;
7463 Nlm_stdAscent = Nlm_Ascent ();
7464 Nlm_stdDescent = Nlm_Descent ();
7465 Nlm_stdLeading = Nlm_Leading ();
7466 Nlm_stdFontHeight = Nlm_FontHeight ();
7467 Nlm_stdLineHeight = Nlm_LineHeight ();
7468 Nlm_stdCharWidth = Nlm_MaxCharWidth ();
7469
7470 Nlm_hasColor = (Nlm_currentXDisplay != NULL &&
7471 XDisplayCells(Nlm_currentXDisplay, Nlm_currentXScreen) > 2);
7472
7473 if ( Nlm_hasColor )
7474 {
7475 whiteColor = Nlm_GetColorRGB(255, 255, 255);
7476 blackColor = Nlm_GetColorRGB( 0, 0, 0);
7477 redColor = Nlm_GetColorRGB(255, 0, 0);
7478 greenColor = Nlm_GetColorRGB( 0, 255, 0);
7479 blueColor = Nlm_GetColorRGB( 0, 0, 255);
7480 cyanColor = Nlm_GetColorRGB( 0, 255, 255);
7481 magentaColor = Nlm_GetColorRGB(255, 0, 255);
7482 yellowColor = Nlm_GetColorRGB(255, 255, 0);
7483 }
7484 else
7485 {
7486 whiteColor = WhitePixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7487 blackColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7488 redColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7489 greenColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7490 blueColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7491 cyanColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7492 magentaColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7493 yellowColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen);
7494 }
7495
7496 fontInfo.fid = 0;
7497 for (i = 0; i < 256; i++) {
7498 inv = 0;
7499 val = (Nlm_Uint2) i;
7500 for (j = 0; j < 8; j++) {
7501 inv = (inv << 1);
7502 inv += (val % 2);
7503 val = (val >> 1);
7504 }
7505 flip [i] = inv;
7506 }
7507
7508 Nlm_XbackColor = whiteColor;
7509 Nlm_XforeColor = blackColor;
7510 Nlm_XOffset = 0;
7511 Nlm_YOffset = 0;
7512 Nlm_clpRgn = NULL;
7513 #endif
7514 #ifdef WIN_GIF
7515 Nlm_curGIFColor = 1;
7516 Nlm_curGIFLType = GIF_SOLID;
7517 Nlm_curGIFFont = gdFont7X13b;
7518 Nlm_curGIFPoint.x = 0;
7519 Nlm_curGIFPoint.y = 0;
7520 #endif
7521 }
7522
7523 extern void Nlm_CleanUpDrawingTools (void)
7524
7525 {
7526 Nlm_FonT f;
7527 Nlm_FontData fdata;
7528
7529 #ifndef WIN_MAC_QUARTZ
7530 Nlm_ResetDrawingTools ();
7531 #endif
7532 #ifdef WIN_MOTIF
7533 Nlm_GetFontData (Nlm_systemFont, &fdata);
7534 if (fdata.handle != NULL) {
7535 XFreeFont (Nlm_currentXDisplay, fdata.handle);
7536 }
7537 Nlm_GetFontData (Nlm_programFont, &fdata);
7538 if (fdata.handle != NULL) {
7539 XFreeFont (Nlm_currentXDisplay, fdata.handle);
7540 }
7541 #endif
7542 Nlm_HandFree (Nlm_systemFont);
7543 Nlm_HandFree (Nlm_programFont);
7544 f = Nlm_fontList;
7545 while (f != NULL) {
7546 Nlm_GetFontData (f, &fdata);
7547 #ifdef WIN_MSWIN
7548 if (fdata.handle != NULL) {
7549 DeleteObject (fdata.handle);
7550 }
7551 #endif
7552 #ifdef WIN_MOTIF
7553 if (fdata.handle != NULL) {
7554 XFreeFont (Nlm_currentXDisplay, fdata.handle);
7555 }
7556 #endif
7557 Nlm_HandFree (f);
7558 f = fdata.next;
7559 }
7560
7561 #ifdef WIN_MOTIF
7562 XDestroyRegion (emptyRgn);
7563 #endif
7564 }
7565
7566
7567 size_t UpdateColorTable(Nlm_RGBColoR table[], size_t table_size,
7568 const Nlm_Char PNTR filename)
7569 {
7570 size_t n_done = 0;
7571 FILE *file;
7572 Nlm_Char str[128];
7573
7574 if (table_size < 1 || filename == NULL) return 0;
7575
7576 file = Nlm_FileOpen(filename, "r");
7577 if (file == NULL)
7578 {
7579 Nlm_ErrLogPrintf("\n\
7580 Warning: Cannot open the user's color description file \"%s\"\n",
7581 filename);
7582 return 0;
7583 }
7584
7585 while (Nlm_FileGets(str, sizeof(str), file) != NULL)
7586 {
7587 int index;
7588 int red, green, blue;
7589 int n_char_read;
7590 if (sscanf(str, "%i %i %i %i %n",
7591 &index, &red, &green, &blue, &n_char_read) != 4)
7592 {
7593 Nlm_ErrLogPrintf("\n\
7594 [%s] Warning:\n\
7595 Cannot extract <index> <red> <green> <blue> from the stroke:\n\
7596 \"%s\"\n",
7597 filename, str);
7598 continue;
7599 }
7600
7601 if (index < 0 || table_size <= (size_t)index)
7602 {
7603 Nlm_ErrLogPrintf("\n\
7604 [%s] Warning:\n\
7605 The color index is out of range = %d (must be: 0 <= index <= %l)\n",
7606 filename, index, (long)(table_size - 1));
7607 continue;
7608 }
7609
7610 #ifdef WIN_MOTIF
7611 {{
7612 Nlm_CharPtr name, s;
7613 for (name=str+n_char_read; *name != '\0' && !isalnum(*name); name++);
7614 for (s =name; *s != '\0' && isalnum(*s ); s++ );
7615 *s = '\0';
7616
7617 if (*name != '\0')
7618 {
7619 XColor rgb_db_def, hardware_def;
7620 if ( XLookupColor(Nlm_currentXDisplay,
7621 Nlm_VibrantDefaultColormap(),
7622 name,
7623 &rgb_db_def, &hardware_def) )
7624 {
7625 red = (int)(hardware_def.red >> 8);
7626 green = (int)(hardware_def.green >> 8);
7627 blue = (int)(hardware_def.blue >> 8);
7628 }
7629 else
7630 {
7631 Nlm_ErrLogPrintf("\n\
7632 [%s] Warning:\n\
7633 Cannot find color of name \"%s\" in the X11 color database",
7634 filename, name);
7635 continue;
7636 }
7637 }
7638 }}
7639 #endif
7640
7641 if (red < 0 || 255 < red ||
7642 green < 0 || 255 < green ||
7643 blue < 0 || 255 < blue)
7644 {
7645 Nlm_ErrLogPrintf("\n\
7646 [%s] Warning:\n\
7647 The color component values are out of range = (%d, %d, %d)\n\
7648 (must be: 0 <= value <= 255)\n",
7649 filename, red, green, blue);
7650 continue;
7651 }
7652
7653 table[index].red = (Nlm_Uint1) red;
7654 table[index].green = (Nlm_Uint1) green;
7655 table[index].blue = (Nlm_Uint1) blue;
7656 n_done++;
7657 }
7658
7659 Nlm_FileClose( file );
7660 return n_done;
7661 }
7662
7663
7664 static Nlm_Boolean s_VibrantIsGUI = FALSE;
7665 extern Nlm_Boolean Nlm_VibrantIsGUI(void) {
7666 return s_VibrantIsGUI;
7667 }
7668 extern void Nlm_VibrantSetGUI(void) {
7669 s_VibrantIsGUI = TRUE;
7670 }
7671 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |