home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / ppc / ppcWLine.c < prev   
C/C++ Source or Header  |  1989-11-14  |  11KB  |  380 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23. /***********************************************************
  24. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  25. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  26.  
  27.             All Rights Reserved
  28.  
  29. Permission to use, copy, modify, and distribute this software and its 
  30. documentation for any purpose and without fee is hereby granted, 
  31. provided that the above copyright notice appear in all copies and that
  32. both that copyright notice and this permission notice appear in 
  33. supporting documentation, and that the names of Digital or MIT not be
  34. used in advertising or publicity pertaining to distribution of the
  35. software without specific, written prior permission.  
  36.  
  37. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44.  
  45. ******************************************************************/
  46.  
  47. /* $Header: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcWLine.c,v 9.2 89/05/07 15:33:16 jeff Exp $ */
  48. /* $Source: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcWLine.c,v $ */
  49.  
  50. #ifndef lint
  51. static char *rcsid = "$Header: /andrew/X11/r3src/r3plus/server/ddx/ibm/ppc/RCS/ppcWLine.c,v 9.2 89/05/07 15:33:16 jeff Exp $" ;
  52. #endif
  53.  
  54. #include "X.h"
  55. #include "misc.h"
  56. #include "windowstr.h"
  57. #include "Xprotostr.h"
  58. #include "gcstruct.h"
  59. #include "scrnintstr.h"
  60. #include "miscstruct.h"
  61. #include "pixmap.h"
  62. #include "pixmapstr.h"
  63. #include "mifpoly.h"
  64. #include "mi.h"
  65.  
  66. #include "OScompiler.h"
  67.  
  68. static DDXPointPtr ppcRoundCap() ;
  69.  
  70. #define IS_VERT(pp) (pp[0].x == pp[1].x)
  71. #define IS_HORZ(pp) (pp[0].y == pp[1].y)
  72.  
  73. void
  74. ppcWideLine(pDrawable, pGC, mode, npt, pPts)
  75.     DrawablePtr pDrawable ;
  76.     GCPtr    pGC ;
  77.     int        mode ;
  78.     int        npt ;
  79.     DDXPointRec pPts[] ;
  80. {
  81.     miWideLine(pDrawable, pGC, mode, npt, nPts);
  82. }
  83.  
  84. #ifdef notdef
  85. /* PPCWIDELINE - Public entry for PolyLine call
  86.  * handles 1 segment wide lines specially.  Calls miWideLine
  87.  * for all other cases.  Code taken from miOneSegment.
  88.  */
  89. void
  90. ppcWideLine(pDrawable, pGC, mode, npt, pPts)
  91.     DrawablePtr pDrawable ;
  92.     GCPtr    pGC ;
  93.     int        mode ;
  94.     int        npt ;
  95.     DDXPointRec pPts[] ;
  96. {
  97.     int        width = (pGC->lineWidth ? pGC->lineWidth : 1) ;
  98.     DDXPointRec    tmpPts[4] ;
  99.     DDXPointRec    otmpPts[2] ;
  100.     SppPointRec SppPts[2] ;
  101.     SppPointRec PolyPoints[4] ;
  102.     xRectangle    tmpRect ;
  103.  
  104.     if ( pDrawable->type != DRAWABLE_WINDOW || npt > 2 ) {
  105.     miWideLine( pDrawable, pGC, mode, npt, pPts ) ;
  106.     return ;
  107.     }
  108.  
  109.     if ( npt == 1 )
  110.     tmpPts[0] = tmpPts[1] = pPts[0] ;
  111.     if ( npt == 2 ) {
  112.     tmpPts[0] = pPts[0] ;
  113.     tmpPts[1] = pPts[1] ;
  114.     }
  115.  
  116.     /* make everything absolute */
  117.     if ( mode == CoordModePrevious ) {
  118.     tmpPts[1].x += tmpPts[0].x ;
  119.         tmpPts[1].y += tmpPts[0].y ;
  120.     }
  121.     otmpPts[0] = tmpPts[0] ;
  122.     otmpPts[1] = tmpPts[1] ;
  123.  
  124.     if ( tmpPts[0].x > tmpPts[1].x ) {
  125.     DDXPointRec tp ;
  126.  
  127.     tp = tmpPts[0] ;
  128.     tmpPts[0] = tmpPts[1] ;
  129.     tmpPts[1] = tp ;
  130.     }
  131.  
  132.     if ( pGC->capStyle == CapProjecting ) {
  133.     if ( PtEqual(pPts[0], pPts[1] ) ) {
  134.         tmpPts[0].y -= width / 2.0 ;
  135.         tmpPts[1].y += width / 2.0 ;
  136.     }
  137.     else {
  138.         if ( IS_VERT( tmpPts ) ) {
  139.         tmpPts[0].y -= width / 2 ;
  140.         tmpPts[1].y += width / 2 ;
  141.         }
  142.         else {
  143.             if ( IS_HORZ( tmpPts ) ) {
  144.             tmpPts[0].x -= width / 2 ;
  145.             tmpPts[1].x += width / 2 ;
  146.             }
  147.             else {
  148.             SppPts[0].x = (double)tmpPts[0].x ;
  149.             SppPts[0].y = (double)tmpPts[0].y ;
  150.             SppPts[1].x = (double)tmpPts[1].x ;
  151.             SppPts[1].y = (double)tmpPts[1].y ;
  152.             if ( PtEqual( SppPts[0], SppPts[1] ) ) {
  153.                     SppPts[0].y -= width / 2.0 ;
  154.                     SppPts[1].y += width / 2.0 ;
  155.             }
  156.                 SppPts[0] = 
  157.                 miExtendSegment( SppPts[0], SppPts[1],
  158.                          width / 2 ) ;
  159.                 SppPts[1] =
  160.                 miExtendSegment( SppPts[1], SppPts[0],
  161.                          width / 2 ) ;
  162.         }
  163.         }
  164.     }
  165.     }
  166.  
  167.     /* get points for rect */
  168.  
  169.     if ( IS_VERT( tmpPts ) ) {
  170.     tmpRect.x = tmpPts[0].x - width / 2 ;
  171.     tmpRect.y = MIN(tmpPts[0].y, tmpPts[1].y) ;
  172.     tmpRect.width = width ;
  173.     tmpRect.height = ABS(tmpPts[1].y - tmpPts[0].y) ;
  174.     }
  175.     else {
  176.         if ( IS_HORZ( tmpPts ) ) {
  177.         tmpRect.y = tmpPts[0].y - width / 2 ;
  178.         tmpRect.x = tmpPts[0].x ;
  179.         tmpRect.height = width ;
  180.         tmpRect.width = tmpPts[1].x - tmpPts[0].x ;
  181.     }
  182.     else {
  183.         if ( pGC->capStyle != CapProjecting ) {
  184.             SppPts[0].x = (double)tmpPts[0].x ;
  185.             SppPts[0].y = (double)tmpPts[0].y ;
  186.             SppPts[1].x = (double)tmpPts[1].x ;
  187.             SppPts[1].y = (double)tmpPts[1].y ;
  188.         }
  189.             miGetPts( SppPts[0], SppPts[1], &PolyPoints[0], 
  190.                 &PolyPoints[1], &PolyPoints[2], &PolyPoints[3],
  191.               width ) ;
  192.  
  193.             if ( pGC->capStyle == CapRound ) {
  194.             register n ;
  195.             int n1, n2 ;
  196.             DDXPointPtr pt ;
  197.             DDXPointPtr pt1 ;
  198.             DDXPointPtr pt2 ;
  199.             DDXPointPtr ptOrig ;
  200.             DDXPointPtr pt1Orig ;
  201.             DDXPointPtr pt2Orig ;
  202.  
  203.             pt1Orig = pt1 = ppcRoundCap(pDrawable, pGC,
  204.                 SppPts[0], SppPts[1], PolyPoints[0],
  205.                   PolyPoints[3], FirstEnd, 0, 0, &n1) ;
  206.             pt2Orig = pt2 = ppcRoundCap(pDrawable, pGC,
  207.                 SppPts[1], SppPts[0], PolyPoints[2],
  208.                   PolyPoints[1], SecondEnd, 0, 0, &n2) ;
  209.             ptOrig = pt = ALLOCATE_LOCAL((n1 + n2) * sizeof(DDXPointRec)) ;
  210.             for ( n = n1 ; n-- ; pt++, pt1++ ) {
  211.                 pt->x = pt1->x ;
  212.                 pt->y = pt1->y ;
  213.             }
  214.             Xfree(pt1Orig) ;
  215.             for(n=n2 ;n-- ;pt++,pt2++) {
  216.                 pt->x = pt2->x ;
  217.                 pt->y = pt2->y ;
  218.             }
  219.             Xfree(pt2Orig) ;
  220.             (*pGC->ops->FillPolygon)(pDrawable, pGC,
  221.                 Convex, CoordModeOrigin, n1 + n2, ptOrig) ;
  222.             DEALLOCATE_LOCAL(ptOrig) ;
  223.             } else {
  224.             tmpPts[0].x = ROUNDTOINT(PolyPoints[0].x) ;
  225.             tmpPts[0].y = ROUNDTOINT(PolyPoints[0].y) ;
  226.             tmpPts[1].x = ROUNDTOINT(PolyPoints[1].x) ;
  227.             tmpPts[1].y = ROUNDTOINT(PolyPoints[1].y) ;
  228.             tmpPts[2].x = ROUNDTOINT(PolyPoints[2].x) ;
  229.             tmpPts[2].y = ROUNDTOINT(PolyPoints[2].y) ;
  230.             tmpPts[3].x = ROUNDTOINT(PolyPoints[3].x) ;
  231.             tmpPts[3].y = ROUNDTOINT(PolyPoints[3].y) ;
  232.             if(tmpPts[0].x == tmpPts[3].x)
  233.                 tmpPts[3].x++;
  234.             if(tmpPts[0].y == tmpPts[3].y)
  235.                 tmpPts[3].y++;
  236.             if(tmpPts[1].x == tmpPts[2].x)
  237.                 tmpPts[2].x++;
  238.             if(tmpPts[1].y == tmpPts[2].y)
  239.                 tmpPts[2].y++;
  240.             (*pGC->ops->FillPolygon)(pDrawable, pGC,
  241.                 Convex, CoordModeOrigin, 4, tmpPts) ;
  242.         }
  243.         return ;
  244.     }
  245.     }
  246.  
  247.     (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &tmpRect) ;
  248.  
  249.     if ( pGC->capStyle == CapRound ) {
  250.     register int w2 = width / 2 ;
  251.     SppPointRec pCenter, pEnd ;
  252.     SppPointRec pCorner, pOtherCorner ;
  253.  
  254.     pCenter.x = (double)otmpPts[0].x ;
  255.     pCenter.y = (double)otmpPts[0].y ;
  256.     pEnd.x = (double)otmpPts[1].x ;
  257.     pEnd.y = (double)otmpPts[1].y ;
  258.  
  259.     if (IS_VERT(otmpPts)) {
  260.         pCorner.x = pCenter.x + w2 ;
  261.         pCorner.y = pCenter.y ;
  262.         pOtherCorner.x = pCenter.x - w2 ;
  263.         pOtherCorner.y = pCenter.y ;
  264.     } else
  265.     if (IS_HORZ(otmpPts)) {
  266.         pCorner.x = pCenter.x ;
  267.         pCorner.y = pCenter.y + w2 ;
  268.         pOtherCorner.x = pCenter.x ;
  269.         pOtherCorner.y = pCenter.y - w2 ;
  270.     }
  271.     miRoundCap(pDrawable, pGC, pCenter, pEnd, pCorner,
  272.       pOtherCorner, FirstEnd, 0, 0, 0.0, 0.0) ;
  273.  
  274.     pCenter.x = (double)otmpPts[1].x ;
  275.     pCenter.y = (double)otmpPts[1].y ;
  276.     pEnd.x = (double)otmpPts[0].x ;
  277.     pEnd.y = (double)otmpPts[0].y ;
  278.  
  279.     if (IS_VERT(otmpPts)) {
  280.         pCorner.x = pCenter.x + w2 ;
  281.         pCorner.y = pCenter.y ;
  282.         pOtherCorner.x = pCenter.x - w2 ;
  283.         pOtherCorner.y = pCenter.y ;
  284.     } else {
  285.         pCorner.x = pCenter.x ;
  286.         pCorner.y = pCenter.y + w2 ;
  287.         pOtherCorner.x = pCenter.x ;
  288.         pOtherCorner.y = pCenter.y - w2 ;
  289.     }
  290.     miRoundCap(pDrawable, pGC, pCenter, pEnd, pCorner,
  291.       pOtherCorner, SecondEnd, 0, 0, 0.0, 0.0) ;
  292.     }
  293.     return ;
  294. }
  295.  
  296. /* ppcROUNDCAP -- a private helper function
  297.  * Put Rounded cap on end. pCenter is the center of this end of the line
  298.  * pEnd is the center of the other end of the line. pCorner is one of the
  299.  * two corners at this end of the line.  It doesn't matter which of the two
  300.  * corners you give it. pOtherCorner is the other one.
  301.  */
  302. static
  303. DDXPointPtr
  304. ppcRoundCap(pDraw, pGC, pCenter, pEnd, pCorner, pOtherCorner, fLineEnd,
  305.      xOrg, yOrg, cpt)
  306.     DrawablePtr    pDraw ;
  307.     GCPtr    pGC ;
  308.     SppPointRec    pCenter, pEnd ;
  309.     SppPointRec    pCorner, pOtherCorner ;
  310.     int        fLineEnd, xOrg, yOrg ;
  311.     int *cpt ;
  312. {
  313.     int        c, signc ;
  314.     double    width ;
  315.     double    dx, dy, hypot() ;
  316.     xArc    arc ;
  317.     DDXPointPtr pArcPts ;
  318.  
  319.     if (fLineEnd == NotEnd)
  320.     {
  321.     dx = pCenter.x - pCorner.x ;
  322.     dy = pCenter.y - pCorner.y ;
  323.     width = hypot(dx, dy) ;
  324.     }
  325.     else
  326.     width = (pGC->lineWidth ? pGC->lineWidth : 1) ;
  327.     if (PtEqual(pCenter, pEnd))
  328.     {
  329.     signc = 1 ;
  330.     }
  331.     else
  332.     {
  333.     c = (pCenter.x - pEnd.x) * (pCorner.y - pCenter.y) -
  334.          (pCorner.x - pCenter.x) * (pCenter.y - pEnd.y) ;
  335.     signc = -sign(c) ;
  336.     }
  337.  
  338.     /* These come back scaled by 64 and all ready to use */
  339.     arc.x = ROUNDTOINT(pCenter.x - width / 2) ;
  340.     arc.y = ROUNDTOINT(pCenter.y - width / 2) ;
  341.     arc.width = ROUNDTOINT(width) ;
  342.     arc.height = arc.width ;
  343.     arc.angle1 = -PtToAngle(pCenter, pCorner) ;
  344.     arc.angle2 = -signc * 180 * 64 ;
  345.     pArcPts = (DDXPointPtr)NULL ;
  346.     *cpt = miGetArcPts(&arc, 0, &pArcPts) ;
  347.     return(pArcPts) ;
  348. }
  349.  
  350. /* these are from <math.h>, but I'm told some systems don't have math.h Psi! */
  351. extern double sqrt(), cos(), sin(), atan() ;
  352. #define M_PI    3.14159265358979323846
  353. #define M_PI_2    1.57079632679489661923
  354.  
  355. /* PTTOANGLE -- a private helper function
  356.  * Given two points, compute the slope of the line segment
  357.  * Result is in radians * 64
  358.  */
  359. static
  360. int
  361. PtToAngle(c, p)
  362.     SppPointRec    c, p ;
  363. {
  364.     double    dx, dy, theta ;
  365.  
  366.     dx = p.x - c.x ;
  367.     dy  = p.y - c.y ;
  368.     if (dx == 0)
  369.     {
  370.     theta = (dy > 0) ? M_PI_2 : -M_PI_2 ;
  371.     }
  372.     else
  373.         theta =(atan(dy/dx)) ;
  374.     if (dx < 0)
  375.     theta += M_PI ;
  376.     theta = (theta * 64 * 180/M_PI) ;
  377.     return ROUNDTOINT(theta) ;
  378. }
  379. #endif /* notdef */
  380.