Merge branch 'hotfix-1.6.2' into develop
This commit is contained in:
		
						commit
						8d22ff3b51
					
				| @ -23,9 +23,10 @@ namespace nana | |||||||
| 	class drawing | 	class drawing | ||||||
| 		:private nana::noncopyable | 		:private nana::noncopyable | ||||||
| 	{ | 	{ | ||||||
|  | 		struct draw_fn_handle; | ||||||
| 	public: | 	public: | ||||||
| 		typedef struct{}* diehard_t;                                ///< A handle to a drawing method
 | 		using diehard_t = draw_fn_handle * ;						///< A handle to a drawing method
 | ||||||
| 		typedef std::function<void(paint::graphics&)> draw_fn_t;    ///< A function to draw
 | 		using draw_fn_t = std::function<void(paint::graphics&)>;    ///< A function to draw
 | ||||||
| 
 | 
 | ||||||
| 		drawing(window w);              ///< Create a drawing object for a widget w
 | 		drawing(window w);              ///< Create a drawing object for a widget w
 | ||||||
| 		 | 		 | ||||||
|  | |||||||
| @ -682,7 +682,6 @@ namespace nana{ namespace widgets{	namespace skeletons | |||||||
| 		{ | 		{ | ||||||
| 			return lines_.end(); | 			return lines_.end(); | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 	private: | 	private: | ||||||
| 		void _m_parse_format(tokenizer & tknizer, std::stack<fblock*> & fbstack) | 		void _m_parse_format(tokenizer & tknizer, std::stack<fblock*> & fbstack) | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ | |||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| namespace nana | namespace nana | ||||||
| { | { | ||||||
| 	namespace drawerbase | 	namespace drawerbase | ||||||
| @ -82,7 +83,7 @@ namespace nana | |||||||
| 					dstream_.parse(s, format_enabled_); | 					dstream_.parse(s, format_enabled_); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				bool format(bool fm) | 				bool format(bool fm) noexcept | ||||||
| 				{ | 				{ | ||||||
| 					if (fm == format_enabled_) | 					if (fm == format_enabled_) | ||||||
| 						return false; | 						return false; | ||||||
| @ -95,64 +96,35 @@ namespace nana | |||||||
| 				{ | 				{ | ||||||
| 					traceable_.clear(); | 					traceable_.clear(); | ||||||
| 
 | 
 | ||||||
| 					auto pre_font = graph.typeface();	//used for restoring the font
 |  | ||||||
| 
 |  | ||||||
| #ifdef _nana_std_has_string_view |  | ||||||
| 					const unsigned def_line_pixels = graph.text_extent_size(std::wstring_view{ L" ", 1 }).height; |  | ||||||
| #else |  | ||||||
| 					const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 					font_ = pre_font; |  | ||||||
| 					fblock_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 					_m_set_default(pre_font, fgcolor); |  | ||||||
| 
 |  | ||||||
| 					_m_measure(graph); |  | ||||||
| 
 |  | ||||||
| 					render_status rs; | 					render_status rs; | ||||||
| 
 | 
 | ||||||
| 					rs.allowed_width = graph.size().width; | 					rs.allowed_width = graph.size().width; | ||||||
| 					rs.text_align = th; | 					rs.text_align = th; | ||||||
| 					rs.text_align_v = tv; | 					rs.text_align_v = tv; | ||||||
| 
 | 
 | ||||||
|  | 					::nana::size extent_size; | ||||||
|  | 
 | ||||||
| 					//All visual lines data of whole text.
 | 					//All visual lines data of whole text.
 | ||||||
| 					std::deque<std::vector<visual_line>> content_lines; | 					auto content_lines = _m_measure_extent_size(graph, th, tv, true, graph.size().width, extent_size); | ||||||
| 
 | 
 | ||||||
| 					std::size_t extent_v_pixels = 0;	//the pixels, in height, that text will be painted.
 | 					if ((tv != align_v::top) && extent_size.height < graph.height()) | ||||||
| 
 |  | ||||||
| 					for (auto & line : dstream_) |  | ||||||
| 					{ | 					{ | ||||||
| 						_m_prepare_visual_lines(graph, line, def_line_pixels, rs); | 						rs.pos.y = static_cast<int>(graph.height() - extent_size.height); | ||||||
| 
 | 
 | ||||||
| 						for (auto & vsline : rs.vslines) | 						if (align_v::center == tv) | ||||||
| 							extent_v_pixels += vsline.extent_height_px; |  | ||||||
| 
 |  | ||||||
| 						content_lines.emplace_back(std::move(rs.vslines)); |  | ||||||
| 
 |  | ||||||
| 						if(extent_v_pixels >= graph.height()) |  | ||||||
| 							break; |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					if((tv != align_v::top) && extent_v_pixels < graph.height()) |  | ||||||
| 					{ |  | ||||||
| 						rs.pos.y = static_cast<int>(graph.height() - extent_v_pixels); |  | ||||||
| 
 |  | ||||||
| 						if(align_v::center == tv) |  | ||||||
| 							rs.pos.y >>= 1; | 							rs.pos.y >>= 1; | ||||||
| 					} | 					} | ||||||
| 					else | 					else | ||||||
| 						rs.pos.y = 0; | 						rs.pos.y = 0; | ||||||
| 
 | 
 | ||||||
| 					auto vsline_iterator = content_lines.begin(); | 					auto pre_font = graph.typeface();	//used for restoring the font
 | ||||||
| 					for (auto & line : dstream_) | 					_m_set_default(pre_font, fgcolor); | ||||||
| 					{ |  | ||||||
| 						if (rs.pos.y >= static_cast<int>(graph.height())) |  | ||||||
| 							break; |  | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 					for (auto & line : content_lines) | ||||||
|  | 					{ | ||||||
| 						rs.index = 0; | 						rs.index = 0; | ||||||
| 						rs.vslines.clear(); | 						rs.vslines.swap(line); | ||||||
| 						rs.vslines.swap(*vsline_iterator++); |  | ||||||
| 						rs.pos.x = rs.vslines.front().x_base; | 						rs.pos.x = rs.vslines.front().x_base; | ||||||
| 
 | 
 | ||||||
| 						if (!_m_foreach_visual_line(graph, rs)) | 						if (!_m_foreach_visual_line(graph, rs)) | ||||||
| @ -161,14 +133,19 @@ namespace nana | |||||||
| 						rs.pos.y += static_cast<int>(rs.vslines.back().extent_height_px); | 						rs.pos.y += static_cast<int>(rs.vslines.back().extent_height_px); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					graph.typeface(pre_font); | 					if (transient_.current_font != pre_font) | ||||||
|  | 					{ | ||||||
|  | 						graph.typeface(pre_font); | ||||||
|  | 						transient_.current_font.release(); | ||||||
|  | 						transient_.current_fblock = nullptr; | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				bool find(int x, int y, std::wstring& target, std::wstring& url) const noexcept | 				bool find(const point& mouse_pos, std::wstring& target, std::wstring& url) const | ||||||
| 				{ | 				{ | ||||||
| 					for (auto & t : traceable_) | 					for (auto & t : traceable_) | ||||||
| 					{ | 					{ | ||||||
| 						if(t.r.is_hit(x, y)) | 						if(t.r.is_hit(mouse_pos)) | ||||||
| 						{ | 						{ | ||||||
| 							target = t.target; | 							target = t.target; | ||||||
| 							url = t.url; | 							url = t.url; | ||||||
| @ -181,44 +158,10 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 				::nana::size measure(graph_reference graph, unsigned limited, align th, align_v tv) | 				::nana::size measure(graph_reference graph, unsigned limited, align th, align_v tv) | ||||||
| 				{ | 				{ | ||||||
| 					::nana::size retsize; | 					::nana::size extent_size; | ||||||
|  | 					_m_measure_extent_size(graph, th, tv, false, limited, extent_size); | ||||||
| 
 | 
 | ||||||
| 					auto ft = graph.typeface();	//used for restoring the font
 | 					return extent_size; | ||||||
| 
 |  | ||||||
| #ifdef _nana_std_has_string_view |  | ||||||
| 					const unsigned def_line_pixels = graph.text_extent_size(std::wstring_view(L" ", 1)).height; |  | ||||||
| #else |  | ||||||
| 					const unsigned def_line_pixels = graph.text_extent_size(L" ", 1).height; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 					font_ = ft; |  | ||||||
| 					fblock_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 					_m_set_default(ft, colors::black); |  | ||||||
| 					_m_measure(graph); |  | ||||||
| 
 |  | ||||||
| 					render_status rs; |  | ||||||
| 
 |  | ||||||
| 					rs.allowed_width = limited; |  | ||||||
| 					rs.text_align = th; |  | ||||||
| 					rs.text_align_v = tv; |  | ||||||
| 
 |  | ||||||
| 					for(auto & line: dstream_) |  | ||||||
| 					{ |  | ||||||
| 						rs.vslines.clear(); |  | ||||||
| 						auto w = _m_prepare_visual_lines(graph, line, def_line_pixels, rs); |  | ||||||
| 
 |  | ||||||
| 						if(limited && (w > limited)) |  | ||||||
| 							w = limited; |  | ||||||
| 
 |  | ||||||
| 						if(retsize.width < w) |  | ||||||
| 							retsize.width = w; |  | ||||||
| 
 |  | ||||||
| 						for (auto& vsline : rs.vslines) |  | ||||||
| 							retsize.height += static_cast<unsigned>(vsline.extent_height_px); |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					return retsize; |  | ||||||
| 				} | 				} | ||||||
| 			private: | 			private: | ||||||
| 				//Manage the fblock for a specified rectangle if it is a traceable fblock.
 | 				//Manage the fblock for a specified rectangle if it is a traceable fblock.
 | ||||||
| @ -246,6 +189,9 @@ namespace nana | |||||||
| 					def_.font_size = ft.size(); | 					def_.font_size = ft.size(); | ||||||
| 					def_.font_bold = ft.bold(); | 					def_.font_bold = ft.bold(); | ||||||
| 					def_.fgcolor = fgcolor; | 					def_.fgcolor = fgcolor; | ||||||
|  | 
 | ||||||
|  | 					transient_.current_font = ft; | ||||||
|  | 					transient_.current_fblock = nullptr; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				const ::nana::color& _m_fgcolor(nana::widgets::skeletons::fblock* fp) noexcept | 				const ::nana::color& _m_fgcolor(nana::widgets::skeletons::fblock* fp) noexcept | ||||||
| @ -294,39 +240,20 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 				void _m_change_font(graph_reference graph, nana::widgets::skeletons::fblock* fp) | 				void _m_change_font(graph_reference graph, nana::widgets::skeletons::fblock* fp) | ||||||
| 				{ | 				{ | ||||||
| 					if(fp != fblock_) | 					if (fp != transient_.current_fblock) | ||||||
| 					{ | 					{ | ||||||
| 						auto& name = _m_fontname(fp); | 						auto& name = _m_fontname(fp); | ||||||
| 						auto fontsize = _m_font_size(fp); | 						auto fontsize = _m_font_size(fp); | ||||||
| 						bool bold = _m_bold(fp); | 						bool bold = _m_bold(fp); | ||||||
| 
 | 
 | ||||||
| 						if((fontsize != font_.size()) || bold != font_.bold() || name != font_.name()) | 						if((fontsize != transient_.current_font.size()) || bold != transient_.current_font.bold() || name != transient_.current_font.name()) | ||||||
| 						{ | 						{ | ||||||
| 							paint::font::font_style fs; | 							paint::font::font_style fs; | ||||||
| 							fs.weight = (bold ? 800 : 400); | 							fs.weight = (bold ? 800 : 400); | ||||||
| 							font_ = paint::font{ name, fontsize, fs }; | 							transient_.current_font = paint::font{ name, fontsize, fs }; | ||||||
| 							graph.typeface(font_); | 							graph.typeface(transient_.current_font); | ||||||
| 						} | 						} | ||||||
| 						fblock_ = fp; | 						transient_.current_fblock = fp; | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				void _m_measure(graph_reference graph) |  | ||||||
| 				{ |  | ||||||
| 					nana::paint::font ft = font_; |  | ||||||
| 					for (auto & line : dstream_) |  | ||||||
| 					{ |  | ||||||
| 						for (auto & value : line) |  | ||||||
| 						{ |  | ||||||
| 							_m_change_font(graph, value.fblock_ptr); |  | ||||||
| 							value.data_ptr->measure(graph); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					if(font_ != ft) |  | ||||||
| 					{ |  | ||||||
| 						font_ = ft; |  | ||||||
| 						graph.typeface(ft); |  | ||||||
| 						fblock_ = nullptr; |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| @ -346,6 +273,57 @@ namespace nana | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				std::deque<std::vector<visual_line>> _m_measure_extent_size(graph_reference graph, nana::align text_align, nana::align_v text_align_v, bool only_screen, unsigned allowed_width_px, nana::size & extent_size) | ||||||
|  | 				{ | ||||||
|  | 					auto pre_font = graph.typeface();	//used for restoring the font
 | ||||||
|  | 
 | ||||||
|  | 					unsigned text_ascent, text_descent, text_ileading; | ||||||
|  | 					graph.text_metrics(text_ascent, text_descent, text_ileading); | ||||||
|  | 
 | ||||||
|  | 					auto const def_line_pixels = text_ascent + text_descent; | ||||||
|  | 
 | ||||||
|  | 					_m_set_default(pre_font, colors::black); | ||||||
|  | 
 | ||||||
|  | 					render_status rs; | ||||||
|  | 
 | ||||||
|  | 					rs.allowed_width = allowed_width_px; | ||||||
|  | 					rs.text_align = text_align; | ||||||
|  | 					rs.text_align_v = text_align_v; | ||||||
|  | 
 | ||||||
|  | 					//All visual lines data of whole text.
 | ||||||
|  | 					std::deque<std::vector<visual_line>> content_lines; | ||||||
|  | 
 | ||||||
|  | 					extent_size.width = extent_size.height = 0; | ||||||
|  | 
 | ||||||
|  | 					for (auto & line : dstream_) | ||||||
|  | 					{ | ||||||
|  | 						auto width_px = _m_prepare_visual_lines(graph, line, def_line_pixels, rs); | ||||||
|  | 
 | ||||||
|  | 						if (width_px > extent_size.width) | ||||||
|  | 							extent_size.width = width_px; | ||||||
|  | 
 | ||||||
|  | 						for (auto & vsline : rs.vslines) | ||||||
|  | 							extent_size.height += vsline.extent_height_px; | ||||||
|  | 
 | ||||||
|  | 						content_lines.emplace_back(std::move(rs.vslines)); | ||||||
|  | 
 | ||||||
|  | 						if (only_screen && (extent_size.height >= graph.height())) | ||||||
|  | 							break; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					if (allowed_width_px < extent_size.width) | ||||||
|  | 						extent_size.width = allowed_width_px; | ||||||
|  | 
 | ||||||
|  | 					if (transient_.current_font != pre_font) | ||||||
|  | 					{ | ||||||
|  | 						graph.typeface(pre_font); | ||||||
|  | 						transient_.current_font.release(); | ||||||
|  | 						transient_.current_fblock = nullptr; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					return content_lines; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				/**
 | 				/**
 | ||||||
| 				 * prepare data for rendering a line of text. | 				 * prepare data for rendering a line of text. | ||||||
| 				 */ | 				 */ | ||||||
| @ -379,7 +357,10 @@ namespace nana | |||||||
| 					for (auto i = line.cbegin(); i != line.cend(); ++i) | 					for (auto i = line.cbegin(); i != line.cend(); ++i) | ||||||
| 					{ | 					{ | ||||||
| 						auto const data = i->data_ptr; | 						auto const data = i->data_ptr; | ||||||
| 						auto fblock = i->fblock_ptr; | 						auto const fblock = i->fblock_ptr; | ||||||
|  | 
 | ||||||
|  | 						_m_change_font(graph, fblock); | ||||||
|  | 						data->measure(graph); | ||||||
| 
 | 
 | ||||||
| 						abs_text_px += data->size().width; | 						abs_text_px += data->size().width; | ||||||
| 
 | 
 | ||||||
| @ -457,9 +438,7 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 						if (data->is_text()) | 						if (data->is_text()) | ||||||
| 						{ | 						{ | ||||||
| 							_m_change_font(graph, fblock); |  | ||||||
| 							//Split a text into multiple lines
 | 							//Split a text into multiple lines
 | ||||||
| 							auto rest_extent_size = extent_size.width; |  | ||||||
| 							std::size_t text_begin = 0; | 							std::size_t text_begin = 0; | ||||||
| 							while (text_begin < data->text().size()) | 							while (text_begin < data->text().size()) | ||||||
| 							{ | 							{ | ||||||
| @ -593,8 +572,7 @@ namespace nana | |||||||
| 
 | 
 | ||||||
| 					if (data->is_text()) | 					if (data->is_text()) | ||||||
| 					{ | 					{ | ||||||
| 						auto const text = data->text().c_str() + vsline_elm.range.first; | 						auto const reordered = unicode_reorder(data->text().c_str() + vsline_elm.range.first, vsline_elm.range.second); | ||||||
| 						auto const reordered = unicode_reorder(text, vsline_elm.range.second); |  | ||||||
| 
 | 
 | ||||||
| 						_m_change_font(graph, fblock); | 						_m_change_font(graph, fblock); | ||||||
| 						for (auto & bidi : reordered) | 						for (auto & bidi : reordered) | ||||||
| @ -628,25 +606,18 @@ namespace nana | |||||||
| 						rs.pos.x += static_cast<int>(data->size().width); | 						rs.pos.x += static_cast<int>(data->size().width); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 |  | ||||||
| 				static std::pair<std::size_t, std::size_t> _m_locate(dstream::linecontainer::iterator& i, std::size_t pos) |  | ||||||
| 				{ |  | ||||||
| 					std::size_t n = i->data_ptr->text().length(); |  | ||||||
| 					while(pos >= n) |  | ||||||
| 					{ |  | ||||||
| 						pos -= n; |  | ||||||
| 						n = (++i)->data_ptr->text().length(); |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					return{ pos, n - pos }; |  | ||||||
| 				} |  | ||||||
| 			private: | 			private: | ||||||
| 				dstream dstream_; | 				dstream dstream_; | ||||||
| 				bool format_enabled_ = false; | 				bool format_enabled_ = false; | ||||||
| 				::nana::widgets::skeletons::fblock * fblock_ = nullptr; | 
 | ||||||
| 				::std::deque<traceable> traceable_; | 				::std::deque<traceable> traceable_; | ||||||
| 
 | 
 | ||||||
| 				::nana::paint::font font_; | 				struct transient | ||||||
|  | 				{ | ||||||
|  | 					widgets::skeletons::fblock * current_fblock{ nullptr }; | ||||||
|  | 					paint::font current_font; | ||||||
|  | 				}transient_; | ||||||
|  | 
 | ||||||
| 				struct def_font_tag | 				struct def_font_tag | ||||||
| 				{ | 				{ | ||||||
| 					::std::string font_name; | 					::std::string font_name; | ||||||
| @ -744,7 +715,7 @@ namespace nana | |||||||
| 				{ | 				{ | ||||||
| 					std::wstring target, url; | 					std::wstring target, url; | ||||||
| 
 | 
 | ||||||
| 					if(impl_->renderer.find(arg.pos.x, arg.pos.y, target, url)) | 					if(impl_->renderer.find(arg.pos, target, url)) | ||||||
| 					{ | 					{ | ||||||
| 						int cur_state = 0; | 						int cur_state = 0; | ||||||
| 						if(target != impl_->target) | 						if(target != impl_->target) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinhao
						Jinhao