From b0c99fa7805e5fb8ef5ece471affb36944ef482d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 20 Aug 2015 22:34:48 +0800 Subject: [PATCH 1/5] fix an PNG palette color type issue --- source/paint/detail/image_png.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source/paint/detail/image_png.hpp b/source/paint/detail/image_png.hpp index eda096e7..039c7908 100644 --- a/source/paint/detail/image_png.hpp +++ b/source/paint/detail/image_png.hpp @@ -55,6 +55,21 @@ namespace nana 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); + const auto bit_depth = ::png_get_bit_depth(png_ptr, info_ptr); + + //do some extra work for palette/gray color type + if (PNG_COLOR_TYPE_PALETTE == color_type) + ::png_set_palette_to_rgb(png_ptr); + else if ((PNG_COLOR_TYPE_GRAY == color_type) && (bit_depth < 8)) + ::png_set_gray_to_rgb(png_ptr); + + bool is_alpha_enabled = (::png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0); + if (is_alpha_enabled) + ::png_set_tRNS_to_alpha(png_ptr); + + //make sure 8-bit per channel + if (16 == bit_depth) + ::png_set_strip_16(png_ptr); ::png_set_interlace_handling(png_ptr); ::png_read_update_info(png_ptr, info_ptr); @@ -65,7 +80,7 @@ namespace nana pixbuf_.open(png_width, png_height); - const bool is_alpha_enabled = ((PNG_COLOR_MASK_ALPHA & color_type) != 0); + 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))) From 03faa0a7eefa72e5616b0280ca64718524fcc2a6 Mon Sep 17 00:00:00 2001 From: dareg Date: Sat, 22 Aug 2015 23:20:32 +0200 Subject: [PATCH 2/5] Fix missing array declaration in unique_ptr Which was causing a wrong deletion of the array --- source/paint/detail/native_paint_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/paint/detail/native_paint_interface.cpp b/source/paint/detail/native_paint_interface.cpp index 153ac5f0..476fc5c4 100644 --- a/source/paint/detail/native_paint_interface.cpp +++ b/source/paint/detail/native_paint_interface.cpp @@ -187,7 +187,7 @@ namespace detail reinterpret_cast(const_cast(utf8str.c_str())), utf8str.size()); */ auto fs = reinterpret_cast(dw->font->handle); - std::unique_ptr glyphs_ptr(new FT_UInt[len]); + std::unique_ptr glyphs_ptr(new FT_UInt[len]); auto glyphs = glyphs_ptr.get(); const auto endstr = str + len; for(auto chr = str; chr != endstr; ++chr) From 29ab6be21bf37ba8ba12231606883b0c60e37f64 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 23 Aug 2015 17:51:52 +0800 Subject: [PATCH 3/5] add contribution information --- source/paint/detail/native_paint_interface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/paint/detail/native_paint_interface.cpp b/source/paint/detail/native_paint_interface.cpp index 476fc5c4..0222269f 100644 --- a/source/paint/detail/native_paint_interface.cpp +++ b/source/paint/detail/native_paint_interface.cpp @@ -8,6 +8,7 @@ * http://www.boost.org/LICENSE_1_0.txt) * * @file: nana/paint/detail/native_paint_interface.cpp + * @contributors: dareg */ #include @@ -187,6 +188,8 @@ namespace detail reinterpret_cast(const_cast(utf8str.c_str())), utf8str.size()); */ auto fs = reinterpret_cast(dw->font->handle); + + //Fixed missing array declaration by dareg std::unique_ptr glyphs_ptr(new FT_UInt[len]); auto glyphs = glyphs_ptr.get(); const auto endstr = str + len; From 9384baace4a980aae0f139629a2ec48797cbf90a Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 27 Aug 2015 01:40:18 +0800 Subject: [PATCH 4/5] fix a crash caused by calling inner_widget_notifier's destroy twice --- include/nana/gui/widgets/widget.hpp | 2 +- source/gui/detail/window_manager.cpp | 19 ++++++++++++------- source/gui/widgets/tabbar.cpp | 1 - source/gui/widgets/widget.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index 18163f61..0288388e 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -31,7 +31,7 @@ namespace nana : nana::noncopyable, nana::nonmovable { friend class detail::widget_notifier_interface; - class notifier; + class inner_widget_notifier; typedef void(*dummy_bool_type)(widget* (*)(const widget&)); public: virtual ~widget() = default; diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 4ba1c3a2..e9581fd1 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -326,6 +326,9 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd) == false) return; + if (wd->flags.destroying) + return; + if(wd->other.category == category::root_tag::value) { auto &brock = bedrock::instance(); @@ -340,13 +343,15 @@ namespace detail if(wd->flags.modal || (wd->owner == nullptr) || wd->owner->flags.take_active) native_interface::activate_owner(wd->root); - //Close should detach the drawer and send destroy signal to widget object. - //Otherwise, when a widget object is been deleting in other thread by delete operator, the object will be destroyed - //before the window_manager destroyes the window, and then, window_manager detaches the - //non-existing drawer_trigger which is destroyed by destruction of widget. Crash! - wd->drawer.detached(); - - wd->widget_notifier->destroy(); + if (!wd->flags.destroying) + { + //Close should detach the drawer and send destroy signal to widget object. + //Otherwise, when a widget object is been deleting in other thread by delete operator, the object will be destroyed + //before the window_manager destroyes the window, and then, window_manager detaches the + //non-existing drawer_trigger which is destroyed by destruction of widget. Crash! + wd->drawer.detached(); + wd->widget_notifier->destroy(); + } native_interface::close_window(wd->root); } diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index 6532bf6e..8b82c6d0 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -1440,7 +1440,6 @@ namespace nana private: void _m_calc_metrics(graph_reference graph, std::forward_list& items) { - const auto height_px = graph.height(); std::vector pxs; unsigned pixels = 0; diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index af853b38..39a2ac57 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -22,10 +22,10 @@ namespace nana //class widget //@brief:The definition of class widget - class widget::notifier: public detail::widget_notifier_interface + class widget::inner_widget_notifier : public detail::widget_notifier_interface { public: - notifier(widget& wdg) + inner_widget_notifier(widget& wdg) : wdg_(wdg) {} @@ -246,7 +246,7 @@ namespace nana std::unique_ptr<::nana::detail::widget_notifier_interface> widget::_m_wdg_notifier() { - return std::unique_ptr<::nana::detail::widget_notifier_interface>(new notifier(*this)); + return std::unique_ptr<::nana::detail::widget_notifier_interface>(new inner_widget_notifier(*this)); } void widget::_m_complete_creation() @@ -348,7 +348,7 @@ namespace nana { std::unique_ptr widget_notifier_interface::get_notifier(widget* wdg) { - return std::unique_ptr(new widget::notifier(*wdg)); + return std::unique_ptr(new widget::inner_widget_notifier(*wdg)); } } }//end namespace nana From 549acf5aefed06db8b68fe6f487bc453f3d25c5d Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 27 Aug 2015 23:06:03 +0800 Subject: [PATCH 5/5] fix a bug that missed refresh in event handling --- source/gui/detail/bedrock_pi.cpp | 53 +++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 0e6c3cf8..8f2cff1c 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -189,8 +189,6 @@ namespace nana auto retain = wd->together.events_ptr; auto evts_ptr = retain.get(); - //enable refreshing flag, this is a RAII class for exception-safe - flag_guard fguard(this, wd); switch (evt_code) { @@ -199,8 +197,11 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (nullptr == arg) return; - - wd->drawer.click(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.click(*arg); + } if (!draw_only) evts_ptr->click.emit(*arg); } @@ -249,7 +250,11 @@ namespace nana throw std::runtime_error("Invalid mouse event code"); } - (wd->drawer.*drawer_event_fn)(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + (wd->drawer.*drawer_event_fn)(*arg); + } if (!draw_only) evt_addr->emit(*arg); @@ -260,7 +265,12 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (arg) { - wd->drawer.mouse_wheel(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.mouse_wheel(*arg); + } + if (!draw_only) evts_ptr->mouse_wheel.emit(*arg); } @@ -299,7 +309,12 @@ namespace nana default: throw std::runtime_error("Invalid keyboard event code"); } - (wd->drawer.*drawer_event_fn)(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + (wd->drawer.*drawer_event_fn)(*arg); + } + if (!draw_only) evt_addr->emit(*arg); break; @@ -317,7 +332,11 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (arg) { - wd->drawer.focus(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.focus(*arg); + } if (!draw_only) evts_ptr->focus.emit(*arg); } @@ -328,7 +347,11 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (arg) { - wd->drawer.move(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.move(*arg); + } if (!draw_only) evts_ptr->move.emit(*arg); } @@ -339,7 +362,11 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (arg) { - wd->drawer.resizing(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.resizing(*arg); + } if (!draw_only) evts_ptr->resizing.emit(*arg); } @@ -350,7 +377,11 @@ namespace nana auto arg = dynamic_cast(&event_arg); if (arg) { - wd->drawer.resized(*arg); + { + //enable refreshing flag, this is a RAII class for exception-safe + flag_guard fguard(this, wd); + wd->drawer.resized(*arg); + } if (!draw_only) evts_ptr->resized.emit(*arg); }