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