Example #1
0
void Shape2D::add_rect(const Rectf &rect, const Angle &angle, bool reverse)
{
	Path2D path;

	Pointf point_1(rect.left, rect.top);
	Pointf point_2(rect.right, rect.top);
	Pointf point_3(rect.right, rect.bottom);
	Pointf point_4(rect.left, rect.bottom);

	if (angle.to_radians() != 0.0f)
	{
		Pointf center = rect.get_center();
		point_1.rotate(center, angle);
		point_2.rotate(center, angle);
		point_3.rotate(center, angle);
		point_4.rotate(center, angle);
	}

	path.add_line_to(point_1);
	path.add_line_to(point_2);
	path.add_line_to(point_3);
	path.add_line_to(point_4);

	if (reverse)
		path.reverse();

	add_path(path);
}
Example #2
0
void Shape2D::add_ellipse(const Pointf &center, const Pointf &radius, bool reverse)
{
	float offset_x = 0;
	float offset_y = 0;

	int max_radius = max(radius.x, radius.y);

	int rotationcount = max(5, (max_radius - 3));
	float halfpi = 1.5707963267948966192313216916398f;
	float turn = halfpi / rotationcount;

	offset_x = center.x;
	offset_y = -center.y;

	Path2D path;

	rotationcount *= 4;

	std::vector<Pointf> points;
	points.resize(rotationcount);

	for(int i = 0; i < rotationcount ; i++)
	{
		float pos1 = radius.x * cos(i * turn);
		float pos2 = radius.y * sin(i * turn);

		points[i].x = (center.x + pos1);
		points[i].y = (center.y + pos2);
	}

	path.add_line_to(points);

	if (reverse)
		path.reverse();

	add_path(path);
}
Shape2D FontEngine_Freetype::load_glyph_outline(int c, int &out_advance_x)
{
	out_advance_x = 0;

	FT_UInt glyph_index;

	glyph_index = FT_Get_Char_Index( face, FT_ULong(c) );

	FT_Error error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
	if ( error )
	{
		throw Exception("freetype: error loading glyph");
	}

	FT_Glyph glyph;

	error = FT_Get_Glyph( face->glyph, &glyph );

	if ( error )
	{
		throw Exception("freetype: error getting glyph");
	}

	FT_OutlineGlyph ft_outline_glyph_rec = (FT_OutlineGlyph)glyph;
	FT_Outline ft_outline = ft_outline_glyph_rec->outline;

	Shape2D outline;

//	cl_write_console_line(string_format("Num contours: %1", ft_outline.n_contours));

	for( int cont = 0; cont < ft_outline.n_contours; cont++ )
	{
//		cl_write_console_line(string_format("Num points in contour %1: %2", cont, ft_outline.contours[0]+1));

		Path2D contour;

		// debug: dump contents of points array to terminal
//		for( int i = 0; i <= ft_outline.contours[cont]; ++i )
//		{
//			FT_Vector pos = ft_outline.points[i];
//			cl_write_console_line(string_format("dump points[%1]: (%2,%3) \t type: %4", i, pos.x, pos.y, ft_outline.tags[i]));
//		}

		std::vector<TaggedPoint> points = get_contour_points(cont, &ft_outline);
		points.push_back(points.front()); // just to simplify, it's removed later.

		for( unsigned int i = 0; i < points.size()-1; i++ )
		{
			TaggedPoint &tp = points[i];

			if( tp.tag == FT_Curve_Tag_On )
			{
				contour.add_line_to(tp.pos);
			}
			else if( tp.tag == FT_Curve_Tag_Conic )
			{
				// TODO: i - 1 is safe here because we made sure the contour will start with a Tag_On.
				BezierCurve curve;
				curve.add_control_point( points[i-1].pos);
				curve.add_control_point( tp.pos );
				curve.add_control_point( points[i+1].pos );
				contour.add_curve(curve);
			}
			else if( tp.tag == FT_Curve_Tag_Cubic && points[i-1].tag == FT_Curve_Tag_Cubic )
			{
				BezierCurve curve;
				curve.add_control_point( points[i-2].pos);
				curve.add_control_point( points[i-1].pos);
				curve.add_control_point( tp.pos );
				curve.add_control_point( points[i+1].pos );
				contour.add_curve(curve);
			}
		}

		outline.add_path(contour);
	}

	FT_Done_Glyph(glyph);

	out_advance_x = get_advance_x( c );

	return outline;
}