From 1dd492958567493c0e62f5d2614f1a46c50cb7e1 Mon Sep 17 00:00:00 2001
From: Albrecht Schlosser <albrechts.fltk@online.de>
Date: Fri, 5 Jun 2020 21:11:15 +0200
Subject: [PATCH] Add two virtual methods to class Fl_Image

(1) The new virtual method Fl_Image::release() which is equivalent to
  'delete this' automatically extends to Fl_Shared_Image::release()
  which makes the latter method virtual.

  This new method in the base class makes Fl_Image::release() callable
  on all objects derived from Fl_Image.

(2) Add virtual method Fl_Shared_Image *Fl_Image::as_shared_image()

  This new method can be used to detect whether an Fl_Image instance
  is an Fl_Shared_Image or not.
---
 FL/Fl_Image.H        | 44 ++++++++++++++++++++++++++++++++++++++++++++
 FL/Fl_Shared_Image.H |  4 ++++
 2 files changed, 48 insertions(+)

diff --git a/FL/Fl_Image.H b/FL/Fl_Image.H
index c6fb55967..aafd39742 100644
--- a/FL/Fl_Image.H
+++ b/FL/Fl_Image.H
@@ -164,6 +164,50 @@ public:
    */
   const char * const *data() const {return data_;}
   int fail();
+  /**
+    Releases an Fl_Image - the same as '\p delete \p this'.
+
+    This virtual method is for almost all image classes the same as calling
+    \code
+      delete image;
+    \endcode
+    where image is an \p Fl_Image \p * pointer.
+
+    However, for subclass Fl_Shared_Image this virtual method is
+    reimplemented and maintains shared images.
+
+    This virtual method makes it possible to \p delete all image types in
+    the same way by calling
+    \code
+      image->release();
+    \endcode
+
+    Reasoning: If you have an 'Fl_Image *' pointer and don't know if the
+    object is one of the class Fl_Shared_Image or any other subclass 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.
+
+    The virtual method release() handles this properly.
+
+    \since 1.4.0 in the base class Fl_Image and virtual in Fl_Shared_Image
+  */
+  virtual void release() {
+    delete this;
+  }
+
+  /** Returns whether an image is an Fl_Shared_Image or not.
+
+    This virtual method returns a pointer to an Fl_Shared_Image if this
+    object is an instance of Fl_Shared_Image or NULL if not. This can be
+    used to detect if a given Fl_Image object is a shared image, i.e.
+    derived from Fl_Shared_Image.
+
+    \since 1.4.0
+  */
+  virtual class Fl_Shared_Image *as_shared_image() {
+    return 0;
+  }
+
   Fl_Image(int W, int H, int D);
   virtual ~Fl_Image();
   virtual Fl_Image *copy(int W, int H);
diff --git a/FL/Fl_Shared_Image.H b/FL/Fl_Shared_Image.H
index 89d40d9ac..f68ec7af0 100644
--- a/FL/Fl_Shared_Image.H
+++ b/FL/Fl_Shared_Image.H
@@ -99,6 +99,10 @@ public:
   void		release();
   void		reload();
 
+  virtual Fl_Shared_Image *as_shared_image() {
+    return this;
+  }
+
   virtual Fl_Image *copy(int W, int H);
   Fl_Image *copy() { return Fl_Image::copy(); }
   virtual void color_average(Fl_Color c, float i);
-- 
GitLab