fbbits.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. /*
  2. *
  3. * Copyright © 1998 Keith Packard
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and its
  6. * documentation for any purpose is hereby granted without fee, provided that
  7. * the above copyright notice appear in all copies and that both that
  8. * copyright notice and this permission notice appear in supporting
  9. * documentation, and that the name of Keith Packard not be used in
  10. * advertising or publicity pertaining to distribution of the software without
  11. * specific, written prior permission. Keith Packard makes no
  12. * representations about the suitability of this software for any purpose. It
  13. * is provided "as is" without express or implied warranty.
  14. *
  15. * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  16. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  17. * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  18. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  19. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  20. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21. * PERFORMANCE OF THIS SOFTWARE.
  22. */
  23. /*
  24. * This file defines functions for drawing some primitives using
  25. * underlying datatypes instead of masks
  26. */
  27. #define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & 0x80008000)
  28. #ifdef HAVE_DIX_CONFIG_H
  29. #include <dix-config.h>
  30. #endif
  31. #ifdef BITSMUL
  32. #define MUL BITSMUL
  33. #else
  34. #define MUL 1
  35. #endif
  36. #ifdef BITSSTORE
  37. #define STORE(b,x) BITSSTORE(b,x)
  38. #else
  39. #define STORE(b,x) (*(b) = (x))
  40. #endif
  41. #ifdef BITSRROP
  42. #define RROP(b,a,x) BITSRROP(b,a,x)
  43. #else
  44. #define RROP(b,a,x) (*(b) = FbDoRRop (*(b), (a), (x)))
  45. #endif
  46. #ifdef BITSUNIT
  47. #define UNIT BITSUNIT
  48. #define USE_SOLID
  49. #else
  50. #define UNIT BITS
  51. #endif
  52. /*
  53. * Define the following before including this file:
  54. *
  55. * BRESSOLID name of function for drawing a solid segment
  56. * BRESDASH name of function for drawing a dashed segment
  57. * DOTS name of function for drawing dots
  58. * ARC name of function for drawing a solid arc
  59. * BITS type of underlying unit
  60. */
  61. #ifdef BRESSOLID
  62. void
  63. BRESSOLID(DrawablePtr pDrawable,
  64. GCPtr pGC,
  65. int dashOffset,
  66. int signdx,
  67. int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
  68. {
  69. FbBits *dst;
  70. FbStride dstStride;
  71. int dstBpp;
  72. int dstXoff, dstYoff;
  73. FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
  74. UNIT *bits;
  75. FbStride bitsStride;
  76. FbStride majorStep, minorStep;
  77. BITS xor = (BITS) pPriv->xor;
  78. fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
  79. bits =
  80. ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
  81. bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  82. if (signdy < 0)
  83. bitsStride = -bitsStride;
  84. if (axis == X_AXIS) {
  85. majorStep = signdx * MUL;
  86. minorStep = bitsStride;
  87. }
  88. else {
  89. majorStep = bitsStride;
  90. minorStep = signdx * MUL;
  91. }
  92. while (len--) {
  93. STORE(bits, xor);
  94. bits += majorStep;
  95. e += e1;
  96. if (e >= 0) {
  97. bits += minorStep;
  98. e += e3;
  99. }
  100. }
  101. }
  102. #endif
  103. #ifdef BRESDASH
  104. void
  105. BRESDASH(DrawablePtr pDrawable,
  106. GCPtr pGC,
  107. int dashOffset,
  108. int signdx,
  109. int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
  110. {
  111. FbBits *dst;
  112. FbStride dstStride;
  113. int dstBpp;
  114. int dstXoff, dstYoff;
  115. FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
  116. UNIT *bits;
  117. FbStride bitsStride;
  118. FbStride majorStep, minorStep;
  119. BITS xorfg, xorbg;
  120. FbDashDeclare;
  121. int dashlen;
  122. Bool even;
  123. Bool doOdd;
  124. fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
  125. doOdd = pGC->lineStyle == LineDoubleDash;
  126. xorfg = (BITS) pPriv->xor;
  127. xorbg = (BITS) pPriv->bgxor;
  128. FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
  129. bits =
  130. ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
  131. bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  132. if (signdy < 0)
  133. bitsStride = -bitsStride;
  134. if (axis == X_AXIS) {
  135. majorStep = signdx * MUL;
  136. minorStep = bitsStride;
  137. }
  138. else {
  139. majorStep = bitsStride;
  140. minorStep = signdx * MUL;
  141. }
  142. if (dashlen >= len)
  143. dashlen = len;
  144. if (doOdd) {
  145. if (!even)
  146. goto doubleOdd;
  147. for (;;) {
  148. len -= dashlen;
  149. while (dashlen--) {
  150. STORE(bits, xorfg);
  151. bits += majorStep;
  152. if ((e += e1) >= 0) {
  153. e += e3;
  154. bits += minorStep;
  155. }
  156. }
  157. if (!len)
  158. break;
  159. FbDashNextEven(dashlen);
  160. if (dashlen >= len)
  161. dashlen = len;
  162. doubleOdd:
  163. len -= dashlen;
  164. while (dashlen--) {
  165. STORE(bits, xorbg);
  166. bits += majorStep;
  167. if ((e += e1) >= 0) {
  168. e += e3;
  169. bits += minorStep;
  170. }
  171. }
  172. if (!len)
  173. break;
  174. FbDashNextOdd(dashlen);
  175. if (dashlen >= len)
  176. dashlen = len;
  177. }
  178. }
  179. else {
  180. if (!even)
  181. goto onOffOdd;
  182. for (;;) {
  183. len -= dashlen;
  184. while (dashlen--) {
  185. STORE(bits, xorfg);
  186. bits += majorStep;
  187. if ((e += e1) >= 0) {
  188. e += e3;
  189. bits += minorStep;
  190. }
  191. }
  192. if (!len)
  193. break;
  194. FbDashNextEven(dashlen);
  195. if (dashlen >= len)
  196. dashlen = len;
  197. onOffOdd:
  198. len -= dashlen;
  199. while (dashlen--) {
  200. bits += majorStep;
  201. if ((e += e1) >= 0) {
  202. e += e3;
  203. bits += minorStep;
  204. }
  205. }
  206. if (!len)
  207. break;
  208. FbDashNextOdd(dashlen);
  209. if (dashlen >= len)
  210. dashlen = len;
  211. }
  212. }
  213. }
  214. #endif
  215. #ifdef DOTS
  216. void
  217. DOTS(FbBits * dst,
  218. FbStride dstStride,
  219. int dstBpp,
  220. BoxPtr pBox,
  221. xPoint * ptsOrig,
  222. int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor)
  223. {
  224. INT32 *pts = (INT32 *) ptsOrig;
  225. UNIT *bits = (UNIT *) dst;
  226. UNIT *point;
  227. BITS bxor = (BITS) xor;
  228. BITS band = (BITS) and;
  229. FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  230. INT32 ul, lr;
  231. INT32 pt;
  232. ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg);
  233. lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1);
  234. bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL;
  235. if (and == 0) {
  236. while (npt--) {
  237. pt = *pts++;
  238. if (!isClipped(pt, ul, lr)) {
  239. point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
  240. STORE(point, bxor);
  241. }
  242. }
  243. }
  244. else {
  245. while (npt--) {
  246. pt = *pts++;
  247. if (!isClipped(pt, ul, lr)) {
  248. point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
  249. RROP(point, band, bxor);
  250. }
  251. }
  252. }
  253. }
  254. #endif
  255. #ifdef ARC
  256. #define ARCCOPY(d) STORE(d,xorBits)
  257. #define ARCRROP(d) RROP(d,andBits,xorBits)
  258. void
  259. ARC(FbBits * dst,
  260. FbStride dstStride,
  261. int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor)
  262. {
  263. UNIT *bits;
  264. FbStride bitsStride;
  265. miZeroArcRec info;
  266. Bool do360;
  267. int x;
  268. UNIT *yorgp, *yorgop;
  269. BITS andBits, xorBits;
  270. int yoffset, dyoffset;
  271. int y, a, b, d, mask;
  272. int k1, k3, dx, dy;
  273. bits = (UNIT *) dst;
  274. bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  275. andBits = (BITS) and;
  276. xorBits = (BITS) xor;
  277. do360 = miZeroArcSetup(arc, &info, TRUE);
  278. yorgp = bits + ((info.yorg + drawY) * bitsStride);
  279. yorgop = bits + ((info.yorgo + drawY) * bitsStride);
  280. info.xorg = (info.xorg + drawX) * MUL;
  281. info.xorgo = (info.xorgo + drawX) * MUL;
  282. MIARCSETUP();
  283. yoffset = y ? bitsStride : 0;
  284. dyoffset = 0;
  285. mask = info.initialMask;
  286. if (!(arc->width & 1)) {
  287. if (andBits == 0) {
  288. if (mask & 2)
  289. ARCCOPY(yorgp + info.xorgo);
  290. if (mask & 8)
  291. ARCCOPY(yorgop + info.xorgo);
  292. }
  293. else {
  294. if (mask & 2)
  295. ARCRROP(yorgp + info.xorgo);
  296. if (mask & 8)
  297. ARCRROP(yorgop + info.xorgo);
  298. }
  299. }
  300. if (!info.end.x || !info.end.y) {
  301. mask = info.end.mask;
  302. info.end = info.altend;
  303. }
  304. if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
  305. int xoffset = bitsStride;
  306. UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
  307. UNIT *yorgohb = yorghb - info.h * MUL;
  308. yorgp += info.xorg;
  309. yorgop += info.xorg;
  310. yorghb += info.h * MUL;
  311. while (1) {
  312. if (andBits == 0) {
  313. ARCCOPY(yorgp + yoffset + x * MUL);
  314. ARCCOPY(yorgp + yoffset - x * MUL);
  315. ARCCOPY(yorgop - yoffset - x * MUL);
  316. ARCCOPY(yorgop - yoffset + x * MUL);
  317. }
  318. else {
  319. ARCRROP(yorgp + yoffset + x * MUL);
  320. ARCRROP(yorgp + yoffset - x * MUL);
  321. ARCRROP(yorgop - yoffset - x * MUL);
  322. ARCRROP(yorgop - yoffset + x * MUL);
  323. }
  324. if (a < 0)
  325. break;
  326. if (andBits == 0) {
  327. ARCCOPY(yorghb - xoffset - y * MUL);
  328. ARCCOPY(yorgohb - xoffset + y * MUL);
  329. ARCCOPY(yorgohb + xoffset + y * MUL);
  330. ARCCOPY(yorghb + xoffset - y * MUL);
  331. }
  332. else {
  333. ARCRROP(yorghb - xoffset - y * MUL);
  334. ARCRROP(yorgohb - xoffset + y * MUL);
  335. ARCRROP(yorgohb + xoffset + y * MUL);
  336. ARCRROP(yorghb + xoffset - y * MUL);
  337. }
  338. xoffset += bitsStride;
  339. MIARCCIRCLESTEP(yoffset += bitsStride;
  340. );
  341. }
  342. yorgp -= info.xorg;
  343. yorgop -= info.xorg;
  344. x = info.w;
  345. yoffset = info.h * bitsStride;
  346. }
  347. else if (do360) {
  348. while (y < info.h || x < info.w) {
  349. MIARCOCTANTSHIFT(dyoffset = bitsStride;
  350. );
  351. if (andBits == 0) {
  352. ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
  353. ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
  354. ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
  355. ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
  356. }
  357. else {
  358. ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
  359. ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
  360. ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
  361. ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
  362. }
  363. MIARCSTEP(yoffset += dyoffset;
  364. , yoffset += bitsStride;
  365. );
  366. }
  367. }
  368. else {
  369. while (y < info.h || x < info.w) {
  370. MIARCOCTANTSHIFT(dyoffset = bitsStride;
  371. );
  372. if ((x == info.start.x) || (y == info.start.y)) {
  373. mask = info.start.mask;
  374. info.start = info.altstart;
  375. }
  376. if (andBits == 0) {
  377. if (mask & 1)
  378. ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
  379. if (mask & 2)
  380. ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
  381. if (mask & 4)
  382. ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
  383. if (mask & 8)
  384. ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
  385. }
  386. else {
  387. if (mask & 1)
  388. ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
  389. if (mask & 2)
  390. ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
  391. if (mask & 4)
  392. ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
  393. if (mask & 8)
  394. ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
  395. }
  396. if ((x == info.end.x) || (y == info.end.y)) {
  397. mask = info.end.mask;
  398. info.end = info.altend;
  399. }
  400. MIARCSTEP(yoffset += dyoffset;
  401. , yoffset += bitsStride;
  402. );
  403. }
  404. }
  405. if ((x == info.start.x) || (y == info.start.y))
  406. mask = info.start.mask;
  407. if (andBits == 0) {
  408. if (mask & 1)
  409. ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
  410. if (mask & 4)
  411. ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
  412. if (arc->height & 1) {
  413. if (mask & 2)
  414. ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
  415. if (mask & 8)
  416. ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
  417. }
  418. }
  419. else {
  420. if (mask & 1)
  421. ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
  422. if (mask & 4)
  423. ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
  424. if (arc->height & 1) {
  425. if (mask & 2)
  426. ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
  427. if (mask & 8)
  428. ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
  429. }
  430. }
  431. }
  432. #undef ARCCOPY
  433. #undef ARCRROP
  434. #endif
  435. #ifdef GLYPH
  436. #if BITMAP_BIT_ORDER == LSBFirst
  437. # define WRITE_ADDR1(n) (n)
  438. # define WRITE_ADDR2(n) (n)
  439. # define WRITE_ADDR4(n) (n)
  440. #else
  441. # define WRITE_ADDR1(n) ((n) ^ 3)
  442. # define WRITE_ADDR2(n) ((n) ^ 2)
  443. # define WRITE_ADDR4(n) ((n))
  444. #endif
  445. #define WRITE1(d,n,fg) ((d)[WRITE_ADDR1(n)] = (BITS) (fg))
  446. #ifdef BITS2
  447. # define WRITE2(d,n,fg) (*((BITS2 *) &((d)[WRITE_ADDR2(n)])) = (BITS2) (fg))
  448. #else
  449. # define WRITE2(d,n,fg) WRITE1(d,(n)+1,WRITE1(d,n,fg))
  450. #endif
  451. #ifdef BITS4
  452. # define WRITE4(d,n,fg) (*((BITS4 *) &((d)[WRITE_ADDR4(n)])) = (BITS4) (fg))
  453. #else
  454. # define WRITE4(d,n,fg) WRITE2(d,(n)+2,WRITE2(d,n,fg))
  455. #endif
  456. void
  457. GLYPH(FbBits * dstBits,
  458. FbStride dstStride,
  459. int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
  460. {
  461. int lshift;
  462. FbStip bits;
  463. BITS *dstLine;
  464. BITS *dst;
  465. int n;
  466. int shift;
  467. dstLine = (BITS *) dstBits;
  468. dstLine += x & ~3;
  469. dstStride *= (sizeof(FbBits) / sizeof(BITS));
  470. shift = x & 3;
  471. lshift = 4 - shift;
  472. while (height--) {
  473. bits = *stipple++;
  474. dst = (BITS *) dstLine;
  475. n = lshift;
  476. while (bits) {
  477. switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
  478. case 0:
  479. break;
  480. case 1:
  481. WRITE1(dst, 0, fg);
  482. break;
  483. case 2:
  484. WRITE1(dst, 1, fg);
  485. break;
  486. case 3:
  487. WRITE2(dst, 0, fg);
  488. break;
  489. case 4:
  490. WRITE1(dst, 2, fg);
  491. break;
  492. case 5:
  493. WRITE1(dst, 0, fg);
  494. WRITE1(dst, 2, fg);
  495. break;
  496. case 6:
  497. WRITE1(dst, 1, fg);
  498. WRITE1(dst, 2, fg);
  499. break;
  500. case 7:
  501. WRITE2(dst, 0, fg);
  502. WRITE1(dst, 2, fg);
  503. break;
  504. case 8:
  505. WRITE1(dst, 3, fg);
  506. break;
  507. case 9:
  508. WRITE1(dst, 0, fg);
  509. WRITE1(dst, 3, fg);
  510. break;
  511. case 10:
  512. WRITE1(dst, 1, fg);
  513. WRITE1(dst, 3, fg);
  514. break;
  515. case 11:
  516. WRITE2(dst, 0, fg);
  517. WRITE1(dst, 3, fg);
  518. break;
  519. case 12:
  520. WRITE2(dst, 2, fg);
  521. break;
  522. case 13:
  523. WRITE1(dst, 0, fg);
  524. WRITE2(dst, 2, fg);
  525. break;
  526. case 14:
  527. WRITE1(dst, 1, fg);
  528. WRITE2(dst, 2, fg);
  529. break;
  530. case 15:
  531. WRITE4(dst, 0, fg);
  532. break;
  533. }
  534. bits = FbStipLeft(bits, n);
  535. n = 4;
  536. dst += 4;
  537. }
  538. dstLine += dstStride;
  539. }
  540. }
  541. #undef WRITE_ADDR1
  542. #undef WRITE_ADDR2
  543. #undef WRITE_ADDR4
  544. #undef WRITE1
  545. #undef WRITE2
  546. #undef WRITE4
  547. #endif
  548. #ifdef POLYLINE
  549. void
  550. POLYLINE(DrawablePtr pDrawable,
  551. GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig)
  552. {
  553. INT32 *pts = (INT32 *) ptsOrig;
  554. int xoff = pDrawable->x;
  555. int yoff = pDrawable->y;
  556. unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
  557. BoxPtr pBox = REGION_EXTENTS(fbGetCompositeClip(pGC));
  558. FbBits *dst;
  559. int dstStride;
  560. int dstBpp;
  561. int dstXoff, dstYoff;
  562. UNIT *bits, *bitsBase;
  563. FbStride bitsStride;
  564. BITS xor = fbGetGCPrivate(pGC)->xor;
  565. BITS and = fbGetGCPrivate(pGC)->and;
  566. int dashoffset = 0;
  567. INT32 ul, lr;
  568. INT32 pt1, pt2;
  569. int e, e1, e3, len;
  570. int stepmajor, stepminor;
  571. int octant;
  572. if (mode == CoordModePrevious)
  573. fbFixCoordModePrevious(npt, ptsOrig);
  574. fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
  575. bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  576. bitsBase =
  577. ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
  578. ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
  579. lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
  580. pt1 = *pts++;
  581. npt--;
  582. pt2 = *pts++;
  583. npt--;
  584. for (;;) {
  585. if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
  586. fbSegment(pDrawable, pGC,
  587. intToX(pt1) + xoff, intToY(pt1) + yoff,
  588. intToX(pt2) + xoff, intToY(pt2) + yoff,
  589. npt == 0 && pGC->capStyle != CapNotLast, &dashoffset);
  590. if (!npt)
  591. return;
  592. pt1 = pt2;
  593. pt2 = *pts++;
  594. npt--;
  595. }
  596. else {
  597. bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
  598. for (;;) {
  599. CalcLineDeltas(intToX(pt1), intToY(pt1),
  600. intToX(pt2), intToY(pt2),
  601. len, e1, stepmajor, stepminor, 1, bitsStride,
  602. octant);
  603. stepmajor *= MUL;
  604. if (len < e1) {
  605. e3 = len;
  606. len = e1;
  607. e1 = e3;
  608. e3 = stepminor;
  609. stepminor = stepmajor;
  610. stepmajor = e3;
  611. SetYMajorOctant(octant);
  612. }
  613. e = -len;
  614. e1 <<= 1;
  615. e3 = e << 1;
  616. FIXUP_ERROR(e, octant, bias);
  617. if (and == 0) {
  618. while (len--) {
  619. STORE(bits, xor);
  620. bits += stepmajor;
  621. e += e1;
  622. if (e >= 0) {
  623. bits += stepminor;
  624. e += e3;
  625. }
  626. }
  627. }
  628. else {
  629. while (len--) {
  630. RROP(bits, and, xor);
  631. bits += stepmajor;
  632. e += e1;
  633. if (e >= 0) {
  634. bits += stepminor;
  635. e += e3;
  636. }
  637. }
  638. }
  639. if (!npt) {
  640. if (pGC->capStyle != CapNotLast &&
  641. pt2 != *((INT32 *) ptsOrig)) {
  642. RROP(bits, and, xor);
  643. }
  644. return;
  645. }
  646. pt1 = pt2;
  647. pt2 = *pts++;
  648. --npt;
  649. if (isClipped(pt2, ul, lr))
  650. break;
  651. }
  652. }
  653. }
  654. }
  655. #endif
  656. #ifdef POLYSEGMENT
  657. void
  658. POLYSEGMENT(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
  659. {
  660. INT32 *pts = (INT32 *) pseg;
  661. int xoff = pDrawable->x;
  662. int yoff = pDrawable->y;
  663. unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
  664. BoxPtr pBox = REGION_EXTENTS(fbGetCompositeClip(pGC));
  665. FbBits *dst;
  666. int dstStride;
  667. int dstBpp;
  668. int dstXoff, dstYoff;
  669. UNIT *bits, *bitsBase;
  670. FbStride bitsStride;
  671. FbBits xorBits = fbGetGCPrivate(pGC)->xor;
  672. FbBits andBits = fbGetGCPrivate(pGC)->and;
  673. BITS xor = xorBits;
  674. BITS and = andBits;
  675. int dashoffset = 0;
  676. INT32 ul, lr;
  677. INT32 pt1, pt2;
  678. int e, e1, e3, len;
  679. int stepmajor, stepminor;
  680. int octant;
  681. Bool capNotLast;
  682. fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
  683. bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
  684. bitsBase =
  685. ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
  686. ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
  687. lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
  688. capNotLast = pGC->capStyle == CapNotLast;
  689. while (nseg--) {
  690. pt1 = *pts++;
  691. pt2 = *pts++;
  692. if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
  693. fbSegment(pDrawable, pGC,
  694. intToX(pt1) + xoff, intToY(pt1) + yoff,
  695. intToX(pt2) + xoff, intToY(pt2) + yoff,
  696. !capNotLast, &dashoffset);
  697. }
  698. else {
  699. CalcLineDeltas(intToX(pt1), intToY(pt1),
  700. intToX(pt2), intToY(pt2),
  701. len, e1, stepmajor, stepminor, 1, bitsStride,
  702. octant);
  703. if (e1 == 0 && len > 3
  704. #if MUL != 1
  705. && FbCheck24Pix(and) && FbCheck24Pix(xor)
  706. #endif
  707. ) {
  708. int x1, x2;
  709. FbBits *dstLine;
  710. int dstX, width;
  711. FbBits startmask, endmask;
  712. int nmiddle;
  713. if (stepmajor < 0) {
  714. x1 = intToX(pt2);
  715. x2 = intToX(pt1) + 1;
  716. if (capNotLast)
  717. x1++;
  718. }
  719. else {
  720. x1 = intToX(pt1);
  721. x2 = intToX(pt2);
  722. if (!capNotLast)
  723. x2++;
  724. }
  725. dstX = (x1 + xoff + dstXoff) * (sizeof(UNIT) * 8 * MUL);
  726. width = (x2 - x1) * (sizeof(UNIT) * 8 * MUL);
  727. dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride;
  728. dstLine += dstX >> FB_SHIFT;
  729. dstX &= FB_MASK;
  730. FbMaskBits(dstX, width, startmask, nmiddle, endmask);
  731. if (startmask) {
  732. *dstLine =
  733. FbDoMaskRRop(*dstLine, andBits, xorBits, startmask);
  734. dstLine++;
  735. }
  736. if (!andBits)
  737. while (nmiddle--)
  738. *dstLine++ = xorBits;
  739. else
  740. while (nmiddle--) {
  741. *dstLine = FbDoRRop(*dstLine, andBits, xorBits);
  742. dstLine++;
  743. }
  744. if (endmask)
  745. *dstLine =
  746. FbDoMaskRRop(*dstLine, andBits, xorBits, endmask);
  747. }
  748. else {
  749. stepmajor *= MUL;
  750. bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
  751. if (len < e1) {
  752. e3 = len;
  753. len = e1;
  754. e1 = e3;
  755. e3 = stepminor;
  756. stepminor = stepmajor;
  757. stepmajor = e3;
  758. SetYMajorOctant(octant);
  759. }
  760. e = -len;
  761. e1 <<= 1;
  762. e3 = e << 1;
  763. FIXUP_ERROR(e, octant, bias);
  764. if (!capNotLast)
  765. len++;
  766. if (and == 0) {
  767. while (len--) {
  768. STORE(bits, xor);
  769. bits += stepmajor;
  770. e += e1;
  771. if (e >= 0) {
  772. bits += stepminor;
  773. e += e3;
  774. }
  775. }
  776. }
  777. else {
  778. while (len--) {
  779. RROP(bits, and, xor);
  780. bits += stepmajor;
  781. e += e1;
  782. if (e >= 0) {
  783. bits += stepminor;
  784. e += e3;
  785. }
  786. }
  787. }
  788. }
  789. }
  790. }
  791. }
  792. #endif
  793. #undef MUL
  794. #undef STORE
  795. #undef RROP
  796. #undef UNIT
  797. #undef USE_SOLID
  798. #undef isClipped