From 1eb76307e4f3500254c98173ba5459597cd84070 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Mon, 13 Jul 2015 00:23:54 +0800 Subject: [PATCH] image::paste throws exception if graphics or image is empty --- include/nana/gui/detail/effects_renderer.hpp | 2 +- .../widgets/skeletons/text_token_stream.hpp | 2 +- include/nana/paint/detail/image_bmp.hpp | 371 ------------------ include/nana/paint/detail/image_ico.hpp | 43 -- .../paint/detail/image_impl_interface.hpp | 2 +- include/nana/paint/detail/image_png.hpp | 188 --------- include/nana/paint/image.hpp | 2 +- include/nana/paint/pixel_buffer.hpp | 6 +- source/gui/animation.cpp | 4 +- source/gui/widgets/button.cpp | 2 +- source/gui/widgets/treebox.cpp | 2 +- .../paint/detail/native_paint_interface.cpp | 10 +- source/paint/graphics.cpp | 6 +- source/paint/image.cpp | 43 +- source/paint/pixel_buffer.cpp | 18 +- 15 files changed, 59 insertions(+), 642 deletions(-) delete mode 100644 include/nana/paint/detail/image_bmp.hpp delete mode 100644 include/nana/paint/detail/image_ico.hpp delete mode 100644 include/nana/paint/detail/image_png.hpp diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp index 2937a1d5..2c4522a3 100644 --- a/include/nana/gui/detail/effects_renderer.hpp +++ b/include/nana/gui/detail/effects_renderer.hpp @@ -170,7 +170,7 @@ namespace nana{ pixbuf.pixel(0, r.height - 1, px2); pixbuf.pixel(r.width - 1, r.height - 1, px3); - pixbuf.paste(wd->root, r.x, r.y); + pixbuf.paste(wd->root, { r.x, r.y }); std::vector overlaps; if(window_layer::read_overlaps(wd, visual, overlaps)) diff --git a/include/nana/gui/widgets/skeletons/text_token_stream.hpp b/include/nana/gui/widgets/skeletons/text_token_stream.hpp index beae23ee..eef80358 100644 --- a/include/nana/gui/widgets/skeletons/text_token_stream.hpp +++ b/include/nana/gui/widgets/skeletons/text_token_stream.hpp @@ -576,7 +576,7 @@ namespace nana{ namespace widgets{ namespace skeletons if(size_ != image_.size()) image_.stretch(::nana::rectangle{ image_.size() }, graph, nana::rectangle(x, y, size_.width, size_.height)); else - image_.paste(graph, x, y); + image_.paste(graph, point{ x, y }); } virtual const nana::size & size() const override diff --git a/include/nana/paint/detail/image_bmp.hpp b/include/nana/paint/detail/image_bmp.hpp deleted file mode 100644 index 5397faef..00000000 --- a/include/nana/paint/detail/image_bmp.hpp +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Bitmap Format Graphics Implementation - * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * @file: nana/paint/detail/image_bmp.hpp - * @contributors: Ryan Gonzalez - */ -#ifndef NANA_PAINT_DETAIL_IMAGE_BMP_HPP -#define NANA_PAINT_DETAIL_IMAGE_BMP_HPP - -#include "image_impl_interface.hpp" -#include - -namespace nana{ namespace paint -{ - namespace detail - { - -#ifndef NANA_WINDOWS - struct bitmap_file_header - { - unsigned short bfType; - unsigned long bfSize; - unsigned short bfReserved1; - unsigned short bfReserved2; - unsigned long bfOffBits; - } __attribute__((packed)); - - struct bitmap_info_header { - unsigned long biSize; - long biWidth; - long biHeight; - unsigned short biPlanes; - unsigned short biBitCount; - unsigned long biCompression; - unsigned long biSizeImage; - long biXPelsPerMeter; - long biYPelsPerMeter; - unsigned long biClrUsed; - unsigned long biClrImportant; - }__attribute__((packed)); - - struct rgb_quad - { - unsigned char rgbBlue; - unsigned char rgbGreen; - unsigned char rgbRed; - unsigned char rgbReserved; - }; - - struct bitmap_info - { - bitmap_info_header bmiHeader; - rgb_quad bmiColors[1]; - }__attribute__((packed)); -#else - typedef BITMAPFILEHEADER bitmap_file_header; - typedef BITMAPINFO bitmap_info; - typedef RGBQUAD rgb_quad; -#endif - - class image_bmp - :public image::image_impl_interface - { - public: - image_bmp(){} - - ~image_bmp() - { - this->close(); - } - - bool open(const nana::char_t* filename) - { - if(nullptr == filename) return false; - std::ifstream ifs; -#if defined(NANA_UNICODE) - ifs.open(static_cast(nana::charset(filename)).c_str(), std::ios::binary); -#else - ifs.open(filename, std::ios::binary); -#endif - if(ifs) - { - ifs.seekg(0, std::ios::end); - auto size = ifs.tellg(); - ifs.seekg(0, std::ios::beg); - - if(size <= static_cast(sizeof(bitmap_file_header))) - return false; - - std::unique_ptr buffer(new char[static_cast(size)]); - - ifs.read(buffer.get(), size); - if(size == ifs.gcount()) - { - bitmap_file_header * header = reinterpret_cast(buffer.get()); - if((header->bfType == 0x4D42) && (static_cast(header->bfSize) == size)) - { - unsigned char* bits = reinterpret_cast(buffer.get() + header->bfOffBits); - bitmap_info * info = reinterpret_cast(header + 1); - - //Bitmap file is 4byte-aligned for each line. - std::size_t bytes_per_line; - const std::size_t height_pixels = std::abs(info->bmiHeader.biHeight); - if(0 == info->bmiHeader.biSizeImage) - bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3); - else - bytes_per_line = info->bmiHeader.biSizeImage / height_pixels; - - pixbuf_.open(info->bmiHeader.biWidth, height_pixels); - - auto d = pixbuf_.raw_ptr(0); - - if(16 <= info->bmiHeader.biBitCount) - { - pixbuf_.put(bits, info->bmiHeader.biWidth, height_pixels, info->bmiHeader.biBitCount, bytes_per_line, (info->bmiHeader.biHeight < 0)); - } - else if(8 == info->bmiHeader.biBitCount) - { - const auto lend = d + info->bmiHeader.biWidth * height_pixels; - - if(info->bmiHeader.biHeight < 0) - { - auto s = bits; - while(d < lend) - { - auto d_p = d; - auto dpend = d_p + info->bmiHeader.biWidth; - auto s_p = s; - while(d_p != dpend) - { - rgb_quad & rgb = info->bmiColors[*s_p++]; - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - } - d = dpend; - s += bytes_per_line; - } - } - else - { - const auto* s = bits + bytes_per_line * (height_pixels - 1); - while(d < lend) - { - auto d_p = d; - auto* const dpend = d_p + info->bmiHeader.biWidth; - const auto * s_p = s; - while(d_p != dpend) - { - rgb_quad & rgb = info->bmiColors[*s_p++]; - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - } - d = dpend; - s -= bytes_per_line; - } - } - } - else if(4 == info->bmiHeader.biBitCount) - { - const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; - if(info->bmiHeader.biHeight < 0) - { - const unsigned char* s = bits; - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - unsigned index = 0; - while(d_p != dpend) - { - rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s += bytes_per_line; - } - } - else - { - const auto* s = bits + bytes_per_line * (height_pixels - 1); - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - - unsigned index = 0; - while(d_p != dpend) - { - rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s -= bytes_per_line; - } - } - } - else if(2 == info->bmiHeader.biBitCount) - { - const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; - if(info->bmiHeader.biHeight < 0) - { - const unsigned char* s = bits; - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - unsigned index = 0; - while(d_p != dpend) - { - unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2 - rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s += bytes_per_line; - } - } - else - { - const auto* s = bits + bytes_per_line * (height_pixels - 1); - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - - unsigned index = 0; - while(d_p != dpend) - { - unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2 - rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s -= bytes_per_line; - } - } - } - else if(1 == info->bmiHeader.biBitCount) - { - const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; - if(info->bmiHeader.biHeight < 0) - { - const auto* s = bits; - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - unsigned index = 0; - while(d_p != dpend) - { - unsigned bi = (7 - (index & 7)); //(index % 8) - rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s += bytes_per_line; - } - } - else - { - const auto* s = bits + bytes_per_line * (height_pixels - 1); - while(d < lend) - { - auto d_p = d; - auto * const dpend = d_p + info->bmiHeader.biWidth; - - unsigned index = 0; - while(d_p != dpend) - { - unsigned bi = (7 - (index & 7)); - rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi]; - - d_p->element.red = rgb.rgbRed; - d_p->element.green = rgb.rgbGreen; - d_p->element.blue = rgb.rgbBlue; - d_p->element.alpha_channel = rgb.rgbReserved; - ++d_p; - ++index; - } - d = dpend; - s -= bytes_per_line; - } - } - } - } - } - } - return (false == pixbuf_.empty()); - } - - bool alpha_channel() const - { - return false; - } - - bool empty() const - { - return pixbuf_.empty(); - } - - void close() - { - pixbuf_.close(); - } - - nana::size size() const - { - return pixbuf_.size(); - } - - void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const - { - if(graph && pixbuf_) - pixbuf_.paste(src_r, graph.handle(), x, y); - } - - void stretch(const nana::rectangle& src_r, graph_reference graph, const nana::rectangle& r) const - { - if(graph && pixbuf_) - pixbuf_.stretch(src_r, graph.handle(), r); - } - private: - nana::paint::pixel_buffer pixbuf_; - };//end class bmpfile - }//end namespace detail -}//end namespace paint -}//end namespace nana - -#endif diff --git a/include/nana/paint/detail/image_ico.hpp b/include/nana/paint/detail/image_ico.hpp deleted file mode 100644 index 8c66d19b..00000000 --- a/include/nana/paint/detail/image_ico.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef NANA_PAINT_DETAIL_IMAGE_ICO_HPP -#define NANA_PAINT_DETAIL_IMAGE_ICO_HPP - -#include "image_impl_interface.hpp" - -namespace nana{ namespace paint -{ - namespace detail - { - class image_ico - :public image::image_impl_interface - { -#if defined(NANA_WINDOWS) - struct handle_deleter - { - void operator()(HICON* handle) const; - };//end struct handle_deleter - typedef std::shared_ptr ptr_t; -#else - typedef std::shared_ptr ptr_t; -#endif - public: - image_ico(bool is_ico); - - bool open(const nana::char_t* filename); - bool alpha_channel() const; - bool empty() const; - void close(); - nana::size size() const; - virtual void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const; - virtual void stretch(const nana::rectangle&, graph_reference graph, const nana::rectangle& r) const; - - const ptr_t & ptr() const; - private: - const bool is_ico_; - nana::size size_; - ptr_t ptr_; - };//end class image_ico - } -}//end namespace paint -}//end namespace nana - -#endif diff --git a/include/nana/paint/detail/image_impl_interface.hpp b/include/nana/paint/detail/image_impl_interface.hpp index b2a7df50..3d74ce5c 100644 --- a/include/nana/paint/detail/image_impl_interface.hpp +++ b/include/nana/paint/detail/image_impl_interface.hpp @@ -20,7 +20,7 @@ namespace nana{ namespace paint{ virtual bool empty() const = 0; virtual void close() = 0; virtual nana::size size() const = 0; - virtual void paste(const nana::rectangle& src_r, graph_reference dst, int x, int y) const = 0; + virtual void paste(const nana::rectangle& src_r, graph_reference dst, const point& p_dst) const = 0; virtual void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const = 0; };//end class image::image_impl_interface }//end namespace paint diff --git a/include/nana/paint/detail/image_png.hpp b/include/nana/paint/detail/image_png.hpp deleted file mode 100644 index 9f54e8ef..00000000 --- a/include/nana/paint/detail/image_png.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef NANA_PAINT_DETAIL_IMAGE_PNG_HPP -#define NANA_PAINT_DETAIL_IMAGE_PNG_HPP - -#include "image_impl_interface.hpp" - -//Separate the libpng from the package that system provides. -#if defined(NANA_LIBPNG) - #include -#else - #include -#endif - -#include -#include "../pixel_buffer.hpp" - -namespace nana -{ - namespace paint{ namespace detail{ - - class image_png - : public image::image_impl_interface - { - public: - image_png() - { - } - - bool open(const nana::char_t* png_file) - { -#ifdef NANA_UNICODE - FILE * fp = ::fopen(static_cast(nana::charset(png_file)).c_str(), "rb"); -#else - FILE* fp = ::fopen(png_file, "rb"); -#endif - if(nullptr == fp) return false; - - bool is_opened = false; - - png_byte png_sig[8]; - ::fread(png_sig, 1, 8, fp); - - //Test whether the file is a png. - if(0 == png_sig_cmp(png_sig, 0, 8)) - { - png_structp png_ptr = ::png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if(png_ptr) - { - png_infop info_ptr = ::png_create_info_struct(png_ptr); - - if(info_ptr) - { - if(!setjmp(png_jmpbuf(png_ptr))) - { - //The following codes may longjmp while init_io error. - ::png_init_io(png_ptr, fp); - ::png_set_sig_bytes(png_ptr, 8); - ::png_read_info(png_ptr, info_ptr); - - const int png_width = ::png_get_image_width(png_ptr, info_ptr); - const int png_height = ::png_get_image_height(png_ptr, info_ptr); - png_byte color_type = ::png_get_color_type(png_ptr, info_ptr); - - ::png_set_interlace_handling(png_ptr); - ::png_read_update_info(png_ptr, info_ptr); - - //The following codes may longjmp while image_read error. - png_bytep * row_ptrs = new png_bytep[png_height]; - const std::size_t png_rowbytes = ::png_get_rowbytes(png_ptr, info_ptr); - - pixbuf_.open(png_width, png_height); - - const bool is_alpha_enabled = ((PNG_COLOR_MASK_ALPHA & color_type) != 0); - pixbuf_.alpha_channel(is_alpha_enabled); - - if(is_alpha_enabled && (png_rowbytes == png_width * sizeof(pixel_argb_t))) - { - for(int i = 0; i < png_height; ++i) - row_ptrs[i] = reinterpret_cast(pixbuf_.raw_ptr(i)); - - ::png_read_image(png_ptr, row_ptrs); - ::png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - - for (int i = 0; i < png_height; ++i) - { - auto p = pixbuf_.raw_ptr(i); - for (int u = 0; u < png_width; ++u) - { - auto t = p[u].element.red; - p[u].element.red = p[u].element.blue; - p[u].element.blue = t; - } - } - } - else - { - png_byte * png_pixbuf = new png_byte[png_height * png_rowbytes]; - - for(int i = 0; i < png_height; ++i) - row_ptrs[i] = reinterpret_cast(png_pixbuf + png_rowbytes * i); - - ::png_read_image(png_ptr, row_ptrs); - ::png_destroy_read_struct(&png_ptr, &info_ptr, 0); - - std::size_t png_pixel_bytes = png_rowbytes / png_width; - - pixel_argb_t * rgb_row_ptr = pixbuf_.raw_ptr(0); - for(int y = 0; y < png_height; ++y) - { - png_bytep png_ptr = row_ptrs[y]; - - pixel_argb_t * rgb_end = rgb_row_ptr + png_width; - - if(is_alpha_enabled) - { - for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i) - { - i->element.red = png_ptr[0]; - i->element.green = png_ptr[1]; - i->element.blue = png_ptr[2]; - i->element.alpha_channel = png_ptr[3]; - png_ptr += png_pixel_bytes; - } - } - else - { - for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i) - { - i->element.red = png_ptr[0]; - i->element.green = png_ptr[1]; - i->element.blue = png_ptr[2]; - i->element.alpha_channel = 255; - png_ptr += png_pixel_bytes; - } - } - rgb_row_ptr = rgb_end; - } - - delete [] png_pixbuf; - } - delete [] row_ptrs; - is_opened = true; - } - } - } - } - - ::fclose(fp); - return is_opened; - } - - bool alpha_channel() const - { - return pixbuf_.alpha_channel(); - } - - virtual bool empty() const - { - return pixbuf_.empty(); - } - - virtual void close() - { - pixbuf_.close(); - } - - virtual nana::size size() const - { - return pixbuf_.size(); - } - - void paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const - { - pixbuf_.paste(src_r, graph.handle(), x, y); - } - - void stretch(const nana::rectangle& src_r, graph_reference dst, const nana::rectangle& r) const - { - pixbuf_.stretch(src_r, dst.handle(), r); - } - private: - nana::paint::pixel_buffer pixbuf_; - - }; - }//end namespace detail - }//end namespace paint -}//end namespace nana - -#endif diff --git a/include/nana/paint/image.hpp b/include/nana/paint/image.hpp index b335a4fe..2b127586 100644 --- a/include/nana/paint/image.hpp +++ b/include/nana/paint/image.hpp @@ -43,7 +43,7 @@ namespace paint bool alpha() const; nana::size size() const; - void paste(graphics& dst, int x, int y) const; + void paste(graphics& dst, const point& p_dst) const; void paste(const nana::rectangle& r_src, graphics& dst, const point& p_dst) const;///< Paste the area of picture specified by r_src into the destination graphics specified by dst at position p_dst. void stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle& r_dst) const;///paste(tar, pos.x, pos.y); + frmobj.u.oneshot->paste(tar, pos); }); break; case frame::kind::framebuilder: @@ -230,7 +230,7 @@ namespace nana switch(frmobj.type) { case frame::kind::oneshot: - frmobj.u.oneshot->paste(graph, pos.x, pos.y); + frmobj.u.oneshot->paste(graph, pos); break; case frame::kind::framebuilder: if(rebuild_frame) diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index a43c47b4..9a4c676e 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -258,7 +258,7 @@ namespace nana{ namespace drawerbase } if(attr_.icon) - attr_.icon->paste(graph, 3, (gsize.height - icon_sz.height) / 2); + attr_.icon->paste(graph, point{ 3, static_cast(gsize.height - icon_sz.height) / 2 }); } void trigger::_m_draw(graph_reference graph) diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 7e026e6c..98578aad 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1263,7 +1263,7 @@ namespace nana img->stretch(::nana::rectangle{ size }, graph, attr.area); } else - img->paste(graph, attr.area.x + static_cast(attr.area.width - size.width) / 2, attr.area.y + static_cast(attr.area.height - size.height) / 2); + img->paste(graph, point{ attr.area.x + static_cast(attr.area.width - size.width) / 2, attr.area.y + static_cast(attr.area.height - size.height) / 2 }); } } } diff --git a/source/paint/detail/native_paint_interface.cpp b/source/paint/detail/native_paint_interface.cpp index 05b66977..153ac5f0 100644 --- a/source/paint/detail/native_paint_interface.cpp +++ b/source/paint/detail/native_paint_interface.cpp @@ -100,8 +100,8 @@ namespace detail void blend(drawable_type dw, const rectangle& area, pixel_color_t color, double fade_rate) { - if(fade_rate <= 0) return; - if(fade_rate > 1) fade_rate = 1; + if (fade_rate <= 0) return; + if (fade_rate > 1) fade_rate = 1; rectangle r; if (false == ::nana::overlap(rectangle{ drawable_size(dw) }, area, r)) @@ -114,11 +114,11 @@ namespace detail double lrate = 1 - fade_rate; pixel_buffer pixbuf(dw, r.y, r.height); - for(std::size_t row = 0; row < r.height; ++row) + for (std::size_t row = 0; row < r.height; ++row) { auto i = pixbuf.raw_ptr(row) + r.x; const auto end = i + r.width; - for(; i < end; ++i) + for (; i < end; ++i) { unsigned px_r = ((static_cast((i->value & 0xFF0000) * lrate) + red) & 0xFF0000); unsigned px_g = ((static_cast((i->value & 0xFF00) * lrate) + green) & 0xFF00); @@ -126,7 +126,7 @@ namespace detail i->value = (px_r | px_g | px_b); } } - pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, r.x, r.y); + pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, point{r.x, r.y}); } nana::size raw_text_extent_size(drawable_type dw, const nana::char_t* text, std::size_t len) diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 76e9aefc..343f4c6f 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -618,7 +618,7 @@ namespace paint { pixel_buffer pixbuf(handle_, 0, 0); pixbuf.blur(r, radius); - pixbuf.paste(handle_, 0, 0); + pixbuf.paste(handle_, point{}); } } @@ -677,7 +677,7 @@ namespace paint } delete [] tablebuf; - pixbuf.paste(handle_, 0, 0); + pixbuf.paste(handle_, point{}); if(changed_ == false) changed_ = true; } } @@ -1074,7 +1074,7 @@ namespace paint if (pxbuf_.open(handle_)) { pxbuf_.gradual_rectangle(rct, from, to, 0.0, vertical); - pxbuf_.paste(handle_, 0, 0); + pxbuf_.paste(handle_, point{}); } #elif defined(NANA_X11) if (nullptr == handle_) return; diff --git a/source/paint/image.cpp b/source/paint/image.cpp index 39aac942..2312c9c6 100644 --- a/source/paint/image.cpp +++ b/source/paint/image.cpp @@ -16,14 +16,15 @@ #include #include #include +#include #include #include #if defined(NANA_ENABLE_PNG) - #include + #include "detail/image_png.hpp" #endif -#include -#include +#include "detail/image_bmp.hpp" +#include "detail/image_ico.hpp" namespace nana { @@ -89,12 +90,12 @@ namespace paint return size_; } - void image_ico::paste(const nana::rectangle& src_r, graph_reference graph, int x, int y) const + void image_ico::paste(const nana::rectangle& src_r, graph_reference graph, const point& p_dst) const { if(ptr_ && (graph.empty() == false)) { #if defined(NANA_WINDOWS) - ::DrawIconEx(graph.handle()->context, x, y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); + ::DrawIconEx(graph.handle()->context, p_dst.x, p_dst.y, *ptr_, src_r.width, src_r.height, 0, 0, DI_NORMAL); #endif } } @@ -260,22 +261,40 @@ namespace paint return (image_ptr_ ? image_ptr_->size() : nana::size()); } - void image::paste(graphics& dst, int x, int y) const + void image::paste(graphics& dst, const point& p_dst) const { - if(image_ptr_) - image_ptr_->paste(::nana::rectangle{ image_ptr_->size() }, dst, x, y); + if(image_ptr_ && !dst.empty()) + image_ptr_->paste(::nana::rectangle{ image_ptr_->size() }, dst, p_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } void image::paste(const nana::rectangle& r_src, graphics & dst, const nana::point& p_dst) const { - if(image_ptr_) - image_ptr_->paste(r_src, dst, p_dst.x, p_dst.y); + if(image_ptr_ && !dst.empty()) + image_ptr_->paste(r_src, dst, p_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } void image::stretch(const nana::rectangle& r_src, graphics& dst, const nana::rectangle & r_dst) const { - if(image_ptr_) - image_ptr_->stretch(r_src, dst, r_dst); + if(image_ptr_ && !dst.empty()) + image_ptr_->stretch(r_src, dst, r_dst); + + if (!image_ptr_) + throw std::runtime_error("image is empty"); + + if (dst.empty()) + throw std::invalid_argument("graphics is empty"); } //end class image diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index 787d2532..e89c3a0e 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -633,13 +633,13 @@ namespace nana{ namespace paint *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line) = px; } - void pixel_buffer::paste(drawable_type drawable, int x, int y) const + void pixel_buffer::paste(drawable_type drawable, const point& p_dst) const { if(storage_) - paste(nana::rectangle(storage_->pixel_size), drawable, x, y); + paste(nana::rectangle(storage_->pixel_size), drawable, p_dst); } - void pixel_buffer::paste(const nana::rectangle& src_r, drawable_type drawable, int x, int y) const + void pixel_buffer::paste(const nana::rectangle& src_r, drawable_type drawable, const point& p_dst) const { auto sp = storage_.get(); if(drawable && sp) @@ -647,7 +647,7 @@ namespace nana{ namespace paint if(sp->alpha_channel) { nana::rectangle s_good_r, d_good_r; - if(overlap(src_r, sp->pixel_size, nana::rectangle(x, y, src_r.width, src_r.height), paint::detail::drawable_size(drawable), s_good_r, d_good_r)) + if(overlap(src_r, sp->pixel_size, nana::rectangle(p_dst.x, p_dst.y, src_r.width, src_r.height), paint::detail::drawable_size(drawable), s_good_r, d_good_r)) { pixel_buffer d_pixbuf; d_pixbuf.attach(drawable, d_good_r); @@ -660,16 +660,16 @@ namespace nana{ namespace paint assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(drawable->context, - x, y, src_r.width, src_r.height, + p_dst.x, p_dst.y, src_r.width, src_r.height, src_r.x, static_cast(sp->pixel_size.height) - src_r.y - src_r.height, 0, sp->pixel_size.height, sp->raw_pixel_buffer, &bi, DIB_RGB_COLORS); #elif defined(NANA_X11) - sp->put(drawable->pixmap, drawable->context, src_r.x, src_r.y, x, y, src_r.width, src_r.height); + sp->put(drawable->pixmap, drawable->context, src_r.x, src_r.y, p_dst.x, p_dst.y, src_r.width, src_r.height); #endif } } - void pixel_buffer::paste(native_window_type wd, int x, int y) const + void pixel_buffer::paste(native_window_type wd, const point& p_dst) const { auto sp = storage_.get(); if(nullptr == wd || nullptr == sp) return; @@ -681,7 +681,7 @@ namespace nana{ namespace paint assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(handle, - x, y, sp->pixel_size.width, sp->pixel_size.height, + p_dst.x, p_dst.y, sp->pixel_size.width, sp->pixel_size.height, 0, 0, 0, sp->pixel_size.height, sp->raw_pixel_buffer, &bi, DIB_RGB_COLORS); @@ -690,7 +690,7 @@ namespace nana{ namespace paint #elif defined(NANA_X11) auto & spec = nana::detail::platform_spec::instance(); Display * disp = spec.open_display(); - sp->put(reinterpret_cast(wd), XDefaultGC(disp, XDefaultScreen(disp)), 0, 0, x, y, sp->pixel_size.width, sp->pixel_size.height); + sp->put(reinterpret_cast(wd), XDefaultGC(disp, XDefaultScreen(disp)), 0, 0, p_dst.x, p_dst.y, sp->pixel_size.width, sp->pixel_size.height); #endif }