Daniele Bartolini 10 年 前
コミット
2c762c80b9
2 ファイル変更58 行追加45 行削除
  1. 54 42
      src/resource/font_resource.cpp
  2. 4 3
      src/resource/font_resource.h

+ 54 - 42
src/resource/font_resource.cpp

@@ -10,25 +10,37 @@
 #include "compile_options.h"
 #include "sjson.h"
 #include "map.h"
+#include <algorithm>
 
 namespace crown
 {
 namespace font_resource
 {
-	void parse_glyph(const char* json, FontGlyphData& glyph)
+	struct GlyphInfo
+	{
+		CodePoint cp;
+		GlyphData gd;
+
+		bool operator<(const GlyphInfo& a)
+		{
+			return cp < a.cp;
+		}
+	};
+
+	void parse_glyph(const char* json, GlyphInfo& glyph)
 	{
 		TempAllocator512 ta;
 		JsonObject obj(ta);
 		sjson::parse(json, obj);
 
-		glyph.id        = sjson::parse_int(obj["id"]);
-		glyph.x         = sjson::parse_float(obj["x"]);
-		glyph.y         = sjson::parse_float(obj["y"]);
-		glyph.width     = sjson::parse_float(obj["width"]);
-		glyph.height    = sjson::parse_float(obj["height"]);
-		glyph.x_offset  = sjson::parse_float(obj["x_offset"]);
-		glyph.y_offset  = sjson::parse_float(obj["y_offset"]);
-		glyph.x_advance = sjson::parse_float(obj["x_advance"]);
+		glyph.cp           = sjson::parse_int(obj["id"]);
+		glyph.gd.x         = sjson::parse_float(obj["x"]);
+		glyph.gd.y         = sjson::parse_float(obj["y"]);
+		glyph.gd.width     = sjson::parse_float(obj["width"]);
+		glyph.gd.height    = sjson::parse_float(obj["height"]);
+		glyph.gd.x_offset  = sjson::parse_float(obj["x_offset"]);
+		glyph.gd.y_offset  = sjson::parse_float(obj["y_offset"]);
+		glyph.gd.x_advance = sjson::parse_float(obj["x_advance"]);
 	}
 
 	void compile(const char* path, CompileOptions& opts)
@@ -42,49 +54,47 @@ namespace font_resource
 		sjson::parse(buf, object);
 		sjson::parse_array(object["glyphs"], glyphs);
 
-		const u32 size       = sjson::parse_int(object["size"]);
-		const u32 font_size  = sjson::parse_int(object["font_size"]);
-		const u32 num_glyphs = array::size(glyphs);
+		const u32 texture_size = sjson::parse_int(object["size"]);
+		const u32 font_size    = sjson::parse_int(object["font_size"]);
+		const u32 num_glyphs   = array::size(glyphs);
 
-		Array<FontGlyphData> m_glyphs(default_allocator());
+		Array<GlyphInfo> _glyphs(default_allocator());
+		array::resize(_glyphs, num_glyphs);
 
 		for (u32 i = 0; i < num_glyphs; ++i)
 		{
-			FontGlyphData data;
-			parse_glyph(glyphs[i], data);
-			array::push_back(m_glyphs, data);
+			parse_glyph(glyphs[i], _glyphs[i]);
 		}
 
-		// Write
-		FontResource fr;
-		fr.version      = RESOURCE_VERSION_FONT;
-		fr.num_glyphs   = array::size(m_glyphs);
-		fr.texture_size = size;
-		fr.font_size    = font_size;
+		std::sort(array::begin(_glyphs), array::end(_glyphs));
+
+		opts.write(RESOURCE_VERSION_FONT);
+		opts.write(num_glyphs);
+		opts.write(texture_size);
+		opts.write(font_size);
 
-		opts.write(fr.version);
-		opts.write(fr.num_glyphs);
-		opts.write(fr.texture_size);
-		opts.write(fr.font_size);
+		for (u32 i = 0; i < array::size(_glyphs); ++i)
+		{
+			opts.write(_glyphs[i].cp);
+		}
 
-		for (u32 i = 0; i < array::size(m_glyphs); ++i)
+		for (u32 i = 0; i < array::size(_glyphs); ++i)
 		{
-			opts.write(m_glyphs[i].id);
-			opts.write(m_glyphs[i].x);
-			opts.write(m_glyphs[i].y);
-			opts.write(m_glyphs[i].width);
-			opts.write(m_glyphs[i].height);
-			opts.write(m_glyphs[i].x_offset);
-			opts.write(m_glyphs[i].y_offset);
-			opts.write(m_glyphs[i].x_advance);
+			opts.write(_glyphs[i].gd.x);
+			opts.write(_glyphs[i].gd.y);
+			opts.write(_glyphs[i].gd.width);
+			opts.write(_glyphs[i].gd.height);
+			opts.write(_glyphs[i].gd.x_offset);
+			opts.write(_glyphs[i].gd.y_offset);
+			opts.write(_glyphs[i].gd.x_advance);
 		}
 	}
 
 	void* load(File& file, Allocator& a)
 	{
-		const u32 file_size = file.size();
-		void* res = a.allocate(file_size);
-		file.read(res, file_size);
+		const u32 size = file.size();
+		void* res = a.allocate(size);
+		file.read(res, size);
 		CE_ASSERT(*(u32*)res == RESOURCE_VERSION_FONT, "Wrong version");
 		return res;
 	}
@@ -94,16 +104,18 @@ namespace font_resource
 		allocator.deallocate(resource);
 	}
 
-	const FontGlyphData* get_glyph(const FontResource* fr, u32 cp)
+	const GlyphData* get_glyph(const FontResource* fr, CodePoint cp)
 	{
 		CE_ASSERT(cp < fr->num_glyphs, "Index out of bounds");
 
-		FontGlyphData* begin = (FontGlyphData*)&fr[1];
+		const CodePoint* pts  = (CodePoint*)&fr[1];
+		const GlyphData* data = (GlyphData*)(pts + fr->num_glyphs);
 
+		// FIXME: Can do binary search
 		for (u32 i = 0; i < fr->num_glyphs; ++i)
 		{
-			if (begin[i].id == cp)
-				return &begin[i];
+			if (pts[i] == cp)
+				return &data[i];
 		}
 
 		CE_FATAL("Glyph not found");

+ 4 - 3
src/resource/font_resource.h

@@ -22,9 +22,10 @@ struct FontResource
 	u32 font_size;
 };
 
-struct FontGlyphData
+typedef u32 CodePoint;
+
+struct GlyphData
 {
-	u32 id;
 	f32 x;
 	f32 y;
 	f32 width;
@@ -40,6 +41,6 @@ namespace font_resource
 	void* load(File& file, Allocator& a);
 	void unload(Allocator& allocator, void* resource);
 
-	const FontGlyphData* get_glyph(const FontResource* fr, u32 cp);
+	const GlyphData* get_glyph(const FontResource* fr, CodePoint cp);
 } // namespace font_resource
 } // namespace crown