Resource<Font> XMLDisplayCache::get_font(Canvas &canvas, const std::string &family_name, const FontDescription &desc) { auto it = fonts.find(family_name); if (it != fonts.end()) return Font(it->second, desc); bool is_resource_font = false; if (doc.resource_exists(family_name)) { XMLResourceNode resource = doc.get_resource(family_name); if (resource.get_element().get_tag_name() == "font") { is_resource_font = true; } } Font font; FontFamily font_family(family_name); fonts[family_name] = font_family; if (is_resource_font) { font = Font::load(canvas, family_name, desc, font_family, doc, bind_member(this, &XMLDisplayCache::get_sprite)); } else { font = Font(font_family, desc); } return font; }
XMLResourceNode XMLResourceDocument::get_resource( const std::string &resource_id) const { XMLResourceNode node = impl->get_resource(resource_id); if (node.is_null()) throw Exception(string_format("Resource not found: %1", resource_id)); return node; }
std::string XMLResourceDocument::get_string_resource( const std::string &resource_id, const std::string &default_value) const { if (!resource_exists(resource_id)) return default_value; XMLResourceNode resource = get_resource(resource_id); return resource.get_element().get_attribute("value"); }
int XMLResourceDocument::get_integer_resource( const std::string &resource_id, int default_value) const { if (!resource_exists(resource_id)) return default_value; XMLResourceNode resource = get_resource(resource_id); return StringHelp::text_to_int(resource.get_element().get_attribute("value")); }
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); }
XMLResourceNode XMLResourceDocument_Impl::get_resource(const std::string &resource_id) const { std::map<std::string, XMLResourceNode>::const_iterator it; it = resources.find(resource_id); if (it != resources.end()) return it->second; std::vector<XMLResourceDocument>::size_type i; for (i = 0; i < additional_resources.size(); i++) { XMLResourceNode node = additional_resources[i].impl->get_resource(resource_id); if (!node.is_null()) return node; } return XMLResourceNode(); }
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; }
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); } }
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(); } }
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())); }
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; }
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())); }
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; }