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