X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a1cd9564788c4980d1a9feecca5c96a58a80ee0f..41f44cca0a5130f104aaeefad1f07a39a1491c0f:/src/common/image.cpp?ds=sidebyside diff --git a/src/common/image.cpp b/src/common/image.cpp index 807bdd2890..64f367c521 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -14,25 +14,26 @@ #pragma hdrstop #endif -#include "wx/defs.h" - #if wxUSE_IMAGE +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/hash.h" + #include "wx/utils.h" +#endif + #include "wx/image.h" #include "wx/bitmap.h" #include "wx/debug.h" -#include "wx/log.h" -#include "wx/app.h" #include "wx/filefn.h" #include "wx/wfstream.h" #include "wx/intl.h" #include "wx/module.h" -#include "wx/hash.h" -#include "wx/utils.h" #include "wx/math.h" #if wxUSE_XPM -#include "wx/xpmdecod.h" + #include "wx/xpmdecod.h" #endif // For memcpy @@ -148,17 +149,6 @@ wxImage::wxImage( wxInputStream& stream, const wxString& mimetype, int index ) } #endif // wxUSE_STREAMS -wxImage::wxImage( const wxImage& image ) - : wxObject() -{ - Ref(image); -} - -wxImage::wxImage( const wxImage* image ) -{ - if (image) Ref(*image); -} - wxImage::wxImage( const char** xpmData ) { Create(xpmData); @@ -261,9 +251,9 @@ wxImage wxImage::Copy() const image.SetMask( M_IMGDATA->m_hasMask ); memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 ); - + wxImageRefData *imgData = (wxImageRefData *)image.m_refData; - + // also copy the alpha channel if (HasAlpha()) { @@ -271,7 +261,7 @@ wxImage wxImage::Copy() const unsigned char* alpha = image.GetAlpha(); memcpy( alpha, GetAlpha(), M_IMGDATA->m_width*M_IMGDATA->m_height ); } - + // also copy the image options imgData->m_optionNames = M_IMGDATA->m_optionNames; imgData->m_optionValues = M_IMGDATA->m_optionValues; @@ -560,9 +550,16 @@ wxImage wxImage::Mirror( bool horizontally ) const image.Create( M_IMGDATA->m_width, M_IMGDATA->m_height, false ); unsigned char *data = image.GetData(); + unsigned char *alpha = NULL; wxCHECK_MSG( data, image, wxT("unable to create image") ); + if (M_IMGDATA->m_alpha != NULL) { + image.SetAlpha(); + alpha = image.GetAlpha(); + wxCHECK_MSG( alpha, image, wxT("unable to create alpha channel") ); + } + if (M_IMGDATA->m_hasMask) image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue ); @@ -585,6 +582,25 @@ wxImage wxImage::Mirror( bool horizontally ) const target_data -= 3; } } + + if (alpha != NULL) + { + // src_alpha starts at the first pixel and increases by 1 after each step + // (a step here is the copy of the alpha value of one pixel) + const unsigned char *src_alpha = M_IMGDATA->m_alpha; + // dest_alpha starts just beyond the first line, decreases before each step, + // and after each line is finished, increases by 2 widths (skipping the line + // just copied and the line that will be copied next) + unsigned char *dest_alpha = alpha + width; + + for (long jj = 0; jj < height; ++jj) + { + for (long i = 0; i < width; ++i) { + *(--dest_alpha) = *(src_alpha++); // copy one pixel + } + dest_alpha += 2 * width; // advance beyond the end of the next line + } + } } else { @@ -594,6 +610,23 @@ wxImage wxImage::Mirror( bool horizontally ) const memcpy( target_data, source_data, (size_t)3*width ); source_data += 3*width; } + + if (alpha != NULL) + { + // src_alpha starts at the first pixel and increases by 1 width after each step + // (a step here is the copy of the alpha channel of an entire line) + const unsigned char *src_alpha = M_IMGDATA->m_alpha; + // dest_alpha starts just beyond the last line (beyond the whole image) + // and decreases by 1 width before each step + unsigned char *dest_alpha = alpha + width * height; + + for (long jj = 0; jj < height; ++jj) + { + dest_alpha -= width; + memcpy( dest_alpha, src_alpha, (size_t)width ); + src_alpha += width; + } + } } return image; @@ -605,32 +638,47 @@ wxImage wxImage::GetSubImage( const wxRect &rect ) const wxCHECK_MSG( Ok(), image, wxT("invalid image") ); - wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && (rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()), + wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && + (rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()), image, wxT("invalid subimage size") ); - int subwidth=rect.GetWidth(); - const int subheight=rect.GetHeight(); + const int subwidth = rect.GetWidth(); + const int subheight = rect.GetHeight(); image.Create( subwidth, subheight, false ); - unsigned char *subdata = image.GetData(), *data=GetData(); + const unsigned char *src_data = GetData(); + const unsigned char *src_alpha = M_IMGDATA->m_alpha; + unsigned char *subdata = image.GetData(); + unsigned char *subalpha = NULL; wxCHECK_MSG( subdata, image, wxT("unable to create image") ); + if (src_alpha != NULL) { + image.SetAlpha(); + subalpha = image.GetAlpha(); + wxCHECK_MSG( subalpha, image, wxT("unable to create alpha channel")); + } + if (M_IMGDATA->m_hasMask) image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue ); - const int subleft=3*rect.GetLeft(); - const int width=3*GetWidth(); - subwidth*=3; + const int width = GetWidth(); + const int pixsoff = rect.GetLeft() + width * rect.GetTop(); - data+=rect.GetTop()*width+subleft; + src_data += 3 * pixsoff; + src_alpha += pixsoff; // won't be used if was NULL, so this is ok for (long j = 0; j < subheight; ++j) { - memcpy( subdata, data, subwidth); - subdata+=subwidth; - data+=width; + memcpy( subdata, src_data, 3 * subwidth ); + subdata += 3 * subwidth; + src_data += 3 * width; + if (subalpha != NULL) { + memcpy( subalpha, src_alpha, subwidth ); + subalpha += subwidth; + src_alpha += width; + } } return image; @@ -660,6 +708,10 @@ wxImage wxImage::Size( const wxSize& size, const wxPoint& pos, wxRect subRect(pos.x, pos.y, width, height); wxRect finalRect(0, 0, size.GetWidth(), size.GetHeight()); + if (pos.x < 0) + finalRect.width -= pos.x; + if (pos.y < 0) + finalRect.height -= pos.y; subRect.Intersect(finalRect);