示例#1
0
	void graphics_context::fill_shape(const point& aCentre, const vertex_list3& aVertices, const colour& aColour) const
	{
		vertex_list2 vertices;
		vertices.reserve(aVertices.size());
		for (const auto& v : aVertices)
			vertices.push_back(to_device_units(v.xy) + iOrigin.to_vector());
		iNativeGraphicsContext->fill_shape(to_device_units(aCentre) + iOrigin, vertices, aColour);
	}
示例#2
0
	margins units_converter::to_device_units(const margins& aValue) const
	{
		return margins{
			to_device_units(iContext.device_metrics().extents(), size{ aValue.left, 0 }).cx,
			to_device_units(iContext.device_metrics().extents(), size{ 0, aValue.top }).cy,
			to_device_units(iContext.device_metrics().extents(), size{ aValue.right, 0 }).cx,
			to_device_units(iContext.device_metrics().extents(), size{ 0, aValue.bottom }).cy };
	}
示例#3
0
	path graphics_context::to_device_units(const path& aValue) const
	{
		path result = aValue;
		result.set_position(to_device_units(result.position()));
		for (std::size_t i = 0; i < result.paths().size(); ++i)
			for (std::size_t j = 0; j < result.paths()[i].size(); ++j)
				result.paths()[i][j] = to_device_units(result.paths()[i][j]);
		return result;
	}
示例#4
0
	void graphics_context::clip_to(const path& aPath, dimension aPathOutline) const
	{
		path path = to_device_units(aPath);
		path.set_shape(path::ConvexPolygon);
		path.set_position(path.position() + iOrigin);
		iNativeGraphicsContext->clip_to(path, aPathOutline);
	}
示例#5
0
	size graphics_context::draw_glyph(const point& aPoint, const glyph& aGlyph, const font& aFont, const colour& aColour) const
	{
		size result;
		{
			glyph_drawing gd(*this);
			result = iNativeGraphicsContext->draw_glyph(to_device_units(aPoint) + iOrigin, aGlyph, aFont, aColour);
		}
		if (iDrawingGlyphs == 0 && (aGlyph.underline() || (mnemonics_shown() && aGlyph.mnemonic())))
			draw_glyph_underline(aPoint, aGlyph, aFont, aColour);
		return result;
	}
示例#6
0
	rect units_converter::to_device_units(const size& aExtents, const rect& aValue) const
	{
		return rect(to_device_units(aExtents, aValue.position()), to_device_units(aExtents, aValue.extents()));
	}
示例#7
0
	void graphics_context::fill_arc(const point& aCentre, dimension aRadius, angle aStartAngle, angle aEndAngle, const colour& aColour) const
	{
		iNativeGraphicsContext->fill_arc(to_device_units(aCentre) + iOrigin, aRadius, aStartAngle, aEndAngle, aColour);
	}
示例#8
0
	void graphics_context::fill_circle(const point& aCentre, dimension aRadius, const colour& aColour) const
	{
		iNativeGraphicsContext->fill_circle(to_device_units(aCentre) + iOrigin, aRadius, aColour);
	}
示例#9
0
	void graphics_context::fill_rounded_rect(const rect& aRect, dimension aRadius, const gradient& aGradient) const
	{
		iNativeGraphicsContext->fill_rounded_rect(to_device_units(aRect) + iOrigin, aRadius, aGradient);
	}
示例#10
0
	dimension units_converter::to_device_units(dimension aValue) const
	{
		return to_device_units(iContext.device_metrics().extents(), size{ aValue, 0 }).cx;
	}
示例#11
0
	void graphics_context::clip_to(const rect& aRect) const
	{
		iNativeGraphicsContext->clip_to(to_device_units(aRect) + iOrigin);
	}
