@@ -33985,13 +33985,22 @@ namespace csb
3398533985 unsigned int width{};
3398633986 unsigned int height{};
3398733987 };
33988+ struct glyph
33989+ {
33990+ std::uint64_t character{};
33991+ unsigned int x{};
33992+ unsigned int y{};
33993+ unsigned int width{};
33994+ unsigned int height{};
33995+ };
3398833996 std::vector<std::byte> data{};
3398933997 unsigned int width{};
3399033998 unsigned int height{};
3399133999 unsigned int channels{};
3399234000 std::pair<unsigned int, unsigned int> resolution{};
3399334001 std::vector<animation> animations{};
3399434002 std::vector<slice> slices{};
34003+ std::vector<glyph> glyphs{};
3399534004 bool hitboxes{};
3399634005 };
3399734006
@@ -34515,8 +34524,8 @@ namespace csb
3451534524 * | `std::vector<std::string>`: Reads the file into a list of strings, one per line.
3451634525 * | `std::vector<std::byte>`: Reads the file into a byte array.
3451734526 * | `csp::pack`: Reading csp data is not supported.
34518- * | `image`: Reads the file as an image using stb_image - returns data, width, height and channels.
34519- * | `aseprite`: Reads the file as a resource containing image data as well as frame and hitbox data.
34527+ * | `csg:: image`: Reads the file as an image using stb_image - returns data, width, height and channels.
34528+ * | `csg:: aseprite`: Reads the file as a resource containing image data as well as frame, hitbox and glyph data.
3452034529 * | `nlohmann::json`: Reads the file as a JSON object.
3452134530 *
3452234531 * See also: `write_file`, `modify_file`.
@@ -35062,6 +35071,58 @@ namespace csb
3506235071 result.resolution = {frame_width, frame_height};
3506335072 result.slices = std::move(slices);
3506435073 result.hitboxes = hitbox_group;
35074+ if (!result.slices.empty())
35075+ {
35076+ const auto codepoint{[&file](const std::string &name) -> std::uint64_t
35077+ {
35078+ const auto invalid{
35079+ [&file, &name]()
35080+ {
35081+ return std::runtime_error("Aseprite slice name '" + name +
35082+ "' must be a single character: " + file.string());
35083+ }};
35084+ if (name.empty()) throw invalid();
35085+ const auto first{static_cast<unsigned char>(name[0])};
35086+ std::size_t length{1};
35087+ std::uint64_t character{first};
35088+ if (first >= 0xF0)
35089+ length = 4, character = first & 0x07u;
35090+ else if (first >= 0xE0)
35091+ length = 3, character = first & 0x0Fu;
35092+ else if (first >= 0xC0)
35093+ length = 2, character = first & 0x1Fu;
35094+ else if (first >= 0x80)
35095+ throw invalid();
35096+ if (name.size() != length) throw invalid();
35097+ for (std::size_t offset{1}; offset < length; ++offset)
35098+ {
35099+ const auto continuation{static_cast<unsigned char>(name[offset])};
35100+ if ((continuation & 0xC0u) != 0x80u) throw invalid();
35101+ character = (character << 6) | (continuation & 0x3Fu);
35102+ }
35103+ return character;
35104+ }};
35105+ for (const aseprite::slice &entry : result.slices)
35106+ {
35107+ if (entry.x < 0 || entry.y < 0 || entry.width == 0 || entry.height == 0 ||
35108+ static_cast<unsigned int>(entry.x) + entry.width > frame_width ||
35109+ static_cast<unsigned int>(entry.y) + entry.height > frame_height)
35110+ throw std::runtime_error("Aseprite slice '" + entry.name +
35111+ "' must fit within the canvas: " + file.string());
35112+ if (entry.height != result.slices.front().height)
35113+ throw std::runtime_error("Aseprite slice '" + entry.name +
35114+ "' must match the height of every other slice: " + file.string());
35115+ result.glyphs.push_back({codepoint(entry.name), static_cast<unsigned int>(entry.x),
35116+ static_cast<unsigned int>(entry.y), entry.width, entry.height});
35117+ }
35118+ std::sort(result.glyphs.begin(), result.glyphs.end(),
35119+ [](const aseprite::glyph &left, const aseprite::glyph &right)
35120+ { return left.character < right.character; });
35121+ for (std::size_t index{}; index + 1 < result.glyphs.size(); ++index)
35122+ if (result.glyphs[index].character == result.glyphs[index + 1].character)
35123+ throw std::runtime_error("Aseprite file contains duplicate slices for the same character: " +
35124+ file.string());
35125+ }
3506535126 for (const tag_info &tag : tags)
3506635127 {
3506735128 if (tag.from >= frame_count || tag.to >= frame_count || tag.from > tag.to)
@@ -35112,8 +35173,8 @@ namespace csb
3511235173 * | `std::vector<std::string>`: Writes each string in the list to the file, one per line.
3511335174 * | `std::vector<std::byte>`: Writes the byte array to the file.
3511435175 * | `csp::pack`: Writes the csp data to the file.
35115- * | `image`: Writing images is not supported.
35116- * | `aseprite`: Writing aseprite files is not supported.
35176+ * | `csg:: image`: Writing images is not supported.
35177+ * | `csg:: aseprite`: Writing aseprite files is not supported.
3511735178 * | `nlohmann::json`: Writes the JSON object to the file.
3511835179 *
3511935180 * See also: `read_file`, `modify_file`.
@@ -35163,8 +35224,8 @@ namespace csb
3516335224 * | `std::vector<std::string>`: Writes each string in the list to the file, one per line.
3516435225 * | `std::vector<std::byte>`: Writes the byte array to the file.
3516535226 * | `csp::pack`: Modifying csp data is not supported.
35166- * | `image`: Modifying images is not supported.
35167- * | `aseprite`: Modifying aseprite files is not supported.
35227+ * | `csg:: image`: Modifying images is not supported.
35228+ * | `csg:: aseprite`: Modifying aseprite files is not supported.
3516835229 * | `nlohmann::json`: Writes the JSON object to the file.
3516935230 *
3517035231 * See also: `read_file`, `write_file`.
@@ -37389,13 +37450,14 @@ namespace csb
3738937450 compiler = "cl /std:c17 /TC";
3739037451 else
3739137452 compiler = "cl /std:c++" + std::to_string(cxx_standard);
37392- return std::format("{} /nologo /W{} /external:W0 {}/bigobj /Zc:preprocessor /EHsc /MP /{} {}/ifcOutput{}\\ /Fo{}\\ /Fd\"{}\" "
37393- "/sourceDependencies\"{}\" {}{}/c /Yc\"{}\" /Fp\"{}\" \"{}\"",
37394- compiler, std::to_string(warning_level), compile_debug_flags, runtime_library,
37395- compile_definitions, pch_directory.string(), pch_directory.string(),
37396- (pch_directory / "(stem)_pch.pdb").string(), (pch_directory / "(stem)_pch.d").string(),
37397- compile_include_directories, compile_external_include_directories, relative_path,
37398- (pch_directory / "(stem).pch").string(), (pch_directory / "(stem)_pch.cpp").string());
37453+ return std::format(
37454+ "{} /nologo /W{} /external:W0 {}/bigobj /Zc:preprocessor /EHsc /MP /{} {}/ifcOutput{}\\ /Fo{}\\ /Fd\"{}\" "
37455+ "/sourceDependencies\"{}\" {}{}/c /Yc\"{}\" /Fp\"{}\" \"{}\"",
37456+ compiler, std::to_string(warning_level), compile_debug_flags, runtime_library, compile_definitions,
37457+ pch_directory.string(), pch_directory.string(), (pch_directory / "(stem)_pch.pdb").string(),
37458+ (pch_directory / "(stem)_pch.d").string(), compile_include_directories,
37459+ compile_external_include_directories, relative_path, (pch_directory / "(stem).pch").string(),
37460+ (pch_directory / "(stem)_pch.cpp").string());
3739937461 },
3740037462 precompiled_headers, check_files, dependency_handler);
3740137463
@@ -37439,13 +37501,13 @@ namespace csb
3743937501 compiler = "cl /std:c17 /TC";
3744037502 else
3744137503 compiler = "cl /std:c++" + std::to_string(cxx_standard);
37442- return std::format("{} /nologo /W{} /external:W0 {}/bigobj /Zc:preprocessor /EHsc /MP /{} {}/ifcOutput{}\\ /Fo{}\\ /Fd\"{}\" "
37443- "/sourceDependencies\"{}\" {}{}/c {}\"()\"",
37444- compiler, std::to_string(warning_level), compile_debug_flags, runtime_library ,
37445- compile_definitions, utility::build_directory.string( ), utility::build_directory.string() ,
37446- ( utility::build_directory / "(stem).pdb") .string(),
37447- (utility::build_directory / "(stem).d").string(), compile_include_directories ,
37448- compile_external_include_directories, pch_flags);
37504+ return std::format(
37505+ "{} /nologo /W{} /external:W0 {}/bigobj /Zc:preprocessor /EHsc /MP /{} {}/ifcOutput{}\\ /Fo {}\\ /Fd\"{}\" "
37506+ "/sourceDependencies\"{}\" {}{}/c {}\"()\"" ,
37507+ compiler, std::to_string(warning_level ), compile_debug_flags, runtime_library, compile_definitions ,
37508+ utility::build_directory.string(), utility::build_directory .string(),
37509+ (utility::build_directory / "(stem).pdb").string(), (utility::build_directory / "(stem).d").string(),
37510+ compile_include_directories, compile_external_include_directories, pch_flags);
3744937511 },
3745037512 source_files, check_files, dependency_handler);
3745137513 }
0 commit comments