/* ncbidraw.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information (NCBI) * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government do not place any restriction on its use or reproduction. * We would, however, appreciate having the NCBI and the author cited in * any work or product based on this material * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * =========================================================================== * * File Name: ncbidraw.c * * Author: Jonathan Kans, Denis Vakatov * * Version Creation Date: 1/1/91 * * $Revision: 6.46 $ * * File Description: * Vibrant drawing functions. * * Modifications: * -------------------------------------------------------------------------- * * ========================================================================== */ #include #include #ifdef VAR_ARGS # include #else # include #endif #ifdef WIN_GIF # include # ifdef Nlm_RgnTool # undef Nlm_RgnTool # endif # ifdef Nlm_RectTool # undef Nlm_RectTool # endif # define Nlm_RectTool Nlm_RecT # ifdef WIN_MOTIF # undef WIN_MOTIF # ifdef WIN_X # undef WIN_X # endif # define Nlm_RgnTool Nlm_VoidPtr # endif # ifdef WIN_MAC # undef WIN_MAC # ifdef WIN_MAC_ATSUI # undef WIN_MAC_ATSUI # endif # ifdef WIN_MAC_QUARTZ # undef WIN_MAC_QUARTZ # endif # define Nlm_RgnTool Handle # endif # ifdef WIN_MSWIN # undef WIN_MSWIN # define Nlm_RgnTool HANDLE # endif #else /* WIN_GIF */ typedef struct gdImageStruct { void* dummy; } gdImage; #endif /* WIN_GIF */ #if defined(WIN_X) && !defined(__hpux) #include #endif Nlm_Boolean Nlm_nowPrinting = FALSE; #ifdef WIN_MAC #ifdef __MWERKS__ #include "MoreCarbonAccessors.h" #else #define GetPortAndCall_(function, arg) \ do { \ GrafPtr port_; \ GetPort(&port_); \ function(GetWindowFromPort(port_), (arg)); \ } while (0) #define InvalRect(rect) GetPortAndCall_(InvalWindowRect, (rect)) #define InvalRgn(rgn) GetPortAndCall_(InvalWindowRgn, (rgn )) #define ValidRect(rect) GetPortAndCall_(ValidWindowRect, (rect)) #define ValidRgn(rgn) GetPortAndCall_(ValidWindowRgn, (rgn )) #endif #endif #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CFMutableArrayRef Nlm_QContextStack = 0; static void Nlm_PushQContext( CGContextRef ctx ) { if (!Nlm_QContextStack) Nlm_QContextStack = CFArrayCreateMutable (NULL, 0, NULL); CFArrayAppendValue (Nlm_QContextStack, ctx); } static CGContextRef Nlm_PeekQContext (void) { if (!Nlm_QContextStack) return NULL; CFIndex count = CFArrayGetCount (Nlm_QContextStack); return count ? (CGContextRef)CFArrayGetValueAtIndex (Nlm_QContextStack, count - 1) : NULL; } static CGContextRef Nlm_PopQContext (void) { if (!Nlm_QContextStack) return NULL; void *ret = Nlm_PeekQContext(); CFIndex count = CFArrayGetCount (Nlm_QContextStack); if (count) CFArrayRemoveValueAtIndex (Nlm_QContextStack, count - 1); return ret; } WindowRef Nlm_QWindow = 0; Nlm_QuartzColor Nlm_QuartzForeColor; Nlm_QuartzColor Nlm_QuartzBackColor; Nlm_Boolean Nlm_hasColorQD = TRUE; #else RGBColor Nlm_RGBforeColor; RGBColor Nlm_RGBbackColor; Nlm_Boolean Nlm_hasColorQD = FALSE; #endif #endif #ifdef WIN_MSWIN #define ATT_PENSTYLE 1 #define ATT_PENWIDTH 2 #define ATT_PATTERN 4 HWND Nlm_currentHWnd; HDC Nlm_currentHDC; #endif #ifdef WIN_X Display *Nlm_currentXDisplay; int Nlm_currentXScreen; Window Nlm_currentXWindow; GC Nlm_currentXGC; Nlm_Uint4 Nlm_XbackColor; Nlm_Uint4 Nlm_XforeColor; Nlm_Int2 Nlm_XOffset; Nlm_Int2 Nlm_YOffset; Nlm_RegioN Nlm_clpRgn; Nlm_Boolean Nlm_hasColor = FALSE; #endif #ifdef WIN_GIF #define GIF_SOLID 0 #define GIF_DASHED 1 static gdImagePtr Nlm_currentGIF = NULL; static int Nlm_curGIFColor = 1; static int Nlm_curGIFLType = GIF_SOLID; static gdFontPtr Nlm_curGIFFont = NULL; static Nlm_PoinT Nlm_curGIFPoint = {0,0}; #endif Nlm_RegioN Nlm_updateRgn; Nlm_RecT Nlm_updateRect; Nlm_Int2 Nlm_stdAscent; Nlm_Int2 Nlm_stdDescent; Nlm_Int2 Nlm_stdLeading; Nlm_Int2 Nlm_stdFontHeight; Nlm_Int2 Nlm_stdLineHeight; Nlm_Int2 Nlm_stdCharWidth; Nlm_FonT Nlm_systemFont = NULL; Nlm_FonT Nlm_programFont = NULL; #define COPY_MODE 1 #define MERGE_MODE 2 #define INVERT_MODE 3 #define ERASE_MODE 4 static Nlm_Int2 currentMode = COPY_MODE; static Nlm_FonT Nlm_fontList = NULL; static Nlm_FonT Nlm_fontInUse = NULL; #ifndef WIN_GIF static Nlm_RegioN Nlm_scrollRgn; #endif #ifdef WIN_MAC static Nlm_Byte whitePat [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static Nlm_Byte ltGrayPat [] = {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22}; static Nlm_Byte grayPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; static Nlm_Byte dkGrayPat [] = {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD}; static Nlm_Byte blackPat [] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static Nlm_Byte dotPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; static Nlm_Byte dashPat [] = {0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33}; #endif #ifdef WIN_MSWIN static DWORD dash_gap[2]; static Nlm_Int2 currentPenStyle = PS_SOLID; static Nlm_Int2 currentPenWidth = 1; static void *currentPattern = NULL; static COLORREF prevColor = 12346; static Nlm_Int2 prevPenStyle = -1; static Nlm_Int2 prevPenWidth = -1; static void *prevPattern = NULL; static HDC prevPenHDC = NULL; static COLORREF blackColor; static COLORREF redColor; static COLORREF greenColor; static COLORREF blueColor; static COLORREF cyanColor; static COLORREF magentaColor; static COLORREF yellowColor; static COLORREF whiteColor; static Nlm_Uint2 blackPat [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static Nlm_Uint2 dkGrayPat [] = {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22}; static Nlm_Uint2 grayPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; static Nlm_Uint2 ltGrayPat [] = {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD}; static Nlm_Uint2 whitePat [] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static Nlm_Uint2 dotPat [] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; static Nlm_Uint2 dashPat [] = {0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33}; static HPEN hBlackPen; static HPEN hNullPen; static HPEN hWhitePen; static HBRUSH hBlackBrush; static HBRUSH hDkGrayBrush; static HBRUSH hGrayBrush; static HBRUSH hHollowBrush; static HBRUSH hLtGrayBrush; static HBRUSH hNullBrush; static HBRUSH hWhiteBrush; static HFONT hAnsiFixedFont; static HFONT hAnsiVarFont; static HFONT hDeviceDefaultFont; static HFONT hOemFixedFont; static HFONT hSystemFont; static HFONT hSystemFixedFont; static HFONT hDefaultGuiFont; static TEXTMETRIC textMetrics; static COLORREF winTextColor; static COLORREF winBkColor; #endif #ifdef WIN_X static XFontStruct *currentFont; static Pixmap currentPixmap = 0; static Nlm_PoinT currentPoint; static Nlm_Uint4 currentBkColor; static Nlm_Uint4 currentFgColor; static int currentFunction = GXcopy; static int currentFillStyle = FillOpaqueStippled; static Nlm_Uint4 blackColor; static Nlm_Uint4 redColor; static Nlm_Uint4 greenColor; static Nlm_Uint4 blueColor; static Nlm_Uint4 cyanColor; static Nlm_Uint4 magentaColor; static Nlm_Uint4 yellowColor; static Nlm_Uint4 whiteColor; static XFontStruct fontInfo; static Nlm_Uint1 flip [256]; static Nlm_RgnTool emptyRgn; #define ULTRA_SPARC_X_SERVER_BUG #ifdef ULTRA_SPARC_X_SERVER_BUG /* Attention! This looks as an X-server(not X-client) bug; it means * that all X applications intended to run on an Ultra-SPARC's X-server * must be compiled with this option, no matter where the X-client * was built and run on(e.g. SGI, Linux, etc.) */ void Nlm_XSetForeground(Display *display, GC gc, unsigned long color) { if (currentFillStyle == FillOpaqueStippled) { XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillSolid); XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillOpaqueStippled); } XSetForeground(display, gc, color); } #define XSetForeground Nlm_XSetForeground #endif #endif /* WIN_X */ #if defined(WIN_X) || defined(WIN_GIF) static Nlm_Uint1 whitePat []= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static Nlm_Uint1 ltGrayPat[]= {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22}; static Nlm_Uint1 grayPat []= {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; static Nlm_Uint1 dkGrayPat[]= {0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD}; static Nlm_Uint1 blackPat []= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; #endif /* WIN_X | WIN_GIF */ #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ extern void Nlm_SetPort (CGContextRef ctx) { if (Nlm_PeekQContext()) { CGContextSynchronize(Nlm_PeekQContext()); CGContextRelease(Nlm_PeekQContext()); Nlm_PopQContext(); } if (ctx) { Nlm_PushQContext(ctx); CGContextRetain(Nlm_PeekQContext()); } // QUARTZ_FIXME: some of this might be useful, somehow // if (grafptr != 0) { // CGAffineTransform textTransform; // // GetPortBounds(grafptr, &pBounds); // pHeight = pBounds.bottom - pBounds.top; // QDBeginCGContext(grafptr, &Nlm_PeekQContext()); // CGContextTranslateCTM(Nlm_PeekQContext(), 0, pHeight); // CGContextScaleCTM(Nlm_PeekQContext(), 1.0f, -1.0f); // // textTransform = CGAffineTransformMakeScale(1.0f, -1.0f); // CGContextSetTextMatrix(Nlm_PeekQContext(), textTransform); // } else { // Nlm_PeekQContext() = 0; // } } void Nlm_PushPort (CGContextRef ctx) { Nlm_PushQContext (ctx); } CGContextRef Nlm_PopPort (void) { return Nlm_PopQContext (); } #else extern void Nlm_SetPort (GrafPtr grafptr) { SetPort (grafptr); } #endif extern void Nlm_SetPortWindowPort(Nlm_WindowTool wptr) { #ifdef WIN_MAC_QUARTZ Nlm_QWindow = wptr; #else SetPortWindowPort(wptr); #endif } #ifdef WIN_MAC_QUARTZ WindowRef Nlm_GetQuartzCurrentWindow (void) { return Nlm_QWindow; } void Nlm_SetGraphicNeedsDisplay (Nlm_GraphiC graphic) { HIViewSetNeedsDisplay (HIViewGetRoot (Nlm_ParentWindowPtr (graphic)), 1); } #endif #endif #ifdef WIN_MSWIN extern void Nlm_SetPort (HWND hwnd, HDC hdc) { Nlm_currentHWnd = hwnd; Nlm_currentHDC = hdc; } #endif #ifdef WIN_X /* for internal Vibrant use only */ extern XFontStruct * Nlm_XLoadQueryFont (Display *d, Nlm_CharPtr fDescr, Nlm_Boolean critical) { XFontStruct *f; if ((f = XLoadQueryFont(d, fDescr)) == NULL && critical) { fprintf (stderr, "Vibrant: Unable to load critical font <%s>\n", fDescr); exit (1); } return f; } #endif extern Nlm_Boolean Nlm_CreateGIF(Nlm_Int2 width, Nlm_Int2 height, Nlm_Boolean transparent) { #ifdef WIN_GIF gdImage* im = gdImageCreate((int)width, (int)height); if ( im ) { int white_color = gdImageColorAllocate(im, 255, 255, 255); if ( transparent ) gdImageColorTransparent(im, white_color); gdImageColorAllocate(im, 0, 0, 0); Nlm_SetCurrentGIF(im); return TRUE; } #endif /* WIN_GIF */ return FALSE; } extern Nlm_Boolean Nlm_SaveGIF(FILE* out) { #ifdef WIN_GIF if (Nlm_currentGIF && out) { gdImageGif(Nlm_currentGIF, out); return TRUE; } #endif /* WIN_GIF */ return FALSE; } extern void Nlm_DestroyGIF(void) { #ifdef WIN_GIF gdImage* im = Nlm_SetCurrentGIF(0); if ( im ) gdImageDestroy(im); #endif /* WIN_GIF */ } extern struct gdImageStruct* Nlm_SetCurrentGIF(struct gdImageStruct* im) { #ifdef WIN_GIF gdImage* im_prev = Nlm_currentGIF; if (im == im_prev) return im; Nlm_curGIFColor = 1; Nlm_curGIFLType = GIF_SOLID; Nlm_curGIFFont = gdFont7X13b; Nlm_curGIFPoint.x = 0; Nlm_curGIFPoint.y = 0; Nlm_currentGIF = im; return im_prev; #else return 0; #endif /* WIN_GIF */ } static void Nlm_SetFontData (Nlm_FonT f, Nlm_FontData * fdata) { Nlm_FntPtr fp; if (f != NULL && fdata != NULL) { fp = (Nlm_FntPtr) Nlm_HandLock (f); *fp = *fdata; Nlm_HandUnlock (f); } } static void Nlm_GetFontData (Nlm_FonT f, Nlm_FontData * fdata) { Nlm_FntPtr fp; if (f != NULL && fdata != NULL) { fp = (Nlm_FntPtr) Nlm_HandLock (f); *fdata = *fp; Nlm_HandUnlock (f); } } #ifdef WIN_MSWIN static Nlm_Boolean Nlm_NotAStockPen (HPEN pen) { return (Nlm_Boolean) (pen != hBlackPen && pen != hNullPen && pen != hWhitePen); } static Nlm_Boolean Nlm_NotAStockBrush (HBRUSH brush) { return (Nlm_Boolean) (brush != hBlackBrush && brush != hDkGrayBrush && brush != hGrayBrush && brush != hHollowBrush && brush != hLtGrayBrush && hNullBrush && brush != hWhiteBrush); } /* static Nlm_Boolean Nlm_NotAStockFont (HFONT font) { return (Nlm_Boolean) (font != hAnsiFixedFont && font != hAnsiVarFont && font != hDeviceDefaultFont && font != hOemFixedFont && font != hSystemFont && font != hSystemFixedFont); } */ #endif extern void Nlm_SetPenDash(Nlm_Uint1 offset, Nlm_Uint1 dash, Nlm_Uint1 gap) { if (dash == 0) dash = 1; if (gap == 0) gap = 1; #ifdef WIN_X if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XGCValues gcv; char dash_gap[2]; dash_gap[0] = dash; dash_gap[1] = gap; gcv.line_style = LineOnOffDash; XChangeGC(Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &gcv); XSetDashes(Nlm_currentXDisplay, Nlm_currentXGC, (int)offset, dash_gap, sizeof(dash_gap)); } #elif defined(WIN32) && defined(WIN_MSWIN) dash_gap[0] = dash; dash_gap[1] = gap; if ( Nlm_GetPicWinHDC() ) { Nlm_Dashed(); /* metafile-dumping driver does not support ext.pens */ return; } {{ HPEN newPen, oldPen; LOGBRUSH newBrush; newBrush.lbStyle = BS_SOLID; newBrush.lbColor = winTextColor; newBrush.lbHatch = 0; if ((newPen = ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_SQUARE, 1, &newBrush, 2, dash_gap)) == NULL || (oldPen = SelectObject(Nlm_currentHDC, newPen)) == NULL) { if ( newPen ) DeleteObject( newPen ); Nlm_Dashed(); return; } prevColor = winTextColor; if ( Nlm_NotAStockPen( oldPen ) ) DeleteObject( oldPen ); }} #elif defined(WIN_MAC_QUARTZ) { float dashes[2]; dashes[0] = (float) dash; dashes[1] = (float) gap; CGContextSetLineDash(Nlm_PeekQContext(), (float) offset, dashes, 2); } #else Nlm_Dashed(); #endif } #ifdef WIN_MAC static void Nlm_ChooseColor (Nlm_Int4 color) { #ifdef WIN_MAC_QUARTZ ASSERT(false); #else ForeColor (color); #endif } #endif #ifdef WIN_MSWIN static void Nlm_RecreateBrushes (void) { COLORREF color; HBITMAP hBitmap; HBRUSH newBrush; HPEN newPen; HBRUSH oldBrush; HPEN oldPen; if (Nlm_currentHDC != NULL) { color = winTextColor; if ( (prevColor != color)||(prevPenStyle != currentPenStyle)|| (prevPenWidth != currentPenWidth) || (prevPenHDC != Nlm_currentHDC) ){ #ifdef WIN32 if (dash_gap[0] != 0) { if (prevColor != winTextColor) Nlm_SetPenDash(0, (Nlm_Uint1)dash_gap[0], (Nlm_Uint1)dash_gap[1]); return; } if ( Nlm_GetPicWinHDC() ) /* metafile driver does not support ext.pens */ newPen = CreatePen(currentPenStyle, currentPenWidth, color); else { LOGBRUSH brush; brush.lbStyle = BS_SOLID; brush.lbColor = color; brush.lbHatch = 0; newPen = ExtCreatePen(currentPenStyle|PS_GEOMETRIC|PS_ENDCAP_SQUARE, currentPenWidth, &brush, 0, NULL); } #else newPen = CreatePen(currentPenStyle, currentPenWidth, color); #endif /* else!WIN32 */ if (newPen != NULL) { oldPen = SelectObject (Nlm_currentHDC, newPen); if (oldPen == NULL) { OutputDebugString ("Cannot select pen\n"); DeleteObject (newPen); } else { prevColor = color; prevPenStyle = currentPenStyle; prevPenWidth = currentPenWidth; if (Nlm_NotAStockPen (oldPen)) DeleteObject (oldPen); } } } if (currentPattern == NULL) { currentPattern = whitePat; } if ( (currentPattern != prevPattern) || (prevPenHDC != Nlm_currentHDC) ){ hBitmap = CreateBitmap (8, 8, 1, 1, (LPSTR) currentPattern); newBrush = CreatePatternBrush (hBitmap); if (newBrush != NULL) { oldBrush = SelectObject (Nlm_currentHDC, newBrush); if (oldBrush == NULL) { OutputDebugString ("Cannot select brush\n"); DeleteObject (newBrush); } else { prevPenHDC = Nlm_currentHDC; prevPattern = currentPattern; if ( Nlm_NotAStockBrush(oldBrush) ) DeleteObject (oldBrush); } } DeleteObject (hBitmap); } } } static void Nlm_SelectPattern (Nlm_Int2 style, Nlm_Int2 width, void * pat, Nlm_Int1 flags ) { if ( flags & ATT_PENSTYLE ) currentPenStyle = style; if ( flags & ATT_PENWIDTH ) currentPenWidth = width; if ( flags & ATT_PATTERN ) currentPattern = pat; #ifdef WIN32 dash_gap[0] = 0; #endif Nlm_RecreateBrushes (); } static void Nlm_ChooseColor (Nlm_Int4 color) { if (Nlm_currentHDC != NULL) { SetTextColor (Nlm_currentHDC, color); winTextColor = color; Nlm_RecreateBrushes (); } } static Nlm_Boolean Nlm_GetTextMetrics (void) { HDC hDC; Nlm_Boolean success; success = FALSE; if (Nlm_currentHDC != NULL) { success = (Nlm_Boolean) GetTextMetrics (Nlm_currentHDC, &textMetrics); } else { hDC = CreateIC ("DISPLAY", NULL, NULL, NULL); success = (Nlm_Boolean) GetTextMetrics (hDC, &textMetrics); DeleteDC (hDC); } return success; } static HBRUSH GetBackgroundBrush (HWND hwnd) { #ifndef WIN32 return (HBRUSH) GetClassWord (hwnd, GCLP_HBRBACKGROUND); #else return (HBRUSH) GetClassLongPtr (hwnd, GCLP_HBRBACKGROUND); #endif } #endif #ifdef WIN_X static void Nlm_SelectPattern (void * pat) { if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0) { if (currentPixmap != 0) { XFreePixmap (Nlm_currentXDisplay, currentPixmap); } currentPixmap = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow, (char *) pat, 8, 8); if (currentPixmap != 0 && Nlm_currentXGC != NULL) { XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, currentPixmap); } } } static void Nlm_ChooseColor (Nlm_Uint4 color) { if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, color); currentFgColor = color; } } static Nlm_Boolean Nlm_GetTextMetrics (void) { Nlm_Boolean success; success = FALSE; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { if (currentFont != NULL) { fontInfo = *currentFont; success = TRUE; } } return success; } #endif #ifdef WIN_MSWIN extern BOOLEAN Nlm_hasBackColor; extern COLORREF Nlm_crBackColor; extern HBRUSH Nlm_hbrWindowBackground; #endif #ifdef WIN_MAC_QUARTZ static void Nlm_SelectQuartzColor (Nlm_QuartzColor c) { CGContextSetRGBFillColor (Nlm_PeekQContext(), c.r, c.g, c.b, 1.0); CGContextSetRGBStrokeColor(Nlm_PeekQContext(), c.r, c.g, c.b, 1.0); } #endif extern void Nlm_ResetDrawingTools (void) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ if (Nlm_PeekQContext()) { CGContextSetLineWidth(Nlm_PeekQContext(), 1.0); CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0); CGContextSetAlpha(Nlm_PeekQContext(), 1.0); Nlm_SelectQuartzColor(Nlm_QuartzForeColor); } #else PenNormal (); PenMode (patCopy); TextMode (srcOr); if (Nlm_hasColorQD) { RGBForeColor (&Nlm_RGBforeColor); RGBBackColor (&Nlm_RGBbackColor); } else { ForeColor (blackColor); BackColor (whiteColor); } #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetROP2 (Nlm_currentHDC, R2_COPYPEN); SelectObject(Nlm_currentHDC, GetStockObject(SYSTEM_FONT)); winTextColor = GetSysColor (COLOR_WINDOWTEXT); winBkColor = Nlm_hasBackColor ? Nlm_crBackColor : GetSysColor (COLOR_WINDOW); SetTextColor (Nlm_currentHDC, winTextColor); SetBkColor (Nlm_currentHDC, winBkColor); SetBkMode (Nlm_currentHDC, TRANSPARENT); Nlm_SelectPattern (PS_SOLID, 1, blackPat, ATT_PENSTYLE|ATT_PENWIDTH|ATT_PATTERN ); prevPenHDC = NULL; } #endif #ifdef WIN_X if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { currentMode = COPY_MODE; currentFunction = GXcopy; currentFillStyle = FillOpaqueStippled; XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); if (Nlm_hasColor) { XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, Nlm_XbackColor); XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, Nlm_XforeColor); currentBkColor = Nlm_XbackColor; currentFgColor = Nlm_XforeColor; } else { XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, whiteColor); XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, blackColor); currentBkColor = whiteColor; currentFgColor = blackColor; } XSetLineAttributes (Nlm_currentXDisplay, Nlm_currentXGC, 1, LineSolid, CapProjecting, JoinMiter); Nlm_SelectPattern (blackPat); } #endif #ifdef WIN_GIF Nlm_SelectColor (0,0,0); Nlm_curGIFLType = GIF_SOLID; Nlm_curGIFFont = gdFont7X13b; gdImageSelectPattern(Nlm_currentGIF, blackPat); #endif currentMode = COPY_MODE; } /* The following functions: * Local__PointToolToPoinT * Local__PoinTToPointTool * Local__RectToolToRecT * Local__RecTToRectTool * are the local versions of relevant global Nlm_... functions * declared in "vibincld.h" and defined in "vibutils.c" */ #ifdef WIN_MAC static void Local__PointToolToPoinT(Nlm_PointTool src, Nlm_PointPtr dst) { if ( !dst ) return; dst->x = src.h; dst->y = src.v; } #endif /* WIN_MAC */ #ifndef WIN_GIF static void Local__PoinTToPointTool(Nlm_PoinT src, Nlm_PointTool PNTR dst) { if ( !dst ) return; #ifdef WIN_MAC dst->h = src.x; dst->v = src.y; #endif #if defined(WIN_MSWIN) || defined(WIN_X) dst->x = src.x; dst->y = src.y; #endif } static void Local__RectToolToRecT(Nlm_RectTool PNTR src, Nlm_RectPtr dst) { if (!dst || !src) return; #if defined(WIN_MAC) || defined(WIN_MSWIN) dst->left = (Nlm_Int2)src->left; dst->top = (Nlm_Int2)src->top; dst->right = (Nlm_Int2)src->right; dst->bottom = (Nlm_Int2)src->bottom; #endif #ifdef WIN_X dst->left = src->x; dst->top = src->y; dst->right = src->x + src->width; dst->bottom = src->y + src->height; #endif } #endif /* !WIN_GIF */ static void Local__RecTToRectTool(Nlm_RectPtr src, Nlm_RectTool PNTR dst) { if (!dst || !src) return; #if defined(WIN_MAC) || defined(WIN_MSWIN) || defined(WIN_GIF) dst->left = MIN(src->left, src->right ); dst->top = MIN(src->top, src->bottom); dst->right = MAX(src->left, src->right ); dst->bottom = MAX(src->top, src->bottom); #endif #ifdef WIN_X dst->x = MIN(src->left, src->right); dst->y = MIN(src->top, src->bottom); dst->width = ABS(src->right - src->left); dst->height = ABS(src->bottom - src->top); #endif } extern void Nlm_CopyMode (void) { #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ) PenMode (patCopy); TextMode (srcOr); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetROP2 (Nlm_currentHDC, R2_COPYPEN); } #endif #ifdef WIN_X currentFunction = GXcopy; currentFillStyle = FillOpaqueStippled; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #endif currentMode = COPY_MODE; } extern void Nlm_MergeMode (void) { #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ) PenMode (patOr); TextMode (srcOr); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetROP2 (Nlm_currentHDC, R2_MASKPEN); } #endif #ifdef WIN_X if (Nlm_hasColor) { currentFunction = GXand; } else { currentFunction = GXor; } currentFillStyle = FillStippled; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #endif currentMode = MERGE_MODE; } extern void Nlm_InvertMode (void) { #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ) PenMode (patXor); TextMode (srcXor); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetROP2 (Nlm_currentHDC, R2_NOTXORPEN); } #endif #ifdef WIN_X if (Nlm_hasColor) { currentFunction = GXequiv; } else { currentFunction = GXinvert; } currentFillStyle = FillStippled; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #endif currentMode = INVERT_MODE; } extern void Nlm_EraseMode (void) { #if defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ) PenMode (patBic); TextMode (srcBic); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetROP2 (Nlm_currentHDC, R2_MERGENOTPEN); } #endif #ifdef WIN_X if (Nlm_hasColor) { currentFunction = GXorInverted; } else { currentFunction = GXand; } currentFillStyle = FillStippled; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #endif currentMode = ERASE_MODE; } extern void Nlm_Black (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (0, 0, 0); } else { Nlm_ChooseColor (blackColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (blackColor); #endif #ifdef WIN_X Nlm_ChooseColor (blackColor); #endif #ifdef WIN_GIF Nlm_SelectColor (0, 0, 0); #endif } extern void Nlm_Red (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (255, 0, 0); } else { Nlm_ChooseColor (redColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (redColor); #endif #ifdef WIN_X Nlm_ChooseColor (redColor); #endif #ifdef WIN_GIF Nlm_SelectColor (255, 0, 0); #endif } extern void Nlm_Green (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (0, 255, 0); } else { Nlm_ChooseColor (greenColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (greenColor); #endif #ifdef WIN_X Nlm_ChooseColor (greenColor); #endif #ifdef WIN_GIF Nlm_SelectColor (0, 255, 0); #endif } extern void Nlm_Blue (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (0, 0, 255); } else { Nlm_ChooseColor (blueColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (blueColor); #endif #ifdef WIN_X Nlm_ChooseColor (blueColor); #endif #ifdef WIN_GIF Nlm_SelectColor (0, 0, 255); #endif } extern void Nlm_Cyan (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (0, 255, 255); } else { Nlm_ChooseColor (cyanColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (cyanColor); #endif #ifdef WIN_X Nlm_ChooseColor (cyanColor); #endif #ifdef WIN_GIF Nlm_SelectColor (0, 255, 255); #endif } extern void Nlm_Magenta (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (255, 0, 255); } else { Nlm_ChooseColor (magentaColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (magentaColor); #endif #ifdef WIN_X Nlm_ChooseColor (magentaColor); #endif #ifdef WIN_GIF Nlm_SelectColor (255, 0, 255); #endif } extern void Nlm_Yellow (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (255, 255, 0); } else { Nlm_ChooseColor (yellowColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (yellowColor); #endif #ifdef WIN_X Nlm_ChooseColor (yellowColor); #endif #ifdef WIN_GIF Nlm_SelectColor (255, 255, 0); #endif } extern void Nlm_White (void) { #ifdef WIN_MAC if (Nlm_hasColorQD) { Nlm_SelectColor (255, 255, 255); } else { Nlm_ChooseColor (whiteColor); } #endif #ifdef WIN_MSWIN Nlm_ChooseColor (whiteColor); #endif #ifdef WIN_X Nlm_ChooseColor (whiteColor); #endif #ifdef WIN_GIF Nlm_SelectColor (255, 255, 255); #endif } extern void Nlm_Gray (void) { Nlm_SelectColor (127, 127, 127); } extern void Nlm_LtGray (void) { Nlm_SelectColor (191, 191, 191); } extern void Nlm_DkGray (void) { Nlm_SelectColor (63, 63, 63); } #ifdef WIN_X #define COLOR_HASH(lrgb) (lrgb % 251) /* 251 is the largest prime less than 256 */ #define RGB_2_LRGB(red, green, blue) ((red) | (green << 8) | (blue << 16)) #define LRGB_RED(lrgb) ((lrgb) & 0xFF) #define LRGB_GREEN(lrgb) ((lrgb >> 8) & 0xFF) #define LRGB_BLUE(lrgb) (((lrgb >> 16) & 0xFF) /* note: without a lock, the same color may appear multiple times in the hash table (not the end of the world) */ typedef struct nlm_colorHashBucket { Nlm_Uint4 lrgb; XColor xcolor; struct nlm_colorHashBucket PNTR next; } Nlm_ColorHashBucket, PNTR Nlm_ColorHashBucketPtr; #endif extern void Nlm_SelectColor (Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_QuartzForeColor.r = red/255.0; Nlm_QuartzForeColor.g = green/255.0; Nlm_QuartzForeColor.b = blue/255.0; Nlm_SelectQuartzColor (Nlm_QuartzForeColor); #else RGBColor color; Nlm_Uint2 bl; Nlm_Uint2 gn; Nlm_Uint2 rd; if (Nlm_hasColorQD) { rd = (Nlm_Uint2) red; gn = (Nlm_Uint2) green; bl = (Nlm_Uint2) blue; color.red = rd << 8 | rd; color.green = gn << 8 | gn; color.blue = bl << 8 | bl; RGBForeColor (&color); } else if ((int) red + (int) green + (int) blue < 192) { Nlm_ChooseColor (blackColor); } else { Nlm_ChooseColor (whiteColor); } #endif #endif #ifdef WIN_MSWIN COLORREF color; Nlm_Uint2 bl; Nlm_Uint2 gn; Nlm_Uint2 rd; rd = (Nlm_Uint2) red; gn = (Nlm_Uint2) green; bl = (Nlm_Uint2) blue; color = RGB (rd, gn, bl); Nlm_ChooseColor (color); #endif #ifdef WIN_X XColor xcolor; Nlm_Uint1 hash; Nlm_Uint4 lrgb; Nlm_ColorHashBucketPtr CHBP, tail; static Nlm_ColorHashBucketPtr ColorHashBuckets [256] = {NULL}; lrgb = RGB_2_LRGB (red, green, blue); hash = COLOR_HASH (lrgb); tail = NULL; if (ColorHashBuckets [hash] != NULL) { for (CHBP = ColorHashBuckets [hash]; CHBP != NULL; CHBP = CHBP->next) { if (CHBP->lrgb == lrgb) { xcolor = CHBP->xcolor; Nlm_ChooseColor (xcolor.pixel); return; } tail = CHBP; } } Nlm_XAllocColor(&xcolor, Nlm_VibrantDefaultColormap(), red, green, blue); Nlm_ChooseColor(xcolor.pixel ); if (tail != NULL) { tail->next = MemNew (sizeof (Nlm_ColorHashBucket)); tail = tail->next; } else { tail = ColorHashBuckets [hash] = MemNew (sizeof (Nlm_ColorHashBucket)); } if (tail != NULL) { tail->lrgb = lrgb; tail->xcolor = xcolor; } #endif #ifdef WIN_GIF Nlm_curGIFColor = (int)Nlm_GetColorRGB ( red, green, blue ); #endif } #ifdef WIN_X #undef COLOR_HASH #undef RGB_2_LRGB #undef LRGB_RED #undef LRGB_GREEN #undef LRGB_BLUE #endif extern Nlm_Uint4 Nlm_GetColorRGB (Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue) { #ifdef WIN_MAC Nlm_Uint1 colors [4]; colors [0] = 0; colors [1] = red; colors [2] = green; colors [3] = blue; return *((Nlm_Int4Ptr) colors); #endif #ifdef WIN_MSWIN Nlm_Uint2 bl; Nlm_Uint2 gn; Nlm_Uint2 rd; rd = (Nlm_Uint2) red; gn = (Nlm_Uint2) green; bl = (Nlm_Uint2) blue; return (Nlm_Uint4)(RGB(rd, gn, bl)); #endif #ifdef WIN_X XColor xcolor; Nlm_XAllocColor(&xcolor, Nlm_VibrantDefaultColormap(), red, green, blue); return xcolor.pixel; #endif #ifdef WIN_GIF int i; if ( Nlm_currentGIF != NULL ){ i = gdImageColorExact ( Nlm_currentGIF, (int)red, (int)green, (int)blue ); if ( i == -1 ){ i = gdImageColorAllocate ( Nlm_currentGIF, (int)red, (int)green, (int)blue ); if ( i == -1 ){ i = gdImageColorClosest ( Nlm_currentGIF, (int)red, (int)green, (int)blue ); } } } return (Nlm_Uint4)i; #endif } extern Nlm_Uint4 Nlm_GetColor (void) { #ifdef WIN_MAC Nlm_Uint1 colors [4] = { 0 }; Nlm_Int4 fgColor; #ifdef WIN_MAC_QUARTZ colors[0] = 0; colors[1] = Nlm_QuartzForeColor.r * 255.0; colors[2] = Nlm_QuartzForeColor.g * 255.0; colors[3] = Nlm_QuartzForeColor.b * 255.0; #else RGBColor foreColor; if (Nlm_hasColorQD) { GetForeColor (&foreColor); colors [0] = 0; colors [1] = (Nlm_Uint1) (foreColor.red >> 8); colors [2] = (Nlm_Uint1) (foreColor.green >> 8); colors [3] = (Nlm_Uint1) (foreColor.blue >> 8); fgColor = *((Nlm_Int4Ptr) colors); } #endif fgColor = (colors[0] << 24) | (colors[1] << 16) | (colors[2] << 8) | colors[3]; #if !defined( WIN_MAC_QUARTZ ) && !defined( OPAQUE_TOOLBOX_STRUCTS ) if (!Nlm_hasColorQD) { GrafPtr port; GetPort (&port); if (port != NULL) { fgColor = port->fgColor; } } #endif return (Nlm_Uint4) fgColor; #endif #ifdef WIN_MSWIN Nlm_Int4 fgColor; fgColor = 0; if (Nlm_currentHDC != NULL) { fgColor = GetTextColor (Nlm_currentHDC); } return (Nlm_Uint4) fgColor; #endif #ifdef WIN_X return currentFgColor; #endif #ifdef WIN_GIF return (Nlm_Uint4)Nlm_curGIFColor; #endif } /* Used to set the color of text or foreground color. This function is the same as Nlm_SetColor except on Windows, where it does not call the extremely expensive Nlm_RecreateBrushes() */ extern void Nlm_SetColorEx (Nlm_Uint4 color) { #ifdef WIN_MAC Nlm_SetColor (color); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetTextColor (Nlm_currentHDC, (Nlm_Int4) color); winTextColor = color; } #endif #ifdef WIN_X Nlm_SetColor (color); #endif } extern void Nlm_SetColor (Nlm_Uint4 color) { #ifdef WIN_MAC Nlm_Uint2 bl; Nlm_Uint2 gn; Nlm_Uint2 rd; Nlm_Uint1 colors [4]; RGBColor foreColor; GrafPtr port; if (Nlm_hasColorQD) { *((Nlm_Int4Ptr) colors) = color; rd = (Nlm_Uint2) colors [1]; gn = (Nlm_Uint2) colors [2]; bl = (Nlm_Uint2) colors [3]; #ifdef WIN_MAC_QUARTZ Nlm_SelectColor(rd, gn, bl); #else foreColor.red = rd << 8 | rd; foreColor.green = gn << 8 | gn; foreColor.blue = bl << 8 | bl; RGBForeColor (&foreColor); } else { GetPort (&port); if (port != NULL) { ForeColor ((Nlm_Int4) color); } #endif } #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SetTextColor (Nlm_currentHDC, (Nlm_Int4) color); winTextColor = color; Nlm_RecreateBrushes (); } #endif #ifdef WIN_X XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, color); currentFgColor = color; #endif #ifdef WIN_GIF Nlm_curGIFColor = (int)color; #endif } extern void Nlm_InvertColors (void) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_QuartzColor temp = Nlm_QuartzForeColor; Nlm_QuartzForeColor = Nlm_QuartzBackColor; Nlm_QuartzBackColor = temp; Nlm_SelectQuartzColor (Nlm_QuartzForeColor); #else RGBColor backColor; RGBColor foreColor; if (Nlm_hasColorQD) { GetForeColor (&foreColor); GetBackColor (&backColor); RGBForeColor (&backColor); RGBBackColor (&foreColor); #if !OPAQUE_TOOLBOX_STRUCTS } else { Nlm_Int4 bkColor; Nlm_Int4 fgColor; GrafPtr port; GetPort (&port); if (port != NULL) { fgColor = port->fgColor; bkColor = port->bkColor; ForeColor (bkColor); BackColor (fgColor); #endif } #endif #endif #ifdef WIN_MSWIN Nlm_Int4 bkColor; Nlm_Int4 fgColor; if (Nlm_currentHDC != NULL) { fgColor = GetTextColor (Nlm_currentHDC); bkColor = GetBkColor (Nlm_currentHDC); SetTextColor (Nlm_currentHDC, bkColor); winTextColor = bkColor; SetBkColor (Nlm_currentHDC, fgColor); winBkColor = fgColor; Nlm_RecreateBrushes (); } #endif #ifdef WIN_X Nlm_Uint4 newBkColor; Nlm_Uint4 newFgColor; newBkColor = currentFgColor; newFgColor = currentBkColor; XSetBackground (Nlm_currentXDisplay, Nlm_currentXGC, newBkColor); XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, newFgColor); currentBkColor = newBkColor; currentFgColor = newFgColor; #endif #ifdef WIN_GIF #endif } extern void Nlm_DecodeColor (Nlm_Uint4 color, Nlm_Uint1Ptr red, Nlm_Uint1Ptr green, Nlm_Uint1Ptr blue) { #ifdef WIN_MAC Nlm_Uint1Ptr colors; Nlm_Uint1 bl; Nlm_Uint1 gn; Nlm_Uint1 rd; rd = 0; gn = 0; bl = 0; if (Nlm_hasColorQD) { colors = (Nlm_Uint1Ptr) (&color); rd = (Nlm_Uint1) colors [1]; gn = (Nlm_Uint1) colors [2]; bl = (Nlm_Uint1) colors [3]; } else if (color == whiteColor) { rd = 255; gn = 255; bl = 255; } if (red != NULL) { *red = (Nlm_Uint1) rd; } if (green != NULL) { *green = (Nlm_Uint1) gn; } if (blue != NULL) { *blue = (Nlm_Uint1) bl; } #endif #ifdef WIN_MSWIN Nlm_Uint1 bl; Nlm_Uint1 gn; Nlm_Uint1 rd; rd = GetRValue (color); gn = GetGValue (color); bl = GetBValue (color); if (red != NULL) { *red = (Nlm_Uint1) rd; } if (green != NULL) { *green = (Nlm_Uint1) gn; } if (blue != NULL) { *blue = (Nlm_Uint1) bl; } #endif #ifdef WIN_X Nlm_Uint2 bl; Nlm_Uint2 gn; Nlm_Uint2 rd; XColor xcolor; rd = 0; gn = 0; bl = 0; if (Nlm_hasColor) { xcolor.pixel = color; if (Nlm_currentXDisplay != NULL) { XQueryColor(Nlm_currentXDisplay, Nlm_VibrantDefaultColormap(), &xcolor); rd = xcolor.red >> 8; gn = xcolor.green >> 8; bl = xcolor.blue >> 8; } } else if (color == whiteColor) { rd = 255; gn = 255; bl = 255; } if (red != NULL) { *red = (Nlm_Uint1) rd; } if (green != NULL) { *green = (Nlm_Uint1) gn; } if (blue != NULL) { *blue = (Nlm_Uint1) bl; } #endif #ifdef WIN_GIF #endif } extern void Nlm_Dark (void) { #ifdef WIN_MAC_QUARTZ CGContextSetGrayFillColor (Nlm_PeekQContext(), .25, 1.0); CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .25, 1.0); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) dkGrayPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, 1, dkGrayPat, ATT_PATTERN ); #endif #ifdef WIN_X Nlm_SelectPattern (dkGrayPat); #endif #ifdef WIN_GIF gdImageSelectPattern(Nlm_currentGIF, dkGrayPat); #endif } extern void Nlm_Medium (void) { #ifdef WIN_MAC_QUARTZ CGContextSetGrayFillColor (Nlm_PeekQContext(), .5, 1.0); CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .5, 1.0); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) grayPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, 1, grayPat, ATT_PATTERN ); #endif #ifdef WIN_X Nlm_SelectPattern (grayPat); #endif #ifdef WIN_GIF gdImageSelectPattern(Nlm_currentGIF, grayPat); #endif } extern void Nlm_Light (void) { #ifdef WIN_MAC_QUARTZ CGContextSetGrayFillColor (Nlm_PeekQContext(), .75, 1.0); CGContextSetGrayStrokeColor(Nlm_PeekQContext(), .75, 1.0); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) ltGrayPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, 1, ltGrayPat, ATT_PATTERN); #endif #ifdef WIN_X Nlm_SelectPattern (ltGrayPat); #endif #ifdef WIN_GIF gdImageSelectPattern(Nlm_currentGIF, ltGrayPat); #endif } extern void Nlm_Empty (void) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGContextSetGrayFillColor (Nlm_PeekQContext(), 1.0, 1.0); CGContextSetGrayStrokeColor(Nlm_PeekQContext(), 1.0, 1.0); #else PenPat ((ConstPatternParam) whitePat); #endif #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, 1, whitePat, ATT_PATTERN); #endif #ifdef WIN_X Nlm_SelectPattern (whitePat); #endif #ifdef WIN_GIF gdImageSelectPattern(Nlm_currentGIF, whitePat); #endif } extern void Nlm_SetPenPattern (Nlm_VoidPtr pattern) { #ifdef WIN_MAC Nlm_Int2 i; #ifdef WIN_MAC_QUARTZ float pat[8]; #else Nlm_Byte pat [8]; #endif Nlm_BytePtr ptr; #endif #ifdef WIN_MSWIN Nlm_Int2 i; Nlm_Uint2 pat [8]; Nlm_Uint1Ptr ptr; Nlm_Uint1Ptr q; #endif #ifdef WIN_X Nlm_Int2 i; Nlm_Uint1 pat [8]; Nlm_Uint1Ptr ptr; Nlm_Uint1Ptr q; #endif if (pattern != NULL) { #ifdef WIN_MAC ptr = (Nlm_BytePtr) pattern; for (i = 0; i < 8; i++) { pat [i] = *ptr; ptr++; } #ifdef WIN_MAC_QUARTZ CGContextSetLineDash(Nlm_PeekQContext(), 0, pat, 8); #else PenPat ((ConstPatternParam) pat); #endif #endif #ifdef WIN_MSWIN ptr = (Nlm_Uint1Ptr) pattern; q = (Nlm_Uint1Ptr) pat; for (i = 0; i < 8; i++) { *q = (Nlm_Uint1) ~(*ptr); ptr++; q++; *q = 0; q++; } Nlm_SelectPattern (PS_SOLID, 1, pat, ATT_PATTERN); #endif #ifdef WIN_X ptr = (Nlm_Uint1Ptr) pattern; q = (Nlm_Uint1Ptr) pat; for (i = 0; i < 8; i++) { *q = flip [*ptr]; ptr++; q++; } Nlm_SelectPattern (pat); #endif #ifdef WIN_GIF gdImageSelectPattern(Nlm_currentGIF, (const unsigned char*)pattern); #endif } } extern void Nlm_Solid (void) { /* Reset *both* line stile and drawing pattern to SOLID */ #ifdef WIN_MAC_QUARTZ CGContextSetGrayFillColor (Nlm_PeekQContext(), 0.0, 1.0); CGContextSetGrayStrokeColor(Nlm_PeekQContext(), 0.0, 1.0); CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) blackPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, 1, blackPat, ATT_PATTERN|ATT_PENSTYLE ); #endif #ifdef WIN_X Nlm_SelectPattern( blackPat ); if (Nlm_currentXDisplay && Nlm_currentXGC) { XGCValues values; values.line_style = LineSolid; XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values); } #endif #ifdef WIN_GIF Nlm_SetPenPattern( blackPat ); Nlm_curGIFLType = GIF_SOLID; #endif } extern void Nlm_Dotted (void) { #ifdef WIN_MAC_QUARTZ float dashes[] = { 1.0, 1.0 }; CGContextSetLineDash(Nlm_PeekQContext(), 0, dashes, 2); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) dotPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_DOT, 1, dotPat, ATT_PENSTYLE|ATT_PATTERN); #endif #ifdef WIN_X if (Nlm_currentXDisplay && Nlm_currentXGC) { XGCValues values; values.line_style = LineOnOffDash; XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values); } #endif #ifdef WIN_GIF Nlm_curGIFLType = GIF_DASHED; #endif } extern void Nlm_Dashed (void) { #ifdef WIN_MAC_QUARTZ float dashes[] = { 3.0, 1.0 }; CGContextSetLineDash(Nlm_PeekQContext(), 0, dashes, 2); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) dashPat); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_DASH, 1, dashPat, ATT_PENSTYLE|ATT_PATTERN); #endif #ifdef WIN_X if (Nlm_currentXDisplay && Nlm_currentXGC) { XGCValues values; values.line_style = LineOnOffDash; XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineStyle, &values); } #endif #ifdef WIN_GIF Nlm_curGIFLType = GIF_DASHED; #endif } extern void Nlm_WidePen (Nlm_Int2 width) { #ifdef WIN_MAC_QUARTZ CGContextSetLineDash(Nlm_PeekQContext(), 0, NULL, 0); CGContextSetLineWidth(Nlm_PeekQContext(), (float) width); #elif defined(WIN_MAC) PenPat ((ConstPatternParam) blackPat); PenSize (width, width); #endif #ifdef WIN_MSWIN Nlm_SelectPattern (PS_SOLID, width, blackPat, ATT_PENWIDTH); #endif #ifdef WIN_X XGCValues values; if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { values.line_width = width; XChangeGC (Nlm_currentXDisplay, Nlm_currentXGC, GCLineWidth, &values); } #endif #ifdef WIN_GIF #endif } /* esl: changed to work with new FontData format */ static void Nlm_LoadFontData (Nlm_FonT font, Nlm_FonT next, Nlm_Int4 refcnt, Nlm_FontSpecPtr fsp, #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI) Nlm_Int2 num, Nlm_Int2 size, Nlm_Int2 styl, #else Nlm_FontTool hdl, #endif Nlm_FonT print) { /* load font data */ Nlm_FontData fdata; if (font == NULL) return; fdata.next = next; fdata.refcnt = refcnt; if (fsp != NULL) fdata.fontspec = *fsp; else Nlm_MemSet (&fdata.fontspec, 0, sizeof (Nlm_FontSpec)); #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI) fdata.number = num; fdata.size = size; fdata.style = styl; #elif defined(WIN_MSWIN) || defined(WIN_X) || defined(WIN_MAC_ATSUI) fdata.handle = hdl; #endif fdata.print = print; Nlm_SetFontData (font, &fdata); } /* esl: public proc for Windows font mapping (used also in ChooseFont) */ #ifdef WIN_MSWIN extern void Nlm_FontSpecToLOGFONT (Nlm_FontSpecPtr fsp, LOGFONT *lfp) { if (fsp == NULL || lfp == NULL) return; memset (lfp, 0, sizeof (LOGFONT)); { /* height & width */ HDC hDC = GetDC (NULL); lfp->lfHeight = - MulDiv (fsp->size, GetDeviceCaps (hDC, LOGPIXELSY), 72); ReleaseDC (NULL, hDC); lfp->lfWidth = 0; } /* weight & style */ lfp->lfWeight = ((fsp->style & STYLE_BOLD) != 0) ? FW_BOLD : FW_DONTCARE; /*FW_NORMAL?*/ lfp->lfItalic = (BYTE)((fsp->style & STYLE_ITALIC) != 0); lfp->lfUnderline = (BYTE)((fsp->style & STYLE_UNDERLINE) != 0); lfp->lfStrikeOut = (BYTE)((fsp->style & 128) != 0); /* Windows specific */ /* character set */ switch (fsp->charset) { case CHARSET_SYMBOL: lfp->lfCharSet = SYMBOL_CHARSET; break; case CHARSET_KANJI: lfp->lfCharSet = SHIFTJIS_CHARSET; break; default: lfp->lfCharSet = ANSI_CHARSET; break; } /* precisions & quality */ lfp->lfOutPrecision = OUT_DEFAULT_PRECIS; lfp->lfClipPrecision = CLIP_DEFAULT_PRECIS; lfp->lfQuality = DEFAULT_QUALITY; { /* pitch & family */ BYTE pitch, family; switch (fsp->pitch) { case PITCH_FIXED: pitch = FIXED_PITCH; break; case PITCH_VARIABLE: pitch = VARIABLE_PITCH; break; default: pitch = DEFAULT_PITCH; break; } switch (fsp->family) { case FAMILY_ROMAN: family = FF_ROMAN; break; case FAMILY_SWISS: family = FF_SWISS; break; case FAMILY_MODERN: family = FF_MODERN; break; case FAMILY_SCRIPT: family = FF_SCRIPT; break; case FAMILY_DECORATIVE: family = FF_DECORATIVE; break; default: family = FF_DONTCARE; break; } lfp->lfPitchAndFamily = (BYTE)(pitch | family); } /* face name */ Nlm_StringNCpy_0 (lfp->lfFaceName, fsp->name, LF_FACESIZE - 1); } #endif /* WIN_MSWIN */ /* VL */ #ifdef WIN_X static Nlm_CharPtr Xi[]={ "times", "palatino", "utopia", "new century schoolbook", "lucidabright", "lucida", "charter" }; extern XFontStruct *Nlm_XLoadStandardFont(void) { static char* s_StdXFontName[] = { "-*-helvetica-bold-r-*--14-*", "-*-helvetica-bold-r-*--*-140-*", "-*-helvetica-bold-r-*-*-*-140-*", "-*-fixed-medium-r-*--*-120-*", "-*-courier-medium-r-*--*-120-*", "8x13", "9x15", "fixed" }; int i; for (i = 0; i < DIM(s_StdXFontName); i++) { XFontStruct* font = Nlm_XLoadQueryFont(Nlm_currentXDisplay, s_StdXFontName[i], FALSE); if ( font ) return font; } /* the last-chance font */ return Nlm_XLoadQueryFont(Nlm_currentXDisplay, "fixed", TRUE); } #endif #ifdef WIN_MAC_ATSUI static Nlm_FontTool Nlm_FontToATSUStyle(Nlm_FonT f) { Nlm_FontData fontData; Nlm_GetFontData (f, &fontData); return fontData.handle; } static Nlm_FontTool Nlm_NewATSUStyle(Nlm_FontSpecPtr fsp) { OSErr err; Nlm_FontTool style = NULL; /* type ATSUStyle */ err = ATSUCreateStyle(&style); if (err == noErr) { ATSUFontID fontID; Fixed atsuSize; Boolean boldTag = FALSE; Boolean italicTag = FALSE; ATSUAttributeTag theTags[] = {kATSUFontTag, kATSUSizeTag, kATSUQDBoldfaceTag, kATSUQDItalicTag}; ByteCount theSizes[] = {sizeof(ATSUFontID), sizeof(Fixed), sizeof(Boolean), sizeof(Boolean)}; ATSUAttributeValuePtr theValues[] = {&fontID, &atsuSize, &boldTag, &italicTag}; /* Get Font id from the name. */ OSStatus err = ATSUFindFontFromName ( fsp->name, strlen(fsp->name), kFontFullName, // kFontFamilyName, kFontMacintoshPlatform, // kFontUnicodePlatform for Unicode support. kFontNoScriptCode, kFontNoLanguageCode, &fontID ); if (err == kATSUInvalidFontErr) { /* or can we do something more intelligent here? */ return NULL; } if ((fsp->style & STYLE_BOLD) != 0) boldTag = TRUE; if ((fsp->style & STYLE_ITALIC) != 0) italicTag = TRUE; /* get the size ready */ atsuSize = Long2Fix (fsp->size); /* put the attributes in to the style. */ err = ATSUSetAttributes ( style, sizeof(theTags)/sizeof(ATSUAttributeTag), theTags, theSizes, theValues ); } return style; } #endif /* esl: main internal procedure to create fonts */ static Nlm_FonT Nlm_AddNewFont (Nlm_FontSpecPtr fsp, Nlm_Boolean residentp) { Nlm_FonT rsult; #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI) Nlm_Int2 num = 0; Nlm_Int2 styl = 0; #else /* WIN_MSWIN | WIN_X | WIN_GIF | WIN_MAC_ATSUI */ Nlm_FontTool hdl = NULL; #endif if (fsp == NULL) return NULL; if ( (rsult = (Nlm_FonT)Nlm_HandNew( sizeof(Nlm_FontRec) )) == NULL ) return NULL; #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI hdl = Nlm_NewATSUStyle(fsp); #else {{ Nlm_Char temp[256]; if (fsp->name[0] != '\0') { Nlm_StringNCpy_0 (temp, fsp->name, sizeof (temp)); Nlm_CtoPstr (temp); GetFNum ((StringPtr) temp, &num); } if (num == 0) { /* use standard fonts */ if (fsp->charset == CHARSET_KANJI) { if (fsp->pitch == PITCH_FIXED) num = 0x4034; /* osaka(fixed) */ else num = 0x4000; /* osaka */ } else if (fsp->charset == CHARSET_SYMBOL) num = 23; /* symbol */ else if (fsp->family == FAMILY_ROMAN) { if (fsp->pitch == PITCH_FIXED) num = 22; /* courier */ else num = 2; /* new york */ } else if (fsp->family == FAMILY_SWISS) { if (fsp->pitch == PITCH_FIXED) num = 4; /* monaco */ else num = 3; /* geneva */ } else if (fsp->family == FAMILY_MODERN) num = 22; /* courier */ else if (fsp->family == FAMILY_SCRIPT) num = 12; /* los angeles */ else if (fsp->pitch == PITCH_FIXED) num = 4; /* monaco */ else num = 0; /* system */ } if ((fsp->style & STYLE_BOLD) != 0) styl += bold; if ((fsp->style & STYLE_ITALIC) != 0) styl += italic; if ((fsp->style & STYLE_UNDERLINE) != 0) styl += underline; /* other Mac-specific styles??? */ if ((fsp->style & 8) != 0) styl += outline; if ((fsp->style & 16) != 0) styl += shadow; if ((fsp->style & 32) != 0) styl += condense; if ((fsp->style & 64) != 0) styl += extend; }} #endif /* WIN_MAC_ATSUI */ #endif /* WIN_MAC */ #ifdef WIN_MSWIN {{ LOGFONT lf; Nlm_FontSpecToLOGFONT (fsp, &lf); hdl = CreateFontIndirect (&lf); }} #endif /* WIN_MSWIN */ #ifdef WIN_X if ( !Nlm_currentXDisplay ) return (Nlm_FonT) Nlm_MemFree(rsult); {{ Nlm_Char fspec[256]; Nlm_CharPtr bs = ((fsp->style & STYLE_BOLD) != 0) ? "bold" : "medium"; Nlm_CharPtr is = "r"; int sz = (int)fsp->size; if (fsp->style & STYLE_ITALIC) { size_t i; is="o"; for (i=0; iname, Xi[i]) ) { is="i"; break; } } if ( *fsp->name ) { /* try the whole data */ sprintf (fspec, "-*-%s-%s-%s-*--*-%d-*-*-*-*-*-*", fsp->name, bs, is, sz*10); hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE); if ( ! hdl ) { sprintf (fspec, "-*-%s-%s-%s-*-*-*-%d-*-*-*-*-*-*", fsp->name, bs, is, sz*10); hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE); } } if (!hdl && *fsp->name) { /* try the name only */ sprintf (fspec, "-*-%s-*", fsp->name); hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE); } if (hdl == NULL) { /* try charset/pitch/family */ Nlm_CharPtr ns; if (fsp->charset == CHARSET_SYMBOL) ns = "symbol"; else if (fsp->family == FAMILY_ROMAN ) ns = "times"; else if (fsp->family == FAMILY_SWISS ) ns = "helvetica"; else if (fsp->family == FAMILY_MODERN ) ns = "courier"; else if (fsp->pitch == PITCH_FIXED ) ns = "fixed"; else ns = "helvetica"; sprintf(fspec, "-*-%s-%s-%s-*--*-%d-*", ns, bs, is, sz*10); hdl = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fspec, FALSE); if ( !hdl ) { sprintf(fspec, "-*-%s-%s-%s-*-*-*-%d-*", ns, bs, is, sz*10); hdl = Nlm_XLoadQueryFont(Nlm_currentXDisplay, fspec, FALSE); } } if ( !hdl ) /* last resort: try "standard" font */ hdl = Nlm_XLoadStandardFont(); }} #endif /* WIN_X */ Nlm_LoadFontData (rsult, Nlm_fontList, residentp ? -1 : 1, fsp, #if defined(WIN_MAC) && ! defined(WIN_MAC_ATSUI) num, fsp->size, styl, #else /* WIN_MSWIN | WIN_X | WIN_GIF | WIN_MAC_ATSUI */ hdl, #endif NULL); Nlm_fontList = rsult; return rsult; } /* esl: public procedure to compare FontSpecs */ extern Nlm_Boolean Nlm_EqualFontSpec (Nlm_FontSpecPtr fsp1, Nlm_FontSpecPtr fsp2) { if (fsp1 == NULL || fsp2 == NULL) return FALSE; return (Nlm_Boolean) ( (Nlm_StrNICmp (fsp1->name, fsp2->name, FONT_NAME_SIZE) == 0) && fsp1->size == fsp2->size && fsp1->style == fsp2->style && fsp1->charset == fsp2->charset && fsp1->pitch == fsp2->pitch && fsp1->family == fsp2->family ); } /* esl: internal procedure to find existing fonts */ static Nlm_FonT Nlm_FindFont (Nlm_FontSpecPtr fsp) { if (fsp != NULL) { Nlm_FonT font = Nlm_fontList; while (font != NULL) { Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font); Nlm_Boolean found = Nlm_EqualFontSpec (fsp, &fp->fontspec); Nlm_FonT next = fp->next; Nlm_HandUnlock (font); if (found) return font; font = next; } } return NULL; } /* esl: internal procedure to increase refcnt */ static void Nlm_ReuseFont (Nlm_FonT font, Nlm_Boolean residentp) { if (font != NULL) { Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font); /* ASSERT (fp->refcnt != 0) */ if (fp->refcnt > 0) { /* font is temporary: make it resident or increment refcnt */ fp->refcnt = residentp ? -1 : fp->refcnt + 1; } /* else font is resident: just use it */ Nlm_HandUnlock (font); } } /* esl: internal procedure to create resident/temporary fonts */ static Nlm_FonT Nlm_CreateFontIndirect (Nlm_FontSpecPtr fsp, Nlm_Boolean residentp) { if (fsp != NULL) { if (fsp->family == 255) { /* magic number! */ /* conventional specification of the standard fonts */ return (fsp->pitch == PITCH_FIXED) ? Nlm_programFont : Nlm_systemFont; } else { Nlm_FonT font = Nlm_FindFont (fsp); if (font == NULL) { /* create new font and add it to the font list */ return Nlm_AddNewFont (fsp, residentp); } else { /* reuse existing font */ Nlm_ReuseFont (font, residentp); return font; } } } return NULL; } #ifdef WIN_MSWIN /* Creates(if yet no one) FonT based on the properties of "screen_font". * Use this function to choose a font corresponding to a stock font. */ static Nlm_FonT HFONT2Font(HFONT screen_font) { HDC hDC; if ( !screen_font ) return NULL; hDC = GetDC( NULL ); /* CreateIC("DISPLAY", NULL, NULL, NULL); */ if ( !hDC ) return NULL; {{ TEXTMETRIC tMetrics; BOOL ok = SelectObject(hDC, screen_font) && GetTextMetrics(hDC, &tMetrics); int height = MulDiv(tMetrics.tmHeight, 72, GetDeviceCaps(hDC, LOGPIXELSY)); ReleaseDC(NULL, hDC); /* DeleteDC( hDC ); */ if ( !ok ) return NULL; {{ Nlm_FontSpec fs; fs.name[0] = '\0'; fs.size = (Nlm_Int2)height; fs.style = 0; if (tMetrics.tmWeight == FW_BOLD) fs.style |= STYLE_BOLD; if ( tMetrics.tmItalic ) fs.style |= STYLE_ITALIC; if ( tMetrics.tmUnderlined ) fs.style |= STYLE_UNDERLINE; fs.charset = CHARSET_NULL; fs.pitch = (Nlm_Uint1)((tMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH) ? PITCH_VARIABLE : PITCH_FIXED); switch (tMetrics.tmPitchAndFamily & 0xF0) { case FF_DECORATIVE: fs.family = FAMILY_DECORATIVE; break; case FF_MODERN: fs.family = FAMILY_MODERN; break; case FF_ROMAN: fs.family = FAMILY_ROMAN; break; case FF_SCRIPT: fs.family = FAMILY_SCRIPT; break; case FF_SWISS: fs.family = FAMILY_SWISS; break; default: fs.family = FAMILY_NULL; } return Nlm_CreateFontIndirect(&fs, TRUE); }} }} } #endif /* WIN_MSWIN */ /* esl: public procedures to create resident/temporary fonts */ extern Nlm_FonT Nlm_CreateFont (Nlm_FontSpecPtr fsp) { return Nlm_CreateFontIndirect (fsp, FALSE); } extern Nlm_FonT Nlm_GetResidentFont (Nlm_FontSpecPtr fsp) { return Nlm_CreateFontIndirect (fsp, TRUE); } /* esl: public procedure to "copy" font (actually to increment refcnt) */ extern Nlm_FonT Nlm_CopyFont (Nlm_FonT font) { Nlm_ReuseFont (font, FALSE); /* do not make it resident */ return font; } /* esl: fonts created this way are resident for compatibility */ extern Nlm_FonT Nlm_GetFont (Nlm_CharPtr name, Nlm_Int2 size, Nlm_Boolean bld, Nlm_Boolean itlc, Nlm_Boolean undrln, Nlm_CharPtr fmly) { Nlm_Uint1 style, charset, pitch, family; /* style */ style = 0; if (bld) style |= STYLE_BOLD; if (itlc) style |= STYLE_ITALIC; if (undrln) style |= STYLE_UNDERLINE; /* charset */ charset = CHARSET_NULL; /* pitch */ pitch = PITCH_NULL; /* family */ if (fmly == NULL || fmly [0] != '\0') family = FAMILY_NULL; else if (Nlm_StringICmp (fmly, "Roman") == 0) family = FAMILY_ROMAN; else if (Nlm_StringICmp (fmly, "Swiss") == 0) family = FAMILY_SWISS; else if (Nlm_StringICmp (fmly, "Modern") == 0) family = FAMILY_MODERN; else if (Nlm_StringICmp (fmly, "Script") == 0) family = FAMILY_SCRIPT; else if (Nlm_StringICmp (fmly, "Decorative") == 0) family = FAMILY_DECORATIVE; else family = FAMILY_NULL; /* create resident font */ { Nlm_FontSpec fs; Nlm_MemSet (fs.name, 0, FONT_NAME_SIZE); if (name != NULL) Nlm_StringNCpy_0 (fs.name, name, FONT_NAME_SIZE - 1); fs.size = size; fs.style = style; fs.charset = charset; fs.pitch = pitch; fs.family = family; return Nlm_CreateFontIndirect (&fs, TRUE); } } static Nlm_FonT Nlm_ParseFontSpec (Nlm_CharPtr spec) { Nlm_Boolean bold; Nlm_CharPtr fmly; Nlm_Boolean ital; Nlm_Char name [128]; Nlm_CharPtr p; Nlm_CharPtr q; Nlm_CharPtr r; Nlm_FonT rsult; Nlm_Int2 size; Nlm_Char temp [128]; Nlm_Boolean undr; int val; rsult = NULL; if (spec != NULL && spec [0] != '\0') { fmly = NULL; bold = FALSE; ital = FALSE; undr = FALSE; Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1); p = Nlm_StringChr (name, ','); if (p != NULL) { *p = '\0'; p++; q = Nlm_StringChr (p, ','); if (q != NULL) { *q = '\0'; q++; } r = Nlm_StringChr (q, 'B'); if (r == NULL) { r = Nlm_StringChr (q, 'b'); } if (r != NULL) { bold = TRUE; } r = Nlm_StringChr (q, 'I'); if (r == NULL) { r = Nlm_StringChr (q, 'i'); } if (r != NULL) { ital = TRUE; } r = Nlm_StringChr (q, 'U'); if (r == NULL) { r = Nlm_StringChr (q, 'u'); } if (r != NULL) { undr = TRUE; } Nlm_StringNCpy_0 (temp, p, sizeof (temp) - 1); if (sscanf (temp, "%d", &val) != EOF) { size = (Nlm_Int2) val; rsult = Nlm_GetFont (name, size, bold, ital, undr, fmly); } } } return rsult; } /* esl: fonts created this way are resident for compatibility */ extern Nlm_FonT Nlm_ParseFont (Nlm_CharPtr spec) { Nlm_Char name [128]; Nlm_CharPtr p; Nlm_FonT prtr; Nlm_CharPtr q; Nlm_FonT rsult; rsult = NULL; if (spec != NULL && spec [0] != '\0') { Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1); p = Nlm_StringChr (name, '|'); if (p != NULL) { *p = '\0'; p++; while (*p == ' ') { p++; } q = name; while (*q == ' ') { q++; } rsult = Nlm_ParseFontSpec (q); prtr = Nlm_ParseFontSpec (p); Nlm_AssignPrinterFont (rsult, prtr); } else { q = name; while (*q == ' ') { q++; } rsult = Nlm_ParseFontSpec (q); } } return rsult; } extern Nlm_FonT Nlm_GetFontEx (Nlm_CharPtr name, Nlm_Int2 size, Nlm_Boolean bld, Nlm_Boolean itlc, Nlm_Boolean undrln, Nlm_CharPtr fmly, Nlm_CharPtr chset, Nlm_Boolean fixed) { Nlm_Uint1 style, charset, pitch, family; /* style */ style = 0; if (bld) style |= STYLE_BOLD; if (itlc) style |= STYLE_ITALIC; if (undrln) style |= STYLE_UNDERLINE; /* charset */ if (chset == NULL || chset [0] == '\0') charset = CHARSET_NULL; else if (Nlm_StringICmp (chset, "Ansi") == 0) charset = CHARSET_ANSI; else if (Nlm_StringICmp (chset, "Symbol") == 0) charset = CHARSET_SYMBOL; else if (Nlm_StringICmp (chset, "Kanji") == 0) charset = CHARSET_KANJI; else if (Nlm_StringICmp (chset, "Hangul") == 0) charset = CHASET_HANGUL; else charset = CHARSET_NULL; /* pitch */ if (fixed) pitch = PITCH_FIXED; else pitch = PITCH_NULL; /* family */ if (fmly == NULL || fmly [0] == '\0') family = FAMILY_NULL; else if (Nlm_StringICmp (fmly, "Roman") == 0) family = FAMILY_ROMAN; else if (Nlm_StringICmp (fmly, "Swiss") == 0) family = FAMILY_SWISS; else if (Nlm_StringICmp (fmly, "Modern") == 0) family = FAMILY_MODERN; else if (Nlm_StringICmp (fmly, "Script") == 0) family = FAMILY_SCRIPT; else if (Nlm_StringICmp (fmly, "Decorative") == 0) family = FAMILY_DECORATIVE; else family = FAMILY_NULL; /* create resident font */ { Nlm_FontSpec fs; Nlm_MemSet (fs.name, 0, FONT_NAME_SIZE); if (name != NULL) Nlm_StringNCpy_0 (fs.name, name, FONT_NAME_SIZE - 1); fs.size = size; fs.style = style; fs.charset = charset; fs.pitch = pitch; fs.family = family; return Nlm_CreateFontIndirect (&fs, TRUE); } } static Nlm_FonT Nlm_ParseFontSpecEx (Nlm_CharPtr spec) { Nlm_Boolean bold; Nlm_CharPtr fmly; Nlm_Boolean ital; Nlm_Char name [128]; Nlm_CharPtr p; Nlm_CharPtr q; Nlm_CharPtr r; Nlm_CharPtr s; Nlm_FonT rsult; Nlm_Int2 size; Nlm_Char temp [128]; Nlm_Boolean undr; int val; Nlm_Char chst [128]; Nlm_Boolean fixd; rsult = NULL; if (spec != NULL && spec [0] != '\0') { fmly = NULL; bold = FALSE; ital = FALSE; undr = FALSE; fixd = FALSE; chst [0] = '\0'; Nlm_StringNCpy_0 (name, spec, sizeof (name) - 1); p = Nlm_StringChr (name, ','); if (p != NULL) { *p = '\0'; p++; q = Nlm_StringChr (p, ','); if (q != NULL) { *q = '\0'; q++; } s = Nlm_StringChr (q, ','); if (s != NULL) { *s = '\0'; s++; } r = Nlm_StringChr (q, 'B'); if (r == NULL) { r = Nlm_StringChr (q, 'b'); } if (r != NULL) { bold = TRUE; } r = Nlm_StringChr (q, 'I'); if (r == NULL) { r = Nlm_StringChr (q, 'i'); } if (r != NULL) { ital = TRUE; } r = Nlm_StringChr (q, 'U'); if (r == NULL) { r = Nlm_StringChr (q, 'u'); } if (r != NULL) { undr = TRUE; } r = Nlm_StringChr (q, 'F'); if (r == NULL) { r = Nlm_StringChr (q, 'f'); } if (r != NULL) { fixd = TRUE; } if (s != NULL) { Nlm_StringNCpy_0 (chst, s, sizeof (chst) - 1); } Nlm_StringNCpy_0 (temp, p, sizeof (temp) - 1); if (sscanf (temp, "%d", &val) != EOF) { size = (Nlm_Int2) val; rsult = Nlm_GetFontEx (name, size, bold, ital, undr, fmly, chst, fixd); } } } return rsult; } extern Nlm_FonT Nlm_ParseFontEx (Nlm_CharPtr scrSpec, Nlm_CharPtr prtSpec) { Nlm_CharPtr p; Nlm_FonT prtr; Nlm_CharPtr q; Nlm_FonT rsult; rsult = NULL; if (scrSpec != NULL && scrSpec [0] != '\0') { q = scrSpec; while (*q == ' ') { q++; } rsult = Nlm_ParseFontSpecEx(q); } prtr = NULL; if (prtSpec != NULL && prtSpec [0] != '\0') { p = prtSpec; while (*p == ' ') { p++; } prtr = Nlm_ParseFontSpecEx(p); Nlm_AssignPrinterFont (rsult, prtr); } return rsult; } /* esl: public procedures to get specifications for common fonts */ /* ToDo: add platform-dependent names? */ static Nlm_FontSpec Nlm_commonFontSpec; extern Nlm_FontSpecPtr Nlm_Helvetica (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC_QUARTZ strncpy(Nlm_commonFontSpec.name, "Helvetica", sizeof(Nlm_commonFontSpec.name)); #else Nlm_commonFontSpec.name[0] = '\0'; #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_ANSI; Nlm_commonFontSpec.pitch = PITCH_VARIABLE; Nlm_commonFontSpec.family = FAMILY_SWISS; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_Times (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC_QUARTZ strncpy(Nlm_commonFontSpec.name, "Times", sizeof(Nlm_commonFontSpec.name)); #else Nlm_commonFontSpec.name[0] = '\0'; #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_ANSI; Nlm_commonFontSpec.pitch = PITCH_VARIABLE; Nlm_commonFontSpec.family = FAMILY_ROMAN; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_Courier (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC_QUARTZ strncpy(Nlm_commonFontSpec.name, "Courier", sizeof(Nlm_commonFontSpec.name)); #else Nlm_commonFontSpec.name[0] = '\0'; #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_ANSI; Nlm_commonFontSpec.pitch = PITCH_FIXED; Nlm_commonFontSpec.family = FAMILY_MODERN; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_Symbol (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC_QUARTZ strncpy(Nlm_commonFontSpec.name, "Symbol", sizeof(Nlm_commonFontSpec.name)); #else Nlm_commonFontSpec.name[0] = '\0'; #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_SYMBOL; /* should be enough */ Nlm_commonFontSpec.pitch = PITCH_NULL; Nlm_commonFontSpec.family = FAMILY_NULL; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_Gothic (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC strncpy(Nlm_commonFontSpec.name, "Osaka", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MSWIN strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MOTIF strncpy(Nlm_commonFontSpec.name, "gothic", sizeof(Nlm_commonFontSpec.name)); #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_KANJI; Nlm_commonFontSpec.pitch = PITCH_NULL; Nlm_commonFontSpec.family = FAMILY_GOTHIC; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_Minchou (Nlm_Int2 size, Nlm_Uint1 style) { #ifdef WIN_MAC strncpy(Nlm_commonFontSpec.name, "Osaka", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MSWIN strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x82\x6f\x96\xbe\x92\xa9", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MOTIF strncpy(Nlm_commonFontSpec.name, "minchou", sizeof(Nlm_commonFontSpec.name)); #endif Nlm_commonFontSpec.size = size; Nlm_commonFontSpec.style = style; Nlm_commonFontSpec.charset = CHARSET_KANJI; Nlm_commonFontSpec.pitch = PITCH_NULL; Nlm_commonFontSpec.family = FAMILY_MINCHOU; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_GothicFixed (Nlm_Int2 size, Nlm_Uint1 style) { Nlm_Gothic(size, style); #ifdef WIN_MAC strncpy(Nlm_commonFontSpec.name, "Osaka\x81\x7c\x93\x99\x95\x9d", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MSWIN strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x83\x53\x83\x56\x83\x62\x83\x4e", sizeof(Nlm_commonFontSpec.name)); #endif Nlm_commonFontSpec.pitch = PITCH_FIXED; return &Nlm_commonFontSpec; } extern Nlm_FontSpecPtr Nlm_MinchouFixed (Nlm_Int2 size, Nlm_Uint1 style) { Nlm_Minchou(size, style); #ifdef WIN_MAC strncpy(Nlm_commonFontSpec.name, "Osaka\x81\x7c\x93\x99\x95\x9d", sizeof(Nlm_commonFontSpec.name)); #endif #ifdef WIN_MSWIN strncpy(Nlm_commonFontSpec.name, "\x82\x6c\x82\x72\x20\x96\xbe\x92\xa9", sizeof(Nlm_commonFontSpec.name)); #endif Nlm_commonFontSpec.pitch = PITCH_FIXED; return &Nlm_commonFontSpec; } /* esl: public procedure to delete temporary fonts */ /* ToDo: track associated fdata.print font! */ extern Nlm_FonT Nlm_DeleteFont (Nlm_FonT font) { if (font != NULL) { Nlm_FontData fdata; Nlm_GetFontData (font, &fdata); /* ASSERT(fdata.refcnt != 0) */ if (fdata.refcnt > 0) { if (fdata.refcnt > 1) { /* still in use somewhere else: decrement refcnt */ fdata.refcnt--; Nlm_SetFontData (font, &fdata); } else { /* last reference should be lost: remove from the list and delete */ Nlm_FonT prev = NULL; Nlm_FonT curr = Nlm_fontList; while (curr != NULL) { if (curr == font) { /* font is found! */ Nlm_GetFontData (curr, &fdata); curr = fdata.next; if (prev != NULL) { /* remove in the middle */ Nlm_GetFontData (prev, &fdata); fdata.next = curr; Nlm_SetFontData (prev, &fdata); } else { /* remove first */ Nlm_fontList = curr; } } else { /* check next! */ prev = curr; Nlm_GetFontData (curr, &fdata); curr = fdata.next; } } /* if font is selected, unselect it before deletion! */ if (font == Nlm_fontInUse) Nlm_SelectFont (Nlm_systemFont); /* delete it! */ Nlm_GetFontData (font, &fdata); #ifdef WIN_MSWIN if (fdata.handle != NULL) DeleteObject (fdata.handle); #endif #ifdef WIN_MOTIF if (fdata.handle != NULL) XFreeFont (Nlm_currentXDisplay, fdata.handle); #endif Nlm_HandFree (font); } } /* else font is resident: leave it as it is */ } return NULL; } /* esl: procedure to enumerate resident fonts */ extern Nlm_FonT Nlm_FindNextResidentFont (Nlm_FonT font) { Nlm_FonT curr; Nlm_FontData fdata; if (font == NULL) { curr = Nlm_fontList; } else { Nlm_GetFontData (font, &fdata); curr = fdata.next; } while (curr != NULL) { /* skip temporary fonts */ Nlm_GetFontData (curr, &fdata); if (fdata.refcnt < 0) return curr; else curr = fdata.next; } return NULL; } /* esl: procedure to extract specification from font */ extern Nlm_Boolean Nlm_GetFontSpec (Nlm_FonT font, Nlm_FontSpecPtr fsp) { if (font == NULL || fsp == NULL) return FALSE; /* use conventional specification for system/program fonts */ if (font == Nlm_systemFont || font == Nlm_programFont) { /*alexs: copy fontspec for System and Program font */ Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font); *fsp = fp->fontspec; Nlm_HandUnlock (font); fsp->family = 255; /* magic number! */ fsp->pitch = (Nlm_Uint1)((font == Nlm_programFont) ? PITCH_FIXED : PITCH_NULL); } else { Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (font); *fsp = fp->fontspec; Nlm_HandUnlock (font); } return TRUE; } extern void Nlm_SelectFont (Nlm_FonT f) { Nlm_FontData fdata; if (f != NULL) { Nlm_GetFontData (f, &fdata); if (fdata.print != NULL && Nlm_nowPrinting) { f = fdata.print; Nlm_GetFontData (f, &fdata); } #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI Nlm_fontInUse = f; #else TextFont (fdata.number); TextSize (fdata.size); TextFace (fdata.style); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SelectObject (Nlm_currentHDC, fdata.handle); } #endif #ifdef WIN_X if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { if (fdata.handle != NULL) { XSetFont (Nlm_currentXDisplay, Nlm_currentXGC, fdata.handle->fid); currentFont = fdata.handle; } } #endif #ifdef WIN_GIF if (fdata.fontspec.size >= 16) { Nlm_curGIFFont = gdFont8X16; } else if (fdata.fontspec.size >= 15) { Nlm_curGIFFont = gdFont9X15b; } else if (fdata.fontspec.size >= 13) { Nlm_curGIFFont = gdFont7X13b; } else if (fdata.fontspec.size >= 10) { Nlm_curGIFFont = gdFont6X12; } else { Nlm_curGIFFont = gdFont5X8; } #endif Nlm_fontInUse = f; } } /* esl ToDo: increment refcnt for fdata.print font? */ extern void Nlm_AssignPrinterFont (Nlm_FonT scrnFont, Nlm_FonT prtrFont) { if (scrnFont != NULL) { Nlm_FntPtr fp = (Nlm_FntPtr) Nlm_HandLock (scrnFont); fp->print = prtrFont; Nlm_HandUnlock (scrnFont); } } extern Nlm_Int2 Nlm_CharWidth (Nlm_Char ch) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ return Nlm_TextWidth (&ch, 1); #else return (CharWidth (ch)); #endif #endif #ifdef WIN_MSWIN Nlm_Char str [4]; str [0] = ch; str [1] = '\0'; return (Nlm_TextWidth (str, 1)); #endif #ifdef WIN_X Nlm_Char str [4]; str [0] = ch; str [1] = '\0'; return (Nlm_TextWidth (str, 1)); #endif #ifdef WIN_GIF return (Nlm_Int2)Nlm_curGIFFont->w; #endif } extern Nlm_Int2 Nlm_StringWidth(const Nlm_Char* text) { return Nlm_TextWidth(text, Nlm_StringLen(text)); } extern Nlm_Int2 Nlm_TextWidth(const Nlm_Char* text, size_t len) { if (text && len) { #if defined(WIN_MAC) #if defined(WIN_MAC_ATSUI) OSErr err; Nlm_PoinT pt; CFStringRef cfString; CFIndex cfsLen; const UniChar * unicodeString; ATSUTextLayout layout; Nlm_FontTool curStyle; Rect tr; /* convert the string to Unicode */ cfString = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingMacRoman); if (cfString == NULL) return 0; cfsLen = CFStringGetLength(cfString); unicodeString = CFStringGetCharactersPtr(cfString); if (unicodeString == NULL) { CFRange range; static UniChar ucbuf[1024]; range.location = 0; range.length = MIN(cfsLen, 1024); CFStringGetCharacters (cfString, range, ucbuf); unicodeString = ucbuf; } /* get the current style */ curStyle = Nlm_FontToATSUStyle(Nlm_fontInUse); /* create the layout */ err = ATSUCreateTextLayoutWithTextPtr ( unicodeString, 0, cfsLen, cfsLen, 1, (unsigned long *)&cfsLen, &curStyle, &layout ); /* how big is the text. */ err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &tr); if (err == noErr) return (tr.right - tr.left) + 3; #else return TextWidth(text, 0, (Nlm_Int2)len); #endif #elif defined(WIN_MSWIN) SIZE tag; if ( Nlm_currentHDC ) GetTextExtentPoint(Nlm_currentHDC, text, (int)len, &tag); else { HDC hDC = CreateIC("DISPLAY", NULL, NULL, NULL); GetTextExtentPoint (hDC, text, (int)len, &tag); DeleteDC(hDC); } return (Nlm_Int2)tag.cx; #elif defined(WIN_X) if ( Nlm_GetTextMetrics() ) return (Nlm_Int2)XTextWidth(&fontInfo, text, (int)len); #elif defined(WIN_GIF) return (Nlm_Int2)(Nlm_curGIFFont->w * len); #endif } return 0; } #if defined(WIN_MAC) && defined(WIN_MAC_ATSUI) static ATSFontMetrics Nlm_CurrentATSUFontMetrics(void) { Nlm_FontTool curStyle = Nlm_FontToATSUStyle (Nlm_fontInUse); ATSUFontID fontID = 0; ByteCount ignoredCount; ATSUGetAttribute (curStyle, kATSUFontTag, sizeof (fontID), &fontID, &ignoredCount); ATSFontRef font = FMGetATSFontRefFromFont (fontID); ATSFontMetrics metrics; memset (&metrics, 0, sizeof (metrics)); ATSFontGetHorizontalMetrics (font, kATSOptionFlagsDefault, &metrics); return metrics; } static Fixed Nlm_CurrentATSUFontSize(void) { Nlm_FontTool curStyle = Nlm_FontToATSUStyle (Nlm_fontInUse); Fixed size = 0; ByteCount ignoredCount; ATSUGetAttribute (curStyle, kATSUSizeTag, sizeof (size), &size, &ignoredCount); return size; } #endif extern Nlm_Int2 Nlm_Ascent (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return ceilf (Nlm_CurrentATSUFontMetrics().ascent * Nlm_CurrentATSUFontSize() / 65536.0); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.ascent); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) textMetrics.tmAscent; } return rsult; #endif #ifdef WIN_X Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = MAX (fontInfo.ascent, fontInfo.max_bounds.ascent); } return rsult; #endif #ifdef WIN_GIF return (Nlm_Int2)Nlm_curGIFFont->h - (Nlm_Int2)Nlm_curGIFFont->d; #endif } extern Nlm_Int2 Nlm_Descent (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return ceilf (-Nlm_CurrentATSUFontMetrics().descent * Nlm_CurrentATSUFontSize() / 65536.0); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.descent); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) textMetrics.tmDescent; } return rsult; #endif #ifdef WIN_X Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = MAX (fontInfo.descent, fontInfo.max_bounds.descent); } return rsult; #endif #ifdef WIN_GIF return (Nlm_Int2)Nlm_curGIFFont->d; #endif } extern Nlm_Int2 Nlm_Leading (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return ceilf (Nlm_CurrentATSUFontMetrics().leading * Nlm_CurrentATSUFontSize() / 65536.0); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.leading); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) textMetrics.tmExternalLeading; } return rsult; #endif #ifdef WIN_X return 0; #endif #ifdef WIN_GIF return 0; #endif } extern Nlm_Int2 Nlm_FontHeight (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return Nlm_Ascent() + Nlm_Descent(); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.ascent + fontinfo.descent); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) textMetrics.tmHeight; } return rsult; #endif #ifdef WIN_X Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (MAX (fontInfo.ascent, fontInfo.max_bounds.ascent) + MAX (fontInfo.descent, fontInfo.max_bounds.descent)); } return rsult; #endif #ifdef WIN_GIF return (Nlm_Int2)Nlm_curGIFFont->h; #endif } extern Nlm_Int2 Nlm_LineHeight (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return Nlm_Ascent() + Nlm_Descent() + Nlm_Leading(); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.ascent + fontinfo.descent + fontinfo.leading); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) (textMetrics.tmHeight + textMetrics.tmExternalLeading); } return rsult; #endif #ifdef WIN_X Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (MAX (fontInfo.ascent, fontInfo.max_bounds.ascent) + MAX (fontInfo.descent, fontInfo.max_bounds.descent)); } return rsult; #endif #ifdef WIN_GIF return (Nlm_Int2)(Nlm_curGIFFont->h + 1); #endif } extern Nlm_Int2 Nlm_MaxCharWidth (void) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI return ceilf (Nlm_CurrentATSUFontMetrics().maxAdvanceWidth * Nlm_CurrentATSUFontSize() / 65536.0); #else FontInfo fontinfo; GetFontInfo (&fontinfo); return (fontinfo.widMax); #endif #endif #ifdef WIN_MSWIN Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = (Nlm_Int2) textMetrics.tmMaxCharWidth; } return rsult; #endif #ifdef WIN_X Nlm_Int2 rsult; rsult = 0; if (Nlm_GetTextMetrics ()) { rsult = fontInfo.max_bounds.width; } return rsult; #endif #ifdef WIN_GIF return (Nlm_Int2)Nlm_curGIFFont->w; #endif } size_t Nlm_FitStringWidth(const Nlm_Char PNTR str, Nlm_Int4 max_width) { size_t len; if (!str || !*str || max_width < 1) return 0; #if defined(WIN_X) {{ if ( !Nlm_GetTextMetrics() ) return 0; if (fontInfo.min_byte1 || fontInfo.max_byte1) return 0; /* two-byte font */ if ( !fontInfo.per_char ) /* non-proportional font */ return (fontInfo.max_bounds.width > 0 ? max_width / fontInfo.max_bounds.width : 0); {{ Nlm_Int4 width = 0; unsigned min_char = fontInfo.min_char_or_byte2; unsigned max_char = fontInfo.max_char_or_byte2; XCharStruct *per_char = fontInfo.per_char; int def_char_width = (min_char <= fontInfo.default_char && fontInfo.default_char <= max_char) ? per_char[fontInfo.default_char - min_char].width : 0; const unsigned char *ustr = (const unsigned char *) str; for (len = 0; width <= max_width && *ustr; len++, ustr++) { if (min_char <= *ustr && *ustr <= max_char) { int w = per_char[*ustr - min_char].width; width += w ? w : def_char_width; } else width += def_char_width; } return (width > max_width ? len-1 : len); }} }} #else {{ /* platform-independent algorithm */ Nlm_Int2 max_char_width = Nlm_MaxCharWidth(); if (max_char_width < 1) return 0; ASSERT ( max_width > 0 ); if (Nlm_StringWidth( (Nlm_CharPtr)str ) <= max_width) return Nlm_StringLen( str ); len = (size_t)(max_width / max_char_width); ASSERT ( len < StringLen( str ) ); while (str[len] != '\0' && Nlm_TextWidth((Nlm_CharPtr)str, len) <= max_width) len++; return (len ? len-1 : 0); }} #endif } extern void Nlm_SetPen (Nlm_PoinT pt) { #ifdef WIN_MAC Nlm_MoveTo (pt.x, pt.y); #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { MoveToEx (Nlm_currentHDC, pt.x, pt.y, NULL); } #endif #ifdef WIN_X currentPoint = pt; #endif #ifdef WIN_GIF Nlm_curGIFPoint = pt; #endif } extern void Nlm_GetPen (Nlm_PointPtr pt) { #ifdef WIN_MAC_QUARTZ CGPoint cgp; if (pt != NULL) { cgp = CGContextGetPathCurrentPoint(Nlm_PeekQContext()); } pt->x = cgp.x; pt->y = cgp.y; #elif defined(WIN_MAC) Nlm_PointTool ptool; if (pt != NULL) { GetPen (&ptool); Local__PointToolToPoinT (ptool, pt); } #endif #ifdef WIN_MSWIN POINT pos; if (pt != NULL && Nlm_currentHDC != NULL) { GetCurrentPositionEx (Nlm_currentHDC, &pos); pt->x = (Nlm_Int2) pos.x; pt->y = (Nlm_Int2) pos.y; } #endif #ifdef WIN_X if (pt != NULL) { *pt = currentPoint; } #endif #ifdef WIN_GIF *pt = Nlm_curGIFPoint; #endif } void Nlm_SetPenWidth(Nlm_Int2 width) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGContextSetLineWidth (Nlm_PeekQContext(), width); #else PenSize (width, width); #endif #endif } extern void Nlm_PaintChar (Nlm_Char ch) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_PoinT pt; Nlm_GetPen (& pt); CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, & ch, 1); #else DrawChar (ch); #endif #endif #ifdef WIN_MSWIN Nlm_PoinT pt; Nlm_Char str [2]; if (Nlm_currentHDC != NULL) { str [0] = ch; str [1] = '\0'; Nlm_GetPen (&pt); TextOut (Nlm_currentHDC, pt.x, pt.y - Nlm_Ascent (), str, 1); pt.x += Nlm_CharWidth (ch); Nlm_MoveTo (pt.x, pt.y); } #endif #ifdef WIN_X Nlm_PoinT pt; Nlm_Char str [2]; if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { str [0] = ch; str [1] = '\0'; Nlm_GetPen (&pt); XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, str, 1); pt.x += Nlm_CharWidth (ch); Nlm_MoveTo (pt.x, pt.y); } #endif #ifdef WIN_GIF if ( Nlm_currentGIF != NULL ){ gdImageChar ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y - Nlm_Ascent(), (int)ch, Nlm_curGIFColor ); Nlm_curGIFPoint.x += Nlm_CharWidth (ch); } #endif } extern void Nlm_PaintStringEx(Nlm_CharPtr text, Nlm_Int2 x, Nlm_Int2 y) { #ifdef WIN_MSWIN if (!text || !*text || !Nlm_currentHDC) return; TextOut(Nlm_currentHDC, x, y - Nlm_Ascent(), text, (Nlm_Int2)Nlm_StringLen( text )); Nlm_MoveTo((Nlm_Int2)(x + Nlm_StringWidth(text)), y); #else Nlm_MoveTo(x, y); Nlm_PaintString( text ); #endif } extern void Nlm_PaintString (Nlm_CharPtr text) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI OSErr err; Nlm_PoinT pt; CFStringRef cfString; CFIndex cfsLen; const UniChar * unicodeString; ATSUTextLayout layout; Nlm_FontTool curStyle; /* convert the string to Unicode */ cfString = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingMacRoman); if (cfString == NULL) return; cfsLen = CFStringGetLength(cfString); unicodeString = CFStringGetCharactersPtr(cfString); if (unicodeString == NULL) { CFRange range; static UniChar ucbuf[1024]; range.location = 0; range.length = MIN(cfsLen, 1024); CFStringGetCharacters (cfString, range, ucbuf); unicodeString = ucbuf; } /* get the current style */ curStyle = Nlm_FontToATSUStyle(Nlm_fontInUse); /* create the layout */ err = ATSUCreateTextLayoutWithTextPtr ( unicodeString, 0, cfsLen, cfsLen, 1, (unsigned long *)&cfsLen, &curStyle, &layout ); /* draw where? */ Nlm_GetPen (&pt); /* CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, text, Nlm_StringLen (text)); */ err = ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd, Long2Fix(pt.x), Long2Fix(pt.y)); #else Nlm_PoinT pt; Nlm_Char str [256]; if (text != NULL) { Nlm_GetPen (&pt); if (Nlm_StringLen (text) > 0) { Nlm_StringNCpy_0 (str, text, sizeof (str)); Nlm_CtoPstr (str); DrawString ((StringPtr) str); } pt.x += Nlm_StringWidth (text); Nlm_MoveTo (pt.x, pt.y); } #endif #endif #ifdef WIN_MSWIN Nlm_PoinT pt; Nlm_GetPen( &pt ); Nlm_PaintStringEx(text, pt.x, pt.y); #endif #ifdef WIN_X Nlm_Int2 len; Nlm_PoinT pt; if (text != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { len = (Nlm_Int2) Nlm_StringLen (text); Nlm_GetPen (&pt); if (len > 0) { XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, text, len); } pt.x += Nlm_StringWidth (text); Nlm_MoveTo (pt.x, pt.y); } #endif #ifdef WIN_GIF if ( text != NULL && Nlm_currentGIF != NULL ){ gdImageString ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y - Nlm_Ascent(), text, Nlm_curGIFColor ); Nlm_curGIFPoint.x += Nlm_StringWidth (text); } #endif } #ifdef VAR_ARGS void CDECL Nlm_PaintText (format, va_alist) char *format; va_dcl #else void CDECL Nlm_PaintText (char *format, ...) #endif { #ifdef WIN_MAC va_list args; Nlm_PoinT pt; Nlm_Char str [256]; if (format != NULL) { #ifdef VAR_ARGS va_start(args); #else va_start(args, format); #endif vsprintf(str, format, args); va_end(args); Nlm_GetPen (&pt); #ifdef WIN_MAC_QUARTZ CGContextShowTextAtPoint(Nlm_PeekQContext(), pt.x, pt.y, str, Nlm_StringLen (str)); #else if (Nlm_StringLen (str) > 0) { Nlm_CtoPstr (str); DrawString ((StringPtr) str); } pt.y += Nlm_LineHeight (); Nlm_MoveTo (pt.x, pt.y); #endif } #endif #ifdef WIN_MSWIN va_list args; Nlm_Int2 len; Nlm_PoinT pt; Nlm_Char str [256]; if (format != NULL && Nlm_currentHDC != NULL) { #ifdef VAR_ARGS va_start(args); #else va_start(args, format); #endif vsprintf(str, format, args); va_end(args); len = (Nlm_Int2) Nlm_StringLen (str); Nlm_GetPen (&pt); if (len > 0) { TextOut (Nlm_currentHDC, pt.x, pt.y - Nlm_Ascent (), str, len); } pt.y += Nlm_LineHeight (); Nlm_MoveTo (pt.x, pt.y); } #endif #ifdef WIN_X va_list args; Nlm_Int2 len; Nlm_PoinT pt; Nlm_Char str [256]; if (format != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { #ifdef VAR_ARGS va_start(args); #else va_start(args, format); #endif vsprintf(str, format, args); va_end(args); len = (Nlm_Int2) Nlm_StringLen (str); Nlm_GetPen (&pt); if (len > 0) { XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, pt.x - Nlm_XOffset, pt.y - Nlm_YOffset, str, len); } pt.y += Nlm_LineHeight (); Nlm_MoveTo (pt.x, pt.y); } #endif #ifdef WIN_GIF va_list args; Nlm_Char str [256]; if ( format != NULL && Nlm_currentGIF != NULL ){ #ifdef VAR_ARGS va_start(args); #else va_start(args, format); #endif vsprintf(str, format, args); va_end(args); gdImageString ( Nlm_currentGIF, Nlm_curGIFFont, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y - Nlm_Ascent(), str, Nlm_curGIFColor ); Nlm_curGIFPoint.x += Nlm_StringWidth (str); } #endif } extern void Nlm_DrawString (Nlm_RectPtr r, Nlm_CharPtr text, Nlm_Char jst, Nlm_Boolean gray) { Nlm_DrawText (r, text, Nlm_StringLen (text), jst, gray); } extern void Nlm_DrawText (Nlm_RectPtr r, Nlm_CharPtr text, size_t len, Nlm_Char jst, Nlm_Boolean gray) { #ifdef WIN_MAC #ifdef WIN_MAC_ATSUI CFStringRef cfString; CFIndex cfsLen; Nlm_RectTool rtool; OSStatus err; ATSUStyle aStyle; TXNTextBoxOptionsData boxOptions; if (r != NULL) { Nlm_EraseRect (r); if (text != NULL && len > 0) { cfString = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)text, len, kCFStringEncodingMacRoman, false); if (cfString == NULL) return; cfsLen = CFStringGetLength(cfString); Local__RecTToRectTool(r, &rtool); boxOptions.optionTags = kTXNSetFlushnessMask; switch (jst) { case 'r': boxOptions.flushness = kATSUEndAlignment; break; case 'l': boxOptions.flushness = kATSUStartAlignment; break; case 'c': boxOptions.flushness = kATSUCenterAlignment; break; default: boxOptions.flushness = kATSUStartAlignment; break; } aStyle = Nlm_FontToATSUStyle(Nlm_fontInUse); #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: is this stuff necessary? // boxOptions.optionTags |= kTXNUseCGContextRefMask; // boxOptions.options = Nlm_PeekQContext(); // CGContextSaveGState(Nlm_PeekQContext()); // /* need to undo the coordinate transforms, otherwise the text comes out upside down. */ // CGContextScaleCTM(Nlm_PeekQContext(), 1.0f, -1.0f); // { // Rect pBounds; // int pHeight; // GrafPtr grafptr; // // GetPort(&grafptr); // GetPortBounds(grafptr, &pBounds); // pHeight = pBounds.bottom - pBounds.top; // CGContextTranslateCTM(Nlm_PeekQContext(), 0, -pHeight); // } #endif err = TXNDrawCFStringTextBox(cfString, &rtool, aStyle, &boxOptions); CFRelease(cfString); //#ifdef WIN_MAC_QUARTZ // CGContextRestoreGState(Nlm_PeekQContext()); //#endif } } #else Nlm_Int2 delta; Nlm_Int2 height; Nlm_Int2 just; Nlm_Int2 limit; PenState pnState; Nlm_RectTool rtool; if (r != NULL) { Nlm_EraseRect (r); if (text != NULL && len > 0) { Local__RecTToRectTool (r, &rtool); limit = ABS (r->bottom - r->top); height = Nlm_LineHeight (); delta = limit - height; if (delta > 0) { rtool.top += delta / 2; rtool.bottom = rtool.top + height; } switch (jst) { case 'r': just = -1; break; case 'l': just = 0; break; case 'c': just = 1; break; default: just = 0; break; } TETextBox (text, len, &rtool, just); if (gray) { GetPenState (&pnState); PenMode (patBic); PenPat ((ConstPatternParam) grayPat); PaintRect (&rtool); SetPenState (&pnState); } } } #endif #endif #ifdef WIN_MSWIN Nlm_Int2 format; Nlm_Int4 oldcolor = 0; Nlm_RectTool rtool; Nlm_FontData fdata; SIZE tsize; HDC hdc; if (r != NULL && Nlm_currentHDC != NULL) { Local__RecTToRectTool (r, &rtool); if (Nlm_currentHWnd != NULL) { Nlm_EraseRect (r); } else { FillRect (Nlm_currentHDC, &rtool, hWhiteBrush); } if (text != NULL && len > 0) { switch (jst) { case 'r': format = DT_RIGHT; break; case 'l': format = DT_LEFT; break; case 'c': format = DT_CENTER; break; default: format = DT_LEFT; break; } if (gray) { winTextColor = GetSysColor (COLOR_GRAYTEXT); oldcolor = SetTextColor (Nlm_currentHDC, winTextColor); } hdc = Nlm_GetPicWinHDC(); if ( hdc == NULL ){ /* esl: DT_VCENTER must be combined with DT_SINGLELINE! */ DrawText (Nlm_currentHDC, text, (Nlm_Int2) len, &rtool, format | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE); } else { if ( Nlm_fontInUse != NULL ){ Nlm_GetFontData (Nlm_fontInUse, &fdata); SelectObject (hdc, fdata.handle); } GetTextExtentPoint ( hdc, text, len, &tsize ); tsize.cy = (r->top + r->bottom)/2 - tsize.cy/2; switch ( format ){ case DT_LEFT: tsize.cx = r->left; break; case DT_RIGHT: tsize.cx = r->right - tsize.cx; break; default: tsize.cx = (r->left + r->right)/2 - tsize.cx/2; } Nlm_PaintStringEx(text, (Nlm_Int2)tsize.cx, (Nlm_Int2)tsize.cy); } if (gray) { SetTextColor (Nlm_currentHDC, oldcolor); winTextColor = oldcolor; } } } #endif #ifdef WIN_X Nlm_Int2 delta; Nlm_Int2 height; Nlm_Int2 limit; Pixmap pix = 0; Nlm_PoinT pt; Nlm_Int2 width; if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { Nlm_EraseRect (r); if (text != NULL && len > 0) { pt.x = r->left; pt.y = r->top; limit = ABS (r->right - r->left); width = Nlm_TextWidth (text, len); while (len > 0 && width > limit) { len--; width = Nlm_TextWidth (text, len); } delta = limit - width; switch (jst) { case 'r': pt.x += delta; break; case 'l': break; case 'c': pt.x += delta / 2; break; default: break; } limit = ABS (r->bottom - r->top); height = Nlm_LineHeight (); delta = limit - height; if (delta > 0) { pt.y += delta / 2; } if (limit >= height) { if (gray) { pix = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow, (char *) grayPat, 8, 8); if (pix != 0 && Nlm_currentXGC != NULL) { XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, pix); } } XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled); XDrawString (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, pt.x - Nlm_XOffset, pt.y + Nlm_Ascent () - Nlm_YOffset, text, (int) len); if (gray && pix != 0) { XFreePixmap (Nlm_currentXDisplay, pix); if (Nlm_currentXGC != NULL) { XSetStipple (Nlm_currentXDisplay, Nlm_currentXGC, currentPixmap); } } XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } } } #endif #ifdef WIN_GIF Nlm_Int2 delta; Nlm_Int2 height; Nlm_Int2 limit; Nlm_PoinT pt; Nlm_Int2 width; if (r != NULL && Nlm_currentGIF != NULL ) { Nlm_EraseRect (r); if (text != NULL && len > 0) { pt.x = r->left; pt.y = r->top; limit = ABS (r->right - r->left); width = Nlm_TextWidth (text, len); while (len > 0 && width > limit) { len--; width = Nlm_TextWidth (text, len); } delta = limit - width; switch (jst) { case 'r': pt.x += delta; break; case 'l': break; case 'c': pt.x += delta / 2; break; default: break; } limit = ABS (r->bottom - r->top); height = Nlm_LineHeight (); delta = limit - height; if (delta > 0) { pt.y += delta / 2; } if (limit >= height) { char save; save = text[len]; text[len] = 0; gdImageString ( Nlm_currentGIF, Nlm_curGIFFont, pt.x, pt.y, text, Nlm_curGIFColor ); text[len] = save; } } } #endif } extern void Nlm_MoveTo (Nlm_Int2 x, Nlm_Int2 y) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGContextMoveToPoint(Nlm_PeekQContext(), x, y); #else MoveTo (x, y); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { MoveToEx (Nlm_currentHDC, x, y, NULL); } #endif #ifdef WIN_X currentPoint.x = x; currentPoint.y = y; #endif #ifdef WIN_GIF Nlm_curGIFPoint.x = x; Nlm_curGIFPoint.y = y; #endif } extern void Nlm_LineTo (Nlm_Int2 x, Nlm_Int2 y) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGContextAddLineToPoint(Nlm_PeekQContext(), x, y); CGContextStrokePath(Nlm_PeekQContext()); CGContextMoveToPoint(Nlm_PeekQContext(), x, y); #else LineTo (x, y); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { LineTo (Nlm_currentHDC, x, y); } #endif #ifdef WIN_X Nlm_PoinT to_point; to_point.x = x; to_point.y = y; Nlm_DrawLine(currentPoint, to_point); #endif #ifdef WIN_GIF if ( Nlm_currentGIF != NULL ){ if ( Nlm_curGIFLType == GIF_DASHED ) { gdImageDashedLine ( Nlm_currentGIF, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y, x, y, Nlm_curGIFColor ); } else { gdImageLine ( Nlm_currentGIF, Nlm_curGIFPoint.x, Nlm_curGIFPoint.y, x, y, Nlm_curGIFColor ); } Nlm_MoveTo ( x,y ); } #endif } extern void Nlm_DrawLine (Nlm_PoinT pt1, Nlm_PoinT pt2) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGContextMoveToPoint(Nlm_PeekQContext(), pt1.x, pt1.y); CGContextAddLineToPoint(Nlm_PeekQContext(), pt2.x, pt2.y); CGContextStrokePath(Nlm_PeekQContext()); #else MoveTo (pt1.x, pt1.y); LineTo (pt2.x, pt2.y); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { if (pt1.x == pt2.x && pt1.y == pt2.y) { SetPixel(Nlm_currentHDC, pt1.x, pt1.y, winTextColor); /* just a dot */ } else { MoveToEx(Nlm_currentHDC, pt1.x, pt1.y, NULL); LineTo (Nlm_currentHDC, pt2.x, pt2.y); } } #endif #ifdef WIN_X if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { XDrawLine(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, pt1.x - Nlm_XOffset, pt1.y - Nlm_YOffset, pt2.x - Nlm_XOffset, pt2.y - Nlm_YOffset); currentPoint.x = pt2.x; currentPoint.y = pt2.y; } #endif #ifdef WIN_GIF if ( Nlm_currentGIF != NULL ){ if ( Nlm_curGIFLType == GIF_DASHED ) { gdImageDashedLine ( Nlm_currentGIF, pt1.x, pt1.y, pt2.x, pt2.y, Nlm_curGIFColor ); } else { gdImageLine ( Nlm_currentGIF, pt1.x, pt1.y, pt2.x, pt2.y, Nlm_curGIFColor ); } Nlm_MoveTo ( pt2.x, pt2.y ); } #endif } #ifdef WIN_GIF static void Nlm_GIFRgnToRect ( Nlm_RgnTool t, Nlm_RectPtr r ) { Nlm_RectPtr rTool; if ( t != NULL && r != NULL ){ rTool = (Nlm_RectPtr)HandLock(t); *r = *rTool; HandUnlock(rTool); } } static void Nlm_RectToGIFRgn ( Nlm_RectPtr r, Nlm_RgnTool t ) { Nlm_RectPtr rTool; if ( t != NULL && r != NULL ){ rTool = (Nlm_RectPtr)HandLock(t); *rTool = *r; HandUnlock(rTool); } } #endif extern void Nlm_LoadPt (Nlm_PointPtr pt, Nlm_Int2 x, Nlm_Int2 y) { if (pt != NULL) { pt->x = x; pt->y = y; } } extern void Nlm_AddPt (Nlm_PoinT src, Nlm_PointPtr dst) { if (dst != NULL) { dst->x += src.x; dst->y += src.y; } } extern void Nlm_SubPt (Nlm_PoinT src, Nlm_PointPtr dst) { if (dst != NULL) { dst->x -= src.x; dst->y -= src.y; } } extern Nlm_Boolean Nlm_EqualPt (Nlm_PoinT p1, Nlm_PoinT p2) { return (Nlm_Boolean) (p1.x == p2.x && p1.y == p2.y); } extern Nlm_Boolean Nlm_PtInRect (Nlm_PoinT pt, Nlm_RectPtr r) { return (Nlm_Boolean) (r != NULL && pt.x >= r->left && pt.x < r->right && pt.y >= r->top && pt.y < r->bottom); } extern Nlm_Boolean Nlm_PtInRgn (Nlm_PoinT pt, Nlm_RegioN rgn) { Nlm_RgnTool ntool; Nlm_Boolean rsult; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGPoint ptool; #else Nlm_PointTool ptool; #endif #endif #ifdef WIN_GIF Nlm_RecT r; #endif rsult = FALSE; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ ptool = Nlm_PoinTToCGPoint (pt); rsult = HIShapeContainsPoint (ntool, &ptool); #else Local__PoinTToPointTool (pt, &ptool); rsult = PtInRgn (ptool, ntool); #endif #endif #ifdef WIN_MSWIN rsult = (Nlm_Boolean) PtInRegion (ntool, pt.x, pt.y); #endif #ifdef WIN_X rsult = (XPointInRegion (ntool, pt.x, pt.y) != 0); #endif #ifdef WIN_GIF Nlm_GIFRgnToRect ( ntool, &r ); rsult = Nlm_PtInRect (pt, &r); #endif } return rsult; } extern void Nlm_LoadRect (Nlm_RectPtr r, Nlm_Int2 lf, Nlm_Int2 tp, Nlm_Int2 rt, Nlm_Int2 bt) { if (r != NULL) { r->left = lf; r->top = tp; r->right = rt; r->bottom = bt; } } extern void Nlm_UpsetRect (Nlm_RectPtr r, Nlm_Int2 lf, Nlm_Int2 tp, Nlm_Int2 rt, Nlm_Int2 bt) { if (r != NULL) { r->left += lf; r->top += tp; r->right -= rt; r->bottom -= bt; } } extern void Nlm_OffsetRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy) { if (r != NULL) { r->left += dx; r->top += dy; r->right += dx; r->bottom += dy; } } extern void Nlm_InsetRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy) { if (r != NULL) { r->left += dx; r->top += dy; r->right -= dx; r->bottom -= dy; } } static void Nlm_LoadNormalized (Nlm_RectPtr dst, Nlm_RectPtr src) { if (!src || !dst) return; Nlm_LoadRect(dst, (Nlm_Int2)MIN(src->left, src->right), (Nlm_Int2)MIN(src->top, src->bottom), (Nlm_Int2)MAX(src->left, src->right), (Nlm_Int2)MAX(src->top, src->bottom)); } extern Nlm_Boolean Nlm_SectRect(Nlm_RectPtr src1, Nlm_RectPtr src2, Nlm_RectPtr dst) { #ifdef WIN_MAC_QUARTZ CGRect r1 = Nlm_RecTToCGRect (*src1); CGRect r2 = Nlm_RecTToCGRect (*src2); CGRect d = CGRectIntersection (r1, r2); *dst = Nlm_CGRectToRecT (d); return !CGRectIsNull (d); #else #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)) Nlm_Boolean rsult; Nlm_RectTool rtool1; Nlm_RectTool rtool2; Nlm_RectTool rtool3; #elif defined(WIN_X) || defined(WIN_GIF) Nlm_RecT rect1; Nlm_RecT rect2; #endif if (!src1 || !src2 || !dst) return FALSE; #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)) Local__RecTToRectTool(src1, &rtool1); Local__RecTToRectTool(src2, &rtool2); #ifdef WIN_MSWIN rsult = (Nlm_Boolean)IntersectRect(&rtool3, &rtool1, &rtool2); #else rsult = SectRect(&rtool1, &rtool2, &rtool3); #endif Local__RectToolToRecT(&rtool3, dst); return rsult; #elif defined(WIN_X) || defined(WIN_GIF) Nlm_LoadNormalized(&rect1, src1); Nlm_LoadNormalized(&rect2, src2); dst->left = MAX(rect1.left, rect2.left ); dst->right = MIN(rect1.right, rect2.right ); dst->top = MAX(rect1.top, rect2.top ); dst->bottom = MIN(rect1.bottom, rect2.bottom); if (dst->left > dst->right || dst->top > dst->bottom) { Nlm_LoadRect(dst, 0, 0, 0, 0); return FALSE; } return TRUE; #endif #endif } extern Nlm_Boolean Nlm_UnionRect(Nlm_RectPtr src1, Nlm_RectPtr src2, Nlm_RectPtr dst) { #ifdef WIN_MAC_QUARTZ CGRect r1 = Nlm_RecTToCGRect (*src1); CGRect r2 = Nlm_RecTToCGRect (*src2); CGRect d = CGRectUnion (r1, r2); *dst = Nlm_CGRectToRecT (d); return CGRectIsEmpty (d); #else #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)) Nlm_Boolean rsult; Nlm_RectTool rtool1; Nlm_RectTool rtool2; Nlm_RectTool rtool3; #elif defined(WIN_X) || defined(WIN_GIF) Nlm_RecT rect1; Nlm_RecT rect2; #endif if (!src1 || !src2 || !dst) return FALSE; #if defined(WIN_MSWIN) || (defined(WIN_MAC) && !defined(WIN_MAC_QUARTZ)) Local__RecTToRectTool(src1, &rtool1); Local__RecTToRectTool(src2, &rtool2); #ifdef WIN_MSWIN rsult = (Nlm_Boolean)UnionRect(&rtool3, &rtool1, &rtool2); #else UnionRect(&rtool1, &rtool2, &rtool3); rsult = EmptyRect(&rtool3); #endif Local__RectToolToRecT(&rtool3, dst); return rsult; #elif defined(WIN_X) || defined(WIN_GIF) Nlm_LoadNormalized (&rect1, src1); Nlm_LoadNormalized (&rect2, src2); dst->left = MIN(rect1.left, rect2.left ); dst->right = MAX(rect1.right, rect2.right ); dst->top = MIN(rect1.top, rect2.top ); dst->bottom = MAX(rect1.bottom, rect2.bottom); return TRUE; #endif #endif } extern Nlm_Boolean Nlm_EqualRect (Nlm_RectPtr r1, Nlm_RectPtr r2) { return (Nlm_Boolean) (r1 != NULL && r2 != NULL && r1->left == r2->left && r1->top == r2->top && r1->right == r2->right && r1->bottom == r2->bottom); } extern Nlm_Boolean Nlm_EmptyRect (Nlm_RectPtr r) { return (Nlm_Boolean) ! (r != NULL && r->bottom > r->top && r->right > r->left); } extern Nlm_Boolean Nlm_RectInRect (Nlm_RectPtr r1, Nlm_RectPtr r2) { Nlm_Boolean rsult; rsult = FALSE; if (r1 != NULL && r2 != NULL && r1->top >= r2->top && r1->bottom <= r2->bottom && r1->left >= r2->left && r1->right <= r2->right) { rsult = TRUE; } return rsult; } extern Nlm_Boolean Nlm_RectInRgn (Nlm_RectPtr r, Nlm_RegioN rgn) { Nlm_RgnTool ntool; Nlm_Boolean rsult; Nlm_RectTool rtool; #ifdef WIN_MAC_QUARTZ CGRect rect; #endif #ifdef WIN_GIF Nlm_RecT rect; #endif rsult = FALSE; if (r != NULL && rgn != NULL) { Local__RecTToRectTool (r, &rtool); ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ rect = Nlm_RecTToCGRect (*r); rsult = HIShapeIntersectsRect (ntool, &rect); #else rsult = RectInRgn (&rtool, ntool); #endif #endif #ifdef WIN_MSWIN rsult = (Nlm_Boolean) RectInRegion (ntool, &rtool); #endif #ifdef WIN_X rsult = (XRectInRegion (ntool, rtool.x, rtool.y, rtool.width+1, rtool.height+1) != 0); #endif #ifdef WIN_GIF Nlm_GIFRgnToRect ( ntool, &rect ); rsult = Nlm_RectInRect (r, &rect) ; #endif } return rsult; } extern void Nlm_EraseRect (Nlm_RectPtr r) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGRect cgr; cgr = Nlm_RecTToCGRect(*r); CGContextSaveGState(Nlm_PeekQContext()); Nlm_White(); CGContextFillRect(Nlm_PeekQContext(), cgr); CGContextRestoreGState(Nlm_PeekQContext()); #else EraseRect (&rtool); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC && Nlm_currentHWnd) { Nlm_Int4 bkColor = GetBkColor (Nlm_currentHDC); HBRUSH hBackBrush = CreateSolidBrush (bkColor); FillRect (Nlm_currentHDC, &rtool, hBackBrush); DeleteObject (hBackBrush); } #endif #ifdef WIN_X if (Nlm_currentXDisplay && Nlm_currentXWindow) { XGCValues values; XGetGCValues(Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values); XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid); XFillRectangle (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width+1, rtool.height+1); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style); XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor); } #endif #ifdef WIN_GIF if ( Nlm_currentGIF ) gdImageFilledRectangle(Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, 0); #endif } extern void Nlm_FrameRect (Nlm_RectPtr r) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGRect rtool; rtool = Nlm_RecTToCGRect(*r); CGContextStrokeRect(Nlm_PeekQContext(), rtool); #else Nlm_RectTool rtool; if (r != NULL) { Local__RecTToRectTool (r, &rtool); if (rtool.right == rtool.left) { rtool.right = rtool.left + 1; } if (rtool.bottom == rtool.top) { rtool.bottom = rtool.top + 1; } FrameRect (&rtool); } #endif #endif #ifdef WIN_MSWIN HBRUSH oldBrush; POINT pos; Nlm_RectTool rtool; if (r != NULL && Nlm_currentHDC != NULL) { oldBrush = SelectObject (Nlm_currentHDC, GetStockObject (NULL_BRUSH)); Local__RecTToRectTool (r, &rtool); if (rtool.right == rtool.left) { rtool.right = rtool.left + 1; } if (rtool.bottom == rtool.top) { rtool.bottom = rtool.top + 1; } if ( (rtool.bottom == (rtool.top+1)) && (rtool.right == (rtool.left+1)) ){ GetCurrentPositionEx (Nlm_currentHDC, &pos); MoveToEx (Nlm_currentHDC, rtool.left, rtool.top, NULL); LineTo (Nlm_currentHDC, rtool.left+1, rtool.top); MoveToEx (Nlm_currentHDC, pos.x, pos.y, NULL); } else { Rectangle (Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1); } if (oldBrush != NULL) { SelectObject (Nlm_currentHDC, oldBrush); } } #endif #ifdef WIN_X Nlm_RectTool rtool; if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { Local__RecTToRectTool (r, &rtool); if ( !rtool.width ) rtool.width++; if ( !rtool.height ) rtool.height++; XDrawRectangle (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height); } #endif #ifdef WIN_GIF Nlm_RectTool rtool; if ( r != NULL && Nlm_currentGIF != NULL ){ Local__RecTToRectTool (r, &rtool); gdImageRectangle (Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, Nlm_curGIFColor ); } #endif } extern void Nlm_PaintRect(Nlm_RectPtr r) { #ifndef WIN_MAC_QUARTZ Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #endif #ifdef WIN_MAC_QUARTZ CGRect cgr; cgr = Nlm_RecTToCGRect(*r); CGContextFillRect(Nlm_PeekQContext(), cgr); #elif defined(WIN_MAC) if (rtool.right == rtool.left) { rtool.right = rtool.left + 1; } if (rtool.bottom == rtool.top) { rtool.bottom = rtool.top + 1; } PaintRect(&rtool); #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN oldPen = SelectObject (Nlm_currentHDC, GetStockObject (NULL_PEN)); Rectangle(Nlm_currentHDC, rtool.left, rtool.top, rtool.right+2, rtool.bottom+2); if ( oldPen ) SelectObject(Nlm_currentHDC, oldPen); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XFillRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width + 1, rtool.height + 1); } #elif defined(WIN_GIF) if ( Nlm_currentGIF ) { gdImageFilledRectangle(Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, Nlm_curGIFColor); } #endif } extern void Nlm_InvertRect (Nlm_RectPtr r) { #ifndef WIN_GIF Nlm_RectTool rtool; #endif if (r == NULL) return; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ /* ASSERT(false); */ /* Can't invert rectangles in Quartz */ #else Local__RecTToRectTool (r, &rtool); InvertRect (&rtool); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC == NULL) return; Local__RecTToRectTool (r, &rtool); InvertRect (Nlm_currentHDC, &rtool); #endif #ifdef WIN_X if (Nlm_currentXDisplay == NULL || Nlm_currentXWindow == 0 || Nlm_currentXGC == NULL) return; Local__RecTToRectTool (r, &rtool); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled); XFillRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width + 1, rtool.height + 1); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); #endif } extern void Nlm_ScrollRect (Nlm_RectPtr r, Nlm_Int2 dx, Nlm_Int2 dy) { #ifdef WIN_MAC Nlm_RectTool rtool; if (r != NULL) { Local__RecTToRectTool (r, &rtool); #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: might want to do a little more than this HIViewSetNeedsDisplay (HIViewGetRoot (Nlm_QWindow), 1); #else ScrollRect (&rtool, dx, dy, (Nlm_RgnTool) Nlm_scrollRgn); InvalRgn ((Nlm_RgnTool) Nlm_scrollRgn); #endif } #endif #ifdef WIN_MSWIN Nlm_RectTool rtool; if (r != NULL && Nlm_currentHDC != NULL) { SetRectRgn ((Nlm_RgnTool) Nlm_scrollRgn, 0, 0, 0, 0); Local__RecTToRectTool (r, &rtool); ScrollDC (Nlm_currentHDC, dx, dy, &rtool, &rtool, (Nlm_RgnTool) Nlm_scrollRgn, NULL); if (Nlm_currentHWnd != NULL && Nlm_scrollRgn != NULL) { FillRgn (Nlm_currentHDC, (Nlm_RgnTool) Nlm_scrollRgn, GetBackgroundBrush (Nlm_currentHWnd)); } InvalidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) Nlm_scrollRgn, TRUE); } #endif #ifdef WIN_X XEvent event; unsigned int height; Nlm_RecT rct; Nlm_RectTool rtool; unsigned int width; unsigned int dstX; unsigned int dstY; unsigned int srcX; unsigned int srcY; if (r != NULL) { if (ABS (dy) >= ABS (r->bottom - r->top) || ABS (dx) >= ABS (r->right - r->left)) { Nlm_InvalRect (r); return; } } if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL && Nlm_currentXWindow != 0) { height = ABS (r->bottom - r->top) - ABS (dy); width = ABS (r->right - r->left) - ABS (dx); if (dx > 0) { srcX = r->left - Nlm_XOffset; dstX = r->left - Nlm_XOffset + dx; } else if (dx < 0) { srcX = r->left - Nlm_XOffset - dx; dstX = r->left - Nlm_XOffset; } else { srcX = r->left - Nlm_XOffset; dstX = r->left - Nlm_XOffset; } if (dy > 0) { srcY = r->top - Nlm_YOffset; dstY = r->top - Nlm_YOffset + dy; } else if (dy < 0) { srcY = r->top - Nlm_YOffset - dy; dstY = r->top - Nlm_YOffset; } else { srcY = r->top - Nlm_YOffset; dstY = r->top - Nlm_YOffset; } if (Nlm_hasColor) { XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor); } XCopyArea (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXWindow, Nlm_currentXGC, srcX, srcY, width, height, dstX, dstY); XSync (Nlm_currentXDisplay, FALSE); if (! XCheckTypedWindowEvent (Nlm_currentXDisplay, Nlm_currentXWindow, NoExpose, &event)) { while (XCheckTypedWindowEvent (Nlm_currentXDisplay, Nlm_currentXWindow, GraphicsExpose, &event)) { XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, event.xgraphicsexpose.x, event.xgraphicsexpose.y, event.xgraphicsexpose.width, event.xgraphicsexpose.height, TRUE); } } if (dx > 0) { rct = *r; rct.right = rct.left + dx; Local__RecTToRectTool (&rct, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, TRUE); } else if (dx < 0) { rct = *r; rct.left = rct.right + dx; Local__RecTToRectTool (&rct, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, TRUE); } if (dy > 0) { rct = *r; rct.bottom = rct.top + dy; Local__RecTToRectTool (&rct, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, TRUE); } else if (dy < 0) { rct = *r; rct.top = rct.bottom + dy; Local__RecTToRectTool (&rct, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, TRUE); } if (Nlm_hasColor) { XSetForeground (Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor); } } #endif #ifdef WIN_GIF #endif } #ifdef WIN_MAC_QUARTZ static void Nlm_addOvalToPath(CGContextRef context, CGRect r) { CGAffineTransform matrix; CGContextSaveGState(context); matrix = CGAffineTransformMake((r.size.width)/2, 0, 0, (r.size.height)/2, r.origin.x + (r.size.width)/2, r.origin.y + (r.size.height)/2); CGContextConcatCTM(context, matrix); CGContextBeginPath(context); CGContextAddArc(context, 0, 0, 1, 0, 2*pi, true); CGContextRestoreGState(context); } #endif extern void Nlm_EraseOval (Nlm_RectPtr r) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); Nlm_addOvalToPath(Nlm_PeekQContext(), cgr); } CGContextSaveGState(Nlm_PeekQContext()); Nlm_White(); CGContextFillPath(Nlm_PeekQContext()); CGContextRestoreGState(Nlm_PeekQContext()); #else EraseOval(&rtool); #endif #elif defined(WIN_MSWIN) if (Nlm_currentHDC && Nlm_currentHWnd) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetBackgroundBrush(Nlm_currentHWnd)); Ellipse(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow) { XGCValues values; XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid); XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, 0, 23040); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor); } #elif defined(WIN_GIF) gdImageEllipse(Nlm_currentGIF, (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2, (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2, 0, TRUE); #endif } extern void Nlm_FrameOval(Nlm_RectPtr r) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); Nlm_addOvalToPath(Nlm_PeekQContext(), cgr); } CGContextStrokePath(Nlm_PeekQContext()); #else FrameOval(&rtool); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH)); Ellipse(Nlm_currentHDC, rtool.left, rtool.top, rtool.right, rtool.bottom); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if ( Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XDrawArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width - 1, rtool.height - 1, 0, 23040); } #elif defined(WIN_GIF) gdImageEllipse(Nlm_currentGIF, (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2, (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2, Nlm_curGIFColor, FALSE); #endif } extern void Nlm_PaintOval(Nlm_RectPtr r) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); Nlm_addOvalToPath(Nlm_PeekQContext(), cgr); } CGContextFillPath(Nlm_PeekQContext()); #else PaintOval(&rtool); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); Ellipse(Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, 0, 23040); } #elif defined(WIN_GIF) gdImageEllipse(Nlm_currentGIF, (rtool.left + rtool.right) /2, (rtool.top + rtool.bottom) /2, (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2, Nlm_curGIFColor, TRUE); #endif } extern void Nlm_InvertOval(Nlm_RectPtr r) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) #ifdef WIN_MAC_QUARTZ /* QUART_FIXME: can't invert, what to do? */ Nlm_PaintOval (r); #else InvertOval (&rtool); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN )); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH)); int xMode = GetROP2(Nlm_currentHDC); SetROP2(Nlm_currentHDC, R2_NOTXORPEN); Ellipse(Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); SetROP2(Nlm_currentHDC, xMode); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert); XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillStippled); XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, 0, 23040); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #elif defined(WIN_GIF) #endif } static void s_AdjustRoundRect(const Nlm_RecT* r, Nlm_Int2 *w, Nlm_Int2 *h) { Nlm_Int2 w2, h2; w2 = r->right - r->left; w2 = ABS(w2) / 2; if (*w > w2) *w = w2; h2 = r->bottom - r->top; h2 = ABS(h2) / 2; if (*h > h2) *h = h2; } #ifdef WIN_MAC_QUARTZ static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, ovalWidth, ovalHeight); fw = CGRectGetWidth (rect) / ovalWidth; fh = CGRectGetHeight (rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh/2); CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); CGContextClosePath(context); CGContextRestoreGState(context); } #endif extern void Nlm_EraseRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); s_AdjustRoundRect(r, &ovlWid, &ovlHgt); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt); } CGContextSaveGState(Nlm_PeekQContext()); Nlm_White(); CGContextFillPath(Nlm_PeekQContext()); CGContextRestoreGState(Nlm_PeekQContext()); #else EraseRoundRect(&rtool, ovlWid, ovlHgt); #endif #elif defined(WIN_MSWIN) if (Nlm_currentHDC && Nlm_currentHWnd) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetBackgroundBrush(Nlm_currentHWnd)); RoundRect(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XGCValues values; XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid); XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width+1, rtool.height+1, ovlWid, ovlHgt); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor); } #elif defined(WIN_GIF) if ( Nlm_currentGIF ) { gdImageRoundRectangle(Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, ovlWid, ovlHgt, 0, TRUE); } #endif } extern void Nlm_FrameRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); s_AdjustRoundRect(r, &ovlWid, &ovlHgt); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt); } CGContextStrokePath(Nlm_PeekQContext()); #else FrameRoundRect(&rtool, ovlWid, ovlHgt); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH)); RoundRect(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 1, rtool.bottom + 1, ovlWid, ovlHgt); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XmuDrawRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, ovlWid, ovlHgt); } #elif defined(WIN_GIF) if ( Nlm_currentGIF ) { gdImageRoundRectangle(Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, ovlWid, ovlHgt, Nlm_curGIFColor, FALSE); } #endif } extern void Nlm_PaintRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); s_AdjustRoundRect(r, &ovlWid, &ovlHgt); #if defined(WIN_MAC) #if defined(WIN_MAC_QUARTZ) { CGRect cgr; cgr = Nlm_RecTToCGRect(*r); addRoundedRectToPath(Nlm_PeekQContext(), cgr, ovlWid, ovlHgt); } CGContextFillPath(Nlm_PeekQContext()); #else PaintRoundRect(&rtool, ovlWid, ovlHgt); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); RoundRect(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width+1, rtool.height+1, ovlWid, ovlHgt); } #elif defined(WIN_GIF) if ( Nlm_currentGIF ) { gdImageRoundRectangle(Nlm_currentGIF, rtool.left, rtool.top, rtool.right, rtool.bottom, ovlWid, ovlHgt, Nlm_curGIFColor, TRUE); } #endif } extern void Nlm_InvertRoundRect(Nlm_RectPtr r, Nlm_Int2 ovlWid, Nlm_Int2 ovlHgt) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); s_AdjustRoundRect(r, &ovlWid, &ovlHgt); #if defined(WIN_MAC) #ifdef WIN_MAC_QUARTZ /* QUARTZ_FIXME: can't invert, what to do? */ Nlm_PaintRoundRect (r, ovlWid, ovlHgt); #else InvertRoundRect (&rtool, ovlWid, ovlHgt); #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN )); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH)); int xMode = GetROP2(Nlm_currentHDC); SetROP2(Nlm_currentHDC, R2_NOTXORPEN); RoundRect(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, ovlWid, ovlHgt); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); SetROP2(Nlm_currentHDC, xMode); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillStippled); XmuFillRoundedRectangle(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width+1, rtool.height+1, ovlWid, ovlHgt); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #elif defined(WIN_GIF) #endif } #ifdef WIN_X static int Nlm_PtToAngle (Nlm_RectPtr r, Nlm_PoinT pt) { int rsult; double val; double x; double y; x = pt.x - (r->right + r->left) / 2; y = (r->bottom + r->top) / 2 - pt.y; if (x == 0) { rsult = 5760; } else if (y == 0) { rsult = 0; } else { val = atan2 (ABS (y), ABS (x)); rsult = (int)(val * 11520.0 / 3.14159); } if (x < 0) { if (y < 0) { rsult = 11520 + rsult; } else { rsult = 11520 - rsult; } } else if (y < 0) { rsult = 23040 - rsult; } return rsult; } #endif #ifdef WIN_MAC_QUARTZ /* static void pathForArc (CGContextRef context, CGRect r, int startAngle, int arcAngle) { float start, end; CGAffineTransform matrix; CGContextSaveGState(context); matrix = CGAffineTransformMake(r.size.width/2, 0, 0, r.size.height/2, r.origin.x + r.size.width/2, r.origin.y + r.size.height/2); CGContextConcatCTM(context, matrix); if (arcAngle > 0) { start = (90 - startAngle - arcAngle) * M_PI / 180; end = (90 - startAngle) * M_PI / 180; } else { start = (90 - startAngle) * M_PI / 180; end = (90 - startAngle - arcAngle) * M_PI / 180; } CGContextAddArc (context, 0, 0, 1, start, end, false); CGContextRestoreGState(context); } */ static void pathForArc (CGContextRef context, CGRect r, CGPoint startPt, CGPoint endPt) { float start, end; CGAffineTransform matrix, invMatrix; CGContextSaveGState(context); matrix = CGAffineTransformMake(r.size.width/2, 0, 0, r.size.height/2, r.origin.x + r.size.width/2, r.origin.y + r.size.height/2); CGContextConcatCTM(context, matrix); invMatrix = CGAffineTransformInvert(matrix); startPt = CGPointApplyAffineTransform(startPt, invMatrix); endPt = CGPointApplyAffineTransform(endPt, invMatrix); start = atan2(startPt.y, startPt.x); end = atan2( endPt.y, endPt.x); CGContextAddArc (context, 0, 0, 1, start, end, 0); CGContextRestoreGState(context); } #endif extern void Nlm_EraseArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) {{ #if defined(WIN_MAC_QUARTZ) CGRect cgr; CGPoint startPt; CGPoint endPt; cgr = Nlm_RecTToCGRect(*r); startPt = Nlm_PoinTToCGPoint(start); endPt = Nlm_PoinTToCGPoint(end); Nlm_MoveTo((r->right + r->left)/2, (r->top + r->bottom)/2); pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt); CGContextSaveGState(Nlm_PeekQContext()); Nlm_White(); CGContextFillPath(Nlm_PeekQContext()); CGContextRestoreGState(Nlm_PeekQContext()); #else Nlm_Int2 angle1; Nlm_Int2 angle2; Nlm_Int2 arcAngle; Nlm_PointTool ptool1; Nlm_PointTool ptool2; Nlm_RectTool rtool; Local__RecTToRectTool(r, &rtool); Local__PoinTToPointTool(start, &ptool1); Local__PoinTToPointTool( end, &ptool2); PtToAngle(&rtool, ptool1, &angle1); PtToAngle(&rtool, ptool2, &angle2); if (angle2 > angle1) arcAngle = angle2 - angle1; else arcAngle = 360 - angle1 + angle2; EraseArc(&rtool, angle1, arcAngle); #endif }} #elif defined(WIN_MSWIN) if (Nlm_currentHDC && Nlm_currentHWnd) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetBackgroundBrush(Nlm_currentHWnd)); Pie(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, end.x, end.y, start.x, start.y); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow) { XGCValues values; int angle1 = Nlm_PtToAngle(r, start); int angle2 = Nlm_PtToAngle(r, end); int arcAngle; if (angle1 > angle2) arcAngle = angle1 - angle2; else arcAngle = 23040 - angle2 + angle1; XGetGCValues (Nlm_currentXDisplay, Nlm_currentXGC, GCFillStyle, &values); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentBkColor); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, FillSolid); XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, angle1, -arcAngle); XSetFillStyle (Nlm_currentXDisplay, Nlm_currentXGC, values.fill_style); XSetForeground(Nlm_currentXDisplay, Nlm_currentXGC, currentFgColor); } #elif defined(WIN_GIF) #endif } extern void Nlm_FrameArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) {{ #if defined(WIN_MAC_QUARTZ) CGRect cgr; CGPoint startPt; CGPoint endPt; cgr = Nlm_RecTToCGRect(*r); startPt = Nlm_PoinTToCGPoint(start); endPt = Nlm_PoinTToCGPoint(end); pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt); CGContextStrokePath(Nlm_PeekQContext()); #else Nlm_Int2 angle1; Nlm_Int2 angle2; Nlm_Int2 arcAngle; Nlm_PointTool ptool1; Nlm_PointTool ptool2; Local__PoinTToPointTool(start, &ptool1); Local__PoinTToPointTool( end, &ptool2); PtToAngle(&rtool, ptool1, &angle1); PtToAngle(&rtool, ptool2, &angle2); if (angle2 > angle1) { arcAngle = angle2 - angle1; } else { arcAngle = 360 - angle1 + angle2; } FrameArc (&rtool, angle1, arcAngle); #endif }} #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(NULL_BRUSH)); Arc(Nlm_currentHDC, rtool.left, rtool.top, rtool.right+1, rtool.bottom+1, end.x, end.y, start.x, start.y); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { int angle1 = Nlm_PtToAngle(r, start); int angle2 = Nlm_PtToAngle(r, end); int arcAngle = angle1 > angle2 ? angle1 - angle2 : 23040 - angle2 + angle1; XDrawArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width - 1, rtool.height - 1, angle1, -arcAngle); } #elif defined(WIN_GIF) {{ int cx = (rtool.left + rtool.right) / 2; int cy = (rtool.top + rtool.bottom) / 2; double s_angle = atan2(start.x - cx, start.y - cy); double e_angle = atan2(end.x - cx, end.y - cy); gdImageArcEx(Nlm_currentGIF, cx, cy, (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2, s_angle, e_angle, Nlm_curGIFColor, FALSE); }} #endif } extern void Nlm_PaintArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) {{ #if defined(WIN_MAC_QUARTZ) CGRect cgr; CGPoint startPt; CGPoint endPt; cgr = Nlm_RecTToCGRect(*r); startPt = Nlm_PoinTToCGPoint(start); endPt = Nlm_PoinTToCGPoint(end); Nlm_MoveTo((r->right + r->left)/2, (r->top + r->bottom)/2); pathForArc (Nlm_PeekQContext(), cgr, startPt, endPt); CGContextFillPath(Nlm_PeekQContext()); #else Nlm_Int2 angle1; Nlm_Int2 angle2; Nlm_Int2 arcAngle; Nlm_PointTool ptool1; Nlm_PointTool ptool2; Local__PoinTToPointTool(start, &ptool1); Local__PoinTToPointTool(end, &ptool2); PtToAngle(&rtool, ptool1, &angle1); PtToAngle(&rtool, ptool2, &angle2); if (angle2 > angle1) arcAngle = angle2 - angle1; else arcAngle = 360 - angle1 + angle2; PaintArc(&rtool, angle1, arcAngle); #endif }} #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(NULL_PEN)); Pie(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, end.x, end.y, start.x, start.y); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { int angle1 = Nlm_PtToAngle(r, start); int angle2 = Nlm_PtToAngle(r, end); int arcAngle; if (angle1 > angle2) arcAngle = angle1 - angle2; else arcAngle = 23040 - angle2 + angle1; XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, angle1, -arcAngle); } #elif defined(WIN_GIF) {{ int cx = (rtool.left + rtool.right) / 2; int cy = (rtool.top + rtool.bottom) / 2; double s_angle = atan2(start.x - cx, start.y - cy); double e_angle = atan2(end.x - cx, end.y - cy); gdImageArcEx(Nlm_currentGIF, cx, cy, (rtool.right - rtool.left) /2, (rtool.bottom - rtool.top) /2, s_angle, e_angle, Nlm_curGIFColor, TRUE); }} #endif } extern void Nlm_InvertArc(Nlm_RectPtr r, Nlm_PoinT start, Nlm_PoinT end) { Nlm_RectTool rtool; if ( !r ) return; Local__RecTToRectTool(r, &rtool); #if defined(WIN_MAC) #ifdef WIN_MAC_QUARTZ /* QUARTZ_FIXME: can't invert, what to do? */ Nlm_PaintArc (r, start, end); #else {{ Nlm_Int2 angle1; Nlm_Int2 angle2; Nlm_Int2 arcAngle; Nlm_PointTool ptool1; Nlm_PointTool ptool2; Nlm_RectTool rtool; Local__RecTToRectTool(r, &rtool); Local__PoinTToPointTool(start, &ptool1); Local__PoinTToPointTool(end, &ptool2); PtToAngle(&rtool, ptool1, &angle1); PtToAngle(&rtool, ptool2, &angle2); if (angle2 > angle1) arcAngle = angle2 - angle1; else arcAngle = 360 - angle1 + angle2; InvertArc(&rtool, angle1, arcAngle); }} #endif #elif defined(WIN_MSWIN) if ( Nlm_currentHDC ) { HPEN xPen = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_PEN )); HBRUSH xBrush = SelectObject(Nlm_currentHDC, GetStockObject(BLACK_BRUSH)); int xMode = GetROP2(Nlm_currentHDC); SetROP2(Nlm_currentHDC, R2_NOTXORPEN); Pie(Nlm_currentHDC, rtool.left, rtool.top, rtool.right + 2, rtool.bottom + 2, end.x, end.y, start.x, start.y); if ( xPen ) SelectObject(Nlm_currentHDC, xPen); if ( xBrush ) SelectObject(Nlm_currentHDC, xBrush); SetROP2(Nlm_currentHDC, xMode); } #elif defined(WIN_X) if (Nlm_currentXDisplay && Nlm_currentXWindow && Nlm_currentXGC) { int angle1 = Nlm_PtToAngle(r, start); int angle2 = Nlm_PtToAngle(r, end); int arcAngle; if (angle1 > angle2) arcAngle = angle1 - angle2; else arcAngle = 23040 - angle2 + angle1; XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXinvert); XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, FillStippled); XFillArc(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, angle1, -arcAngle); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, currentFunction); XSetFillStyle(Nlm_currentXDisplay, Nlm_currentXGC, currentFillStyle); } #elif defined(WIN_GIF) #endif } typedef enum { eDM_Erase = 0, eDM_Frame, eDM_Paint, eDM_Invert } EDrawMethod; /********************************* * QUADRANT */ static void s_DoQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant, EDrawMethod method) { Nlm_RecT rr; Nlm_Int2 rx, ry; Nlm_LoadNormalized(&rr, r); rx = rr.right - rr.left; ry = rr.bottom - rr.top; #ifdef WIN_GIF {{ int cx = 0, cy = 0; switch ( quadrant ) { case eQ_RightTop: cx = rr.left; cy = rr.bottom; break; case eQ_LeftTop: cx = rr.right; cy = rr.bottom; break; case eQ_LeftBottom: cx = rr.right; cy = rr.top; break; case eQ_RightBottom: cx = rr.left; cy = rr.top; break; } gdImageQuadrant(Nlm_currentGIF, cx, cy, rx, ry, (method == eDM_Erase) ? 0 : Nlm_curGIFColor, (method != eDM_Frame), (int)quadrant); }} #else {{ Nlm_PoinT start, stop; switch ( quadrant ) { case eQ_RightTop: start.x = rr.left; start.y = rr.top; stop.x = rr.right; stop.y = rr.bottom; rr.left -= rx; rr.bottom += ry; break; case eQ_LeftTop: start.x = rr.left; start.y = rr.bottom; stop.x = rr.right; stop.y = rr.top; rr.right += rx; rr.bottom += ry; break; case eQ_LeftBottom: start.x = rr.right; start.y = rr.bottom; stop.x = rr.left; stop.y = rr.top; rr.right += rx; rr.top -= ry; break; case eQ_RightBottom: start.x = rr.right; start.y = rr.top; stop.x = rr.left; stop.y = rr.bottom; rr.left -= rx; rr.top -= ry; break; } switch ( method ) { case eDM_Erase: Nlm_EraseArc(&rr, start, stop); break; case eDM_Frame: Nlm_FrameArc(&rr, start, stop); break; case eDM_Paint: Nlm_PaintArc(&rr, start, stop); break; case eDM_Invert: Nlm_InvertArc(&rr, start, stop); break; } }} #endif } void Nlm_EraseQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) { s_DoQuadrant(r, quadrant, eDM_Erase); } void Nlm_FrameQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) { s_DoQuadrant(r, quadrant, eDM_Frame); } void Nlm_PaintQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) { s_DoQuadrant(r, quadrant, eDM_Paint); } void Nlm_InvertQuadrant(Nlm_RectPtr r, Nlm_EQuadrant quadrant) { s_DoQuadrant(r, quadrant, eDM_Invert); } /********************************* * POLYGON */ #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ static void Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts) { Nlm_PoinT firstPt; Nlm_Int2 i; Nlm_PoinT pt; if (pts != NULL && num > 0) { firstPt = pts [0]; CGContextMoveToPoint(Nlm_PeekQContext(), (float) firstPt.x, (float) firstPt.y); for (i = 1; i < num; i++) { pt = pts [i]; CGContextAddLineToPoint(Nlm_PeekQContext(), (float) pt.x, (float) pt.y); } if (! Nlm_EqualPt (pt, firstPt)) { CGContextClosePath(Nlm_PeekQContext()); } } } #else static PolyHandle Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts) { Nlm_PoinT firstPt; Nlm_Int2 i; Nlm_PoinT pt; PolyHandle rsult; rsult = NULL; if (pts != NULL && num > 0) { rsult = OpenPoly (); firstPt = pts [0]; MoveTo (firstPt.x, firstPt.y); for (i = 1; i < num; i++) { pt = pts [i]; LineTo (pt.x, pt.y); } if (! Nlm_EqualPt (pt, firstPt)) { LineTo (firstPt.x, firstPt.y); } ClosePoly (); } return rsult; } static void Nlm_DestroyPoly (PolyHandle ply) { if (ply != NULL) { KillPoly (ply); } } #endif #endif #ifdef WIN_MSWIN static LPPOINT Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts) { Nlm_PoinT firstPt; Nlm_Int2 i; Nlm_PoinT pt; Nlm_PointTool ptool; LPPOINT rsult; rsult = NULL; if (pts != NULL && num > 0) { rsult = (LPPOINT) Nlm_MemNew ((size_t) ((num + 1) * sizeof (POINT))); if (rsult != NULL) { firstPt = pts [0]; for (i = 0; i < num; i++) { pt = pts [i]; Local__PoinTToPointTool (pt, &ptool); rsult [i] = ptool; } if (! Nlm_EqualPt (pt, firstPt)) { Local__PoinTToPointTool (firstPt, &ptool); rsult [i] = ptool; } } } return rsult; } static void Nlm_DestroyPoly (LPPOINT ply) { if (ply != NULL) { Nlm_MemFree (ply); } } #endif #ifdef WIN_X static XPoint *Nlm_CreatePoly (Nlm_Int2 num, Nlm_PointPtr pts) { Nlm_PoinT firstPt; Nlm_Int2 i; Nlm_PoinT pt; Nlm_PointTool ptool; XPoint *rsult; rsult = NULL; if (pts != NULL && num > 0) { rsult = (XPoint *) Nlm_MemNew ((size_t) ((num + 1) * sizeof (XPoint))); if (rsult != NULL) { firstPt = pts [0]; firstPt.x -= Nlm_XOffset; firstPt.y -= Nlm_YOffset; for (i = 0; i < num; i++) { pt = pts [i]; pt.x -= Nlm_XOffset; pt.y -= Nlm_YOffset; Local__PoinTToPointTool (pt, &ptool); rsult [i] = ptool; } if (! Nlm_EqualPt (pt, firstPt)) { Local__PoinTToPointTool (firstPt, &ptool); rsult [i] = ptool; } } } return rsult; } static void Nlm_DestroyPoly (XPoint *ply) { if (ply != NULL) { Nlm_MemFree (ply); } } #endif extern void Nlm_ErasePoly (Nlm_Int2 num, Nlm_PointPtr pts) { if (pts != NULL && num > 1) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_CreatePoly (num, pts); CGContextSaveGState(Nlm_PeekQContext()); Nlm_White(); CGContextEOFillPath(Nlm_PeekQContext()); CGContextRestoreGState(Nlm_PeekQContext()); #else PolyHandle ply; ply = Nlm_CreatePoly (num, pts); if (ply != NULL) { ErasePoly (ply); } Nlm_DestroyPoly (ply); #endif #endif #ifdef WIN_MSWIN #endif #ifdef WIN_X #endif #ifdef WIN_GIF #endif } } extern void Nlm_FramePoly(Nlm_Int2 num, Nlm_PointPtr pts) { if (pts != NULL && num > 1) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_CreatePoly (num, pts); CGContextStrokePath(Nlm_PeekQContext()); #else PolyHandle ply; ply = Nlm_CreatePoly (num, pts); if (ply != NULL) { FramePoly (ply); } Nlm_DestroyPoly (ply); #endif #endif #ifdef WIN_MSWIN LPPOINT ply; ply = Nlm_CreatePoly (num, pts); if (Nlm_currentHDC != NULL && ply != NULL) { if (! Nlm_EqualPt (pts [0], pts [num - 1])) { num++; } Polyline (Nlm_currentHDC, ply, num); } Nlm_DestroyPoly (ply); #endif #ifdef WIN_X XPoint *ply; ply = Nlm_CreatePoly (num, pts); if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL && ply != NULL) { if (! Nlm_EqualPt (pts [0], pts [num - 1])) { num++; } XDrawLines (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, ply, num, CoordModeOrigin); } Nlm_DestroyPoly (ply); #endif #ifdef WIN_GIF gdPointPtr pPtr; int i; if (Nlm_currentGIF != NULL && pts != NULL) { pPtr = (gdPointPtr)Nlm_MemNew(num * sizeof(gdPoint)); for ( i=0; i 1) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ Nlm_CreatePoly (num, pts); CGContextEOFillPath(Nlm_PeekQContext()); #else PolyHandle ply; ply = Nlm_CreatePoly (num, pts); if (ply != NULL) { PaintPoly (ply); } Nlm_DestroyPoly (ply); #endif #endif #ifdef WIN_MSWIN LPPOINT ply; ply = Nlm_CreatePoly (num, pts); if (Nlm_currentHDC != NULL && ply != NULL) { if (! Nlm_EqualPt (pts [0], pts [num - 1])) { num++; } SetPolyFillMode (Nlm_currentHDC, ALTERNATE); Polygon (Nlm_currentHDC, ply, num); } Nlm_DestroyPoly (ply); #endif #ifdef WIN_X XPoint *ply = Nlm_CreatePoly (num, pts); if (Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL && ply != NULL) { int i; short left=32767, top=32767; for (i = 0; i < num; i++) { if (ply[i].x < left) left = ply[i].x; if (ply[i].y < top) top = ply[i].y; } for (i = 0; i < num; i++) { if (ply[i].x != left) ply[i].x++; if (ply[i].y != top) ply[i].y++; } XSetFillRule (Nlm_currentXDisplay, Nlm_currentXGC, EvenOddRule); XFillPolygon (Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, ply, num, Complex, CoordModeOrigin); } Nlm_DestroyPoly (ply); #endif #ifdef WIN_GIF gdPointPtr pPtr; int i; if (Nlm_currentGIF != NULL && pts != NULL) { pPtr = (gdPointPtr)Nlm_MemNew(num * sizeof(gdPoint)); for ( i=0; i 1) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ #else PolyHandle ply; ply = Nlm_CreatePoly (num, pts); if (ply != NULL) { InvertPoly (ply); } Nlm_DestroyPoly (ply); #endif #endif #ifdef WIN_MSWIN #endif #ifdef WIN_X #endif #ifdef WIN_GIF #endif } } extern Nlm_RegioN Nlm_CreateRgn (void) { Nlm_RgnTool ntool; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ ntool = HIShapeCreateMutable(); #else ntool = NewRgn (); #endif #endif #ifdef WIN_MSWIN ntool = CreateRectRgn (0, 0, 0, 0); #endif #ifdef WIN_X ntool = XCreateRegion (); #endif #ifdef WIN_GIF ntool = HandNew ( sizeof(Nlm_RecT) ); #endif return (Nlm_RegioN) ntool; } extern Nlm_RegioN Nlm_DestroyRgn (Nlm_RegioN rgn) { Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CFRelease (ntool); #else DisposeRgn (ntool); #endif #endif #ifdef WIN_MSWIN DeleteObject (ntool); #endif #ifdef WIN_X XDestroyRegion (ntool); #endif #ifdef WIN_GIF HandFree ( ntool ); #endif } return NULL; } extern void Nlm_ClearRgn (Nlm_RegioN rgn) { Nlm_RgnTool ntool; #ifdef WIN_MSWIN Nlm_RgnTool temp; #endif if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeSetEmpty (ntool); #else SetEmptyRgn (ntool); #endif #endif #ifdef WIN_MSWIN temp = CreateRectRgn (0, 0, 0, 0); CombineRgn (ntool, temp, temp, RGN_COPY); DeleteObject (temp); #endif #ifdef WIN_X XUnionRegion (emptyRgn, emptyRgn, ntool); #endif } } extern void Nlm_LoadRectRgn (Nlm_RegioN rgn, Nlm_Int2 lf, Nlm_Int2 tp, Nlm_Int2 rt, Nlm_Int2 bt) { Nlm_RgnTool ntool; #ifdef WIN_X Nlm_RecT rct; Nlm_RectTool rtool; #endif #ifdef WIN_GIF Nlm_RecT rct; #endif if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeSetEmpty (ntool); CGRect r = CGRectMake (lf, tp, rt - lf, bt - tp); HIShapeRef tempShape = HIShapeCreateWithRect (&r); HIShapeUnion (tempShape, ntool, ntool); CFRelease (tempShape); #else SetRectRgn (ntool, lf, tp, rt, bt); #endif #endif #ifdef WIN_MSWIN SetRectRgn (ntool, lf, tp, rt, bt); #endif #ifdef WIN_X Nlm_LoadRect (&rct, lf, tp, rt, bt); Local__RecTToRectTool (&rct, &rtool); XUnionRectWithRegion (&rtool, emptyRgn, ntool); #endif #ifdef WIN_GIF Nlm_LoadRect (&rct, lf, tp, rt, bt); Nlm_RectToGIFRgn ( &rct, ntool ); #endif } } extern void Nlm_OffsetRgn (Nlm_RegioN rgn, Nlm_Int2 dx, Nlm_Int2 dy) { Nlm_RgnTool ntool; #ifdef WIN_GIF Nlm_RecT rTool; #endif if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeOffset (ntool, dx, dy); #else OffsetRgn (ntool, dx, dy); #endif #endif #ifdef WIN_MSWIN OffsetRgn (ntool, dx, dy); #endif #ifdef WIN_X XOffsetRegion (ntool, dx, dy); #endif #ifdef WIN_GIF Nlm_GIFRgnToRect ( ntool, &rTool ); Nlm_OffsetRect ( &rTool, dx, dy ); Nlm_RectToGIFRgn ( &rTool, ntool ); #endif } } extern void Nlm_SectRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst) { Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_RgnTool ntool3; #ifdef WIN_X Nlm_RgnTool temp; #endif #ifdef WIN_GIF Nlm_RecT rsrc1; Nlm_RecT rsrc2; Nlm_RecT rdst; #endif if (src1 != NULL && src2 != NULL && dst != NULL) { ntool1 = (Nlm_RgnTool) src1; ntool2 = (Nlm_RgnTool) src2; ntool3 = (Nlm_RgnTool) dst; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeIntersect (ntool1, ntool2, ntool3); #else SectRgn (ntool1, ntool2, ntool3); #endif #endif #ifdef WIN_MSWIN CombineRgn (ntool3, ntool1, ntool2, RGN_AND); #endif #ifdef WIN_X temp = XCreateRegion (); XIntersectRegion (ntool1, ntool2, temp); XUnionRegion (temp, emptyRgn, ntool3); XDestroyRegion (temp); #endif #ifdef WIN_GIF Nlm_GIFRgnToRect ( ntool1, &rsrc1 ); Nlm_GIFRgnToRect ( ntool2, &rsrc2 ); Nlm_SectRect ( &rsrc1, &rsrc2, &rdst ); Nlm_RectToGIFRgn ( &rdst, ntool3 ); #endif } } extern void Nlm_UnionRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst) { Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_RgnTool ntool3; #ifdef WIN_X Nlm_RgnTool temp; #endif #ifdef WIN_GIF Nlm_RecT rsrc1; Nlm_RecT rsrc2; Nlm_RecT rdst; #endif if (src1 != NULL && src2 != NULL && dst != NULL) { ntool1 = (Nlm_RgnTool) src1; ntool2 = (Nlm_RgnTool) src2; ntool3 = (Nlm_RgnTool) dst; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeUnion( ntool1, ntool2, ntool3); #else UnionRgn (ntool1, ntool2, ntool3); #endif #endif #ifdef WIN_MSWIN CombineRgn (ntool3, ntool1, ntool2, RGN_OR); #endif #ifdef WIN_X temp = XCreateRegion (); XUnionRegion (ntool1, ntool2, temp); XUnionRegion (temp, emptyRgn, ntool3); XDestroyRegion (temp); #endif #ifdef WIN_GIF Nlm_GIFRgnToRect ( ntool1, &rsrc1 ); Nlm_GIFRgnToRect ( ntool2, &rsrc2 ); Nlm_UnionRect ( &rsrc1, &rsrc2, &rdst ); Nlm_RectToGIFRgn ( &rdst, ntool3 ); #endif } } extern void Nlm_DiffRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst) { Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_RgnTool ntool3; #ifdef WIN_X Nlm_RgnTool temp; #endif if (src1 != NULL && src2 != NULL && dst != NULL) { ntool1 = (Nlm_RgnTool) src1; ntool2 = (Nlm_RgnTool) src2; ntool3 = (Nlm_RgnTool) dst; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ HIShapeDifference (ntool1, ntool2, ntool3); #else DiffRgn (ntool1, ntool2, ntool3); #endif #endif #ifdef WIN_MSWIN CombineRgn (ntool3, ntool1, ntool2, RGN_DIFF); #endif #ifdef WIN_X temp = XCreateRegion (); XSubtractRegion (ntool1, ntool2, temp); XUnionRegion (temp, emptyRgn, ntool3); XDestroyRegion (temp); #endif } } extern void Nlm_XorRgn (Nlm_RegioN src1, Nlm_RegioN src2, Nlm_RegioN dst) { #ifdef WIN_MAC_QUARTZ /* this is actually a general solution, but less efficient Quartz has no choice but to use it since HIShape does not support the xor operation natively xor is equivalent to the union minus the intersection, so we do that */ Nlm_RegioN sum = Nlm_CreateRgn(); Nlm_RegioN intersection = Nlm_CreateRgn(); Nlm_UnionRgn (src1, src2, sum); Nlm_SectRgn (src1, src2, intersection); Nlm_DiffRgn (sum, intersection, dst); Nlm_DestroyRgn (sum); Nlm_DestroyRgn (intersection); #else Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_RgnTool ntool3; #ifdef WIN_X Nlm_RgnTool temp; #endif if (src1 != NULL && src2 != NULL && dst != NULL) { ntool1 = (Nlm_RgnTool) src1; ntool2 = (Nlm_RgnTool) src2; ntool3 = (Nlm_RgnTool) dst; #ifdef WIN_MAC XorRgn (ntool1, ntool2, ntool3); #endif #ifdef WIN_MSWIN CombineRgn (ntool3, ntool1, ntool2, RGN_XOR); #endif #ifdef WIN_X temp = XCreateRegion (); XXorRegion (ntool1, ntool2, temp); XUnionRegion (temp, emptyRgn, ntool3); XDestroyRegion (temp); #endif } #endif } extern Nlm_Boolean Nlm_EqualRgn (Nlm_RegioN rgn1, Nlm_RegioN rgn2) { Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_Boolean rsult; rsult = FALSE; if (rgn1 != NULL && rgn2 != NULL) { ntool1 = (Nlm_RgnTool) rgn1; ntool2 = (Nlm_RgnTool) rgn2; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ /* HIShapeRefs are CFTypeRefs so we can use CFEqual */ rsult = CFEqual (ntool1, ntool2); #else rsult = EqualRgn (ntool1, ntool2); #endif #endif #ifdef WIN_MSWIN rsult = (Nlm_Boolean) EqualRgn (ntool1, ntool2); #endif #ifdef WIN_X rsult = (XEqualRegion (ntool1, ntool2) != 0); #endif } return rsult; } extern Nlm_Boolean Nlm_EmptyRgn (Nlm_RegioN rgn) { Nlm_RgnTool ntool; Nlm_Boolean rsult; #ifdef WIN_MSWIN Nlm_RectTool rtool; #endif rsult = FALSE; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ rsult = HIShapeIsEmpty (ntool); #else rsult = EmptyRgn (ntool); #endif #endif #ifdef WIN_MSWIN rsult = (Nlm_Boolean) (GetRgnBox (ntool, &rtool) == NULLREGION); #endif #ifdef WIN_X rsult = (XEmptyRegion (ntool) != 0); #endif } return rsult; } extern void Nlm_EraseRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC_QUARTZ HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext()); Nlm_SelectQuartzColor (Nlm_QuartzBackColor); CGContextFillPath (Nlm_PeekQContext()); Nlm_SelectQuartzColor (Nlm_QuartzForeColor); #else EraseRgn (ntool); #endif } #endif #ifdef WIN_MSWIN Nlm_RgnTool ntool; if (rgn != NULL && Nlm_currentHDC != NULL && Nlm_currentHWnd != NULL) { ntool = (Nlm_RgnTool) rgn; FillRgn (Nlm_currentHDC, ntool, GetBackgroundBrush (Nlm_currentHWnd)); } #endif #ifdef WIN_X #endif } extern void Nlm_FrameRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC_QUARTZ HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext()); CGContextStrokePath (Nlm_PeekQContext()); #else FrameRgn (ntool); #endif } #endif #ifdef WIN_MSWIN Nlm_RgnTool ntool; if (rgn != NULL && Nlm_currentHDC != NULL) { ntool = (Nlm_RgnTool) rgn; FrameRgn (Nlm_currentHDC, ntool, GetStockObject (BLACK_BRUSH), 1, 1); } #endif #ifdef WIN_X #endif } extern void Nlm_PaintRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC_QUARTZ HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext()); CGContextFillPath (Nlm_PeekQContext()); #else PaintRgn (ntool); #endif } #endif #ifdef WIN_MSWIN Nlm_RgnTool ntool; HBRUSH oldBrush; if (rgn != NULL && Nlm_currentHDC != NULL) { ntool = (Nlm_RgnTool) rgn; oldBrush = SelectObject (Nlm_currentHDC, GetStockObject (BLACK_BRUSH)); if (oldBrush != NULL) { SelectObject (Nlm_currentHDC, oldBrush); FillRgn (Nlm_currentHDC, ntool, oldBrush); } } #endif #ifdef WIN_X #endif } extern void Nlm_InvertRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: this operation does not make sense in quartz, what to do? #else InvertRgn (ntool); #endif } #endif #ifdef WIN_MSWIN Nlm_RgnTool ntool; if (rgn != NULL && Nlm_currentHDC != NULL) { ntool = (Nlm_RgnTool) rgn; InvertRgn (Nlm_currentHDC, ntool); } #endif #ifdef WIN_X #endif } extern void Nlm_ClipRect (Nlm_RectPtr r) { #ifdef WIN_MAC Nlm_RectTool rtool; if (r != NULL) { Local__RecTToRectTool (r, &rtool); #ifdef WIN_MAC_QUARTZ if (Nlm_PeekQContext()) { CGRect cgr = Nlm_RecTToCGRect (*r); CGContextClipToRect (Nlm_PeekQContext(), cgr); } #else ClipRect (&rtool); #endif } #endif #ifdef WIN_MSWIN HRGN hRgnClip; if (r != NULL && Nlm_currentHDC != NULL) { hRgnClip = CreateRectRgn (r->left, r->top, r->right, r->bottom); SelectClipRgn (Nlm_currentHDC, hRgnClip); DeleteObject (hRgnClip); } #endif #ifdef WIN_X Nlm_RectTool rtool; if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { Local__RecTToRectTool (r, &rtool); rtool.x -= Nlm_XOffset; rtool.y -= Nlm_YOffset; XSetClipRectangles (Nlm_currentXDisplay, Nlm_currentXGC, 0, 0, &rtool, 1, Unsorted); if (Nlm_clpRgn != NULL) { XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn); Nlm_clpRgn = NULL; } Nlm_clpRgn = (Nlm_RegioN) XCreateRegion (); XUnionRectWithRegion (&rtool, (Nlm_RgnTool) Nlm_clpRgn, (Nlm_RgnTool) Nlm_clpRgn); XOffsetRegion ((Nlm_RgnTool) Nlm_clpRgn, Nlm_XOffset, Nlm_YOffset); } #endif } extern void Nlm_ClipRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC Nlm_RgnTool ntool; if (rgn != NULL) { ntool = (Nlm_RgnTool) rgn; #ifdef WIN_MAC_QUARTZ HIShapeReplacePathInCGContext (ntool, Nlm_PeekQContext()); CGContextClip (Nlm_PeekQContext()); #else SetClip (ntool); #endif } #endif #ifdef WIN_MSWIN Nlm_RgnTool ntool; if (rgn != NULL && Nlm_currentHDC != NULL) { ntool = (Nlm_RgnTool) rgn; SelectClipRgn (Nlm_currentHDC, ntool); } #endif #ifdef WIN_X Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; if (rgn != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { ntool1 = XCreateRegion (); ntool2 = XCreateRegion (); XUnionRegion ((Nlm_RgnTool) rgn, ntool1, ntool2); XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset); XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2); if (Nlm_clpRgn != NULL) { XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn); Nlm_clpRgn = NULL; } Nlm_clpRgn = (Nlm_RegioN) XCreateRegion (); XUnionRegion ((Nlm_RgnTool) rgn, ntool1, (Nlm_RgnTool) Nlm_clpRgn); XOffsetRegion ((Nlm_RgnTool) Nlm_clpRgn, -Nlm_XOffset, -Nlm_YOffset); XDestroyRegion (ntool1); XDestroyRegion (ntool2); } #endif } extern void Nlm_ResetClip (void) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ // 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? #else Nlm_RecT r; Nlm_RectTool rtool; Nlm_LoadRect (&r, -32767, -32767, 32767, 32767); Local__RecTToRectTool (&r, &rtool); ClipRect (&rtool); #endif #endif #ifdef WIN_MSWIN if (Nlm_currentHDC != NULL) { SelectClipRgn (Nlm_currentHDC, NULL); } #endif #ifdef WIN_X if (Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL) { XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None); if (Nlm_clpRgn != NULL) { XDestroyRegion ((Nlm_RgnTool) Nlm_clpRgn); Nlm_clpRgn = NULL; } } #endif } extern void Nlm_ValidRect (Nlm_RectPtr r) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: do we care? just let it redraw #else Nlm_RectTool rtool; if (r != NULL) { Local__RecTToRectTool (r, &rtool); ValidRect (&rtool); } #endif #endif #ifdef WIN_MSWIN Nlm_RectTool rtool; if (r != NULL && Nlm_currentHWnd != NULL) { Local__RecTToRectTool (r, &rtool); ValidateRect (Nlm_currentHWnd, &rtool); } #endif #ifdef WIN_X #endif } extern void Nlm_InvalRect (Nlm_RectPtr r) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: this could stand to be a little more fine-grained HIViewRef view = HIViewGetRoot (Nlm_QWindow); HIViewSetNeedsDisplay (view, 1); #else Nlm_RectTool rtool; if (r != NULL) { Local__RecTToRectTool (r, &rtool); InvalRect (&rtool); } #endif #endif #ifdef WIN_MSWIN Nlm_RectTool rtool; if (r != NULL && Nlm_currentHWnd != NULL) { Local__RecTToRectTool (r, &rtool); InvalidateRect (Nlm_currentHWnd, &rtool, TRUE); } #endif #ifdef WIN_X Nlm_RectTool rtool; if (r != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0) { Local__RecTToRectTool (r, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x - Nlm_XOffset, rtool.y - Nlm_YOffset, rtool.width, rtool.height, TRUE); } #endif } extern void Nlm_ValidRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC if (rgn != NULL) { #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: do we care? just let it redraw #else ValidRgn ((Nlm_RgnTool) rgn); #endif } #endif #ifdef WIN_MSWIN if (rgn != NULL && Nlm_currentHWnd != NULL) { ValidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) rgn); } #endif #ifdef WIN_X #endif } extern void Nlm_InvalRgn (Nlm_RegioN rgn) { #ifdef WIN_MAC if (rgn != NULL) { #ifdef WIN_MAC_QUARTZ // QUARTZ_FIXME: this could stand to be a little more fine-grained HIViewRef view = HIViewGetRoot (Nlm_QWindow); HIViewSetNeedsDisplay (view, 1); #else InvalRgn ((Nlm_RgnTool) rgn); #endif } #endif #ifdef WIN_MSWIN if (rgn != NULL && Nlm_currentHWnd != NULL) { InvalidateRgn (Nlm_currentHWnd, (Nlm_RgnTool) rgn, TRUE); } #endif #ifdef WIN_X Nlm_RgnTool ntool1; Nlm_RgnTool ntool2; Nlm_RectTool rtool; if (rgn != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXGC != NULL && Nlm_currentXWindow != 0) { ntool1 = XCreateRegion (); ntool2 = XCreateRegion (); XUnionRegion ((Nlm_RgnTool) rgn, ntool1, ntool2); XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset); XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2); XClipBox (ntool2, &rtool); XClearArea (Nlm_currentXDisplay, Nlm_currentXWindow, rtool.x, rtool.y, rtool.width, rtool.height, TRUE); XDestroyRegion (ntool1); XDestroyRegion (ntool2); if (Nlm_clpRgn != NULL) { ntool1 = XCreateRegion (); ntool2 = XCreateRegion (); XUnionRegion ((Nlm_RgnTool) Nlm_clpRgn, ntool1, ntool2); XOffsetRegion (ntool2, -Nlm_XOffset, -Nlm_YOffset); XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, ntool2); XDestroyRegion (ntool1); XDestroyRegion (ntool2); } else { XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None); } } #endif } extern void Nlm_CopyBits (Nlm_RectPtr r, Nlm_VoidPtr source) { #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGRect rect = Nlm_RecTToCGRect (*r); int width = r->left - r->right; int height = r->bottom - r->top; int bytesPerRow = (width - 1) / 8 + 1; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL, source, bytesPerRow * height, NULL); CGImageRef image = CGImageCreate ( width, height, 1, /* bits per component */ 1, /* bits per pixel */ bytesPerRow, colorSpace, 0, /* bitmap info */ dataProvider, NULL, 1, /* should interpolate */ kCGRenderingIntentDefault); CGContextDrawImage (Nlm_PeekQContext(), rect, image); CFRelease (image); CFRelease (dataProvider); CFRelease (colorSpace); #else const BitMap *dstBitsPtr; Nlm_Int2 mode; PenState pnState; GrafPtr port; Rect rect; BitMap srcBits; Rect srcRect; if (r != NULL && source != NULL) { GetPort (&port); GetPenState (&pnState); switch (pnState.pnMode) { case patCopy: mode = srcCopy; break; case patOr: mode = srcOr; break; case patXor: mode = srcXor; break; case patBic: mode = srcBic; break; default: mode = srcCopy; break; } Local__RecTToRectTool (r, &rect); srcRect = rect; OffsetRect (&srcRect, -rect.left, -rect.top); srcBits.baseAddr = (Ptr) source; srcBits.rowBytes = (rect.right - rect.left - 1) / 8 + 1; srcBits.bounds = srcRect; #if OPAQUE_TOOLBOX_STRUCTS dstBitsPtr = GetPortBitMapForCopyBits(port); #else dstBitsPtr = &port->portBits; #endif CopyBits (&srcBits, dstBitsPtr, &srcRect, &rect, mode, NULL); } #endif #endif #ifdef WIN_MSWIN Nlm_Int2 cols; HBITMAP hBitmap; HBITMAP hOldBitmap; HDC hMemoryDC; int rop2; Nlm_Int2 i; Nlm_Int2 j; Nlm_Int4 mode; Nlm_Int4 num; Nlm_Boolean odd; Nlm_Uint1Ptr p; Nlm_Uint1Ptr ptr; Nlm_Uint1Ptr q; Nlm_Int2 rows; if (r != NULL && source != NULL && Nlm_currentHDC != NULL) { rows = (Nlm_Int2)((r->right - r->left - 1) / 8 + 1); odd = (Nlm_Boolean) ((rows & 1) != 0); cols = (Nlm_Int2)(r->bottom - r->top); num = rows * cols; if (odd) { num += cols; } ptr = (Nlm_Uint1Ptr) Nlm_MemNew ((size_t) num * sizeof (Nlm_Uint1)); if (ptr != NULL) { p = source; q = ptr; for (i = 0; i < cols; i++) { j = 0; while (j < rows) { *q = *p; p++; q++; j++; } if (odd) { *q = 0; q++; } } q = ptr; while (num > 0) { *q = (Nlm_Uint1) ~(*q); q++; num--; } hBitmap = CreateBitmap (r->right - r->left, r->bottom - r->top, 1, 1, (LPSTR) ptr); hMemoryDC = CreateCompatibleDC (Nlm_currentHDC); if ( hMemoryDC == NULL ) { hMemoryDC = CreateCompatibleDC (NULL); hOldBitmap = SelectObject (hMemoryDC, hBitmap); mode = SRCCOPY; BitBlt (Nlm_currentHDC, r->left, r->top, r->right - r->left, r->bottom - r->top, hMemoryDC, 0, 0, mode); SelectObject (hMemoryDC, hOldBitmap); } else { hOldBitmap = SelectObject (hMemoryDC, hBitmap); if (hOldBitmap != NULL) { rop2 = GetROP2( Nlm_currentHDC ); switch (rop2) { case R2_COPYPEN: mode = SRCCOPY; break; case R2_MASKPEN: mode = SRCAND; break; case R2_NOTXORPEN: mode = 0x00990066; break; case R2_MERGENOTPEN: mode = MERGEPAINT; break; default: mode = WHITENESS; break; } BitBlt (Nlm_currentHDC, r->left, r->top, r->right - r->left, r->bottom - r->top, hMemoryDC, 0, 0, mode); SelectObject (hMemoryDC, hOldBitmap); } } Nlm_MemFree (ptr); DeleteDC (hMemoryDC); DeleteObject (hBitmap); } } #endif #ifdef WIN_X Nlm_Int2 cols; Nlm_Int2 height; Nlm_Int4 num; Pixmap pixmap; Nlm_Uint1Ptr ptr; Nlm_Uint1Ptr q; Nlm_Int2 rows; Nlm_Int2 width; if (r != NULL && source != NULL && Nlm_currentXDisplay != NULL && Nlm_currentXWindow != 0 && Nlm_currentXGC != NULL) { rows = (r->right - r->left - 1) / 8 + 1; cols = r->bottom - r->top; num = rows * cols; ptr = (Nlm_Uint1Ptr) Nlm_MemNew ((size_t) num * sizeof (Nlm_Uint1)); if (ptr != NULL) { Nlm_MemCopy (ptr, source, (size_t) num); q = ptr; while (num > 0) { *q = flip [*q]; q++; num--; } width = r->right - r->left; height = r->bottom - r->top; pixmap = XCreateBitmapFromData (Nlm_currentXDisplay, Nlm_currentXWindow, (char *) ptr, width, height); XSetGraphicsExposures (Nlm_currentXDisplay, Nlm_currentXGC, FALSE); if (currentMode != MERGE_MODE) { XCopyPlane (Nlm_currentXDisplay, pixmap, Nlm_currentXWindow, Nlm_currentXGC, 0, 0, width, height, r->left - Nlm_XOffset, r->top - Nlm_YOffset, 1); } else { XSetClipOrigin (Nlm_currentXDisplay, Nlm_currentXGC, r->left - Nlm_XOffset, r->top - Nlm_YOffset); XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, pixmap); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXcopy); XCopyPlane (Nlm_currentXDisplay, pixmap, Nlm_currentXWindow, Nlm_currentXGC, 0, 0, width, height, r->left - Nlm_XOffset, r->top - Nlm_YOffset, 1); XSetFunction (Nlm_currentXDisplay, Nlm_currentXGC, GXand); XSetClipOrigin (Nlm_currentXDisplay, Nlm_currentXGC, 0, 0); if (Nlm_clpRgn != NULL) { XSetRegion (Nlm_currentXDisplay, Nlm_currentXGC, (Nlm_RgnTool) Nlm_clpRgn); } else { XSetClipMask (Nlm_currentXDisplay, Nlm_currentXGC, None); } } XSetGraphicsExposures (Nlm_currentXDisplay, Nlm_currentXGC, TRUE); XFreePixmap (Nlm_currentXDisplay, pixmap); Nlm_MemFree (ptr); } } #endif #ifdef WIN_GIF if (r != NULL && source != NULL && Nlm_currentGIF != NULL ){ gdImageCopyBits ( Nlm_currentGIF, r->left, r->top, r->right - r->left, r->bottom - r->top, (char*)source, Nlm_curGIFColor ); } #endif } extern void Nlm_CopyPixmap ( Nlm_RectPtr r, Nlm_Int1Ptr source, Nlm_Uint1 totalColors, Nlm_RGBColoRPtr colorTable ) { #ifdef WIN_MSWIN BITMAPINFO PNTR bInfoPtr; RGBQUAD PNTR quadPtr; BITMAPINFOHEADER PNTR bmpHeader; HBITMAP pixMap; HDC hMemDC; #endif #ifdef WIN_MAC PixMap PNTR pixelMap; Rect rectSrc; Rect rectDst; GrafPtr port; CTabHandle tabHandle; CTabPtr tabPtr; #endif Nlm_Int2 width; Nlm_Int2 height; #ifndef WIN_GIF Nlm_Int2 i; #endif if ( (r==NULL)||(source==NULL)||(totalColors==0)|| (colorTable==NULL) ) return; width = (Nlm_Int2)(r->right - r->left); height = (Nlm_Int2)(r->bottom - r->top); #ifdef WIN_MSWIN bInfoPtr = (BITMAPINFO*)MemNew ( sizeof(BITMAPINFOHEADER) + totalColors*sizeof(RGBQUAD) ); bInfoPtr->bmiHeader.biClrUsed = totalColors; for( i=0; i<(Nlm_Int2)totalColors; i++ ) { quadPtr = &(bInfoPtr->bmiColors[i]); quadPtr->rgbRed = colorTable[i].red; quadPtr->rgbGreen = colorTable[i].green; quadPtr->rgbBlue = colorTable[i].blue; quadPtr->rgbReserved = 0; } bmpHeader = &(bInfoPtr->bmiHeader); bmpHeader->biWidth = width; bmpHeader->biHeight = height; bmpHeader->biSize = sizeof(BITMAPINFOHEADER); bmpHeader->biCompression = BI_RGB; bmpHeader->biXPelsPerMeter = 2000; bmpHeader->biYPelsPerMeter = 2000; bmpHeader->biClrImportant = 0; bmpHeader->biSizeImage = 0; bmpHeader->biBitCount = 8; bmpHeader->biPlanes = 1; pixMap = CreateDIBitmap( Nlm_currentHDC, (BITMAPINFOHEADER*)bInfoPtr, CBM_INIT, source, bInfoPtr, DIB_RGB_COLORS ); if ( pixMap != NULL ){ hMemDC = CreateCompatibleDC ( Nlm_currentHDC ); if ( hMemDC != NULL ){ SelectObject( hMemDC, pixMap ); StretchBlt ( Nlm_currentHDC, r->left, r->top+height, width, -height, hMemDC, 0, 0, width, height, SRCCOPY ); /* BitBlt( Nlm_currentHDC, r->left, r->top, width, height, hMemDC, 0, 0, SRCCOPY );*/ DeleteDC( hMemDC ); } DeleteObject( pixMap ); } MemFree(bInfoPtr); #endif #ifdef WIN_MAC #ifdef WIN_MAC_QUARTZ CGRect rect = Nlm_RecTToCGRect (*r); width = r->left - r->right; height = r->bottom - r->top; CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB (); /* we're going to pass the color table directly; it's an array of structs containing r, g, b, and the function wants an array of unsigned char containing r, g, b, so they all line up */ CGColorSpaceRef colorSpace = CGColorSpaceCreateIndexed (baseSpace, totalColors - 1, (const unsigned char *)colorTable); CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL, source, width * height, NULL); CGImageRef image = CGImageCreate ( width, height, 8, /* bits per component */ 8, /* bits per pixel */ width * height, colorSpace, 0, /* bitmap info */ dataProvider, NULL, 1, /* should interpolate */ kCGRenderingIntentDefault); CGContextDrawImage (Nlm_PeekQContext(), rect, image); CFRelease (image); CFRelease (dataProvider); CFRelease (colorSpace); CFRelease (baseSpace); #else pixelMap = (PixMap*)MemNew(sizeof(PixMap)); pixelMap->hRes = 72; pixelMap->vRes = 72; pixelMap->bounds.left = 0; pixelMap->bounds.top = 0; pixelMap->cmpSize = 8; /* 2001-03-22: Joshua Juran */ /* Evidently these two members don't exist in Carbon. So don't set them. */ #if !TARGET_API_MAC_CARBON pixelMap->planeBytes = 0; pixelMap->pmReserved = 0; #endif pixelMap->pmVersion = 0; pixelMap->packType = 0; pixelMap->packSize = 0; pixelMap->pixelSize = 8; pixelMap->pixelType = 0; pixelMap->cmpCount = 1; pixelMap->rowBytes = width | 0x8000; pixelMap->bounds.right = width; pixelMap->bounds.bottom = height; pixelMap->pmTable = tabHandle = GetCTable(72); if ( tabHandle != NULL ) { HLock ( (Handle)tabHandle ); tabPtr = *tabHandle; for ( i=0; i<(Nlm_Int2)totalColors; i++ ){ tabPtr->ctTable[i].rgb.red = (Nlm_Uint2)colorTable[i].red<<8 | (Nlm_Uint2)colorTable[i].red; tabPtr->ctTable[i].rgb.green = (Nlm_Uint2)colorTable[i].green<<8 | (Nlm_Uint2)colorTable[i].green; tabPtr->ctTable[i].rgb.blue = (Nlm_Uint2)colorTable[i].blue<<8 | (Nlm_Uint2)colorTable[i].blue; if (i >= 254) break; } tabPtr->ctSeed = GetCTSeed(); HUnlock((Handle)tabHandle ); pixelMap->baseAddr = (Ptr)source; rectSrc.top = 0; rectSrc.bottom = height; rectSrc.left = 0; rectSrc.right = width; rectDst.top = r->top; rectDst.bottom = r->bottom; rectDst.left = r->left; rectDst.right = r->right; GetPort(&port); #ifdef CopyBits #undef CopyBits #endif CopyBits((BitMap*)pixelMap, GetPortBitMapForCopyBits(port), &rectSrc, &rectDst, srcCopy, NULL); DisposeCTable(tabHandle); } MemFree(pixelMap); #endif #endif #ifdef WIN_MOTIF {{ XVisualInfo visinfo; if (XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen, 8, PseudoColor, &visinfo) || XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen, 8, GrayScale, &visinfo) ) { Visual* vis = visinfo.visual; Nlm_Uint1Ptr nSource = (Nlm_Uint1Ptr)MemNew(width * height); Nlm_Uint1Ptr iMap = (Nlm_Uint1Ptr)MemNew( totalColors ); XImage* imageX11; Nlm_Uint1Ptr curPtr; Nlm_Uint1Ptr endPtr; for (i = 0; i < (Nlm_Int2)totalColors; i++) { XColor colorCell; Nlm_XAllocColor(&colorCell, Nlm_VibrantDefaultColormap(), colorTable[i].red, colorTable[i].green, colorTable[i].blue); iMap[i] = (Nlm_Uint1)colorCell.pixel; } curPtr = (Nlm_Uint1Ptr)nSource; endPtr = curPtr + width * height; while ( curPtr != endPtr ) *curPtr++ = iMap[*source++]; imageX11 = XCreateImage(Nlm_currentXDisplay, vis, 8, ZPixmap, 0, (char*)nSource, width, height, 8 , 0 ); XPutImage(Nlm_currentXDisplay, Nlm_currentXWindow, Nlm_currentXGC, imageX11, 0, 0, r->left-Nlm_XOffset, r->top-Nlm_YOffset, width, height ); XFlush ( Nlm_currentXDisplay ); XDestroyImage( imageX11 ); MemFree( nSource ); MemFree( iMap ); } }} #endif } extern void Nlm_SetUpDrawingTools (void) { #ifdef WIN_MAC Rect bounds; Nlm_FontSpec fsp; long gval; char tmpFontName[256]; #ifdef WIN_MAC_QUARTZ CGRect r = CGRectMake (-32768, -32768, 65535, 65535); HIShapeRef rectShape = HIShapeCreateWithRect (&r); Nlm_scrollRgn = HIShapeCreateMutableCopy (rectShape); Nlm_updateRgn = HIShapeCreateMutableCopy (rectShape); CFRelease (rectShape); /* can't use QuickDraw functions to get the system font, no replacemet available, so just hardcode it */ memset ( &fsp, 0, sizeof(Nlm_FontSpec)); Nlm_StrCpy (fsp.name, "Lucida Grande"); fsp.size = 13; #else Nlm_scrollRgn = (Nlm_RegioN) (NewRgn ()); Nlm_updateRgn = (Nlm_RegioN) (NewRgn ()); SetRectRgn ((Nlm_RgnTool) Nlm_updateRgn, -32768, -32768, 32767, 32767); /* HLock ((Handle) Nlm_updateRgn); */ GetRegionBounds(Nlm_updateRgn, &bounds); Local__RectToolToRecT (&bounds, &Nlm_updateRect); /* HUnlock ((Handle) Nlm_updateRgn); */ /* esl: LoadFontData changed to work with new FontData format */ /* alexs get font name */ memset ( &fsp, 0, sizeof(Nlm_FontSpec)); GetFontName ( GetSysFont(), (StringPtr) tmpFontName ); Nlm_PtoCstr ( tmpFontName ); Nlm_StringNCpy_0 (fsp.name, tmpFontName, FONT_NAME_SIZE - 1); fsp.name[FONT_NAME_SIZE - 1] = 0; fsp.size = GetDefFontSize (); #endif Nlm_fontList = NULL; Nlm_fontInUse = NULL; Nlm_systemFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec)); #ifdef WIN_MAC_ATSUI Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, Nlm_NewATSUStyle(&fsp), NULL); #else Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, 0, fsp.size, 0, NULL); #endif Nlm_programFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec)); /* esl: LoadFontData changed to work with new FontData format */ Nlm_StrCpy (fsp.name, "Monaco"); fsp.size = 9; #ifdef WIN_MAC_ATSUI Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, Nlm_NewATSUStyle(&fsp), NULL); #else Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, 4, 9, 0, NULL); #endif Nlm_fontList = NULL; Nlm_fontInUse = Nlm_systemFont; Nlm_stdAscent = Nlm_Ascent (); Nlm_stdDescent = Nlm_Descent (); Nlm_stdLeading = Nlm_Leading (); Nlm_stdFontHeight = Nlm_FontHeight (); Nlm_stdLineHeight = Nlm_LineHeight (); Nlm_stdCharWidth = Nlm_MaxCharWidth (); /* gestalt for quickdraw features are defined as bits in a bitfield for example gestaltHasColor = 0, thus we need to test for lsb set */ if( Gestalt( gestaltQuickdrawFeatures, &gval) == noErr){ Nlm_hasColorQD = (gval && (1 << gestaltHasColor)); } if (Nlm_hasColorQD) { #ifdef WIN_MAC_QUARTZ Nlm_QuartzForeColor.r = 0; Nlm_QuartzForeColor.g = 0; Nlm_QuartzForeColor.b = 0; Nlm_QuartzBackColor.r = 1.0; Nlm_QuartzBackColor.g = 1.0; Nlm_QuartzBackColor.b = 1.0; #else Nlm_RGBforeColor.red = 0; Nlm_RGBforeColor.green = 0; Nlm_RGBforeColor.blue = 0; Nlm_RGBbackColor.red = 65535; Nlm_RGBbackColor.green = 65535; Nlm_RGBbackColor.blue = 65535; #endif } #endif #ifdef WIN_MSWIN Nlm_scrollRgn = (Nlm_RegioN)CreateRectRgn(0, 0, 0, 0); Nlm_updateRgn = (Nlm_RegioN)CreateRectRgn(-32767, -32767, 32767, 32767); {{ Nlm_RectTool rtool; GetRgnBox((Nlm_RgnTool)Nlm_updateRgn, &rtool); Local__RectToolToRecT(&rtool, &Nlm_updateRect); }} /* Stock fonts */ hAnsiFixedFont = GetStockObject( ANSI_FIXED_FONT ); hAnsiVarFont = GetStockObject( ANSI_VAR_FONT ); hDeviceDefaultFont = GetStockObject( DEVICE_DEFAULT_FONT ); hOemFixedFont = GetStockObject( OEM_FIXED_FONT ); hSystemFont = GetStockObject( SYSTEM_FONT ); hSystemFixedFont = GetStockObject( SYSTEM_FIXED_FONT ); hDefaultGuiFont = GetStockObject( DEFAULT_GUI_FONT ); Nlm_systemFont = (Nlm_FonT) Nlm_HandNew( sizeof(Nlm_FontRec) ); Nlm_LoadFontData(Nlm_systemFont, NULL, -1, NULL, hDefaultGuiFont, HFONT2Font( hDefaultGuiFont )); Nlm_fontList = NULL; Nlm_fontInUse = Nlm_systemFont; Nlm_stdAscent = Nlm_Ascent(); Nlm_stdDescent = Nlm_Descent(); Nlm_stdLeading = Nlm_Leading(); Nlm_stdFontHeight = Nlm_FontHeight(); Nlm_stdLineHeight = Nlm_LineHeight(); Nlm_stdCharWidth = Nlm_MaxCharWidth(); Nlm_programFont = (Nlm_FonT) Nlm_HandNew( sizeof(Nlm_FontRec) ); Nlm_LoadFontData(Nlm_programFont, NULL, -1, NULL, hAnsiFixedFont, HFONT2Font( hAnsiFixedFont )); blackColor = RGB( 0, 0, 0); redColor = RGB(255, 0, 0); greenColor = RGB( 0, 255, 0); blueColor = RGB( 0, 0, 255); cyanColor = RGB( 0, 255, 255); magentaColor = RGB(255, 0, 255); yellowColor = RGB(255, 255, 0); whiteColor = RGB(255, 255, 255); hBlackPen = GetStockObject( BLACK_PEN ); hNullPen = GetStockObject( NULL_PEN ); hWhitePen = GetStockObject( WHITE_PEN ); hBlackBrush = GetStockObject( BLACK_BRUSH ); hDkGrayBrush = GetStockObject( DKGRAY_BRUSH ); hGrayBrush = GetStockObject( GRAY_BRUSH ); hHollowBrush = GetStockObject( HOLLOW_BRUSH ); hLtGrayBrush = GetStockObject( LTGRAY_BRUSH ); hNullBrush = GetStockObject( NULL_BRUSH ); hWhiteBrush = GetStockObject( WHITE_BRUSH ); #endif #ifdef WIN_X XFontStruct *f; Nlm_Int2 i; Nlm_Uint2 inv; Nlm_Int2 j; XFontStruct *p; Nlm_RecT r; Nlm_RectTool rtool; Nlm_Uint2 val; Nlm_FontSpec fsp; Nlm_Char fSpecName[64]; Nlm_scrollRgn = (Nlm_RegioN) (XCreateRegion ()); Nlm_updateRgn = (Nlm_RegioN) (XCreateRegion ()); Nlm_LoadRect (&r, -32767, -32767, 32767, 32767); Local__RecTToRectTool (&r, &rtool); XUnionRectWithRegion (&rtool, (Nlm_RgnTool) Nlm_updateRgn, (Nlm_RgnTool) Nlm_updateRgn); Local__RectToolToRecT (&rtool, &Nlm_updateRect); emptyRgn = XCreateRegion (); Nlm_fontList = NULL; Nlm_fontInUse = NULL; {{ XFontStruct *F =XQueryFont(Nlm_currentXDisplay, XGContextFromGC(DefaultGC(Nlm_currentXDisplay, Nlm_currentXScreen))); i = F->ascent + F->descent; XFreeFontInfo(NULL, F, 1); }} sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i ); f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE); if ( f == NULL ){ i++; sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i ); f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE); } if ( f == NULL ){ i--; i--; sprintf ( fSpecName, "-*-helvetica-bold-r-*--%d-*-*", i ); f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE); } if ( f == NULL ){ f = Nlm_XLoadQueryFont (Nlm_currentXDisplay, "-*-helvetica-bold-r-*--*-140-*", FALSE); i = 14; } memset(&fsp, 0, sizeof(Nlm_FontSpec)); if ( f ) { Nlm_StrCpy(fsp.name, "helvetica"); fsp.style = STYLE_BOLD; } else { f = Nlm_XLoadStandardFont(); fsp.name[0] = '\0'; fsp.style = STYLE_REGULAR; i = f->ascent + f->descent; } fsp.size = i; Nlm_systemFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec)); Nlm_LoadFontData (Nlm_systemFont, NULL, -1, &fsp, f, NULL); sprintf ( fSpecName, "-*-fixed-medium-r-*--%d-*-*", i ); p = Nlm_XLoadQueryFont (Nlm_currentXDisplay, fSpecName, FALSE); Nlm_StrCpy ( fsp.name, "fixed" ); fsp.size = i; fsp.style = STYLE_REGULAR; if (p == NULL) { p = Nlm_XLoadQueryFont (Nlm_currentXDisplay, "-*-fixed-medium-r-*--*-120-*", FALSE); Nlm_StrCpy ( fsp.name, "fixed" ); fsp.size = 12; } if (p == NULL) { p = Nlm_XLoadQueryFont (Nlm_currentXDisplay, "-*-courier-medium-r-*--*-120-*", FALSE); Nlm_StrCpy ( fsp.name, "courier" ); fsp.size = 12; } if ( !p ) { p = Nlm_XLoadStandardFont(); fsp.name[0] = '\0'; fsp.size = p->ascent + p->descent; } Nlm_programFont = (Nlm_FonT) Nlm_HandNew (sizeof (Nlm_FontRec)); /* esl: LoadFontData changed to work with new FontData format */ Nlm_LoadFontData (Nlm_programFont, NULL, -1, &fsp, p, NULL); Nlm_fontList = NULL; Nlm_fontInUse = Nlm_systemFont; XSetFont (Nlm_currentXDisplay, Nlm_currentXGC, f->fid); currentFont = f; Nlm_stdAscent = Nlm_Ascent (); Nlm_stdDescent = Nlm_Descent (); Nlm_stdLeading = Nlm_Leading (); Nlm_stdFontHeight = Nlm_FontHeight (); Nlm_stdLineHeight = Nlm_LineHeight (); Nlm_stdCharWidth = Nlm_MaxCharWidth (); Nlm_hasColor = (Nlm_currentXDisplay != NULL && XDisplayCells(Nlm_currentXDisplay, Nlm_currentXScreen) > 2); if ( Nlm_hasColor ) { whiteColor = Nlm_GetColorRGB(255, 255, 255); blackColor = Nlm_GetColorRGB( 0, 0, 0); redColor = Nlm_GetColorRGB(255, 0, 0); greenColor = Nlm_GetColorRGB( 0, 255, 0); blueColor = Nlm_GetColorRGB( 0, 0, 255); cyanColor = Nlm_GetColorRGB( 0, 255, 255); magentaColor = Nlm_GetColorRGB(255, 0, 255); yellowColor = Nlm_GetColorRGB(255, 255, 0); } else { whiteColor = WhitePixel(Nlm_currentXDisplay, Nlm_currentXScreen); blackColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); redColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); greenColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); blueColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); cyanColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); magentaColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); yellowColor = BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen); } fontInfo.fid = 0; for (i = 0; i < 256; i++) { inv = 0; val = (Nlm_Uint2) i; for (j = 0; j < 8; j++) { inv = (inv << 1); inv += (val % 2); val = (val >> 1); } flip [i] = inv; } Nlm_XbackColor = whiteColor; Nlm_XforeColor = blackColor; Nlm_XOffset = 0; Nlm_YOffset = 0; Nlm_clpRgn = NULL; #endif #ifdef WIN_GIF Nlm_curGIFColor = 1; Nlm_curGIFLType = GIF_SOLID; Nlm_curGIFFont = gdFont7X13b; Nlm_curGIFPoint.x = 0; Nlm_curGIFPoint.y = 0; #endif } extern void Nlm_CleanUpDrawingTools (void) { Nlm_FonT f; Nlm_FontData fdata; #ifndef WIN_MAC_QUARTZ Nlm_ResetDrawingTools (); #endif #ifdef WIN_MOTIF Nlm_GetFontData (Nlm_systemFont, &fdata); if (fdata.handle != NULL) { XFreeFont (Nlm_currentXDisplay, fdata.handle); } Nlm_GetFontData (Nlm_programFont, &fdata); if (fdata.handle != NULL) { XFreeFont (Nlm_currentXDisplay, fdata.handle); } #endif Nlm_HandFree (Nlm_systemFont); Nlm_HandFree (Nlm_programFont); f = Nlm_fontList; while (f != NULL) { Nlm_GetFontData (f, &fdata); #ifdef WIN_MSWIN if (fdata.handle != NULL) { DeleteObject (fdata.handle); } #endif #ifdef WIN_MOTIF if (fdata.handle != NULL) { XFreeFont (Nlm_currentXDisplay, fdata.handle); } #endif Nlm_HandFree (f); f = fdata.next; } #ifdef WIN_MOTIF XDestroyRegion (emptyRgn); #endif } size_t UpdateColorTable(Nlm_RGBColoR table[], size_t table_size, const Nlm_Char PNTR filename) { size_t n_done = 0; FILE *file; Nlm_Char str[128]; if (table_size < 1 || filename == NULL) return 0; file = Nlm_FileOpen(filename, "r"); if (file == NULL) { Nlm_ErrLogPrintf("\n\ Warning: Cannot open the user's color description file \"%s\"\n", filename); return 0; } while (Nlm_FileGets(str, sizeof(str), file) != NULL) { int index; int red, green, blue; int n_char_read; if (sscanf(str, "%i %i %i %i %n", &index, &red, &green, &blue, &n_char_read) != 4) { Nlm_ErrLogPrintf("\n\ [%s] Warning:\n\ Cannot extract from the stroke:\n\ \"%s\"\n", filename, str); continue; } if (index < 0 || table_size <= (size_t)index) { Nlm_ErrLogPrintf("\n\ [%s] Warning:\n\ The color index is out of range = %d (must be: 0 <= index <= %l)\n", filename, index, (long)(table_size - 1)); continue; } #ifdef WIN_MOTIF {{ Nlm_CharPtr name, s; for (name=str+n_char_read; *name != '\0' && !isalnum(*name); name++); for (s =name; *s != '\0' && isalnum(*s ); s++ ); *s = '\0'; if (*name != '\0') { XColor rgb_db_def, hardware_def; if ( XLookupColor(Nlm_currentXDisplay, Nlm_VibrantDefaultColormap(), name, &rgb_db_def, &hardware_def) ) { red = (int)(hardware_def.red >> 8); green = (int)(hardware_def.green >> 8); blue = (int)(hardware_def.blue >> 8); } else { Nlm_ErrLogPrintf("\n\ [%s] Warning:\n\ Cannot find color of name \"%s\" in the X11 color database", filename, name); continue; } } }} #endif if (red < 0 || 255 < red || green < 0 || 255 < green || blue < 0 || 255 < blue) { Nlm_ErrLogPrintf("\n\ [%s] Warning:\n\ The color component values are out of range = (%d, %d, %d)\n\ (must be: 0 <= value <= 255)\n", filename, red, green, blue); continue; } table[index].red = (Nlm_Uint1) red; table[index].green = (Nlm_Uint1) green; table[index].blue = (Nlm_Uint1) blue; n_done++; } Nlm_FileClose( file ); return n_done; } static Nlm_Boolean s_VibrantIsGUI = FALSE; extern Nlm_Boolean Nlm_VibrantIsGUI(void) { return s_VibrantIsGUI; } extern void Nlm_VibrantSetGUI(void) { s_VibrantIsGUI = TRUE; }