示例#12
0
	void graphics_context::draw_multiline_text(const point& aPoint, const string& aText, const font& aFont, dimension aMaxWidth, const colour& aColour, alignment aAlignment, bool aUseCache) const
	{
		const auto& glyphText = aUseCache && !iGlyphTextCache->empty() ? *iGlyphTextCache : to_glyph_text(aText.begin(), aText.end(), aFont);
		if (aUseCache && iGlyphTextCache->empty())
			*iGlyphTextCache = glyphText;
		typedef std::pair<glyph_text::const_iterator, glyph_text::const_iterator> line_t;
		typedef std::vector<line_t> lines_t;
		lines_t lines;
		std::array<glyph, 2> delimeters = { glyph(text_direction::Whitespace, '\r'), glyph(text_direction::Whitespace, '\n') };
		neolib::tokens(glyphText.cbegin(), glyphText.cend(), delimeters.begin(), delimeters.end(), lines, 0, false);
		size textExtent = multiline_text_extent(aText, aFont, aMaxWidth, aUseCache);
		point pos = aPoint;
		for (lines_t::const_iterator i = lines.begin(); i != lines.end(); ++i)
		{
			const auto& line = (logical_coordinates()[1] > logical_coordinates()[3] ? *i : *(lines.rbegin() + (i - lines.begin())));
			if (aMaxWidth == 0)
			{
				point linePos = pos;
				size lineExtent = from_device_units(glyph_text::extents(aFont, line.first, line.second));
				if (glyph_text_direction(line.first, line.second) == text_direction::RTL)
					linePos.x += textExtent.cx - lineExtent.cx;
				draw_glyph_text(linePos, line.first, line.second, aFont, aColour);
				pos.y += lineExtent.cy;
			}
			else
			{
				glyph_text::const_iterator next = line.first;
				glyph_text::const_iterator lineStart = next;
				glyph_text::const_iterator lineEnd = line.second;
				dimension maxWidth = to_device_units(size(aMaxWidth, 0)).cx;
				dimension lineWidth = 0;
				while(next != line.second)
				{
					bool gotLine = false;
					if (lineWidth + next->advance().cx > maxWidth)
					{
						std::pair<glyph_text::const_iterator, glyph_text::const_iterator> wordBreak = glyphText.word_break(lineStart, next);
						lineWidth -= glyph_text::extents(aFont, wordBreak.first, next).cx;
						lineEnd = wordBreak.first;
						next = wordBreak.second;
						if (lineEnd == next)
						{
							while(lineEnd != line.second && (lineEnd + 1)->source() == wordBreak.first->source())
								++lineEnd;
							next = lineEnd;
						}
						gotLine = true;
					}
					else
					{
						lineWidth += next->advance().cx;
						++next;
					}
					if (gotLine || next == line.second)
					{
						point linePos = pos;
						if (aAlignment == alignment::Left && glyph_text_direction(lineStart, next) == text_direction::RTL ||
							aAlignment == alignment::Right && glyph_text_direction(lineStart, next) == text_direction::LTR)
							linePos.x += textExtent.cx - from_device_units(size(lineWidth, 0)).cx;
						else if (aAlignment == alignment::Centre)
							linePos.x += std::ceil((textExtent.cx - from_device_units(size(lineWidth, 0)).cx) / 2);
						draw_glyph_text(linePos, lineStart, lineEnd, aFont, aColour);
						pos.y += glyph_text::extents(aFont, lineStart, lineEnd).cy;
						lineStart = next;
						lineEnd = line.second;
						lineWidth = 0;
					}
				}
				if (line.first == line.second)
					pos.y += font().height();
			}
		}
	}
示例#13
0
	void graphics_context::draw_arc(const point& aCentre, dimension aRadius, angle aStartAngle, angle aEndAngle, const pen& aPen) const
	{
		iNativeGraphicsContext->draw_arc(to_device_units(aCentre) + iOrigin, aRadius, aStartAngle, aEndAngle, aPen);
	}
示例#14
0
	void graphics_context::draw_circle(const point& aCentre, dimension aRadius, const pen& aPen) const
	{
		iNativeGraphicsContext->draw_circle(to_device_units(aCentre) + iOrigin, aRadius, aPen);
	}
示例#15
0
	void graphics_context::draw_rounded_rect(const rect& aRect, dimension aRadius, const pen& aPen) const
	{
		iNativeGraphicsContext->draw_rounded_rect(to_device_units(aRect) + iOrigin, aRadius, aPen);
	}
示例#16
0
	void graphics_context::draw_rect(const rect& aRect, const pen& aPen) const
	{
		iNativeGraphicsContext->draw_rect(to_device_units(aRect) + iOrigin, aPen);
	}
示例#17
0
	void graphics_context::draw_line(const point& aFrom, const point& aTo, const pen& aPen) const
	{
		iNativeGraphicsContext->draw_line(to_device_units(aFrom) + iOrigin, to_device_units(aTo) + iOrigin, aPen);
	}
示例#18
0
	void graphics_context::draw_pixel(const point& aPoint, const colour& aColour) const
	{
		iNativeGraphicsContext->fill_rect(rect{ to_device_units(aPoint) + iOrigin, size{1.0, 1.0} }, aColour);
	}
示例#19
0
	void graphics_context::set_origin(const point& aOrigin) const
	{
		iOrigin = to_device_units(aOrigin);
	}
示例#20
0
	void graphics_context::fill_and_draw_path(const path& aPath, const colour& aFillColour, const pen& aOutlinePen) const
	{
		path path = to_device_units(aPath);
		path.set_position(path.position() + iOrigin);
		iNativeGraphicsContext->fill_and_draw_path(path, aFillColour, aOutlinePen);
	}
