Author: spitzak Date: 2007-04-08 15:58:56 -0400 (Sun, 08 Apr 2007) New Revision: 5768 Log: Tried to improve the documentation of the Image object. Added a new method, set_forceARGB32(), that will be used to force the buffer to be in ARGB32, to make it practical for other code to access it. This is not implemented yet, but it is a no-op on Windows, on Linux if XRender is used, and on OS/X if the image is ARGB32, so it is probably ok for testing ideas here already.
Modified: trunk/fltk/Image.h trunk/src/Image.cxx trunk/src/SharedImage.cxx trunk/src/osx/Image.cxx trunk/src/win32/Image.cxx trunk/src/x11/Image.cxx Modified: trunk/fltk/Image.h =================================================================== --- trunk/fltk/Image.h 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/fltk/Image.h 2007-04-08 19:58:56 UTC (rev 5768) @@ -34,14 +34,14 @@ PixelType pixeltype_; int w_, h_; Picture* picture; - int flags; enum {COPIED=1, FETCHED=2, SHAREDDATA=4, MEASUREFETCH=8}; + int flags; enum {COPIED=1, FETCHED=2, FORCEARGB32=4, MEASUREFETCH=8}; static unsigned long memused_; public: Image(const char* name=0) : - Symbol(name), pixeltype_(fltk::RGB32), w_(-1), h_(-1), + Symbol(name), pixeltype_(fltk::RGB32), w_(12), h_(12), picture(0), flags(MEASUREFETCH) {} Image(int w, int h, const char* name=0) : Symbol(name), pixeltype_(fltk::RGB32), w_(w), h_(h), @@ -74,6 +74,9 @@ uchar* buffer(); const uchar* buffer() const; + void set_forceARGB32(); + void clear_forceARGB32(); + bool forceARGB32() const {return (flags&FORCEARGB32) != 0;} PixelType buffer_pixeltype() const; int buffer_depth() const; int buffer_width() const; Modified: trunk/src/Image.cxx =================================================================== --- trunk/src/Image.cxx 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/src/Image.cxx 2007-04-08 19:58:56 UTC (rev 5768) @@ -28,19 +28,49 @@ /*! \class fltk::Image - A rectangular buffer of pixels that the program can write (and - read?) and can be efficiently drawn on the screen. The draw() - functions will copy (or "over" composite if there is alpha in the - pixeltype()) onto the output, transformed by the current transform. + A rectangular buffer of pixels that can be efficiently drawn on the + screen. The draw() functions will copy (or "over" composite if there + is alpha in the pixeltype()) onto the output, transformed by the + current transform. - If you already have a set of pixels sitting in your own memory, + NOTE: If you already have a set of pixels sitting in your own memory, drawimage() can draw it and is \e much easier to use. You should use - this class only if you will be drawing the \e same image multiple - times (with no changes to the pixels), or if you can efficiently use - the linebuffer() and setpixels() functions to write your image to - the buffer as you generate it. Otherwise you will have no efficiency - advantages over drawimage() and it may actually perform worse. + this class \e only if you will be drawing the \e same image multiple + times, with no changes to the pixels. + The buffer is created and filled in by setting the type of pixels + with setpixeltype(), the size with setsize(), and then calling + buffer() (note that setpixels() calls buffer() for you). The initial + buffer is filled with undefined contents. + + The best way to put data into the buffer is to make one or more + calls to setpixels(), to replace rectangular regions. + + You can directly address the buffer() to read and write the + pixels. The size of the buffer is in buffer_width() and + buffer_height() (this may be much larger than width() and height()) + and the distance between lines is in buffer_linedelta(). If you + change any pixels you should call buffer_changed() before the + next draw(). + + Due to operating system limitations, buffer() is usually not an + array of pixeltype() pixels. Instead setpixels() converts pixels + into a type the operating system can use. The type of pixels in the + buffer is retured by buffer_pixeltype(). This is really + inconvienent, so you can also call the method + force_ARGB32_on(). This will cause buffer_pixeltype() to return + ARGB32, so you can assume this at compile time. The implementation + of Image may be less efficient (actually the overhead is zero on + Windows and close to zero on most other systems) + + If buffer() has not been called, draw() will call the + fetch() virtual method. It should call setpixeltype(), setsize() and + setpixels(). This is used to defer reading image files or + decompressing data until needed. fetch() will also restore the + buffer contents to the original values if you have written to the + buffer. If fetch() does not allocate a buffer, draw() will draw a + solid rectangle in the current color. + Because Image is a subclass of Symbol, it may be used as a Widget::image() or as the box() in a Style. If you give it a name it can be drawn with "@name;" in a label. If resized, the Symbol @@ -78,13 +108,13 @@ /*! \fn Image::Image(int w, int h, const char* name) Does setsize(w,h). This causes the width() and height() to return - the passed values. No buffer is allocated, call allocate() to do that. + the passed values. No buffer is allocated, call buffer() to do that. The pixeltype() is set to RGB32 (0x00rrggbb). */ /*! \fn Image::Image(PixelType p, int w, int h, const char* name) Does pixeltype(p) and setsize(w,h). No buffer is allocated, call - allocate() to do that. + buffer() to do that. */ /*! \fn Image::Image(const uchar* data, PixelType, int w, int h, int linedelta) @@ -407,7 +437,7 @@ const Rectangle& r, int line_delta) { if (innards(pointer, type, r, line_delta, 0, 0)) return; - // Fake it using a temporary image + // Fake it using a temporary Image if (!reused_image) reused_image = new Image(); reused_image->setimage(pointer, type, r.w(), r.h(), line_delta); reused_image->draw(Rectangle(r.w(),r.h()), r); @@ -472,8 +502,7 @@ void* userdata, fltk::PixelType type, const Rectangle& r) { if (innards(0, type, r, 0, cb, userdata)) return; - // fake it using an Image object - // Fake it using a temporary image + // Fake it using a temporary Image if (!reused_image) reused_image = new Image(); reused_image->setpixeltype(type); reused_image->setsize(r.w(), r.h()); Modified: trunk/src/SharedImage.cxx =================================================================== --- trunk/src/SharedImage.cxx 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/src/SharedImage.cxx 2007-04-08 19:58:56 UTC (rev 5768) @@ -147,8 +147,7 @@ image=create(); image->refcount = 1; image->name = newstring(name); - image->datas=datas; - image->setsize(-1,-1); // We mark the fact the it has never been measured yet + image->datas = datas; image->l1 = image->l2 = 0; SharedImage::insert(first_image, image); } else { Modified: trunk/src/osx/Image.cxx =================================================================== --- trunk/src/osx/Image.cxx 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/src/osx/Image.cxx 2007-04-08 19:58:56 UTC (rev 5768) @@ -108,6 +108,16 @@ return depth(); } +void Image::set_forceARGB32() { + flags |= FORCEARGB32; + // NYI!!! +} + +void Image::clear_forceARGB32() { + flags &= ~FORCEARGB32; + // NYI!!! +} + fltk::PixelType Image::buffer_pixeltype() const { return pixeltype(); } @@ -190,11 +200,6 @@ Image* thisimage = const_cast<Image*>(this); thisimage->fetch(); thisimage->flags |= FETCHED; - // make errors have non-zero size: - if (w_ < 0 || h_ < 0) { - thisimage->destroy(); - thisimage->w_ = thisimage->h_ = 12; - } } } Modified: trunk/src/win32/Image.cxx =================================================================== --- trunk/src/win32/Image.cxx 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/src/win32/Image.cxx 2007-04-08 19:58:56 UTC (rev 5768) @@ -106,6 +106,16 @@ return ARGB32; } +void Image::set_forceARGB32() { + flags |= FORCEARGB32; + // This does nothing, as it always is ARGB32 +} + +void Image::clear_forceARGB32() { + flags &= ~FORCEARGB32; + // This does nothing, as it always is ARGB32 +} + unsigned long Image::mem_used() const { if (picture) return picture->n; return 0; @@ -259,11 +269,6 @@ Image* thisimage = const_cast<Image*>(this); thisimage->fetch(); thisimage->flags |= FETCHED; - // make errors have non-zero size: - if (w_ < 0 || h_ < 0) { - thisimage->destroy(); - thisimage->w_ = thisimage->h_ = 12; - } } } Modified: trunk/src/x11/Image.cxx =================================================================== --- trunk/src/x11/Image.cxx 2007-04-08 19:18:40 UTC (rev 5767) +++ trunk/src/x11/Image.cxx 2007-04-08 19:58:56 UTC (rev 5768) @@ -633,7 +633,7 @@ //////////////////////////////////////////////////////////////// -static XImage i; // this is reused to draw an images +static XImage i; // this is reused to draw images static int bytes_per_pixel; static int scanline_add; static int scanline_mask; @@ -1105,6 +1105,16 @@ return bytes_per_pixel; } +void Image::set_forceARGB32() { + flags |= FORCEARGB32; + // NYI!!! (though it does nothing if USE_XFT is on) +} + +void Image::clear_forceARGB32() { + flags &= ~FORCEARGB32; + // NYI!!! (though it does nothing if USE_XFT is on) +} + PixelType Image::buffer_pixeltype() const { if (!bytes_per_pixel) figure_out_visual(); #if USE_XFT @@ -1262,11 +1272,6 @@ if (!(flags&FETCHED)) { thisimage->fetch(); thisimage->flags |= FETCHED; - // make errors have non-zero size: - if (w_ < 0 || h_ < 0) { - thisimage->destroy(); - thisimage->w_ = thisimage->h_ = 12; - } } } _______________________________________________ fltk-commit mailing list fltk-commit@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-commit