home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / cfb / cfb8line.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-09  |  16.8 KB  |  888 lines

  1. /*
  2.  * $XConsortium: cfb8line.c,v 1.19 91/07/09 16:07:32 rws Exp $
  3.  *
  4.  * Copyright 1990 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, MIT X Consortium
  24.  */
  25.  
  26. #include "X.h"
  27.  
  28. #include "gcstruct.h"
  29. #include "windowstr.h"
  30. #include "pixmapstr.h"
  31. #include "regionstr.h"
  32. #include "scrnintstr.h"
  33. #include "mistruct.h"
  34.  
  35. #include "cfb.h"
  36. #include "cfbmskbits.h"
  37. #include "cfbrrop.h"
  38.  
  39. #if defined(__GNUC__) && defined(mc68020)
  40. #define STUPID volatile
  41. #define REARRANGE
  42. #else
  43. #define STUPID
  44. #endif
  45.  
  46. #ifdef __GNUC__
  47. /* lame compiler doesn't even look at 'register' attributes */
  48. #define I_H do{
  49. #define I_T }while(0);
  50. #define IMPORTANT_START I_H I_H I_H I_H I_H I_H I_H I_H I_H I_H
  51. #define IMPORTANT_END    I_T I_T I_T I_T I_T I_T I_T I_T I_T I_T
  52. #else
  53. #define IMPORTANT_START
  54. #define IMPORTANT_END
  55. #endif
  56.  
  57. #define OUTCODES(result, x, y, box) \
  58.     if (x < box->x1) \
  59.     result |= OUT_LEFT; \
  60.     if (x >= box->x2) \
  61.     result |= OUT_RIGHT; \
  62.     if (y < box->y1) \
  63.     result |= OUT_ABOVE; \
  64.     if (y >= box->y2) \
  65.     result |= OUT_BELOW;
  66.  
  67. #define isClipped(c,ul,lr)  ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
  68.  
  69. #ifdef POLYSEGMENT
  70.  
  71. # ifdef sun
  72. #  define WIDTH_FAST  1152
  73. # endif
  74.  
  75. # ifdef ultrix
  76. #  define WIDTH_FAST  1024
  77. # endif
  78.  
  79. # ifdef Mips
  80. #  define WIDTH_FAST 4096
  81. # endif
  82. # ifdef WIDTH_FAST
  83. #  if WIDTH_FAST == 1024
  84. #   define FAST_MUL(y)    ((y) << 10)
  85. #  endif
  86.  
  87. #  if WIDTH_FAST == 1152
  88. #   define FAST_MUL(y)    (((y) << 10) + ((y) << 7))
  89. #  endif
  90.  
  91. #  if WIDTH_FAST == 1280
  92. #   define FAST_MUL(y)    (((y) << 10) + ((y) << 8))
  93. #  endif
  94.  
  95. #  if WIDTH_FAST == 2048
  96. #   define FAST_MUL(y)    ((y) << 11)
  97. #  endif
  98.  
  99. #  if WIDTH_FAST == 4096
  100. #   define FAST_MUL(y)    ((y) << 12)
  101. #  endif
  102. # endif
  103.  
  104. # if defined(WIDTH_SHIFT)
  105. #  ifdef FAST_MUL
  106. #   define FUNC_NAME(e)        RROP_NAME(RROP_NAME_CAT(e,Shift))
  107. #   if RROP == GXcopy
  108. #    define INCLUDE_OTHERS
  109. #    define SERIOUS_UNROLLING
  110. #   endif
  111. #   define INCLUDE_DRAW
  112. #   define NWIDTH(nwidth)   WIDTH_FAST
  113. #   define WIDTH_MUL(y,w)   FAST_MUL(y)
  114. #  endif
  115. # else
  116. #  define FUNC_NAME(e)        RROP_NAME(e)
  117. #  define WIDTH_MUL(y,w)    ((y) * (w))
  118. #  define NWIDTH(nwidth)    (nwidth)
  119. #  define INCLUDE_DRAW
  120. #  if !defined (FAST_MUL) && RROP == GXcopy
  121. #   define INCLUDE_OTHERS
  122. #   define SERIOUS_UNROLLING
  123. #  endif
  124. # endif
  125. #else
  126.  
  127. # define INCLUDE_DRAW
  128. # define WIDTH_MUL(y,w)    ((y) * (w))
  129. # define NWIDTH(nwidth)    nwidth
  130. # ifdef PREVIOUS
  131. #  define FUNC_NAME(e)    RROP_NAME(RROP_NAME_CAT(e,Previous))
  132. # else
  133. #  define FUNC_NAME(e)    RROP_NAME(e)
  134. #  if RROP == GXcopy
  135. #   define INCLUDE_OTHERS
  136. #   ifdef PLENTIFUL_REGISTERS
  137. #    define SAVE_X2Y2
  138. #   endif
  139. #   define ORIGIN
  140. #   define SERIOUS_UNROLLING
  141. #  else
  142. #   define EITHER_MODE
  143. #  endif
  144. # endif
  145. #endif
  146.  
  147. #ifdef INCLUDE_DRAW
  148.  
  149. int
  150. #ifdef POLYSEGMENT
  151. FUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit)
  152.     DrawablePtr    pDrawable;
  153.     GCPtr    pGC;
  154.     int        nseg;
  155.     xSegment    *pSegInit;
  156. #else
  157. FUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit)
  158.     DrawablePtr pDrawable;
  159.     GCPtr    pGC;
  160.     int    mode;        /* Origin or Previous */
  161.     int    npt;        /* number of points */
  162.     DDXPointPtr pptInit;
  163. #endif
  164. {
  165.     register int    e;
  166.     register int    y1_or_e1;
  167.     register unsigned char   *addrb;
  168.     register int    stepmajor;
  169.     register int    stepminor;
  170. #ifndef REARRANGE
  171.     register int    e3;
  172. #endif
  173. #ifdef mc68000
  174.     register short  x1_or_len;
  175. #else
  176.     register int    x1_or_len;
  177. #endif
  178.     RROP_DECLARE
  179.  
  180. #ifdef SAVE_X2Y2
  181. # define c2 y2
  182. #else
  183.     register int    c2;
  184. #endif
  185.  
  186.     register int    upperleft, lowerright;
  187. #ifdef POLYSEGMENT
  188.     register int    capStyle;
  189. #endif
  190. #ifdef SAVE_X2Y2
  191.     register int    x2, y2;
  192. # define X1  x1_or_len
  193. # define Y1  y1_or_e1
  194. # define X2  x2
  195. # define Y2  y2
  196. #else
  197. # ifdef POLYSEGMENT
  198. #  define X1  x1_or_len
  199. #  define Y1  y1_or_e1
  200. # else
  201. #  define X1  intToX(y1_or_e1)
  202. #  define Y1  intToY(y1_or_e1)
  203. # endif
  204. # define X2  intToX(c2)
  205. # define Y2  intToY(c2)
  206. #endif
  207.     unsigned long    ClipMask = 0x80008000;
  208.     unsigned char   *addr;
  209.     int            nwidth;
  210.     cfbPrivGCPtr    devPriv;
  211.     BoxPtr        extents;
  212.     int            *ppt;
  213.  
  214.     devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); 
  215.     cfbGetByteWidthAndPointer (pDrawable, nwidth, addr);
  216. #ifndef REARRANGE
  217.     RROP_FETCH_GCPRIV(devPriv);
  218. #endif
  219.     extents = &devPriv->pCompositeClip->extents;
  220.     c2 = *((int *) &pDrawable->x);
  221.     c2 -= (c2 & 0x8000) << 1;
  222.     upperleft = *((int *) &extents->x1) - c2;
  223.     lowerright = *((int *) &extents->x2) - c2 - 0x00010001;
  224.     addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x;
  225. #ifdef POLYSEGMENT
  226.     capStyle = pGC->capStyle - CapNotLast;
  227.     ppt = (int *) pSegInit;
  228.     while (nseg--)
  229. #else
  230.  
  231. #ifdef EITHER_MODE
  232.     mode -= CoordModePrevious;
  233. #endif
  234.     ppt = (int *) pptInit;
  235.     c2 = *ppt++;
  236.     if (isClipped (c2, upperleft, lowerright))
  237.     {
  238. #ifndef ORIGIN
  239. #ifdef EITHER_MODE
  240.     if (!mode)
  241. #endif
  242.     {
  243.         e = *ppt;
  244.         *ppt = e + c2 - ((e & 0x8000) << 1);
  245.     }
  246. #endif    
  247.     return 1;
  248.     }
  249. #ifdef SAVE_X2Y2
  250.     intToCoord(c2,x2,y2);
  251. #endif
  252.     addrb = addr + WIDTH_MUL(Y2, nwidth) + X2;
  253.     while (--npt)
  254. #endif
  255.     {
  256. #ifdef POLYSEGMENT
  257.     y1_or_e1 = ppt[0];
  258.     c2 = ppt[1];
  259.     ppt += 2;
  260.     if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright))
  261.         break;
  262.     intToCoord(y1_or_e1,x1_or_len,y1_or_e1);
  263.     /* compute now to avoid needing x1, y1 later */
  264.     addrb = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len;
  265. #else
  266. #ifndef SAVE_X2Y2
  267.     y1_or_e1 = c2;
  268. #else
  269.     y1_or_e1 = y2;
  270.     x1_or_len = x2;
  271. #endif
  272. #ifndef ORIGIN
  273.     e = c2;
  274.     c2 = *ppt++;
  275. #ifdef EITHER_MODE
  276.     if (!mode)
  277. #endif
  278.         c2 = c2 + e - ((c2 & 0x8000) << 1);
  279. #else
  280.     c2 = *ppt++;
  281. #endif
  282.     if (isClipped (c2, upperleft, lowerright))
  283.     {
  284. #ifndef ORIGIN
  285. #ifdef EITHER_MODE
  286.         if (!mode)
  287. #endif
  288.         {
  289.         ppt[-2] = e;
  290.         ppt[-1] = c2;
  291.         }
  292. #endif
  293.         break;
  294.     }
  295. #ifdef SAVE_X2Y2
  296.     intToCoord(c2,x2,y2);
  297. #endif
  298. #endif
  299.     stepmajor = 1;
  300.     if ((x1_or_len = X2 - X1) < 0)
  301.     {
  302.         x1_or_len = -x1_or_len;
  303.         stepmajor = -1;
  304.     }
  305.     stepminor = NWIDTH(nwidth);
  306.     if ((y1_or_e1 = Y2 - Y1) < 0)
  307.     {
  308.         y1_or_e1 = -y1_or_e1;
  309.         stepminor = -stepminor;
  310.     }
  311. #ifdef POLYSEGMENT
  312.     /*
  313.      * although the horizontal code works for polyline, it
  314.      * slows down 10 pixel lines by 15%.  Thus, this
  315.      * code is optimized for horizontal segments and
  316.      * random orientation lines, which seems like a reasonable
  317.      * assumption
  318.      */
  319.     if (y1_or_e1 != 0)
  320.     {
  321. #endif
  322.     if (x1_or_len < y1_or_e1)
  323.     {
  324. #ifdef REARRANGE
  325.         register int    e3;
  326. #endif
  327.  
  328.         e3 = x1_or_len;
  329.         x1_or_len = y1_or_e1;
  330.         y1_or_e1 = e3;
  331.  
  332.         e3 = stepminor;
  333.         stepminor = stepmajor;
  334.         stepmajor = e3;
  335.     }
  336.  
  337.     e = -x1_or_len;
  338. #ifdef POLYSEGMENT
  339.     if (!capStyle)
  340.         x1_or_len--;
  341. #endif
  342.  
  343.     {
  344. #ifdef REARRANGE
  345.     register int e3;
  346.     RROP_DECLARE
  347.     RROP_FETCH_GCPRIV(devPriv);
  348. #endif
  349.  
  350.     y1_or_e1 = y1_or_e1 << 1;
  351.     e3 = e << 1;
  352.  
  353. #define body {\
  354.         RROP_SOLID(addrb); \
  355.         addrb += stepmajor; \
  356.         e += y1_or_e1; \
  357.         if (e >= 0) \
  358.         { \
  359.         addrb += stepminor; \
  360.         e += e3; \
  361.          } \
  362.     }
  363.  
  364. #ifdef LARGE_INSTRUCTION_CACHE
  365.  
  366. # ifdef SERIOUS_UNROLLING
  367. #  define UNROLL    16
  368. # else
  369. #  define UNROLL    4
  370. # endif
  371. # define CASE(n)    case -n: body
  372.  
  373.     while ((x1_or_len -= UNROLL) >= 0)
  374.     {
  375.         body body body body
  376. # if UNROLL >= 8
  377.         body body body body
  378. # endif
  379. # if UNROLL >= 12
  380.         body body body body
  381. # endif
  382. # if UNROLL >= 16
  383.         body body body body
  384. # endif
  385.     }
  386.     switch (x1_or_len)
  387.     {
  388.     CASE(1) CASE(2) CASE(3)
  389. # if UNROLL >= 8
  390.     CASE(4) CASE(5) CASE(6) CASE(7)
  391. # endif
  392. # if UNROLL >= 12
  393.     CASE(8) CASE(9) CASE(10) CASE(11)
  394. # endif
  395. # if UNROLL >= 16
  396.     CASE(12) CASE(13) CASE(14) CASE(15)
  397. # endif
  398.     }
  399. #else
  400.  
  401.     IMPORTANT_START
  402.     IMPORTANT_START
  403.  
  404.     if (x1_or_len & 1)
  405.         body
  406.     x1_or_len >>= 1;
  407.     while (x1_or_len--) {
  408.         body body
  409.     }
  410.  
  411.     IMPORTANT_END
  412.     IMPORTANT_END
  413. #endif
  414.  
  415. #ifdef POLYSEGMENT
  416.     RROP_SOLID(addrb);
  417. #endif
  418.     }
  419. #undef body
  420. #ifdef POLYSEGMENT
  421.     }
  422.     else
  423.     {
  424. # ifndef POLYSEGMENT
  425.         unsigned char    *t;
  426. #endif
  427.  
  428. # ifdef REARRANGE
  429.         register int    e3;
  430.         RROP_DECLARE
  431.         RROP_FETCH_GCPRIV(devPriv);
  432. # endif
  433.         if (stepmajor < 0)
  434.         {
  435.         addrb -= x1_or_len;
  436. # ifndef POLYSEGMENT
  437.         t = addrb;
  438. # else
  439.         if (capStyle)
  440.             x1_or_len++;
  441.         else
  442. # endif
  443.             addrb++;
  444.         }
  445.         else
  446.         {
  447. # ifndef POLYSEGMENT
  448.         t = addrb + x1_or_len;
  449. # else
  450.         if (capStyle)
  451.             x1_or_len++;
  452. # endif
  453.         }
  454.         y1_or_e1 = ((int) addrb) & 3;
  455.         addrb = addrb - y1_or_e1;
  456.         if (y1_or_e1 + x1_or_len <= PPW)
  457.         {
  458.         if (x1_or_len)
  459.         {
  460.             maskpartialbits(y1_or_e1, x1_or_len, e)
  461.             RROP_SOLID_MASK((int *) addrb, e);
  462.         }
  463.         }
  464.         else
  465.         {
  466.             maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
  467.             if (e)
  468.             {
  469.             RROP_SOLID_MASK((int *) addrb, e);
  470.             addrb += 4;
  471.             }
  472.         RROP_SPAN(addrb, x1_or_len)
  473.             if (e3)
  474.             RROP_SOLID_MASK((int *) addrb, e3);
  475.         }
  476. # ifndef POLYSEGMENT
  477.         addrb = t;
  478. # endif
  479.     }
  480. #endif
  481.     }
  482. #ifdef POLYSEGMENT
  483.     if (nseg >= 0)
  484.     return (xSegment *) ppt - pSegInit;
  485. #else
  486.     if (npt)
  487.     return ((DDXPointPtr) ppt - pptInit) - 1;
  488. #endif
  489.  
  490. #ifndef POLYSEGMENT
  491. # ifndef ORIGIN
  492. #  define C2  c2
  493. # else
  494. #  define C2  ppt[-1]
  495. # endif
  496.     if (pGC->capStyle != CapNotLast && C2 != *((int *) pptInit))
  497.     {
  498. # ifdef REARRANGE
  499.     RROP_DECLARE
  500.  
  501.     RROP_FETCH_GCPRIV(devPriv);
  502. # endif
  503.     RROP_SOLID (addrb);
  504.     }
  505. #endif
  506.     return -1;
  507. }
  508.  
  509. #endif /* INCLUDE_DRAW */
  510.  
  511.  
  512. #ifdef INCLUDE_OTHERS
  513.  
  514. extern void cfb8ClippedLineCopy(), cfb8ClippedLineXor(), cfb8ClippedLineGeneral(); 
  515.  
  516. #ifdef POLYSEGMENT
  517.  
  518. extern int cfb8SegmentSS1RectCopy(), cfb8SegmentSS1RectXor(), cfb8SegmentSS1RectGeneral(); 
  519. #ifdef FAST_MUL
  520. extern int cfb8SegmentSS1RectShiftCopy();
  521. #endif
  522.  
  523. void
  524. cfb8SegmentSS1Rect (pDrawable, pGC, nseg, pSegInit)
  525.     DrawablePtr        pDrawable;
  526.     GCPtr        pGC;
  527.     int            nseg;
  528.     xSegment        *pSegInit;
  529. {
  530.     int        (*func)();
  531.     void    (*clip)();
  532.     int        drawn;
  533.     cfbPrivGCPtr    devPriv;
  534.  
  535.     devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); 
  536.     switch (devPriv->rop)
  537.     {
  538.     case GXcopy:
  539.     func = cfb8SegmentSS1RectCopy;
  540.     clip = cfb8ClippedLineCopy;
  541. #ifdef FAST_MUL
  542.     if (cfbGetByteWidth (pDrawable) == WIDTH_FAST)
  543.         func = cfb8SegmentSS1RectShiftCopy;
  544. #endif
  545.     break;
  546.     case GXxor:
  547.     func = cfb8SegmentSS1RectXor;
  548.     clip = cfb8ClippedLineXor;
  549.     break;
  550.     default:
  551.     func = cfb8SegmentSS1RectGeneral;
  552.     clip = cfb8ClippedLineGeneral;
  553.     break;
  554.     }
  555.     while (nseg)
  556.     {
  557.     drawn = (*func) (pDrawable, pGC, nseg, pSegInit);
  558.     if (drawn == -1)
  559.         break;
  560.     (*clip) (pDrawable, pGC,
  561.              pSegInit[drawn-1].x1, pSegInit[drawn-1].y1,
  562.              pSegInit[drawn-1].x2, pSegInit[drawn-1].y2,
  563.              &devPriv->pCompositeClip->extents,
  564.              pGC->capStyle == CapNotLast);
  565.     pSegInit += drawn;
  566.     nseg -= drawn;
  567.     }
  568. }
  569.  
  570. #else /* POLYSEGMENT */
  571.  
  572. extern int cfb8LineSS1RectCopy(), cfb8LineSS1RectXor(), cfb8LineSS1RectGeneral(); 
  573. extern int cfb8LineSS1RectPreviousCopy();
  574.  
  575. void
  576. cfb8LineSS1Rect (pDrawable, pGC, mode, npt, pptInit)
  577.     DrawablePtr    pDrawable;
  578.     GCPtr    pGC;
  579.     int        mode;
  580.     int        npt;
  581.     DDXPointPtr    pptInit;
  582. {
  583.     int        (*func)();
  584.     void    (*clip)();
  585.     int        drawn;
  586.     cfbPrivGCPtr    devPriv;
  587.  
  588.     devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); 
  589.     switch (devPriv->rop)
  590.     {
  591.     case GXcopy:
  592.     func = cfb8LineSS1RectCopy;
  593.     clip = cfb8ClippedLineCopy;
  594.     if (mode == CoordModePrevious)
  595.         func = cfb8LineSS1RectPreviousCopy;
  596.     break;
  597.     case GXxor:
  598.     func = cfb8LineSS1RectXor;
  599.     clip = cfb8ClippedLineXor;
  600.     break;
  601.     default:
  602.     func = cfb8LineSS1RectGeneral;
  603.     clip = cfb8ClippedLineGeneral;
  604.     break;
  605.     }
  606.     while (npt > 1)
  607.     {
  608.     drawn = (*func) (pDrawable, pGC, mode, npt, pptInit);
  609.     if (drawn == -1)
  610.         break;
  611.     (*clip) (pDrawable, pGC,
  612.              pptInit[drawn-1].x, pptInit[drawn-1].y,
  613.              pptInit[drawn].x, pptInit[drawn].y,
  614.              &devPriv->pCompositeClip->extents,
  615.              drawn != npt - 1 || pGC->capStyle == CapNotLast);
  616.     pptInit += drawn;
  617.     npt -= drawn;
  618.     }
  619. }
  620.  
  621. #define round(dividend, divisor) \
  622. ( (((dividend)<<1) + (divisor)) / ((divisor)<<1) )
  623. #define ceiling(m,n)  (((m)-1)/(n) + 1)
  624. #define SignTimes(sign,n)   (((sign) < 0) ? -(n) : (n))
  625.  
  626. cfbClipPoint (oc, xp, yp, dx, dy, boxp)
  627.     int    oc;
  628.     int    *xp, *yp;
  629.     BoxPtr  boxp;
  630. {
  631.     int    x, y;
  632.     int    adx, ady, signdx, signdy;
  633.     int    utmp;
  634.     
  635.     signdx = 1;
  636.     if (dx < 0)
  637.     {
  638.         signdx = -1;
  639.         dx = -dx;
  640.     }
  641.     signdy = 1;
  642.     if (dy  < 0)
  643.     {
  644.         signdy = -1;
  645.         dy = -dy;
  646.     }
  647.     if (oc & (OUT_LEFT | OUT_RIGHT))
  648.     {
  649.         if (oc & OUT_LEFT)
  650.         {
  651.         x = boxp->x1;
  652.         utmp = x - *xp;
  653.         }
  654.         else
  655.         {
  656.         x = boxp->x2 - 1;
  657.         utmp = *xp - x;
  658.         }
  659.         utmp *= dy;
  660.     if (dy > dx)
  661.     {
  662.         utmp = (utmp << 1) - dy + 1;
  663.         y = *yp + SignTimes(signdy, ceiling(utmp, (dx << 1)));
  664.     }
  665.     else
  666.     {
  667.             y = *yp + SignTimes(signdy, round(utmp, dx));
  668.     }
  669.     oc = 0;
  670.     OUTCODES (oc, x, y, boxp);
  671.     }
  672.     if (oc & (OUT_ABOVE | OUT_BELOW))
  673.     {
  674.         if (oc & OUT_ABOVE)
  675.         {
  676.             y = boxp->y1;
  677.             utmp = y - *yp;
  678.         }
  679.         else
  680.         {
  681.             y = boxp->y2 - 1;
  682.             utmp = *yp - y;
  683.         }
  684.     utmp *= dx;
  685.     if (dx > dy)
  686.     {
  687.         utmp = (utmp << 1) - dx + 1;
  688.         x = *xp + SignTimes(signdx, ceiling(utmp, (dy << 1)));
  689.     }
  690.     else
  691.     {
  692.         x = *xp + SignTimes(signdx, round(utmp, dy));
  693.     }
  694.     oc = 0;
  695.     OUTCODES (oc, x, y, boxp);
  696.     }
  697.     *xp = x;
  698.     *yp = y;
  699.     return oc;
  700. }
  701.  
  702. #endif /* else POLYSEGMENT */
  703. #endif /* INCLUDE_OTHERS */
  704.  
  705. #if !defined(POLYSEGMENT) && !defined (PREVIOUS)
  706.  
  707. void
  708. RROP_NAME (cfb8ClippedLine) (pDrawable, pGC, x1, y1, x2, y2, boxp, shorten)
  709.     DrawablePtr    pDrawable;
  710.     GCPtr    pGC;
  711.     int        x1, y1, x2, y2;
  712.     BoxPtr    boxp;
  713.     Bool    shorten;
  714. {
  715.     int            oc1, oc2;
  716.     int            signdx, signdy, axis, e, e1, e3, len;
  717.     int            adx, ady;
  718.  
  719.     unsigned char   *addr;
  720.     int            nwidth;
  721.     int            stepx, stepy;
  722.     int            xorg, yorg;
  723.  
  724.  
  725.     cfbGetByteWidthAndPointer(pDrawable, nwidth, addr);
  726.  
  727.     xorg = pDrawable->x;
  728.     yorg = pDrawable->y;
  729.     x1 += xorg;
  730.     y1 += yorg;
  731.     x2 += xorg;
  732.     y2 += yorg;
  733.     oc1 = 0;
  734.     oc2 = 0;
  735.     OUTCODES (oc1, x1, y1, boxp);
  736.     OUTCODES (oc2, x2, y2, boxp);
  737.  
  738.     if (oc1 & oc2)
  739.     return;
  740.  
  741.     signdx = 1;
  742.     stepx = 1;
  743.     if ((adx = x2 - x1) < 0)
  744.     {
  745.     adx = -adx;
  746.     signdx = -1;
  747.     stepx = -1;
  748.     }
  749.     signdy = 1;
  750.     stepy = nwidth;
  751.     if ((ady = y2 - y1) < 0)
  752.     {
  753.     ady = -ady;
  754.     signdy = -1;
  755.     stepy = -nwidth;
  756.     }
  757.     axis = X_AXIS;
  758.     if (adx <= ady)
  759.     {
  760.     int    t;
  761.  
  762.     t = adx;
  763.     adx = ady;
  764.     ady = t;
  765.  
  766.     t = stepx;
  767.     stepx = stepy;
  768.     stepy = t;
  769.     
  770.     axis = Y_AXIS;
  771.     }
  772.     e1 = ady << 1;
  773.     e3 = - (adx << 1);
  774.     e = - adx;
  775.     len = adx;
  776.     if (oc2)
  777.     {
  778.     int xt = x2, yt = y2;
  779.     int    dx = x2 - x1, dy = y2 - y1;
  780.     int change;
  781.  
  782.     oc2 = cfbClipPoint (oc2, &xt, &yt, -dx, -dy, boxp);
  783.     if (axis == Y_AXIS)
  784.         change = y2 - yt;
  785.     else
  786.         change = x2 - xt;
  787.     if (change < 0)
  788.         change = -change;
  789.     len -= change;
  790.     } else if (shorten)
  791.     len--;
  792.     if (oc1)
  793.     {
  794.     int    xt = x1, yt = y1;
  795.     int    dx = x2 - x1, dy = y2 - y1;
  796.     int    changex, changey;
  797.  
  798.     oc1 = cfbClipPoint (oc1, &xt, &yt, dx, dy, boxp);
  799.     changex = x1 - xt;
  800.     if (changex < 0)
  801.         changex = -changex;
  802.     changey = y1 - yt;
  803.     if (changey < 0)
  804.         changey = -changey;
  805.     if (axis == X_AXIS)
  806.     {
  807.         len -= changex;
  808.         e = e + changey * e3 + changex * e1;
  809.     }
  810.     else
  811.     {
  812.         len -= changey;
  813.         e = e + changex * e3 + changey * e1;
  814.     }
  815.     x1 = xt;
  816.     y1 = yt;
  817.     }
  818.     if (oc1 | oc2 || len < 0)
  819.     return;
  820.  
  821.     {
  822.     register unsigned char    *addrb;
  823.     RROP_DECLARE
  824.  
  825.     RROP_FETCH_GC(pGC);
  826.  
  827.     addrb = addr + (y1 * nwidth) + x1;
  828.  
  829. #ifndef REARRANGE
  830.     if (!ady)
  831.     {
  832. #define body    { RROP_SOLID(addrb); addrb += stepx; }
  833.     while (len >= 4)
  834.     {
  835.         body body body body
  836.         len -= 4;
  837.     }
  838.     switch (len)
  839.     {
  840.     case  3: body case 2: body case 1: body
  841.     }
  842. #undef body
  843.     }
  844.     else
  845. #endif
  846.     {
  847. #define body {\
  848.         RROP_SOLID(addrb); \
  849.         addrb += stepx; \
  850.         e += e1; \
  851.         if (e >= 0) \
  852.         { \
  853.         addrb += stepy; \
  854.         e += e3; \
  855.          } \
  856.     }
  857.  
  858. #ifdef LARGE_INSTRUCTION_CACHE
  859.     while ((len -= 4) >= 0)
  860.     {
  861.         body body body body
  862.     }
  863.     switch (len)
  864.     {
  865.     case  -1: body case -2: body case -3: body
  866.     }
  867. #else
  868.     IMPORTANT_START
  869.  
  870.     while ((len -= 2) >= 0)
  871.     {
  872.         body body
  873.     }
  874.     if (len & 1)
  875.         body;
  876.  
  877.     IMPORTANT_END
  878.  
  879. #endif
  880.     }
  881.     RROP_SOLID(addrb);
  882. #undef body
  883.  
  884.     }
  885. }
  886.  
  887. #endif /* !POLYSEGMENT && !PREVIOUS */
  888.