From 21dc4be5d27fd73cda55795ab9d1e7e02b494c46 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 2 Apr 2005 21:30:22 +0000
Subject: [PATCH] added wxImage::IsTransparent(x, y)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33284 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt        |  1 +
 docs/latex/wx/image.tex | 11 ++++++-
 include/wx/image.h      | 14 +++++++-
 src/common/image.cpp    | 72 ++++++++++++++++++++++++++++++++---------
 4 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index d8226f0dab..6a6388c212 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -29,6 +29,7 @@ All (GUI):
 - Added wxTE_BESTWRAP (based on patch by Mart Raudsepp).
 - wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED is now only sent once at the end of
   splitter dragging and not after each CHANGING event (Jacobo Vilella Vilahur).
+- Added wxImage::IsTransparent()
 
 Unix:
 
diff --git a/docs/latex/wx/image.tex b/docs/latex/wx/image.tex
index 9d95417a0c..9990550f56 100644
--- a/docs/latex/wx/image.tex
+++ b/docs/latex/wx/image.tex
@@ -270,7 +270,7 @@ Returns number of colours in the histogram.
 
 \membersection{wxImage::ConvertAlphaToMask}\label{wximageconvertalphatomask}
 
-\func{bool}{ConvertAlphaToMask}{\param{unsigned char}{ threshold = 128}}
+\func{bool}{ConvertAlphaToMask}{\param{unsigned char}{ threshold = $128$}}
 
 If the image has alpha channel, this method converts it to mask. All pixels
 with alpha value less than \arg{threshold} are replaced with mask colour
@@ -708,6 +708,15 @@ of a given handler class in an application session.}
 \helpref{wxImageHandler}{wximagehandler}
 
 
+\membersection{wxImage::IsTransparent}\label{wximageistransparent}
+
+\constfunc{IsTransparent}{\param{int }{x}, \param{int }{y}, \param{unsigned char threshold = $128$}}
+
+Returns \true if the given pixel is transparent, i.e. either has the mask
+colour if this image has a mask or if this image has alpha channel and alpha
+value of this pixel is strictly less than \arg{threshold}.
+
+
 \membersection{wxImage::LoadFile}\label{wximageloadfile}
 
 \func{bool}{LoadFile}{\param{const wxString\&}{ name}, \param{long}{ type = wxBITMAP\_TYPE\_ANY}, \param{int}{ index = -1}}
diff --git a/include/wx/image.h b/include/wx/image.h
index c4737d7273..36843a4122 100644
--- a/include/wx/image.h
+++ b/include/wx/image.h
@@ -46,6 +46,13 @@ enum
     wxIMAGE_RESOLUTION_CM = 2
 };
 
+// alpha channel values: fully transparent, default threshold separating
+// transparent pixels from opaque for a few functions dealing with alpha and
+// fully opaque
+const unsigned char wxIMAGE_ALPHA_TRANSPARENT = 0;
+const unsigned char wxIMAGE_ALPHA_THRESHOLD = 0x80;
+const unsigned char wxIMAGE_ALPHA_OPAQUE = 0xff;
+
 //-----------------------------------------------------------------------------
 // classes
 //-----------------------------------------------------------------------------
@@ -240,7 +247,7 @@ public:
 
     // converts image's alpha channel to mask, if it has any, does nothing
     // otherwise:
-    bool ConvertAlphaToMask(unsigned char threshold = 128);
+    bool ConvertAlphaToMask(unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD);
 
     // This method converts an image where the original alpha
     // information is only available as a shades of a colour
@@ -290,6 +297,11 @@ public:
     void SetAlpha(unsigned char *alpha = NULL, bool static_data=false);
     void InitAlpha();
 
+    // return true if this pixel is masked or has alpha less than specified
+    // threshold
+    bool IsTransparent(int x, int y,
+                       unsigned char threshold = wxIMAGE_ALPHA_THRESHOLD) const;
+
     // Mask functions
     void SetMaskColour( unsigned char r, unsigned char g, unsigned char b );
     // Get the current mask colour or find a suitable colour
diff --git a/src/common/image.cpp b/src/common/image.cpp
index 7767fedb90..3514fd761b 100644
--- a/src/common/image.cpp
+++ b/src/common/image.cpp
@@ -787,6 +787,20 @@ wxImage wxImage::ConvertToMono( unsigned char r, unsigned char g, unsigned char
     return image;
 }
 
