fbbits.h 25 KB

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