KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines

  2. * Paint devices and painters
  3. Chalk's core consists of paint devices and painters:
  4. KisPaintDevice
  5. KisPainter
  6. These classes are (very) loosely modelled on QPaintDevice and
  7. QPainter. KisPaintDevice also takes up some of the roles of QImage,
  8. but isn't all that efficient at it.
  9. This is a write-up of my (Boudewijn's) understanding at this point;
  10. * Getting pixel data in and out of a KisPaintDevice.
  11. Chalk stores all image data in tiles; the tiles are managed by the
  12. aptly named KisTileMgr. Inside the tiles, we have a KisPixelData
  13. structure, which is basically a wrapper that packs together a pointer
  14. to a memory area that contains the pixel data (QUANTUM's) and some
  15. more information.
  16. Ordinarily, you will change the data inside a KisPaintDevice through
  17. the KisPainter. Using KisPainter has the advantage that your changes
  18. will be undoable and that the tile manager is hidden. That's
  19. especially nice, since you generally don't want to work directly with
  20. tiles, not before having bought shares in an aspirin producer.
  21. The other way of messing with the pixels inside a KisPaintDevice is
  22. through the pixel() and and setPixel() methods in KisPaintDevice.
  23. These methods retrieve and set the specified pixel data using the
  24. tiles, but are not undoable. They are also rather ineffcient and slow.
  25. KisPainter and KisPaintDevice do the job of hiding the actual image
  26. data from the chalk hacker, but sometimes it's not enough, sometimes
  27. you need to loop over all the pixels in an image, do
  28. something, and write the pixels back to this or another image (or
  29. sections of images).
  30. In the near future, we will offer an iterator over the pixels, for now
  31. you will have to ask the tile manager to copy all the bytes of the
  32. image data in a buffer for you to read. Likewise, in the future we
  33. will hopefully have something clever to feed pixel data to the tile
  34. manager. For now, you will have to fill a memory buffer with the
  35. desired data and feed that to the tile manager.
  36. ** Getting pixel data into your buffer
  37. Define a pointer to a memory buffer with QUANTUMS
  38. QUANTUM *buf;
  39. Create the buffer. Note that you cannot assume that there is one byte
  40. per channel; QUANTUM can be bigger.
  41. buf = new QUANTUM[width * heigth * depth * sizeof(QUANTUM)];
  42. Fill the buf with the data. x1, y1, x2, y2 are the top left and bottom
  43. right corner of the section you want. stride is the width of the
  44. section in bytes, i.e. (x2 - x1 + 1) * depth. Note that stride does
  45. not need to be pre-multiplied with sizeof(QUANTUM), apparently.
  46. tilemgr -> readPixelData(x1, y1, x2, y2, buf, stride);
  47. Now all the pixels in the tile manager are copied into 'buf' -- the
  48. operative word is 'copy', which means slow, and takes a lot of memory
  49. is the section is big.
  50. If you can stand computing with tiles, you can copy each tile into the
  51. buffer, which takes a lot less memory, but you have to take care when
  52. the image isn't exactly a multiple of the tilesize. See
  53. kis_image_magick_converter.cpp for an example.
  54. ** Getting your data into a KisPaintDevice without using KisPainter
  55. Although in the future we might offer a bitBlt that takes a simple
  56. memory buffer and blits that onto the paint device, for now, you will
  57. have to access the tile manager directly, using writePixelData.
  58. First create a buffer, just as above:
  59. QUANTUM * newData = new QUANTUM[width * height * depth * sizeof(QUANTUM)];
  60. But unless you are sure you are going to fill absolutely every pixel,
  61. you might want to initialize the buffer with memset. Chalk, in
  62. contrast with ImageMagick, uses 0 as the value for transparent
  63. opacity, so that's nice:
  64. memset(newData, width * height * depth * sizeof(QUANTUM), 0);
  65. Then create a new tilemanager, or reuse the old one if the size is
  66. still correct. Stride is again width * depth, not width * depth *
  67. sizeof(QUANTUM)
  68. KisTileMgrSP tm = new KisTileMgr(depth, width, height);
  69. tm -> writePixelData(x1, y1, x2, y2, newData, stride);