diff options
Diffstat (limited to 'chalk/doc/paint_device.txt')
-rw-r--r-- | chalk/doc/paint_device.txt | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/chalk/doc/paint_device.txt b/chalk/doc/paint_device.txt new file mode 100644 index 00000000..a3c34a35 --- /dev/null +++ b/chalk/doc/paint_device.txt @@ -0,0 +1,98 @@ +THIS DOCUMENT IS OBSOLETED BY THE AUTOLAYERS MERGE + +* Paint devices and painters + +Chalk's core consists of paint devices and painters: + +KisPaintDevice +KisPainter + +These classes are (very) loosely modelled on QPaintDevice and +QPainter. KisPaintDevice also takes up some of the roles of QImage, +but isn't all that efficient at it. + +This is a write-up of my (Boudewijn's) understanding at this point; + +* Getting pixel data in and out of a KisPaintDevice. + +Chalk stores all image data in tiles; the tiles are managed by the +aptly named KisTileMgr. Inside the tiles, we have a KisPixelData +structure, which is basically a wrapper that packs together a pointer +to a memory area that contains the pixel data (QUANTUM's) and some +more information. + +Ordinarily, you will change the data inside a KisPaintDevice through +the KisPainter. Using KisPainter has the advantage that your changes +will be undoable and that the tile manager is hidden. That's +especially nice, since you generally don't want to work directly with +tiles, not before having bought shares in an aspirin producer. + +The other way of messing with the pixels inside a KisPaintDevice is +through the pixel() and and setPixel() methods in KisPaintDevice. +These methods retrieve and set the specified pixel data using the +tiles, but are not undoable. They are also rather ineffcient and slow. + +KisPainter and KisPaintDevice do the job of hiding the actual image +data from the chalk hacker, but sometimes it's not enough, sometimes +you need to loop over all the pixels in an image, do +something, and write the pixels back to this or another image (or +sections of images). + +In the near future, we will offer an iterator over the pixels, for now +you will have to ask the tile manager to copy all the bytes of the +image data in a buffer for you to read. Likewise, in the future we +will hopefully have something clever to feed pixel data to the tile +manager. For now, you will have to fill a memory buffer with the +desired data and feed that to the tile manager. + +** Getting pixel data into your buffer + +Define a pointer to a memory buffer with QUANTUMS + + QUANTUM *buf; + +Create the buffer. Note that you cannot assume that there is one byte +per channel; QUANTUM can be bigger. + + buf = new QUANTUM[width * heigth * depth * sizeof(QUANTUM)]; + +Fill the buf with the data. x1, y1, x2, y2 are the top left and bottom +right corner of the section you want. stride is the width of the +section in bytes, i.e. (x2 - x1 + 1) * depth. Note that stride does +not need to be pre-multiplied with sizeof(QUANTUM), aptqparently. + + tilemgr -> readPixelData(x1, y1, x2, y2, buf, stride); + +Now all the pixels in the tile manager are copied into 'buf' -- the +operative word is 'copy', which means slow, and takes a lot of memory +is the section is big. + +If you can stand computing with tiles, you can copy each tile into the +buffer, which takes a lot less memory, but you have to take care when +the image isn't exactly a multiple of the tilesize. See +kis_image_magick_converter.cpp for an example. + +** Getting your data into a KisPaintDevice without using KisPainter + +Although in the future we might offer a bitBlt that takes a simple +memory buffer and blits that onto the paint device, for now, you will +have to access the tile manager directly, using writePixelData. + + +First create a buffer, just as above: + + QUANTUM * newData = new QUANTUM[width * height * depth * sizeof(QUANTUM)]; + +But unless you are sure you are going to fill absolutely every pixel, +you might want to initialize the buffer with memset. Chalk, in +contrast with ImageMagick, uses 0 as the value for transparent +opacity, so that's nice: + + memset(newData, width * height * depth * sizeof(QUANTUM), 0); + +Then create a new tilemanager, or reuse the old one if the size is +still correct. Stride is again width * depth, not width * depth * +sizeof(QUANTUM) + + KisTileMgrSP tm = new KisTileMgr(depth, width, height); + tm -> writePixelData(x1, y1, x2, y2, newData, stride); |