offscr1bpp.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. //*****************************************************************************
  2. //
  3. // offscr1bpp.c - 1 BPP off-screen display buffer driver.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 6288 of the Stellaris Graphics Library.
  22. //
  23. //*****************************************************************************
  24. #include "debug.h"
  25. #include "grlib.h"
  26. //*****************************************************************************
  27. //
  28. //! \addtogroup primitives_api
  29. //! @{
  30. //
  31. //*****************************************************************************
  32. //*****************************************************************************
  33. //
  34. // Translates a 24-bit RGB color to a display driver-specific color.
  35. //
  36. // \param c is the 24-bit RGB color. The least-significant byte is the blue
  37. // channel, the next byte is the green channel, and the third byte is the red
  38. // channel.
  39. //
  40. // This macro translates a 24-bit RGB color into a value that can be written
  41. // into the display's frame buffer in order to reproduce that color, or the
  42. // closest possible approximation of that color.
  43. //
  44. // \return Returns the display-driver specific color.
  45. //
  46. //*****************************************************************************
  47. #define DPYCOLORTRANSLATE(c) ((((((c) & 0x00ff0000) >> 16) * 19661) + \
  48. ((((c) & 0x0000ff00) >> 8) * 38666) + \
  49. (((c) & 0x000000ff) * 7209)) / \
  50. (65536 * 128))
  51. //*****************************************************************************
  52. //
  53. //! Draws a pixel on the screen.
  54. //!
  55. //! \param pvDisplayData is a pointer to the driver-specific data for this
  56. //! display driver.
  57. //! \param lX is the X coordinate of the pixel.
  58. //! \param lY is the Y coordinate of the pixel.
  59. //! \param ulValue is the color of the pixel.
  60. //!
  61. //! This function sets the given pixel to a particular color. The coordinates
  62. //! of the pixel are assumed to be within the extents of the display.
  63. //!
  64. //! \return None.
  65. //
  66. //*****************************************************************************
  67. static void
  68. GrOffScreen1BPPPixelDraw(void *pvDisplayData, int lX, int lY,
  69. unsigned int ulValue)
  70. {
  71. unsigned char *pucData;
  72. int lBytesPerRow;
  73. //
  74. // Check the arguments.
  75. //
  76. ASSERT(pvDisplayData);
  77. //
  78. // Create a character pointer for the display-specific data (which points
  79. // to the image buffer).
  80. //
  81. pucData = (unsigned char *)pvDisplayData;
  82. //
  83. // Compute the number of bytes per row in the image buffer.
  84. //
  85. lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
  86. //
  87. // Get the offset to the byte of the image buffer that contains the pixel
  88. // in question.
  89. //
  90. pucData += (lBytesPerRow * lY) + (lX / 8) + 5;
  91. //
  92. // Determine how much to shift to get to the bit that contains this pixel.
  93. //
  94. lX = 7 - (lX & 7);
  95. //
  96. // Write this pixel into the image buffer.
  97. //
  98. *pucData = (*pucData & ~(1 << lX)) | (ulValue << lX);
  99. }
  100. //*****************************************************************************
  101. //
  102. //! Draws a horizontal sequence of pixels on the screen.
  103. //!
  104. //! \param pvDisplayData is a pointer to the driver-specific data for this
  105. //! display driver.
  106. //! \param lX is the X coordinate of the first pixel.
  107. //! \param lY is the Y coordinate of the first pixel.
  108. //! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
  109. //! or 4 bit per pixel formats.
  110. //! \param lCount is the number of pixels to draw.
  111. //! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
  112. //! \param pucData is a pointer to the pixel data. For 1 and 4 bit per pixel
  113. //! formats, the most significant bit(s) represent the left-most pixel.
  114. //! \param pucPalette is a pointer to the palette used to draw the pixels.
  115. //!
  116. //! This function draws a horizontal sequence of pixels on the screen, using
  117. //! the supplied palette. For 1 bit per pixel format, the palette contains
  118. //! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
  119. //! contains 24-bit RGB values that must be translated before being written to
  120. //! the display.
  121. //!
  122. //! \return None.
  123. //
  124. //*****************************************************************************
  125. static void
  126. GrOffScreen1BPPPixelDrawMultiple(void *pvDisplayData, int lX, int lY,
  127. int lX0, int lCount, int lBPP,
  128. const unsigned char *pucData,
  129. const unsigned char *pucPalette)
  130. {
  131. unsigned char *pucPtr;
  132. unsigned int ulByte;
  133. int lBytesPerRow;
  134. //
  135. // Check the arguments.
  136. //
  137. ASSERT(pvDisplayData);
  138. ASSERT(pucData);
  139. ASSERT(pucPalette);
  140. //
  141. // Create a character pointer for the display-specific data (which points
  142. // to the image buffer).
  143. //
  144. pucPtr = (unsigned char *)pvDisplayData;
  145. //
  146. // Compute the number of bytes per row in the image buffer.
  147. //
  148. lBytesPerRow = (*(unsigned short *)(pucPtr + 1) + 7) / 8;
  149. //
  150. // Get the offset to the byte of the image buffer that contains the
  151. // starting pixel.
  152. //
  153. pucPtr += (lBytesPerRow * lY) + (lX / 8) + 5;
  154. //
  155. // Determine the bit position of the starting pixel.
  156. //
  157. lX = 7 - (lX & 7);
  158. //
  159. // Determine how to interpret the pixel data based on the number of bits
  160. // per pixel.
  161. //
  162. switch(lBPP)
  163. {
  164. //
  165. // The pixel data is in 1 bit per pixel format.
  166. //
  167. case 1:
  168. {
  169. //
  170. // Loop while there are more pixels to draw.
  171. //
  172. while(lCount)
  173. {
  174. //
  175. // Get the next byte of image data.
  176. //
  177. ulByte = *pucData++;
  178. //
  179. // Loop through the pixels in this byte of image data.
  180. //
  181. for(; (lX0 < 8) && lCount; lX0++, lCount--)
  182. {
  183. //
  184. // Draw this pixel in the appropriate color.
  185. //
  186. *pucPtr = ((*pucPtr & ~(1 << lX)) |
  187. ((((unsigned int *)pucPalette)[(ulByte >>
  188. (7 - lX0)) &
  189. 1]) << lX));
  190. if(lX-- == 0)
  191. {
  192. lX = 7;
  193. pucPtr++;
  194. }
  195. }
  196. //
  197. // Start at the beginning of the next byte of image data.
  198. //
  199. lX0 = 0;
  200. }
  201. //
  202. // The image data has been drawn.
  203. //
  204. break;
  205. }
  206. //
  207. // The pixel data is in 4 bit per pixel format.
  208. //
  209. case 4:
  210. {
  211. //
  212. // Loop while there are more pixels to draw. "Duff's device" is
  213. // used to jump into the middle of the loop if the first nibble of
  214. // the pixel data should not be used. Duff's device makes use of
  215. // the fact that a case statement is legal anywhere within a
  216. // sub-block of a switch statement. See
  217. // http://en.wikipedia.org/wiki/Duff's_device for detailed
  218. // information about Duff's device.
  219. //
  220. switch(lX0 & 1)
  221. {
  222. case 0:
  223. while(lCount)
  224. {
  225. //
  226. // Get the upper nibble of the next byte of pixel data
  227. // and extract the corresponding entry from the
  228. // palette.
  229. //
  230. ulByte = (*pucData >> 4) * 3;
  231. ulByte = (*(unsigned int *)(pucPalette + ulByte) &
  232. 0x00ffffff);
  233. //
  234. // Translate this palette entry and write it to the
  235. // screen.
  236. //
  237. *pucPtr = ((*pucPtr & ~(1 << lX)) |
  238. (DPYCOLORTRANSLATE(ulByte) << lX));
  239. if(lX-- == 0)
  240. {
  241. lX = 7;
  242. pucPtr++;
  243. }
  244. //
  245. // Decrement the count of pixels to draw.
  246. //
  247. lCount--;
  248. //
  249. // See if there is another pixel to draw.
  250. //
  251. if(lCount)
  252. {
  253. case 1:
  254. //
  255. // Get the lower nibble of the next byte of pixel
  256. // data and extract the corresponding entry from
  257. // the palette.
  258. //
  259. ulByte = (*pucData++ & 15) * 3;
  260. ulByte = (*(unsigned int *)(pucPalette + ulByte) &
  261. 0x00ffffff);
  262. //
  263. // Translate this palette entry and write it to the
  264. // screen.
  265. //
  266. *pucPtr = ((*pucPtr & ~(1 << lX)) |
  267. (DPYCOLORTRANSLATE(ulByte) << lX));
  268. if(lX-- == 0)
  269. {
  270. lX = 7;
  271. pucPtr++;
  272. }
  273. //
  274. // Decrement the count of pixels to draw.
  275. //
  276. lCount--;
  277. }
  278. }
  279. }
  280. //
  281. // The image data has been drawn.
  282. //
  283. break;
  284. }
  285. //
  286. // The pixel data is in 8 bit per pixel format.
  287. //
  288. case 8:
  289. {
  290. //
  291. // Loop while there are more pixels to draw.
  292. //
  293. while(lCount--)
  294. {
  295. //
  296. // Get the next byte of pixel data and extract the
  297. // corresponding entry from the palette.
  298. //
  299. ulByte = *pucData++ * 3;
  300. ulByte = *(unsigned int *)(pucPalette + ulByte) & 0x00ffffff;
  301. //
  302. // Translate this palette entry and write it to the screen.
  303. //
  304. *pucPtr = ((*pucPtr & ~(1 << lX)) |
  305. (DPYCOLORTRANSLATE(ulByte) << lX));
  306. if(lX-- == 0)
  307. {
  308. lX = 7;
  309. pucPtr++;
  310. }
  311. }
  312. //
  313. // The image data has been drawn.
  314. //
  315. break;
  316. }
  317. }
  318. }
  319. //*****************************************************************************
  320. //
  321. //! Draws a horizontal line.
  322. //!
  323. //! \param pvDisplayData is a pointer to the driver-specific data for this
  324. //! display driver.
  325. //! \param lX1 is the X coordinate of the start of the line.
  326. //! \param lX2 is the X coordinate of the end of the line.
  327. //! \param lY is the Y coordinate of the line.
  328. //! \param ulValue is the color of the line.
  329. //!
  330. //! This function draws a horizontal line on the display. The coordinates of
  331. //! the line are assumed to be within the extents of the display.
  332. //!
  333. //! \return None.
  334. //
  335. //*****************************************************************************
  336. static void
  337. GrOffScreen1BPPLineDrawH(void *pvDisplayData, int lX1, int lX2, int lY,
  338. unsigned int ulValue)
  339. {
  340. int lBytesPerRow, lMask;
  341. unsigned char *pucData;
  342. //
  343. // Check the arguments.
  344. //
  345. ASSERT(pvDisplayData);
  346. //
  347. // Create a character pointer for the display-specific data (which points
  348. // to the image buffer).
  349. //
  350. pucData = (unsigned char *)pvDisplayData;
  351. //
  352. // Compute the number of bytes per row in the image buffer.
  353. //
  354. lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
  355. //
  356. // Get the offset to the byte of the image buffer that contains the
  357. // starting pixel.
  358. //
  359. pucData += (lBytesPerRow * lY) + (lX1 / 8) + 5;
  360. //
  361. // Copy the pixel value into all 32 pixels of the unsigned int. This will
  362. // be used later to write multiple pixels into memory (as opposed to one at
  363. // a time).
  364. //
  365. if(ulValue)
  366. {
  367. ulValue = 0xffffffff;
  368. }
  369. //
  370. // See if the current buffer byte contains pixels that should be left
  371. // unmodified.
  372. //
  373. if(lX1 & 7)
  374. {
  375. //
  376. // Compute the mask to access only the appropriate pixels within this
  377. // byte. The line may start and stop within this byte, so the mask may
  378. // need to be shortened to account for this situation.
  379. //
  380. lMask = 8 - (lX1 & 7);
  381. if(lMask > (lX2 - lX1 + 1))
  382. {
  383. lMask = lX2 - lX1 + 1;
  384. }
  385. lMask = ((1 << lMask) - 1) << (8 - (lX1 & 7) - lMask);
  386. //
  387. // Draw the appropriate pixels within this byte.
  388. //
  389. *pucData = (*pucData & ~lMask) | (ulValue & lMask);
  390. pucData++;
  391. lX1 = (lX1 + 7) & ~7;
  392. }
  393. //
  394. // See if the buffer pointer is not half-word aligned and there are at
  395. // least eight pixels left to draw.
  396. //
  397. if(((unsigned int)pucData & 1) && ((lX2 - lX1) > 6))
  398. {
  399. //
  400. // Draw eight pixels to half-word align the buffer pointer.
  401. //
  402. *pucData++ = ulValue & 0xff;
  403. lX1 += 8;
  404. }
  405. //
  406. // See if the buffer pointer is not word aligned and there are at least
  407. // sixteen pixels left to draw.
  408. //
  409. if(((unsigned int)pucData & 2) && ((lX2 - lX1) > 14))
  410. {
  411. //
  412. // Draw sixteen pixels to word align the buffer pointer.
  413. //
  414. *(unsigned short *)pucData = ulValue & 0xffff;
  415. pucData += 2;
  416. lX1 += 16;
  417. }
  418. //
  419. // Loop while there are at least thirty two pixels left to draw.
  420. //
  421. while((lX1 + 31) <= lX2)
  422. {
  423. //
  424. // Draw thirty two pixels.
  425. //
  426. *(unsigned int *)pucData = ulValue;
  427. pucData += 4;
  428. lX1 += 32;
  429. }
  430. //
  431. // See if there are at least sixteen pixels left to draw.
  432. //
  433. if((lX1 + 15) <= lX2)
  434. {
  435. //
  436. // Draw sixteen pixels, leaving the buffer pointer half-word aligned.
  437. //
  438. *(unsigned short *)pucData = ulValue & 0xffff;
  439. pucData += 2;
  440. lX1 += 16;
  441. }
  442. //
  443. // See if there are at least eight pixels left to draw.
  444. //
  445. if((lX1 + 7) <= lX2)
  446. {
  447. //
  448. // Draw eight pixels, leaving the buffer pointer byte aligned.
  449. //
  450. *pucData++ = ulValue & 0xff;
  451. lX1 += 8;
  452. }
  453. //
  454. // See if there are any pixels left to draw.
  455. //
  456. if(lX1 <= lX2)
  457. {
  458. //
  459. // Draw the remaining pixels.
  460. //
  461. lMask = 0xff >> (lX2 - lX1 + 1);
  462. *pucData = (*pucData & lMask) | (ulValue & ~lMask);
  463. }
  464. }
  465. //*****************************************************************************
  466. //
  467. //! Draws a vertical line.
  468. //!
  469. //! \param pvDisplayData is a pointer to the driver-specific data for this
  470. //! display driver.
  471. //! \param lX is the X coordinate of the line.
  472. //! \param lY1 is the Y coordinate of the start of the line.
  473. //! \param lY2 is the Y coordinate of the end of the line.
  474. //! \param ulValue is the color of the line.
  475. //!
  476. //! This function draws a vertical line on the display. The coordinates of the
  477. //! line are assumed to be within the extents of the display.
  478. //!
  479. //! \return None.
  480. //
  481. //*****************************************************************************
  482. static void
  483. GrOffScreen1BPPLineDrawV(void *pvDisplayData, int lX, int lY1, int lY2,
  484. unsigned int ulValue)
  485. {
  486. unsigned char *pucData;
  487. int lBytesPerRow;
  488. //
  489. // Check the arguments.
  490. //
  491. ASSERT(pvDisplayData);
  492. //
  493. // Create a character pointer for the display-specific data (which points
  494. // to the image buffer).
  495. //
  496. pucData = (unsigned char *)pvDisplayData;
  497. //
  498. // Compute the number of bytes per row in the image buffer.
  499. //
  500. lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
  501. //
  502. // Get the offset to the byte of the image buffer that contains the
  503. // starting pixel.
  504. //
  505. pucData += (lBytesPerRow * lY1) + (lX / 8) + 5;
  506. //
  507. // Determine how much to shift to get to the bit that contains this pixel.
  508. //
  509. lX = 7 - (lX & 7);
  510. //
  511. // Shift the pixel value up to the correct bit position, and create a mask
  512. // to preserve the value of the remaining pixels.
  513. //
  514. ulValue <<= lX;
  515. lX = ~(1 << lX);
  516. //
  517. // Loop over the rows of the line.
  518. //
  519. for(; lY1 <= lY2; lY1++)
  520. {
  521. //
  522. // Draw this pixel of the line.
  523. //
  524. *pucData = (*pucData & lX) | ulValue;
  525. pucData += lBytesPerRow;
  526. }
  527. }
  528. //*****************************************************************************
  529. //
  530. //! Fills a rectangle.
  531. //!
  532. //! \param pvDisplayData is a pointer to the driver-specific data for this
  533. //! display driver.
  534. //! \param pRect is a pointer to the structure describing the rectangle.
  535. //! \param ulValue is the color of the rectangle.
  536. //!
  537. //! This function fills a rectangle on the display. The coordinates of the
  538. //! rectangle are assumed to be within the extents of the display, and the
  539. //! rectangle specification is fully inclusive (in other words, both sXMin and
  540. //! sXMax are drawn, along with sYMin and sYMax).
  541. //!
  542. //! \return None.
  543. //
  544. //*****************************************************************************
  545. static void
  546. GrOffScreen1BPPRectFill(void *pvDisplayData, const tRectangle *pRect,
  547. unsigned int ulValue)
  548. {
  549. unsigned char *pucData, *pucColumn;
  550. int lBytesPerRow, lMask, lX, lY;
  551. //
  552. // Check the arguments.
  553. //
  554. ASSERT(pvDisplayData);
  555. ASSERT(pRect);
  556. //
  557. // Create a character pointer for the display-specific data (which points
  558. // to the image buffer).
  559. //
  560. pucData = (unsigned char *)pvDisplayData;
  561. //
  562. // Compute the number of bytes per row in the image buffer.
  563. //
  564. lBytesPerRow = (*(unsigned short *)(pucData + 1) + 7) / 8;
  565. //
  566. // Get the offset to the byte of the image buffer that contains the
  567. // starting pixel.
  568. //
  569. pucData += (lBytesPerRow * pRect->sYMin) + (pRect->sXMin / 8) + 5;
  570. //
  571. // Copy the pixel value into all 32 pixels of the unsigned int. This will
  572. // be used later to write multiple pixels into memory (as opposed to one at
  573. // a time).
  574. //
  575. if(ulValue)
  576. {
  577. ulValue = 0xffffffff;
  578. }
  579. //
  580. // Get the starting X coordinate of the rectangle.
  581. //
  582. lX = pRect->sXMin;
  583. //
  584. // See if the current buffer byte contains pixel columns that should be
  585. // left unmodified.
  586. //
  587. if(lX & 7)
  588. {
  589. //
  590. // Compute the mask to access only the appropriate pixels within this
  591. // byte column. The rectangle may start and stop within this byte
  592. // column, so the mask may need to be shortened to account for this
  593. // situation.
  594. //
  595. lMask = 8 - (lX & 7);
  596. if(lMask > (pRect->sXMax - lX + 1))
  597. {
  598. lMask = pRect->sXMax - lX + 1;
  599. }
  600. lMask = ((1 << lMask) - 1) << (8 - (lX & 7) - lMask);
  601. //
  602. // Draw the appropriate pixels within this column.
  603. //
  604. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  605. lY++, pucColumn += lBytesPerRow)
  606. {
  607. *pucColumn = (*pucColumn & ~lMask) | (ulValue & lMask);
  608. }
  609. pucData++;
  610. lX = (lX + 7) & ~7;
  611. }
  612. //
  613. // See if the buffer pointer is not half-word aligned and there are at
  614. // least eight pixel columns left to draw.
  615. //
  616. if(((unsigned int)pucData & 1) && ((pRect->sXMax - lX) > 6))
  617. {
  618. //
  619. // Draw eight pixel columns to half-word align the buffer pointer.
  620. //
  621. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  622. lY++, pucColumn += lBytesPerRow)
  623. {
  624. *pucColumn = ulValue & 0xff;
  625. }
  626. pucData++;
  627. lX += 8;
  628. }
  629. //
  630. // See if the buffer pointer is not word aligned and there are at least
  631. // sixteen pixel columns left to draw.
  632. //
  633. if(((unsigned int)pucData & 2) && ((pRect->sXMax - lX) > 14))
  634. {
  635. //
  636. // Draw sixteen pixel columns to word align the buffer pointer.
  637. //
  638. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  639. lY++, pucColumn += lBytesPerRow)
  640. {
  641. *(unsigned short *)pucColumn = ulValue & 0xffff;
  642. }
  643. pucData += 2;
  644. lX += 16;
  645. }
  646. //
  647. // Loop while there are at least thirty two pixel columnss left to draw.
  648. //
  649. while((lX + 31) <= pRect->sXMax)
  650. {
  651. //
  652. // Draw thirty two pixel columnss.
  653. //
  654. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  655. lY++, pucColumn += lBytesPerRow)
  656. {
  657. *(unsigned int *)pucColumn = ulValue;
  658. }
  659. pucData += 4;
  660. lX += 32;
  661. }
  662. //
  663. // See if there are at least sixteen pixel columnss left to draw.
  664. //
  665. if((lX + 15) <= pRect->sXMax)
  666. {
  667. //
  668. // Draw sixteen pixel columns, leaving the buffer pointer half-word
  669. // aligned.
  670. //
  671. ulValue &= 0xffff;
  672. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  673. lY++, pucColumn += lBytesPerRow)
  674. {
  675. *(unsigned short *)pucColumn = ulValue;
  676. }
  677. pucData += 2;
  678. lX += 16;
  679. }
  680. //
  681. // See if there are at least eight pixel columns left to draw.
  682. //
  683. if((lX + 7) <= pRect->sXMax)
  684. {
  685. //
  686. // Draw eight pixel columns, leaving the buffer pointer byte aligned.
  687. //
  688. ulValue &= 0xff;
  689. for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
  690. lY++, pucColumn += lBytesPerRow)
  691. {
  692. *pucColumn = ulValue;
  693. }
  694. pucData++;
  695. lX += 8;
  696. }
  697. //
  698. // See if there are any pixel columns left to draw.
  699. //
  700. if(lX <= pRect->sXMax)
  701. {
  702. //
  703. // Draw the remaining pixel columns.
  704. //
  705. lMask = 0xff >> (pRect->sXMax - lX + 1);
  706. ulValue &= ~lMask;
  707. for(lY = pRect->sYMin; lY <= pRect->sYMax;
  708. lY++, pucData += lBytesPerRow)
  709. {
  710. *pucData = (*pucData & lMask) | ulValue;
  711. }
  712. }
  713. }
  714. //*****************************************************************************
  715. //
  716. //! Translates a 24-bit RGB color to a display driver-specific color.
  717. //!
  718. //! \param pvDisplayData is a pointer to the driver-specific data for this
  719. //! display driver.
  720. //! \param ulValue is the 24-bit RGB color. The least-significant byte is the
  721. //! blue channel, the next byte is the green channel, and the third byte is the
  722. //! red channel.
  723. //!
  724. //! This function translates a 24-bit RGB color into a value that can be
  725. //! written into the display's frame buffer in order to reproduce that color,
  726. //! or the closest possible approximation of that color.
  727. //!
  728. //! \return Returns the display-driver specific color.
  729. //
  730. //*****************************************************************************
  731. static unsigned int
  732. GrOffScreen1BPPColorTranslate(void *pvDisplayData, unsigned int ulValue)
  733. {
  734. //
  735. // Check the arguments.
  736. //
  737. ASSERT(pvDisplayData);
  738. //
  739. // Translate from a 24-bit RGB color to black or white.
  740. //
  741. return(DPYCOLORTRANSLATE(ulValue));
  742. }
  743. //*****************************************************************************
  744. //
  745. //! Flushes any cached drawing operations.
  746. //!
  747. //! \param pvDisplayData is a pointer to the driver-specific data for this
  748. //! display driver.
  749. //!
  750. //! This functions flushes any cached drawing operations to the display. This
  751. //! is useful when a local frame buffer is used for drawing operations, and the
  752. //! flush would copy the local frame buffer to the display. For the off-screen
  753. //! display buffer driver, the flush is a no operation.
  754. //!
  755. //! \return None.
  756. //
  757. //*****************************************************************************
  758. static void
  759. GrOffScreen1BPPFlush(void *pvDisplayData)
  760. {
  761. //
  762. // Check the arguments.
  763. //
  764. ASSERT(pvDisplayData);
  765. }
  766. //*****************************************************************************
  767. //
  768. //! Initializes a 1 BPP off-screen buffer.
  769. //!
  770. //! \param pDisplay is a pointer to the display structure to be configured for
  771. //! the 1 BPP off-screen buffer.
  772. //! \param pucImage is a pointer to the image buffer to be used for the
  773. //! off-screen buffer.
  774. //! \param lWidth is the width of the image buffer in pixels.
  775. //! \param lHeight is the height of the image buffer in pixels.
  776. //!
  777. //! This function initializes a display structure, preparing it to draw into
  778. //! the supplied image buffer. The image buffer is assumed to be large enough
  779. //! to hold an image of the specified geometry.
  780. //!
  781. //! \return None.
  782. //
  783. //*****************************************************************************
  784. void
  785. GrOffScreen1BPPInit(tDisplay *pDisplay, unsigned char *pucImage, int lWidth,
  786. int lHeight)
  787. {
  788. //
  789. // Check the arguments.
  790. //
  791. ASSERT(pDisplay);
  792. ASSERT(pucImage);
  793. //
  794. // Initialize the display structure.
  795. //
  796. pDisplay->lSize = sizeof(tDisplay);
  797. pDisplay->pvDisplayData = pucImage;
  798. pDisplay->usWidth = lWidth;
  799. pDisplay->usHeight = lHeight;
  800. pDisplay->pfnPixelDraw = GrOffScreen1BPPPixelDraw;
  801. pDisplay->pfnPixelDrawMultiple = GrOffScreen1BPPPixelDrawMultiple;
  802. pDisplay->pfnLineDrawH = GrOffScreen1BPPLineDrawH;
  803. pDisplay->pfnLineDrawV = GrOffScreen1BPPLineDrawV;
  804. pDisplay->pfnRectFill = GrOffScreen1BPPRectFill;
  805. pDisplay->pfnColorTranslate = GrOffScreen1BPPColorTranslate;
  806. pDisplay->pfnFlush = GrOffScreen1BPPFlush;
  807. //
  808. // Initialize the image buffer.
  809. //
  810. pucImage[0] = IMAGE_FMT_1BPP_UNCOMP;
  811. *(unsigned short *)(pucImage + 1) = lWidth;
  812. *(unsigned short *)(pucImage + 3) = lHeight;
  813. }
  814. //*****************************************************************************
  815. //
  816. // Close the Doxygen group.
  817. //! @}
  818. //
  819. //*****************************************************************************