+int wxImage::GetWidth() const
+{
+    wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+    return M_IMGDATA->m_width;
+}
+
+int wxImage::GetHeight() const
+{
+    wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+    return M_IMGDATA->m_height;
+}
+
 long wxImage::XYToIndex(int x, int y) const
 {
     if ( Ok() &&
@@ -1022,8 +1036,6 @@ void wxImage::InitAlpha()
     unsigned char *alpha = M_IMGDATA->m_alpha;
     const size_t lenAlpha = M_IMGDATA->m_width * M_IMGDATA->m_height;
 
-    static const unsigned char ALPHA_TRANSPARENT = 0;
-    static const unsigned char ALPHA_OPAQUE = 0xff;
     if ( HasMask() )
     {
         // use the mask to initialize the alpha channel.
@@ -1037,8 +1049,8 @@ void wxImage::InitAlpha()
               src += 3, alpha++ )
         {
             *alpha = (src[0] == mr && src[1] == mg && src[2] == mb)
-                            ? ALPHA_TRANSPARENT
-                            : ALPHA_OPAQUE;
+                            ? wxIMAGE_ALPHA_TRANSPARENT
+                            : wxIMAGE_ALPHA_OPAQUE;
         }
 
         M_IMGDATA->m_hasMask = false;
@@ -1046,7 +1058,7 @@ void wxImage::InitAlpha()
     else // no mask
     {
         // make the image fully opaque
-        memset(alpha, ALPHA_OPAQUE, lenAlpha);
+        memset(alpha, wxIMAGE_ALPHA_OPAQUE, lenAlpha);
     }
 }
 
@@ -1117,18 +1129,35 @@ bool wxImage::HasMask() const
     return M_IMGDATA->m_hasMask;
 }
 
-int wxImage::GetWidth() const
+bool wxImage::IsTransparent(int x, int y, unsigned char threshold) const
 {
-    wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+    long pos = XYToIndex(x, y);
+    wxCHECK_MSG( pos != -1, false, wxT("invalid image coordinates") );
 
-    return M_IMGDATA->m_width;
-}
+    // check mask
+    if ( M_IMGDATA->m_hasMask )
+    {
+        const unsigned char *p = M_IMGDATA->m_data + 3*pos;
+        if ( p[0] == M_IMGDATA->m_maskRed &&
+                p[1] == M_IMGDATA->m_maskGreen &&
+                    p[2] == M_IMGDATA->m_maskBlue )
+        {
+            return true;
+        }
+    }
 
-int wxImage::GetHeight() const
-{
-    wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+    // then check alpha
+    if ( M_IMGDATA->m_alpha )
+    {
+        if ( M_IMGDATA->m_alpha[pos] < threshold )
+        {
+            // transparent enough
+            return true;
+        }
+    }
 
-    return M_IMGDATA->m_height;
+    // not transparent
+    return false;
 }
 
 bool wxImage::SetMaskFromImage(const wxImage& mask,
@@ -1216,9 +1245,11 @@ bool wxImage::ConvertAlphaToMask(unsigned char threshold)
     return true;
 }
 
-#if wxUSE_PALETTE
-
+// ----------------------------------------------------------------------------
 // Palette functions
+// ----------------------------------------------------------------------------
+
+#if wxUSE_PALETTE
 
 bool wxImage::HasPalette() const
 {
@@ -1244,7 +1275,10 @@ void wxImage::SetPalette(const wxPalette& palette)
 
 #endif // wxUSE_PALETTE
 
+// ----------------------------------------------------------------------------
 // Option functions (arbitrary name/value mapping)
+// ----------------------------------------------------------------------------
+
 void wxImage::SetOption(const wxString& name, const wxString& value)
 {
     wxCHECK_RET( Ok(), wxT("invalid image") );
@@ -1292,6 +1326,10 @@ bool wxImage::HasOption(const wxString& name) const
     return (M_IMGDATA->m_optionNames.Index(name, false) != wxNOT_FOUND);
 }
 
+// ----------------------------------------------------------------------------
+// image I/O
+// ----------------------------------------------------------------------------
+
 bool wxImage::LoadFile( const wxString& filename, long type, int index )
 {
 #if wxUSE_STREAMS
@@ -1549,6 +1587,10 @@ bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) const
 }
 #endif // wxUSE_STREAMS
 
+// ----------------------------------------------------------------------------
+// image I/O handlers
+// ----------------------------------------------------------------------------
+
 void wxImage::AddHandler( wxImageHandler *handler )
 {
     // Check for an existing handler of the type being added.
-- 
2.50.0