示例#21
0
	size graphics_context::multiline_text_extent(const string& aText, const font& aFont, dimension aMaxWidth, bool aUseCache) const
	{
		const auto& glyphText = aUseCache && !iGlyphTextCache->empty() ? *iGlyphTextCache : to_glyph_text(aText.begin(), aText.end(), aFont);
		if (aUseCache && iGlyphTextCache->empty())
			*iGlyphTextCache = glyphText;
		typedef std::pair<glyph_text::const_iterator, glyph_text::const_iterator> line_t;
		typedef std::vector<line_t> lines_t;
		lines_t lines;
		std::array<glyph, 2> delimeters = { glyph(text_direction::Whitespace, '\r'), glyph(text_direction::Whitespace, '\n') };
		neolib::tokens(glyphText.cbegin(), glyphText.cend(), delimeters.begin(), delimeters.end(), lines, 0, false);
		size result;
		for (lines_t::const_iterator i = lines.begin(); i != lines.end(); ++i)
		{
			if (aMaxWidth == 0)
			{
				size lineExtent = from_device_units(glyph_text::extents(aFont, i->first, i->second));
				result.cx = std::max(result.cx, lineExtent.cx);
				result.cy += lineExtent.cy;
			}
			else
			{
				glyph_text::const_iterator next = i->first;
				glyph_text::const_iterator lineStart = next;
				glyph_text::const_iterator lineEnd = i->second;
				dimension maxWidth = to_device_units(size(aMaxWidth, 0)).cx;
				dimension lineWidth = 0;
				bool gotLine = false;
				while(next != i->second)
				{
					if (lineWidth + next->advance().cx > maxWidth)
					{
						std::pair<glyph_text::const_iterator, glyph_text::const_iterator> wordBreak = glyphText.word_break(lineStart, next);
						lineWidth -= glyph_text::extents(aFont, wordBreak.first, next).cx;
						lineEnd = wordBreak.first;
						next = wordBreak.second;
						if (lineEnd == next)
						{
							while(lineEnd != i->second && (lineEnd + 1)->source() == wordBreak.first->source())
								++lineEnd;
							next = lineEnd;
						}
						gotLine = true;
					}
					else
					{	
						lineWidth += next->advance().cx;
						++next;
					}
					if (gotLine || next == i->second)
					{
						result.cx = std::max(result.cx, from_device_units(size(lineWidth, 0)).cx);
						result.cy += from_device_units(glyph_text::extents(aFont, i->first, i->second)).cy;
						lineStart = next;
						lineEnd = i->second;
						lineWidth = 0;
						gotLine = false;
					}
				}
			}
		}
		if (result.cy == 0)
			result.cy = from_device_units(size(0, aFont.height())).cy;
		return result;
	}
示例#22
0
	void graphics_context::draw_texture(const point& aPoint, const i_texture& aTexture, const rect& aTextureRect, const optional_colour& aColour) const
	{
		iNativeGraphicsContext->draw_texture(rect{to_device_units(aPoint) + iOrigin, aTexture.extents()}.to_vector(), aTexture, aTextureRect, aColour);
	}
示例#23
0
	void graphics_context::scissor_on(const rect& aRect) const
	{
		iNativeGraphicsContext->scissor_on(to_device_units(aRect) + iOrigin);
	}
示例#24
0
	dimension units_converter::to_device_units(const size& aExtents, dimension aValue) const
	{
		return to_device_units(aExtents, size{ aValue, 0 }).cx;
	}
示例#25
0
	void graphics_context::draw_path(const path& aPath, const pen& aPen) const
	{
		path path = to_device_units(aPath);
		path.set_position(path.position() + iOrigin);
		iNativeGraphicsContext->draw_path(path, aPen);
	}
示例#26
0
	rect units_converter::to_device_units(const rect& aValue) const
	{
		return to_device_units(iContext.device_metrics().extents(), aValue);
	}
示例#27
0
	void graphics_context::draw_texture(const texture_map& aTextureMap, const i_texture& aTexture, const optional_colour& aColour) const
	{
		iNativeGraphicsContext->draw_texture(to_device_units(aTextureMap) + iOrigin.to_vector(), aTexture, rect(point(0.0, 0.0), aTexture.extents()), aColour);
	}
示例#28
0
	void graphics_context::fill_rect(const rect& aRect, const colour& aColour) const
	{
		iNativeGraphicsContext->fill_rect(to_device_units(aRect) + iOrigin, aColour);
	}
示例#29
0
	void graphics_context::draw_texture(const texture_map& aTextureMap, const i_texture& aTexture, const rect& aTextureRect, const optional_colour& aColour) const
	{
		iNativeGraphicsContext->draw_texture(to_device_units(aTextureMap) + iOrigin.to_vector(), aTexture, aTextureRect, aColour);
	}
示例#30
0
	void graphics_context::fill_rect(const rect& aRect, const gradient& aGradient) const
	{
		iNativeGraphicsContext->fill_rect(to_device_units(aRect) + iOrigin, aGradient);
	}