예제 #1
0
void Body_Impl::init(PhysicsContext &pc, const std::string &resource_id, const XMLResourceDocument &resources)
{
	XMLResourceNode resource = resources.get_resource(resource_id);

	// Create body from body description
	BodyDescription desc(pc, resource_id, resources);

	create_body(desc);

	//Load fixture and joint parameters here.
}
예제 #2
0
	Texture Texture::load(GraphicContext &gc, const std::string &id, const XMLResourceDocument &doc, const ImageImportDescription &import_desc)
	{
		XMLResourceNode resource = doc.get_resource(id);

		std::string type = resource.get_type();

		if (type != "texture")
			throw Exception(string_format("Resource '%1' is not of type 'texture'", id));

		std::string filename = resource.get_element().get_attribute("file");
		FileSystem fs = resource.get_file_system();

		Texture2D texture(gc, PathHelp::combine(resource.get_base_path(), filename), fs, import_desc);

		return Resource<Texture>(texture);
	}
ProgramObject ProgramObject::load(
    GraphicContext &gc,
    const std::string &resource_id,
    const XMLResourceDocument &resources)
{
    ProgramObject program_object(gc);

    XMLResourceNode resource = resources.get_resource(resource_id);

    DomNode node = resource.get_element().get_first_child();

    while (!node.is_null())
    {
        if (node.is_element())
        {
            DomElement element = node.to_element();
            if (element.get_tag_name() == "shader")
            {
                ShaderObject shader = ShaderObject::load(gc, element.get_attribute("name"), resources);
                program_object.attach(shader);
            }
            else if (element.get_tag_name() == "bind-attribute")
            {
                program_object.bind_attribute_location(
                    StringHelp::text_to_int(element.get_attribute("index")),
                    element.get_attribute("name"));
            }
        }
        node = node.get_next_sibling();
    }

    if (!resource.get_element().get_attribute("shader").empty())
    {
        ShaderObject shader = ShaderObject::load(gc, resource.get_element().get_attribute("shader"), resources);
        program_object.attach(shader);
    }

    if (resource.get_element().get_attribute("link", "true") == "true")
        if(!program_object.link())
            throw Exception(string_format("Unable to link program object: %1", program_object.get_info_log()));

    return program_object;
}
예제 #4
0
CollisionOutline CollisionOutline::load(const std::string &id, const XMLResourceDocument &doc)
{
	XMLResourceNode resource = doc.get_resource(id);

	if (resource.get_type() != "collisionoutline")
		throw Exception(string_format("Resource '%1' is not of type 'collisionoutline'", id));

	std::string filename = resource.get_element().get_attribute("file");
	int alpha_limit = StringHelp::text_to_int( (resource.get_element().get_attribute("alpha_value", "128")));
	std::string accuracy_str = resource.get_element().get_attribute("accuracy", "medium");
	OutlineAccuracy accuracy;

	if(accuracy_str == "high")
		accuracy = accuracy_high;
	else if(accuracy_str == "medium")
		accuracy = accuracy_medium;
	else if(accuracy_str == "low")
		accuracy = accuracy_low;
	else if(accuracy_str == "poor")
		accuracy = accuracy_poor;
    else
		accuracy = accuracy_raw;

	if (filename.length() >= 3 && filename.substr(filename.length()-3, 3) == "out" )
	{
		IODevice file = resource.get_file_system().open_file(PathHelp::combine(resource.get_base_path(), filename));
		OutlineProviderFile outline_provider(file);
		return CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy_raw);
	}
	else
	{
		PixelBuffer pbuf = ImageProviderFactory::load(PathHelp::combine(resource.get_base_path(), filename), resource.get_file_system(), "");
		OutlineProviderBitmap outline_provider(pbuf, alpha_limit);
		return CollisionOutline(outline_provider.get_contours(), outline_provider.get_size(), accuracy);
	}
}
예제 #5
0
BodyDescription::BodyDescription(const PhysicsContext &pc, const std::string &resource_id, const XMLResourceDocument &resources)
: impl(new BodyDescription_Impl(pc.impl->get_owner()))
{
	/* example resource entry with all parameters:
	
	<body2d name="TestBody" type="static">
        <position x="0" y="0"/>
        <rotation angle="180"/>
        <velocity x="0" y="0" angular="0"/>
        <damping linear="0" angular="0"/>
		<parameters awake="true" can_sleep="true" bullet="false" active="true" />
    </body2d>

	*/
	XMLResourceNode resource = resources.get_resource(resource_id);
	if (resource.get_type() != "body2d" && resource.get_type() != "body2d_description")
		throw Exception(string_format("Resource '%1' is not of type 'body2d' or 'body2d_description'", resource_id));

	DomNode cur_node = resource.get_element().get_first_child();

	//Body type
	std::string body_type = resource.get_element().get_attribute("type","static");
	if(body_type == "kinematic") set_type(body_kinematic);
	else if(body_type == "dynamic") set_type(body_dynamic);
	else set_type(body_static);

	while(!cur_node.is_null())
	{
		if (!cur_node.is_element()) 
			continue;
		
		DomElement cur_element = cur_node.to_element();
		std::string tag_name = cur_element.get_tag_name();

		//<position x="0" y="0"/>
		if(tag_name == "position")
		{
			float pos_x = 0.0f;
			float pos_y = 0.0f;

			if(cur_element.has_attribute("x"))
			{
				pos_x = StringHelp::text_to_float(cur_element.get_attribute("x"));
			}

			if(cur_element.has_attribute("y"))
			{
				pos_y = StringHelp::text_to_float(cur_element.get_attribute("y"));
			}

			set_position(pos_x, pos_y);
		}

		//<rotation angle="180"/>
		else if(tag_name == "rotation")
		{
			Angle angle(0.0f, angle_degrees);

			if(cur_element.has_attribute("angle"))
			{
				angle = Angle(StringHelp::text_to_float(cur_element.get_attribute("angle")), angle_degrees);
			}

			set_angle(angle);
		}

		//<velocity x="0" y="0" angular="0"/>
		else if(tag_name == "velocity")
		{
			Vec2f velocity(0.0f, 0.0f);
			Angle angular_velocity(0.0f, angle_degrees);

			if(cur_element.has_attribute("x"))
			{
				velocity.x = StringHelp::text_to_float(cur_element.get_attribute("x"));
			}

			if(cur_element.has_attribute("y"))
			{
				velocity.y = StringHelp::text_to_float(cur_element.get_attribute("y"));
			}

			if(cur_element.has_attribute("angular"))
			{
				angular_velocity = Angle(StringHelp::text_to_float(cur_element.get_attribute("angular")), angle_degrees);
			}

			set_linear_velocity(velocity);
			set_angular_velocity(angular_velocity);
		}

		//<damping linear="0" angular="0"/>
		else if(tag_name == "damping")
		{
			float linear;
			float angular;

			if(cur_element.has_attribute("linear"))
			{
				linear = StringHelp::text_to_float(cur_element.get_attribute("linear"));
			}

			if(cur_element.has_attribute("angular"))
			{
				angular = StringHelp::text_to_float(cur_element.get_attribute("angular"));
			}

			set_linear_damping(linear);
			set_angular_damping(angular);
		}

		//<parameters awake="true" can_sleep="true" bullet="false" active="true" />
		else if(tag_name == "parameters")
		{
			bool value;
		
			if(cur_element.has_attribute("awake"))
			{
				value = true;
				value = StringHelp::text_to_bool(cur_element.get_attribute("awake"));
				set_awake(value);
			}
			if(cur_element.has_attribute("active"))
			{
				value = true;
				value = StringHelp::text_to_bool(cur_element.get_attribute("active"));
				set_active(value);
			}
			if(cur_element.has_attribute("bullet"))
			{
				value = false;
				value = StringHelp::text_to_bool(cur_element.get_attribute("bullet"));
				set_as_bullet(value);
			}
			if(cur_element.has_attribute("can_sleep"))
			{
				value = true;
				value = StringHelp::text_to_bool(cur_element.get_attribute("can_sleep"));
				allow_sleep(value);
			}
		}

		cur_node = cur_node.get_next_sibling();
	}
}
예제 #6
0
	Font Font::load(Canvas &canvas, const std::string &family_name, const FontDescription &reference_desc, FontFamily &font_family, const XMLResourceDocument &doc, std::function<Resource<Sprite>(Canvas &, const std::string &)> cb_get_sprite)
	{
		DomElement font_element;
		XMLResourceNode resource;

		resource = doc.get_resource(family_name);
		font_element = resource.get_element();

		DomElement sprite_element = font_element.named_item("sprite").to_element();

		if (!sprite_element.is_null())
		{
			if (!sprite_element.has_attribute("glyphs"))
				throw Exception(string_format("Font resource %1 has no 'glyphs' attribute.", resource.get_name()));

			if (!sprite_element.has_attribute("letters"))
				throw Exception(string_format("Font resource %1 has no 'letters' attribute.", resource.get_name()));

			if (!cb_get_sprite)
				throw Exception(string_format("Font resource %1 requires a sprite loader callback specified.", resource.get_name()));
				
			Resource<Sprite> spr_glyphs = cb_get_sprite(canvas, sprite_element.get_attribute("glyphs"));

			const std::string &letters = sprite_element.get_attribute("letters");

			int spacelen = StringHelp::text_to_int(sprite_element.get_attribute("spacelen", "-1"));
			bool monospace = StringHelp::text_to_bool(sprite_element.get_attribute("monospace", "false"));

			// Modify the default font metrics, if specified

			float height = 0.0f;
			float line_height = 0.0f;
			float ascent = 0.0f;
			float descent = 0.0f;
			float internal_leading = 0.0f;
			float external_leading = 0.0f;

			if (sprite_element.has_attribute("height"))
				height = StringHelp::text_to_float(sprite_element.get_attribute("height", "0"));

			if (sprite_element.has_attribute("line_height"))
				line_height = StringHelp::text_to_float(sprite_element.get_attribute("line_height", "0"));

			if (sprite_element.has_attribute("ascent"))
				ascent = StringHelp::text_to_float(sprite_element.get_attribute("ascent", "0"));

			if (sprite_element.has_attribute("descent"))
				descent = StringHelp::text_to_float(sprite_element.get_attribute("descent", "0"));

			if (sprite_element.has_attribute("internal_leading"))
				internal_leading = StringHelp::text_to_float(sprite_element.get_attribute("internal_leading", "0"));

			if (sprite_element.has_attribute("external_leading"))
				external_leading = StringHelp::text_to_float(sprite_element.get_attribute("external_leading", "0"));

			FontMetrics font_metrics(height, ascent, descent, internal_leading, external_leading, line_height, canvas.get_pixel_ratio());

			font_family.add(canvas, spr_glyphs.get(), letters, spacelen, monospace, font_metrics);

			FontDescription desc = reference_desc.clone();
			return Font(font_family, desc);
		}

		DomElement ttf_element = font_element.named_item("ttf").to_element();
		if (ttf_element.is_null())
			ttf_element = font_element.named_item("freetype").to_element();

		if (!ttf_element.is_null())
		{
			FontDescription desc = reference_desc.clone();

			std::string filename;
			if (ttf_element.has_attribute("file"))
			{
				filename = PathHelp::combine(resource.get_base_path(), ttf_element.get_attribute("file"));
			}

			if (!ttf_element.has_attribute("typeface"))
				throw Exception(string_format("Font resource %1 has no 'typeface' attribute.", resource.get_name()));

			std::string font_typeface_name = ttf_element.get_attribute("typeface");

			if (ttf_element.has_attribute("height"))
				desc.set_height(ttf_element.get_attribute_int("height", 0));

			if (ttf_element.has_attribute("average_width"))
				desc.set_average_width(ttf_element.get_attribute_int("average_width", 0));

			if (ttf_element.has_attribute("anti_alias"))
				desc.set_anti_alias(ttf_element.get_attribute_bool("anti_alias", true));

			if (ttf_element.has_attribute("subpixel"))
				desc.set_subpixel(ttf_element.get_attribute_bool("subpixel", true));

			if (filename.empty())
			{
				font_family.add(font_typeface_name, desc);
				return Font(font_family, desc);
			}
			else
			{
				font_family.add(desc, filename, resource.get_file_system());
				return Font(font_family, desc);
			}
		}

		throw Exception(string_format("Font resource %1 did not have a <sprite> or <ttf> child element", resource.get_name()));
	}
