Clarify documentation of Fl_Image::copy() and more (#431)

- emphasize that Fl_Image::copy(W, H) creates an image with
  w() == data_w() == W and h() == data_h() == H
- clarify some more docs of Fl_Image methods (ensure that data_w()
  and data_h() are used where appropriate rather than w() and h()
- improve wording, examples, and formatting of related docs.

Closes #431
This commit is contained in:
Albrecht Schlosser
2022-04-15 02:01:33 +02:00
parent 290c856739
commit 114dbc9c81
2 changed files with 114 additions and 88 deletions
+52 -37
View File
@@ -40,23 +40,22 @@ enum Fl_RGB_Scaling {
/** /**
\brief Base class for image caching, scaling and drawing. Base class for image caching, scaling and drawing.
Fl_Image is the base class used for caching, scaling and drawing all kinds of images Fl_Image is the base class used for caching, scaling and drawing all kinds of
in FLTK. This class keeps track of common image data such as the pixels, images in FLTK. This class keeps track of common image data such as the pixels,
colormap, width, height, and depth. Virtual methods are used to provide colormap, width, height, and depth. Virtual methods are used to provide
type-specific image handling. type-specific image handling.
Each image possesses two (width, height) pairs. 1) The width and height of the Each image possesses two (width, height) pairs:
image raw data are returned by data_w() and data_h(). These values are set -# The width and height of the raw image data are returned by data_w() and
when the image is created and remain unchanged. 2) The width and height data_h(). These values are set when the image is created and remain unchanged.
of the area filled by the image when it gets drawn are returned by w() and h(). -# The width and height of the area filled by the image when it gets drawn are
The values are equal to data_w() and data_h() when the image is created, returned by w() and h(). These values are equal to data_w() and data_h() when
and can be changed by the scale() member function. the image is created and can be changed by the scale() member function.
Since the Fl_Image class does not support image Since the Fl_Image class does not support image drawing by itself, calling
drawing by itself, calling the draw() method results in the draw() method results in a box with an X in it being drawn instead.
a box with an X in it being drawn instead.
*/ */
class FL_EXPORT Fl_Image { class FL_EXPORT Fl_Image {
friend class Fl_Graphics_Driver; friend class Fl_Graphics_Driver;
@@ -96,15 +95,15 @@ protected:
*/ */
void d(int D) {d_ = D;} void d(int D) {d_ = D;}
/** /**
Sets the current line data size in bytes. Sets the current line data size in bytes.
Color images may contain extra data that is included after every Color images may contain extra data (padding) that is included after every
line of color image data and is normally not present. line of color image data and is normally not present.
If \p LD is zero, then line data size is assumed to be w() * d() bytes. If \p LD is zero, then line data size is assumed to be data_w() * d() bytes.
If \p LD is non-zero, then it must be positive and larger than w() * d() If \p LD is non-zero, then it must be positive and larger than data_w() * d()
to account for the extra data per line. to account for the extra data per line.
*/ */
void ld(int LD) {ld_ = LD;} void ld(int LD) {ld_ = LD;}
/** /**
@@ -177,15 +176,17 @@ public:
Fl_RGB_Image has exactly one pointer which points at the R, G, B [, A] Fl_RGB_Image has exactly one pointer which points at the R, G, B [, A]
data array of the image. The total size of this array depends on data array of the image. The total size of this array depends on
several attributes like w(), h(), data_w(), data_h(), d() and ld() several attributes like data_w(), data_h(), d() and ld() and is basically
and is basically data_w() * data_h() * d() but there are exceptions data_w() * data_h() * d() but there are exceptions if ld() is non-zero:
if ld() is non-zero: see description of ld(). see description of ld(). Since FLTK 1.4.0 w() and h() are no longer
significant for the image data size if scale() has been called on the
image to set a different display size.
Other image types have different numbers and types of data pointers Other image types have different numbers and types of data pointers
which are implementation details and not documented here. which are implementation details and not documented here.
\see count(), w(), h(), data_w(), data_h(), d(), ld() \see count(), w(), h(), data_w(), data_h(), d(), ld()
*/ */
const char * const *data() const {return data_;} const char * const *data() const {return data_;}
int fail() const; int fail() const;
/** /**
@@ -197,18 +198,18 @@ public:
\endcode \endcode
where image is an \p Fl_Image \p * pointer. where image is an \p Fl_Image \p * pointer.
However, for subclass Fl_Shared_Image this virtual method is However, for subclass Fl_Shared_Image and its subclasses this virtual
reimplemented and maintains shared images. method is reimplemented and maintains shared images.
This virtual method makes it possible to \p delete all image types in This virtual method makes it possible to \p destroy all image types in
the same way by calling the same way by calling
\code \code
image->release(); image->release();
\endcode \endcode
Reasoning: If you have an 'Fl_Image *' pointer and don't know if the Reasoning: If you have an 'Fl_Image *' base class pointer and don't know
object is one of the class Fl_Shared_Image or any other subclass of if the object is one of the class Fl_Shared_Image or any other subclass
Fl_Image (for instance Fl_RGB_Image) then you can't just use operator of Fl_Image (for instance Fl_RGB_Image) then you can't just use operator
delete since this is not appropriate for Fl_Shared_Image objects. delete since this is not appropriate for Fl_Shared_Image objects.
The virtual method release() handles this properly. The virtual method release() handles this properly.
@@ -236,16 +237,30 @@ public:
virtual ~Fl_Image(); virtual ~Fl_Image();
virtual Fl_Image *copy(int W, int H) const; virtual Fl_Image *copy(int W, int H) const;
/** /**
Creates a copy of the specified image. Creates a copy of the image in the same size.
The image should be released when you are done with it.
Note: since FLTK 1.4.0 you can use Fl_Image::release() for The copied image should be released when you are done with it.
all types of images (i.e. all subclasses of Fl_Image) instead
of operator \em delete for Fl_Image's and release() for
Fl_Shared_Image's.
This does exactly the same as 'Fl_Image::copy(int W, int H) const' where
\p W and \p H are the width and height of the source image, respectively.
This applies also to all subclasses of Fl_Image in the FLTK library.
The following two copy() calls are equivalent:
\code
Fl_Image *img1 = new Fl_Image(...);
// ...
Fl_Image *img2 = img1->copy();
Fl_Image *img3 = img1->copy(img1->w(), img1->h())
\endcode
For details see 'Fl_Image::copy(int w, int h) const'.
\see Fl_Image::release() \see Fl_Image::release()
\see Fl_Image::copy(int w, int h)
\note Since FLTK 1.4.0 this method is 'const'. If you derive your own class
from Fl_Image or any subclass your overridden methods of 'Fl_Image::copy() const'
and Fl_Image::copy(int, int) const' \b must also be 'const' for inheritage
to work properly. This is different than in FLTK 1.3.x and earlier where these
methods have not been 'const'.
*/ */
Fl_Image *copy() const { return copy(w(), h()); } Fl_Image *copy() const { return copy(w(), h()); }
virtual void color_average(Fl_Color c, float i); virtual void color_average(Fl_Color c, float i);
+62 -51
View File
@@ -76,17 +76,28 @@ void Fl_Image::draw_empty(int X, int Y) {
} }
/** /**
Creates a resized copy of the specified image. Creates a resized copy of the image.
The image should be released when you are done with it.
Note: since FLTK 1.4.0 you can use Fl_Image::release() for The copied image should be released when you are done with it.
all types of images (i.e. all subclasses of Fl_Image) instead
of operator \em delete for Fl_Image's and release() for
Fl_Shared_Image's.
\see Fl_Image::release() Note: since FLTK 1.4.0 you can use Fl_Image::release() for all types
of images (i.e. all subclasses of Fl_Image) instead of operator \em delete
for Fl_Image's and Fl_Image::release() for Fl_Shared_Image's.
The copied image data will be converted to the requested size. RGB images
are resized using the algorithm set by Fl_Image::RGB_scaling().
For the copied image the following equations are true:
- w() == data_w() == \p W
- h() == data_h() == \p H
\param[in] W,H Requested width and height of the copied image \param[in] W,H Requested width and height of the copied image
\note Since FLTK 1.4.0 this method is 'const'. If you derive your own class
from Fl_Image or any subclass your overridden methods of 'Fl_Image::copy() const'
and Fl_Image::copy(int, int) const' \b must also be 'const' for inheritage
to work properly. This is different than in FLTK 1.3.x and earlier where these
methods have not been 'const'.
*/ */
Fl_Image *Fl_Image::copy(int W, int H) const { Fl_Image *Fl_Image::copy(int W, int H) const {
return new Fl_Image(W, H, d()); return new Fl_Image(W, H, d());
@@ -107,12 +118,13 @@ void Fl_Image::color_average(Fl_Color, float) {
} }
/** /**
The desaturate() method converts an image to The desaturate() method converts an image to grayscale.
grayscale. If the image contains an alpha channel (depth = 4),
If the image contains an alpha channel (depth = 4),
the alpha channel is preserved. the alpha channel is preserved.
An internal copy is made of the original image before An internal copy is made of the original image data before
changes are applied, to avoid modifying the original image. changes are applied, to avoid modifying the original image data.
*/ */
void Fl_Image::desaturate() { void Fl_Image::desaturate() {
} }
@@ -128,63 +140,62 @@ Fl_Labeltype Fl_Image::define_FL_IMAGE_LABEL() {
} }
/** /**
The label() methods are an obsolete way to set the This method is an obsolete way to set the image attribute of a widget
image attribute of a widget or menu item. Use the or menu item.
image() or deimage() methods of the
Fl_Widget and Fl_Menu_Item classes Use the image() or deimage() methods of the Fl_Widget and Fl_Menu_Item
instead. classes instead.
*/ */
void Fl_Image::label(Fl_Widget* widget) { void Fl_Image::label(Fl_Widget* widget) {
widget->image(this); widget->image(this);
} }
/** /**
The label() methods are an obsolete way to set the This method is an obsolete way to set the image attribute of a widget
image attribute of a widget or menu item. Use the or menu item.
image() or deimage() methods of the
Fl_Widget and Fl_Menu_Item classes Use the image() or deimage() methods of the Fl_Widget and Fl_Menu_Item
instead. classes instead.
*/ */
void Fl_Image::label(Fl_Menu_Item* m) { void Fl_Image::label(Fl_Menu_Item* m) {
m->label(FL_IMAGE_LABEL, (const char*)this); m->label(FL_IMAGE_LABEL, (const char*)this);
} }
/** /**
Returns a value that is not 0 if there is currently no image Returns a value that is not 0 if there is currently no image available.
available.
Example use: Example use:
\code \code
[..] // [..]
Fl_Box box(X,Y,W,H); Fl_Box box(X, Y, W, H);
Fl_JPEG_Image jpg("/tmp/foo.jpg"); Fl_JPEG_Image jpg("/tmp/foo.jpg");
switch ( jpg.fail() ) { switch (jpg.fail()) {
case Fl_Image::ERR_NO_IMAGE: case Fl_Image::ERR_NO_IMAGE:
case Fl_Image::ERR_FILE_ACCESS: case Fl_Image::ERR_FILE_ACCESS:
fl_alert("/tmp/foo.jpg: %s", strerror(errno)); // shows actual os error to user fl_alert("/tmp/foo.jpg: %s", strerror(errno)); // shows actual os error to user
exit(1); exit(1);
case Fl_Image::ERR_FORMAT: case Fl_Image::ERR_FORMAT:
fl_alert("/tmp/foo.jpg: couldn't decode image"); fl_alert("/tmp/foo.jpg: couldn't decode image");
exit(1); exit(1);
} }
box.image(jpg); box.image(jpg);
[..] \endcode
\endcode
\return ERR_NO_IMAGE if no image was found \returns Image load failure if non-zero
\return ERR_FILE_ACCESS if there was a file access related error (errno should be set) \retval 0 the image was loaded successfully
\return ERR_FORMAT if image decoding failed. \retval ERR_NO_IMAGE no image was found
*/ \retval ERR_FILE_ACCESS there was a file access related error (errno should be set)
int Fl_Image::fail() const \retval ERR_FORMAT image decoding failed
{ */
// if no image exists, ld_ may contain a simple error code int Fl_Image::fail() const {
if ( (w_<=0) || (h_<=0) || (d_<=0) ) { // if no image exists, ld_ may contain a simple error code
if (ld_==0) if ((w_ <= 0) || (h_ <= 0) || (d_ <= 0)) {
return ERR_NO_IMAGE; if (ld_ == 0)
else return ERR_NO_IMAGE;
return ld_; else
} return ld_;
return 0; }
return 0;
} }
void void