Font::Font(const string& font) { string dir = Utils::basedir(font); xml_document doc; if (!doc.load_file(font.c_str())) throw runtime_error(Utils::join("Failed to load font: ", font, ".")); xml_node glyph = doc.child("font").child("glyphs"); char start_ascii = glyph.attribute("startascii").as_int(); int width = glyph.attribute("width").as_int(); int height = glyph.attribute("height").as_int(); glyphwidth = glyph.attribute("glyphwidth").as_int(); glyphheight = glyph.attribute("glyphheight").as_int(); const char_t* source = glyph.attribute("source").value(); if (!width || !height || !glyphwidth || !glyphheight) throw logic_error("Invalid glpyh arguments."); SurfaceCache cache; Surface surf = cache.from_image(Utils::join(dir, "/", source)); if (surf.rect().w != width * glyphwidth || surf.rect().h != height * glyphheight) throw logic_error("Geometry of font and attributes do not match."); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, start_ascii++) { surf_map[start_ascii] = surf.sub(Rect(Pos(x * glyphwidth, y * glyphheight), glyphwidth, glyphheight)); surf_map[start_ascii].ignore_camera(true); } } }
void Tilemap::add_tileset(std::map<unsigned, Surface>& tiles, xml_node node) { int first_gid = node.attribute("firstgid").as_int(); int id_cnt = 0; int tilewidth = node.attribute("tilewidth").as_int(); int tileheight = node.attribute("tileheight").as_int(); pugi::xml_node image = node.child("image"); const char *source = image.attribute("source").value(); int width = image.attribute("width").as_int(); int height = image.attribute("height").as_int(); #if 0 std::cerr << "Adding tileset:" << " Name: " << node.attribute("name").value() << " Gid: " << first_gid << " Tilewidth: " << tilewidth << " Tileheight: " << tileheight << " Source: " << source << " Width: " << width << " Height: " << height << std::endl; #endif if (!width || !height || !tilewidth || !tileheight) throw std::logic_error("Tilemap is malformed."); SurfaceCache cache; Blit::Surface surf = cache.from_image(Utils::join(dir, "/", source)); if (surf.rect().w != width || surf.rect().h != height) throw std::logic_error("Tilemap geometry does not correspond with image values."); std::map<std::basic_string<char>, std::basic_string<char> > global_attr = get_attributes(node.child("properties"), "property"); #if 0 std::cerr << "Dumping attrs:" << std::endl; for (auto& attr : global_attr) std::cerr << "Found global attr (" << attr.first << " => " << attr.second << ")." << std::endl; std::cerr << "Dumped attrs." << std::endl; #endif for (int y = 0; y < height; y += tileheight) { for (int x = 0; x < width; x += tilewidth, id_cnt++) { int id = first_gid + id_cnt; tiles[id] = surf.sub({{x, y}, tilewidth, tileheight}); std::copy(global_attr.begin(), global_attr.end(), std::inserter(tiles[id].attr(), tiles[id].attr().begin())); } } // Load all attributes for a tile into the surface. for (auto tile = node.child("tile"); tile; tile = tile.next_sibling("tile")) { int id = first_gid + tile.attribute("id").as_int(); std::map<std::basic_string<char>, std::basic_string<char> > attrs = get_attributes(tile.child("properties"), "property"); std::copy(global_attr.begin(), global_attr.end(), std::inserter(attrs, attrs.begin())); auto itr = attrs.find("sprite"); if (itr != attrs.end()) tiles[id] = cache.from_sprite(Utils::join(dir, "/", itr->second)); tiles[id].attr() = std::move(attrs); } }