예제 #7
0
	Sprite Sprite::load(Canvas &canvas, const std::string &id, const XMLResourceDocument &doc)
	{
		Sprite sprite(canvas);

		XMLResourceNode resource = doc.get_resource(id);
		if (resource.get_type() != "sprite")
			throw Exception(string_format("Resource '%1' is not of type 'sprite'", id));

		// Load base angle
		float work_angle = StringHelp::text_to_float(resource.get_element().get_attribute("base_angle", "0"));
		sprite.set_base_angle(Angle(work_angle, angle_degrees));

		// Load id
		sprite.set_id(StringHelp::text_to_int(resource.get_element().get_attribute("id", "0")));

		// Load play options	
		DomNode cur_node = resource.get_element().get_first_child();
		while (!cur_node.is_null())
		{
			if (!cur_node.is_element())
			{
				cur_node = cur_node.get_next_sibling();
				continue;
			}

			DomElement cur_element = cur_node.to_element();

			std::string tag_name = cur_element.get_tag_name();

			if (tag_name == "image" || tag_name == "image-file")
			{
				if (cur_element.has_attribute("fileseq"))
				{
					int start_index = 0;
					if (cur_element.has_attribute("start_index"))
						start_index = StringHelp::text_to_int(cur_element.get_attribute("start_index"));

					int skip_index = 1;
					if (cur_element.has_attribute("skip_index"))
						skip_index = StringHelp::text_to_int(cur_element.get_attribute("skip_index"));

					int leading_zeroes = 0;
					if (cur_element.has_attribute("leading_zeroes"))
						leading_zeroes = StringHelp::text_to_int(cur_element.get_attribute("leading_zeroes"));

					std::string prefix = cur_element.get_attribute("fileseq");
					std::string suffix = "." + PathHelp::get_extension(prefix);
					prefix.erase(prefix.length() - suffix.length(), prefix.length()); //remove the extension

					FileSystem fs = resource.get_file_system();

					bool found_initial = false;
					for (int i = start_index;; i = skip_index)
					{
						std::string file_name = prefix;

						std::string frame_text = StringHelp::int_to_text(i);
						for (int zeroes_to_add = (leading_zeroes + 1) - frame_text.length(); zeroes_to_add > 0; zeroes_to_add--)
							file_name = "0";

						file_name = frame_text + suffix;

						try
						{
							Texture2D texture = Texture2D(canvas, PathHelp::combine(resource.get_base_path(), file_name), fs);
							sprite.add_frame(texture);
							found_initial = true;
						}
						catch (const Exception&)
						{
							if (!found_initial)
							{
								//must have been an error, pass it down
								throw;
							}
							//can't find anymore pics
							break;
						}
					}
				}
				else
				{
					std::string image_name = cur_element.get_attribute("file");
					FileSystem fs = resource.get_file_system();
					Texture2D texture = Texture2D(canvas, PathHelp::combine(resource.get_base_path(), image_name), fs);

					DomNode cur_child(cur_element.get_first_child());
					if (cur_child.is_null())
					{
						sprite.add_frame(texture);
					}
					else
					{
						do {
							DomElement cur_child_elemnt = cur_child.to_element();
							if (cur_child.get_node_name() == "grid")
							{
								int xpos = 0;
								int ypos = 0;
								int xarray = 1;
								int yarray = 1;
								int array_skipframes = 0;
								int xspacing = 0;
								int yspacing = 0;
								int width = 0;
								int height = 0;

								std::vector<std::string> image_size = StringHelp::split_text(cur_child_elemnt.get_attribute("size"), ",");
								if (image_size.size() > 0)
									width = StringHelp::text_to_int(image_size[0]);
								if (image_size.size() > 1)
									height = StringHelp::text_to_int(image_size[1]);

								if (cur_child_elemnt.has_attribute("pos"))
								{
									std::vector<std::string> image_pos = StringHelp::split_text(cur_child_elemnt.get_attribute("pos"), ",");
									if (image_pos.size() > 0)
										xpos = StringHelp::text_to_int(image_pos[0]);
									if (image_pos.size() > 1)
										ypos = StringHelp::text_to_int(image_pos[1]);
								}

								if (cur_child_elemnt.has_attribute("array"))
								{
									std::vector<std::string> image_array = StringHelp::split_text(cur_child_elemnt.get_attribute("array"), ",");
									if (image_array.size() == 2)
									{
										xarray = StringHelp::text_to_int(image_array[0]);
										yarray = StringHelp::text_to_int(image_array[1]);
									}
									else
									{
										throw Exception("Resource '" + resource.get_name() + "' has incorrect array attribute, must be \"X,Y\"!");
									}
								}

								if (cur_child_elemnt.has_attribute("array_skipframes"))
								{
									array_skipframes = StringHelp::text_to_int(cur_child_elemnt.get_attribute("array_skipframes"));
								}

								if (cur_child_elemnt.has_attribute("spacing"))
								{
									std::vector<std::string> image_spacing = StringHelp::split_text(cur_child_elemnt.get_attribute("spacing"), ",");
									xspacing = StringHelp::text_to_int(image_spacing[0]);
									yspacing = StringHelp::text_to_int(image_spacing[1]);
								}

								sprite.add_gridclipped_frames(canvas,
									texture,
									xpos, ypos,
									width, height,
									xarray, yarray,
									array_skipframes,
									xspacing, yspacing);
							}
							else if (cur_child.get_node_name() == "palette")
							{
								throw Exception("Resource '" + resource.get_name() + "' uses palette cutter - which is not supported anymore");
							}
							else if (cur_child.get_node_name() == "alpha")
							{
								int xpos = 0;
								int ypos = 0;
								float trans_limit = 0.05f;

								if (cur_child_elemnt.has_attribute("pos"))
								{
									std::vector<std::string> image_pos = StringHelp::split_text(cur_child_elemnt.get_attribute("pos"), ",");
									xpos = StringHelp::text_to_int(image_pos[0]);
									ypos = StringHelp::text_to_int(image_pos[1]);
								}

								if (cur_child_elemnt.has_attribute("trans_limit"))
								{
									trans_limit = StringHelp::text_to_float(cur_child_elemnt.get_attribute("trans_limit"));
								}

								if (cur_child_elemnt.has_attribute("free"))
								{
									sprite.add_alphaclipped_frames_free(canvas,
										texture,
										xpos, ypos,
										trans_limit);
								}
								else
								{
									sprite.add_alphaclipped_frames(canvas,
										texture,
										xpos, ypos,
										trans_limit);
								}
							}

							cur_child = cur_child.get_next_sibling();
						} while (!cur_child.is_null());
					}
				}
			}
			cur_node = cur_node.get_next_sibling();
		}

		cur_node = resource.get_element().get_first_child();
		while (!cur_node.is_null())
		{
			if (!cur_node.is_element())
			{
				cur_node = cur_node.get_next_sibling();
				continue;
			}

			DomElement cur_element = cur_node.to_element();

			std::string tag_name = cur_element.get_tag_name();

			// <color red="float" green="float" blue="float" alpha="float" />
			if (tag_name == "color")
			{
				Colorf color;
				color.r = (float)StringHelp::text_to_float(cur_element.get_attribute("red", "1.0"));
				color.g = (float)StringHelp::text_to_float(cur_element.get_attribute("green", "1.0"));
				color.b = (float)StringHelp::text_to_float(cur_element.get_attribute("blue", "1.0"));
				color.a = (float)StringHelp::text_to_float(cur_element.get_attribute("alpha", "1.0"));
				sprite.set_color(color);
			}
			// <animation speed="integer" loop="[yes,no]" pingpong="[yes,no]" direction="[backward,forward]" on_finish="[blank,last_frame,first_frame]"/>
			else if (tag_name == "animation")
			{
				int delay_ms = StringHelp::text_to_int(cur_element.get_attribute("speed", "60"));

				int frame_count = sprite.get_frame_count();
				for (int i = 0; i < frame_count; ++i)
					sprite.set_frame_delay(i, delay_ms);

				sprite.set_play_loop((cur_element.get_attribute("loop", "yes")) == "yes");
				sprite.set_play_pingpong((cur_element.get_attribute("pingpong", "no")) == "yes");
				sprite.set_play_backward((cur_element.get_attribute("direction", "forward")) == "backward");

				std::string on_finish = cur_element.get_attribute("on_finish", "blank");
				if (on_finish == "first_frame")
					sprite.set_show_on_finish(Sprite::show_first_frame);
				else if (on_finish == "last_frame")
					sprite.set_show_on_finish(Sprite::show_last_frame);
				else
					sprite.set_show_on_finish(Sprite::show_blank);
			}
			// <scale x="float" y="float />
			else if (tag_name == "scale")
			{
				float scale_x = StringHelp::text_to_float(cur_element.get_attribute("x", "1.0"));
				float scale_y = StringHelp::text_to_float(cur_element.get_attribute("y", "1.0"));
				sprite.set_scale(scale_x, scale_y);
			}
			// <translation origin="string" x="integer" y="integer" />
			else if (tag_name == "translation")
			{
				std::string hotspot = cur_element.get_attribute("origin", "top_left");
				Origin origin;

				if (hotspot == "center")
					origin = origin_center;
				else if (hotspot == "top_center")
					origin = origin_top_center;
				else if (hotspot == "top_right")
					origin = origin_top_right;
				else if (hotspot == "center_left")
					origin = origin_center_left;
				else if (hotspot == "center_right")
					origin = origin_center_right;
				else if (hotspot == "bottom_left")
					origin = origin_bottom_left;
				else if (hotspot == "bottom_center")
					origin = origin_bottom_center;
				else if (hotspot == "bottom_right")
					origin = origin_bottom_right;
				else
					origin = origin_top_left;

				int xoffset = StringHelp::text_to_int(cur_element.get_attribute("x", "0"));
				int yoffset = StringHelp::text_to_int(cur_element.get_attribute("y", "0"));

				sprite.set_alignment(origin, xoffset, yoffset);
			}
			// <rotation origin="string" x="integer" y="integer" />
			else if (tag_name == "rotation")
			{
				std::string hotspot = cur_element.get_attribute("origin", "center");
				Origin origin;

				if (hotspot == "top_left")
					origin = origin_top_left;
				else if (hotspot == "top_center")
					origin = origin_top_center;
				else if (hotspot == "top_right")
					origin = origin_top_right;
				else if (hotspot == "center_left")
					origin = origin_center_left;
				else if (hotspot == "center_right")
					origin = origin_center_right;
				else if (hotspot == "bottom_left")
					origin = origin_bottom_left;
				else if (hotspot == "bottom_center")
					origin = origin_bottom_center;
				else if (hotspot == "bottom_right")
					origin = origin_bottom_right;
				else
					origin = origin_center;

				int xoffset = StringHelp::text_to_int(cur_element.get_attribute("x", "0"));
				int yoffset = StringHelp::text_to_int(cur_element.get_attribute("y", "0"));

				sprite.set_rotation_hotspot(origin, xoffset, yoffset);
			}
			// <frame nr="integer" speed="integer" x="integer" y="integer" />
			else if (tag_name == "frame")
			{
				int nr = StringHelp::text_to_int(cur_element.get_attribute("nr", "0"));

				int yoffset = StringHelp::text_to_int(cur_element.get_attribute("y", "0"));
				int xoffset = StringHelp::text_to_int(cur_element.get_attribute("x", "0"));

				if (nr < 0 || nr >= sprite.get_frame_count())
				{
					throw Exception("Invalid sprite frame index specified");
				}

				if (cur_element.has_attribute("speed"))
				{
					sprite.set_frame_delay(nr, StringHelp::text_to_int(cur_element.get_attribute("speed", "60")));
				}

				sprite.set_frame_offset(nr, Point(xoffset, yoffset));
			}

			cur_node = cur_node.get_next_sibling();
		}

		sprite.restart();

		return sprite;
	}
