home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / vibrant / drawing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-05  |  15.1 KB  |  543 lines  |  [TEXT/R*ch]

  1. /*   drawing.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE
  5. *            National Center for Biotechnology Information (NCBI)
  6. *
  7. *  This software/database is a "United States Government Work" under the
  8. *  terms of the United States Copyright Act.  It was written as part of
  9. *  the author's official duties as a United States Government employee and
  10. *  thus cannot be copyrighted.  This software/database is freely available
  11. *  to the public for use. The National Library of Medicine and the U.S.
  12. *  Government do not place any restriction on its use or reproduction.
  13. *  We would, however, appreciate having the NCBI and the author cited in
  14. *  any work or product based on this material
  15. *
  16. *  Although all reasonable efforts have been taken to ensure the accuracy
  17. *  and reliability of the software and data, the NLM and the U.S.
  18. *  Government do not and cannot warrant the performance or results that
  19. *  may be obtained by using this software or data. The NLM and the U.S.
  20. *  Government disclaim all warranties, express or implied, including
  21. *  warranties of performance, merchantability or fitness for any particular
  22. *  purpose.
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  drawing.c
  27. *
  28. * Author:  Jonathan Kans, Jill Shermer
  29. *
  30. * Version Creation Date:   11/13/92
  31. *
  32. * $Revision: 1.13 $
  33. *
  34. * File Description: 
  35. *
  36. * Modifications:  
  37. * --------------------------------------------------------------------------
  38. * Date     Name        Description of modification
  39. * -------  ----------  -----------------------------------------------------
  40. *
  41. *
  42. * ==========================================================================
  43. */
  44.  
  45. #ifndef _VIBRANT_
  46. #include <vibrant.h>
  47. #endif
  48.  
  49. #ifndef _PICTURE_
  50. #include <picture.h>
  51. #endif
  52.  
  53. #ifndef _PICTUREP_
  54. #include <pictureP.h>
  55. #endif
  56.  
  57. #ifndef _MAPPINGP_
  58. #include <mappingP.h>
  59. #endif
  60.  
  61. #ifndef _DRAWINGP_
  62. #include <drawingP.h>
  63. #endif
  64.  
  65. #ifndef _VIEWERP_
  66. #include <viewerP.h>
  67. #endif
  68.  
  69. /*****************************************************************************
  70. *
  71. *   EXTERNAL VARIABLES
  72. *
  73. *****************************************************************************/
  74.  
  75. FonT  smallFont = NULL;
  76. FonT  mediumFont = NULL;
  77. FonT  largeFont = NULL;
  78.  
  79. /*****************************************************************************
  80. *
  81. *   SetXXXFont (void)
  82. *       Creates fonts of various sizes.
  83. *
  84. *****************************************************************************/
  85.  
  86. FonT SetSmallFont (void)
  87.  
  88. {
  89.   if (smallFont == NULL) {
  90. #ifdef WIN_MAC
  91.     smallFont = ParseFont ("Monaco,9");
  92. #endif
  93. #ifdef WIN_MSWIN
  94.     smallFont = ParseFont ("Courier,9");
  95. #endif
  96. #ifdef WIN_MOTIF
  97.     smallFont = ParseFont ("Courier,12");
  98. #endif
  99.   }
  100.   return smallFont;
  101. }
  102.  
  103. FonT SetMediumFont (void)
  104.  
  105. {
  106.   if (mediumFont == NULL) {
  107. #ifdef WIN_MAC
  108.     mediumFont = ParseFont ("Monaco,12");
  109. #endif
  110. #ifdef WIN_MSWIN
  111.     mediumFont = ParseFont ("Courier,12");
  112. #endif
  113. #ifdef WIN_MOTIF
  114.     mediumFont = ParseFont ("Courier,14");
  115. #endif
  116.   }
  117.   return mediumFont;
  118. }
  119.  
  120. FonT SetLargeFont (void)
  121.  
  122. {
  123.   if (largeFont == NULL) {
  124. #ifdef WIN_MAC
  125.     largeFont = ParseFont ("Monaco,18");
  126. #endif
  127. #ifdef WIN_MSWIN
  128.     largeFont = ParseFont ("Courier,18");
  129. #endif
  130. #ifdef WIN_MOTIF
  131.     largeFont = ParseFont ("Courier,18");
  132. #endif
  133.   }
  134.   return largeFont;
  135. }
  136.  
  137. /*****************************************************************************
  138. *
  139. *   DrawRectPrim (rec, highlight, scale)
  140. *       Draws a rectangle primitive with an optional arrow.
  141. *
  142. *****************************************************************************/
  143.  
  144. static void DrawRectPrim (RecPPtr rec, Int1 highlight, ScaleInfo *scale)
  145.  
  146. {
  147.   PoinT  pts [4];
  148.   RecT   r;
  149.  
  150.   if (rec != NULL && scale != NULL) {
  151.     if (BoxInViewport (&r, &(rec->box), &(rec->rct), scale)) {
  152.       InsetRect (&r, -ARROW_PIXELS - ARROW_OVERHANG, -ARROW_PIXELS - ARROW_OVERHANG);
  153.       if (scale->force || RectInRgn (&r, updateRgn)) {
  154.         InsetRect (&r, ARROW_PIXELS + ARROW_OVERHANG, ARROW_PIXELS + ARROW_OVERHANG);
  155.         switch (rec->arrow) {
  156.           case NO_ARROW :
  157.             break;
  158.           case LEFT_ARROW :
  159.             if (r.right - r.left >= ARROW_PIXELS) {
  160.               r.left += ARROW_PIXELS;
  161.             } else {
  162.               r.right = r.left;
  163.             }
  164.             break;
  165.           case RIGHT_ARROW :
  166.             if (r.right - r.left >= ARROW_PIXELS) {
  167.               r.right -= ARROW_PIXELS;
  168.             } else {
  169.               r.left = r.right;
  170.             }
  171.             break;
  172.           case UP_ARROW :
  173.             if (r.bottom - r.top >= ARROW_PIXELS) {
  174.               r.top += ARROW_PIXELS;
  175.             } else {
  176.               r.bottom = r.top;
  177.             }
  178.             break;
  179.           case DOWN_ARROW :
  180.             if (r.bottom - r.top >= ARROW_PIXELS) {
  181.               r.bottom -= ARROW_PIXELS;
  182.             } else {
  183.               r.top = r.bottom;
  184.             }
  185.             break;
  186.           default :
  187.             break;
  188.         }
  189.         if (rec->fill) {
  190.           PaintRect (&r);
  191.         } else {
  192.           FrameRect (&r);
  193.         }
  194.         if (highlight == FRAME_CONTENTS || rec->highlight == FRAME_PRIMITIVE) {
  195.           InsetRect (&r, -1, -1);
  196.           FrameRect (&r);
  197.           InsetRect (&r, 1, 1);
  198.           FrameRect (&r);
  199.           InsetRect (&r, 1, 1);
  200.           FrameRect (&r);
  201.           InsetRect (&r, -1, -1);
  202.         } else if (highlight == FILL_CONTENTS || rec->highlight == FILL_PRIMITIVE) {
  203.           InsetRect (&r, -1, -1);
  204.           PaintRect (&r);
  205.           InsetRect (&r, 1, 1);
  206.         }
  207.         if (rec->arrow >= LEFT_ARROW && rec->arrow <= DOWN_ARROW) {
  208.           switch (rec->arrow) {
  209.             case LEFT_ARROW :
  210.               r.right = r.left;
  211.               r.left = r.right - ARROW_PIXELS;
  212.               r.bottom--;
  213.               r.top -= ARROW_OVERHANG;
  214.               r.bottom += ARROW_OVERHANG;
  215.               LoadPt (&(pts [0]), r.right, r.top);
  216.               LoadPt (&(pts [1]), r.right, r.bottom);
  217.               LoadPt (&(pts [2]), r.left, (r.top + r.bottom) / 2);
  218.               break;
  219.             case RIGHT_ARROW :
  220.               r.left = r.right - 1;
  221.               r.right = r.left + ARROW_PIXELS;
  222.               r.bottom--;
  223.               r.top -= ARROW_OVERHANG;
  224.               r.bottom += ARROW_OVERHANG;
  225.               LoadPt (&(pts [0]), r.left, r.top);
  226.               LoadPt (&(pts [1]), r.left, r.bottom);
  227.               LoadPt (&(pts [2]), r.right, (r.top + r.bottom) / 2);
  228.               break;
  229.             case UP_ARROW :
  230.               r.right--;
  231.               r.bottom = r.top;
  232.               r.top = r.bottom - ARROW_PIXELS;
  233.               r.left -= ARROW_OVERHANG;
  234.               r.right += ARROW_OVERHANG;
  235.               LoadPt (&(pts [0]), r.left, r.bottom);
  236.               LoadPt (&(pts [1]), r.right, r.bottom);
  237.               LoadPt (&(pts [2]), (r.left + r.right) / 2, r.top);
  238.               break;
  239.             case DOWN_ARROW :
  240.               r.right--;
  241.               r.top = r.bottom - 1;
  242.               r.bottom = r.top + ARROW_PIXELS;
  243.               r.left -= ARROW_OVERHANG;
  244.               r.right += ARROW_OVERHANG;
  245.               LoadPt (&(pts [0]), r.left, r.top);
  246.               LoadPt (&(pts [1]), r.right, r.top);
  247.               LoadPt (&(pts [2]), (r.left + r.right) / 2, r.bottom);
  248.               break;
  249.             default :
  250.               break;
  251.           }
  252.           if (rec->fill) {
  253.             FramePoly (3, pts);
  254.             PaintPoly (3, pts);
  255.           } else {
  256.             FramePoly (3, pts);
  257.           }
  258.         }
  259.       }
  260.     }
  261.   }
  262. }
  263.  
  264. /*****************************************************************************
  265. *
  266. *   DrawLinePrim (lin, penWidth, highlight, scale)
  267. *       Draws a line primitive.  Since polygon framing encompasses more
  268. *       area than painting, both operations are performed to form the
  269. *       optional arrowhead.
  270. *
  271. *****************************************************************************/
  272.  
  273. static PoinT offsetByOne = {1, 1};
  274.  
  275. static void DrawLinePrim (LinPPtr lin, Int1 penWidth, Int1 highlight, ScaleInfo *scale)
  276.  
  277. {
  278.   double   aspect;
  279.   double   cosTheta;
  280.   double   head;
  281.   PoinT    pt1;
  282.   PoinT    pt2;
  283.   PoinT    pts [4];
  284.   RecT     r;
  285.   double   sinTheta;
  286.   double   theta;
  287.  
  288.   if (lin != NULL && scale != NULL) {
  289.     if (LineInViewport (&pt1, &pt2, &(lin->pnt1), &(lin->pnt2), &(lin->rct), scale)) {
  290.       LoadRect (&r, MIN (pt1.x, pt2.x), MIN (pt1.y, pt2.y),
  291.                 MAX (pt1.x, pt2.x), MAX (pt1.y, pt2.y));
  292.       InsetRect (&r, -6, -6);
  293.       if (scale->force || RectInRgn (&r, updateRgn)) {
  294.         DrawLine (pt1, pt2);
  295.         if (highlight == FRAME_CONTENTS || highlight == FILL_CONTENTS ||
  296.            lin->highlight == FRAME_PRIMITIVE || lin->highlight == FILL_PRIMITIVE) {
  297.           WidePen (penWidth + 2);
  298.           SubPt (offsetByOne, &pt1);
  299.           SubPt (offsetByOne, &pt2);
  300.           DrawLine (pt1, pt2);
  301.           AddPt (offsetByOne, &pt1);
  302.           AddPt (offsetByOne, &pt2);
  303.           WidePen (penWidth);
  304.         }
  305.         if (lin->arrow && (pt1.x != pt2.x || pt1.y != pt2.y)) {
  306.           if (penWidth > 0) {
  307.             head = (double) (ARROW_LENGTH + penWidth);
  308.           } else {
  309.             head = (double) ARROW_LENGTH;
  310.           }
  311.           if (pt1.x != pt2.x) {
  312.             theta = atan2 ((double) (pt2.y - pt1.y), (double) (pt2.x - pt1.x));
  313.             cosTheta = cos (theta);
  314.             sinTheta = sin (theta);
  315.           } else if (pt2.y > pt1.y) {
  316.             cosTheta = 0.0;
  317.             sinTheta = 1.0;
  318.           } else {
  319.             cosTheta = 0.0;
  320.             sinTheta = -1.0;
  321.           }
  322.           pts [0].x = pt2.x;
  323.           pts [0].y = pt2.y;
  324.           aspect = (double) ARROW_ASPECT;
  325.           pts [1].x = pt2.x - (Int2) (head * (sinTheta + aspect * cosTheta));
  326.           pts [1].y = pt2.y + (Int2) (head * (cosTheta - aspect * sinTheta));
  327.           pts [2].x = pt2.x + (Int2) (head * (sinTheta - aspect * cosTheta));
  328.           pts [2].y = pt2.y - (Int2) (head * (cosTheta + aspect * sinTheta));
  329.           FramePoly (3, pts);
  330.           PaintPoly (3, pts);
  331.         }
  332.       }
  333.     }
  334.   }
  335. }
  336.  
  337. /*****************************************************************************
  338. *
  339. *   DrawBitmap (source, pt, rct, scale)
  340. *       Draws a symbol or bitmap
  341. *
  342. *****************************************************************************/
  343.  
  344. static void DrawBitmap (Uint1Ptr source, PoinT pt, RectPtr rct, ScaleInfo *scale)
  345.  
  346. {
  347.   RecT  r;
  348.  
  349.   if (source != NULL && rct != NULL && scale != NULL) {
  350.     r = *rct;
  351.     OffsetRect (&r, pt.x, pt.y);
  352.     InsetRect (&r, -1, -1);
  353.     if (scale->force || RectInRgn (&r, updateRgn)) {
  354.       InsetRect (&r, 1, 1);
  355.       CopyBits (&r, source);
  356.     }
  357.   }
  358. }
  359.  
  360. /*****************************************************************************
  361. *
  362. *   DrawSymPrim (sym, scale)
  363. *       Draws a symbol primitive
  364. *
  365. *****************************************************************************/
  366.  
  367. static void DrawSymPrim (SymPPtr sym, ScaleInfo *scale)
  368.  
  369. {
  370.   PoinT  pt;
  371.  
  372.   if (sym != NULL && scale != NULL && sym->data != NULL) {
  373.     if (PntInViewport (&pt, &(sym->pnt), &(sym->rct), scale)) {
  374.       DrawBitmap (sym->data, pt, &(sym->rct), scale);
  375.     }
  376.   }
  377. }
  378.  
  379. /*****************************************************************************
  380. *
  381. *   DrawBitmapPrim (btm, scale)
  382. *       Draws a bitmap primitive
  383. *
  384. *****************************************************************************/
  385.  
  386. static void DrawBitmapPrim (BtmPPtr btm, ScaleInfo *scale)
  387.  
  388. {
  389.   PoinT  pt;
  390.  
  391.   if (btm != NULL && scale != NULL && btm->data != NULL) {
  392.     if (PntInViewport (&pt, &(btm->pnt), &(btm->rct), scale)) {
  393.       DrawBitmap (btm->data, pt, &(btm->rct), scale);
  394.     }
  395.   }
  396. }
  397.  
  398. /*****************************************************************************
  399. *
  400. *   DrawCustomPrim (cst, scale)
  401. *       Draws a custom primitive
  402. *
  403. *****************************************************************************/
  404.  
  405. static void DrawCustomPrim (CstPPtr cst, ScaleInfo *scale)
  406.  
  407. {
  408.   PoinT  pt;
  409.   RecT   r;
  410.  
  411.   if (cst != NULL && scale != NULL && cst->proc != NULL) {
  412.     if (PntInViewport (&pt, &(cst->pnt), &(cst->rct), scale)) {
  413.       r = cst->rct;
  414.       OffsetRect (&r, pt.x, pt.y);
  415.       InsetRect (&r, -1, -1);
  416.       if (scale->force || RectInRgn (&r, updateRgn)) {
  417.         InsetRect (&r, 1, 1);
  418.         cst->proc (r.left, r.top, r.right, r.bottom);
  419.       }
  420.     }
  421.   }
  422. }
  423.  
  424. /*****************************************************************************
  425. *
  426. *   DrawMarkerPrim (mrk, scale)
  427. *       Draws a marker primitive
  428. *
  429. *****************************************************************************/
  430.  
  431. static void DrawMarkerPrim (MrkPPtr mrk, ScaleInfo *scale)
  432.  
  433. {
  434.   PoinT  pt;
  435.   RecT   r;
  436.  
  437.   if (mrk != NULL && scale != NULL) {
  438.     if (PntInViewport (&pt, &(mrk->pnt), &(mrk->rct), scale)) {
  439.       r = mrk->rct;
  440.       OffsetRect (&r, pt.x, pt.y);
  441.       InsetRect (&r, -1, -1);
  442.       if (scale->force || RectInRgn (&r, updateRgn)) {
  443.         InsetRect (&r, 1, 1);
  444.         MoveTo (r.left, r.top);
  445.         LineTo (r.right, r.bottom);
  446.       }
  447.     }
  448.   }
  449. }
  450.  
  451. /*****************************************************************************
  452. *
  453. *   DrawLabelPrim (lbl, scale)
  454. *       Draws a label primitive
  455. *
  456. *****************************************************************************/
  457.  
  458. static void DrawLabelPrim (LblPPtr lbl, ScaleInfo *scale)
  459.  
  460. {
  461.   FonT     fnt;
  462.   PoinT    pt;
  463.   RecT     r;
  464.   CharPtr  str;
  465.  
  466.   if (lbl != NULL && scale != NULL && lbl->str != NULL) {
  467.     if (PntInViewport (&pt, &(lbl->pnt), &(lbl->rct), scale)) {
  468.       r = lbl->rct;
  469.       OffsetRect (&r, pt.x, pt.y);
  470.       InsetRect (&r, -1, -1);
  471.       if (scale->force || RectInRgn (&r, updateRgn)) {
  472.         InsetRect (&r, 1, 1);
  473.         str = lbl->str;
  474.         switch (lbl->size) {
  475.           case SMALL_TEXT:
  476.             if (smallFont == NULL) {
  477.               SetSmallFont ();
  478.             }
  479.             fnt = smallFont;
  480.             break;
  481.           case MEDIUM_TEXT:
  482.             if (mediumFont == NULL) {
  483.               SetMediumFont ();
  484.             }
  485.             fnt = mediumFont;
  486.             break;
  487.           case LARGE_TEXT:
  488.             if (largeFont == NULL) {
  489.               SetLargeFont ();
  490.             }
  491.             fnt = largeFont;
  492.             break;
  493.           default :
  494.             fnt = programFont;
  495.             break;
  496.         }
  497.         SelectFont (fnt);
  498.         DrawString (&r, str, 'l', FALSE);
  499.       }
  500.     }
  501.   }
  502. }
  503.  
  504. /*****************************************************************************
  505. *
  506. *   DrawPrimitive (item, atts, scale)
  507. *       Draws a primitive
  508. *
  509. *****************************************************************************/
  510.  
  511. void DrawPrimitive (BasePPtr item, AttPData *atts, ScaleInfo *scale)
  512.  
  513. {
  514.   if (item != NULL && atts != NULL && scale != NULL) {
  515.     switch (item->code) {
  516.       case RECTANGLE :
  517.         DrawRectPrim ((RecPPtr) item, atts->highlight, scale);
  518.         break;
  519.       case LINE :
  520.         DrawLinePrim ((LinPPtr) item, atts->penwidth, atts->highlight, scale);
  521.         break;
  522.       case SYMBOL :
  523.         DrawSymPrim ((SymPPtr) item, scale);
  524.         break;
  525.       case BITMAP :
  526.         DrawBitmapPrim ((BtmPPtr) item, scale);
  527.         break;
  528.       case CUSTOM :
  529.         DrawCustomPrim ((CstPPtr) item, scale);
  530.         break;
  531.       case MARKER :
  532.         DrawMarkerPrim ((MrkPPtr) item, scale);
  533.         break;
  534.       case LABEL :
  535.         DrawLabelPrim ((LblPPtr) item, scale);
  536.         break;
  537.       default :
  538.         Message (MSG_ERROR, "DrawPrimitive item unknown");
  539.         break;
  540.     }
  541.   }
  542. }
  543.