예제 #8
0
파일: font.cpp 프로젝트: kyelin/ClanLib
Font Font_Impl::load(Canvas &canvas, const FontDescription &reference_desc, const std::string &id, const XMLResourceDocument &doc, Callback_2<Resource<Sprite>, Canvas &, const std::string &> cb_get_sprite)
{
	XMLResourceNode resource = doc.get_resource(id);
	std::string type = resource.get_element().get_tag_name();
	
	if (type != "font")
		throw Exception(string_format("Resource '%1' is not of type 'font'", id));

	DomElement sprite_element = resource.get_element().named_item("sprite").to_element();

	FontMetrics font_metrics;

	if (!sprite_element.is_null())
	{
		if (!sprite_element.has_attribute("glyphs")) 
			throw Exception(string_format("Font resource %1 has no 'glyphs' attribute.", resource.get_name()));
		
		if (!sprite_element.has_attribute("letters")) 
			throw Exception(string_format("Font resource %1 has no 'letters' attribute.", resource.get_name()));

		Resource<Sprite> spr_glyphs = cb_get_sprite.invoke(canvas, sprite_element.get_attribute("glyphs"));

		const std::string &letters = sprite_element.get_attribute("letters");

		int spacelen = StringHelp::text_to_int(sprite_element.get_attribute("spacelen", "-1"));
		bool monospace = StringHelp::text_to_bool(sprite_element.get_attribute("monospace", "false"));

		// Modify the default font metrics, if specified

		if (sprite_element.has_attribute("height")) 
			font_metrics.set_height(StringHelp::text_to_float(sprite_element.get_attribute("height", "0")));

		if (sprite_element.has_attribute("ascent")) 
			font_metrics.set_ascent(StringHelp::text_to_float(sprite_element.get_attribute("ascent", "0")));

		if (sprite_element.has_attribute("descent")) 
			font_metrics.set_descent(StringHelp::text_to_float(sprite_element.get_attribute("descent", "0")));

		if (sprite_element.has_attribute("internal_leading")) 
			font_metrics.set_internal_leading(StringHelp::text_to_float(sprite_element.get_attribute("internal_leading", "0")));

		if (sprite_element.has_attribute("external_leading")) 
			font_metrics.set_external_leading(StringHelp::text_to_float(sprite_element.get_attribute("external_leading", "0")));

		if (sprite_element.has_attribute("average_character_width")) 
			font_metrics.set_average_character_width(StringHelp::text_to_float(sprite_element.get_attribute("average_character_width", "0")));

		if (sprite_element.has_attribute("max_character_width")) 
			font_metrics.set_max_character_width(StringHelp::text_to_float(sprite_element.get_attribute("max_character_width", "0")));

		font_metrics.set_weight(400.0f);
		if (sprite_element.has_attribute("weight")) 
			font_metrics.set_weight(StringHelp::text_to_float(sprite_element.get_attribute("weight", "0")));

		if (sprite_element.has_attribute("overhang")) 
			font_metrics.set_overhang(StringHelp::text_to_float(sprite_element.get_attribute("overhang", "0")));

		font_metrics.set_digitized_aspect_x(96.0f);
		if (sprite_element.has_attribute("digitized_aspect_x")) 
			font_metrics.set_digitized_aspect_x(StringHelp::text_to_float(sprite_element.get_attribute("digitized_aspect_x", "0")));

		font_metrics.set_digitized_aspect_y(96.0f);
		if (sprite_element.has_attribute("digitized_aspect_y")) 
			font_metrics.set_digitized_aspect_y(StringHelp::text_to_float(sprite_element.get_attribute("digitized_aspect_y", "0")));

		if (sprite_element.has_attribute("italic")) 
			font_metrics.set_italic(StringHelp::text_to_bool(sprite_element.get_attribute("italic", "0")));

		if (sprite_element.has_attribute("underlined")) 
			font_metrics.set_underlined(StringHelp::text_to_bool(sprite_element.get_attribute("underlined", "0")));

		if (sprite_element.has_attribute("struck_out")) 
			font_metrics.set_struck_out(StringHelp::text_to_bool(sprite_element.get_attribute("struck_out", "0")));

		if (sprite_element.has_attribute("fixed_pitch")) 
			font_metrics.set_fixed_pitch(StringHelp::text_to_bool(sprite_element.get_attribute("fixed_pitch", "0")));

		return Font(canvas, spr_glyphs.get(), letters, spacelen, monospace, font_metrics);
	}

	DomElement ttf_element = resource.get_element().named_item("ttf").to_element();
	if (ttf_element.is_null())
		ttf_element = resource.get_element().named_item("freetype").to_element();

	if (!ttf_element.is_null())
	{
		FontDescription desc = reference_desc.clone();

		std::string filename;

		if (ttf_element.has_attribute("file"))
			filename = ttf_element.get_attribute("file"); desc.set_typeface_name(ttf_element.get_attribute("file"));

		if (ttf_element.has_attribute("typeface"))
			desc.set_typeface_name(ttf_element.get_attribute("typeface"));

		if (ttf_element.has_attribute("height"))
			desc.set_height(ttf_element.get_attribute_int("height", 0));

		if (ttf_element.has_attribute("average_width"))
			desc.set_average_width(ttf_element.get_attribute_int("average_width", 0));

		if (ttf_element.has_attribute("anti_alias"))
			desc.set_anti_alias(ttf_element.get_attribute_bool("anti_alias", true));

		if (ttf_element.has_attribute("subpixel"))
			desc.set_subpixel(ttf_element.get_attribute_bool("subpixel", true));

		return Font(canvas, desc, filename);
	}

	throw Exception(string_format("Font resource %1 did not have a <sprite> or <ttf> child element", resource.get_name()));

}
예제 #9
0
	Image Image::load(Canvas &canvas, const std::string &id, const XMLResourceDocument &doc)
	{
		Image image;

		XMLResourceNode resource = doc.get_resource(id);

		DomNode cur_node = resource.get_element().get_first_child();
		while (!cur_node.is_null())
		{
			if (!cur_node.is_element())
			{
				cur_node = cur_node.get_next_sibling();
				continue;
			}

			DomElement cur_element = cur_node.to_element();
			std::string tag_name = cur_element.get_tag_name();
			if (tag_name == "image" || tag_name == "image-file")
			{
				std::string image_name = cur_element.get_attribute("file");
				Texture2D texture = Texture2D(canvas, PathHelp::combine(resource.get_base_path(), image_name), resource.get_file_system());

				DomNode cur_child(cur_element.get_first_child());
				if (cur_child.is_null())
				{
					image = Image(texture, texture.get_size());
				}
				else
				{
					do {
						DomElement cur_child_elemnt = cur_child.to_element();
						if (cur_child.get_node_name() == "grid")
						{
							Point position;
							Size texture_size = texture.get_size();
							Size size = texture_size;

							std::vector<std::string> image_size = StringHelp::split_text(cur_child_elemnt.get_attribute("size"), ",");
							if (image_size.size() > 0)
								size.width = StringHelp::text_to_int(image_size[0]);
							if (image_size.size() > 1)
								size.height = StringHelp::text_to_int(image_size[1]);

							if (cur_child_elemnt.has_attribute("pos"))
							{
								std::vector<std::string> image_pos = StringHelp::split_text(cur_child_elemnt.get_attribute("pos"), ",");
								if (image_pos.size() > 0)
									position.x = StringHelp::text_to_int(image_pos[0]);
								if (image_pos.size() > 1)
									position.y = StringHelp::text_to_int(image_pos[1]);
							}
							if ((size.width + position.x) > texture_size.width)
								size.width = (texture_size.width - position.x);
							if ((size.height + position.y) > texture_size.height)
								size.height = (texture_size.height - position.y);

							image = Image(texture, Rect(position, size));
						}

						cur_child = cur_child.get_next_sibling();
					} while (!cur_child.is_null());
				}

				break;
			}
			cur_node = cur_node.get_next_sibling();
		}
		if (image.is_null())
			throw Exception("Image resource contained no frames!");

		cur_node = resource.get_element().get_first_child();
		while (!cur_node.is_null())
		{
			if (!cur_node.is_element())
			{
				cur_node = cur_node.get_next_sibling();
				continue;
			}

			DomElement cur_element = cur_node.to_element();

			std::string tag_name = cur_element.get_tag_name();

			// <color red="float" green="float" blue="float" alpha="float" />
			if (tag_name == "color")
			{
				Colorf color;
				color.r = (float)StringHelp::text_to_float(cur_element.get_attribute("red", "1.0"));
				color.g = (float)StringHelp::text_to_float(cur_element.get_attribute("green", "1.0"));
				color.b = (float)StringHelp::text_to_float(cur_element.get_attribute("blue", "1.0"));
				color.a = (float)StringHelp::text_to_float(cur_element.get_attribute("alpha", "1.0"));
				image.set_color(color);
			}
			// <scale x="float" y="float />
			else if (tag_name == "scale")
			{
				float scale_x = StringHelp::text_to_float(cur_element.get_attribute("x", "1.0"));
				float scale_y = StringHelp::text_to_float(cur_element.get_attribute("y", "1.0"));
				image.set_scale(scale_x, scale_y);
			}
			// <translation origin="string" x="integer" y="integer" />
			else if (tag_name == "translation")
			{
				std::string hotspot = cur_element.get_attribute("origin", "top_left");
				Origin origin;

				if (hotspot == "center")
					origin = origin_center;
				else if (hotspot == "top_center")
					origin = origin_top_center;
				else if (hotspot == "top_right")
					origin = origin_top_right;
				else if (hotspot == "center_left")
					origin = origin_center_left;
				else if (hotspot == "center_right")
					origin = origin_center_right;
				else if (hotspot == "bottom_left")
					origin = origin_bottom_left;
				else if (hotspot == "bottom_center")
					origin = origin_bottom_center;
				else if (hotspot == "bottom_right")
					origin = origin_bottom_right;
				else
					origin = origin_top_left;

				int xoffset = StringHelp::text_to_int(cur_element.get_attribute("x", "0"));
				int yoffset = StringHelp::text_to_int(cur_element.get_attribute("y", "0"));

				// TODO Find out what is going on here...
				xoffset /= image.get_texture().get_texture().get_pixel_ratio();
				yoffset /= image.get_texture().get_texture().get_pixel_ratio();

				image.set_alignment(origin, xoffset, yoffset);
			}

			cur_node = cur_node.get_next_sibling();
		}

		return image;
	}