Panagiotis Christopoulos Charitos 14 rokov pred
rodič
commit
e7687321c6

BIN
engine-rsrc/ModernAntiqua.ttf


+ 1 - 1
src/Main.cpp

@@ -433,7 +433,7 @@ void mainLoop()
 int main(int argc, char* argv[])
 {
 	FT_Vector s = {100, 100};
-	Ui::FtFontLoader fnt("/usr/share/fonts/truetype/msttcorefonts/Andale_Mono.ttf", s);
+	Ui::FtFontLoader fnt("engine-rsrc/ModernAntiqua.ttf", s);
 	fnt.saveImage("/tmp/test.tga");
 
 	return 0;

+ 61 - 169
src/Ui/UiFont.cpp

@@ -1,198 +1,90 @@
+#include <GL/glew.h>
 #include <boost/foreach.hpp>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-
 #include "UiFont.h"
-#include "Vec.h"
 #include "Texture.h"
 #include "Exception.h"
 #include "Assert.h"
+#include "UiFtFontLoader.h"
 
 
 namespace Ui {
 
 
-struct FtGlyph
-{
-	FT_Glyph glyph;
-	FT_Glyph_Metrics metrics;
-};
-
-
-inline FT_Int toPixels(FT_Int a)
-{
-	return a >> 6;
-}
-
-
-/// Get 127 glyphs from a face
-static void getGlyphs(FT_Face& face, Vec<FtGlyph>& glyphs)
+//======================================================================================================================
+// create                                                                                                              =
+//======================================================================================================================
+void Font::create(const char* fontFilename, uint nominalWidth, uint NominalHeight)
 {
-	const uint MAX_GLYPHS = 127;
-	ASSERT(glyphs.size() == 0);
-	glyphs.resize(MAX_GLYPHS);
+	FT_Vector ftSize = {nominalWidth, NominalHeight};
+	FtFontLoader ft(fontFilename, ftSize);
 
-	for(uint n = 0; n < MAX_GLYPHS; n++)
+	// - Create glyphs
+	// - Get metrics
+	BOOST_FOREACH(const FtFontLoader::Glyph& ftGlyph, ft.getGlyphs())
 	{
-		char c = '!' + n;
-
-		FT_UInt glyph_index = FT_Get_Char_Index(face, c);
-
-		FT_Error error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
-		if(error)
-		{
-			throw EXCEPTION("FT_Load_Glyph failed");
-		}
-
-		glyphs[n].metrics = face->glyph->metrics;
-
-		error = FT_Get_Glyph(face->glyph, &glyphs[n].glyph);
-		if(error)
-		{
-			throw EXCEPTION("FT_Get_Glyph failed");
-		}
+		// Create
+		glyphs.push_back(new Glyph);
+		Glyph& glyph = glyphs.back();
+
+		// Metrics
+		glyph.width = FtFontLoader::toPixels(ftGlyph.getMetrics().width);
+		glyph.height = FtFontLoader::toPixels(ftGlyph.getMetrics().height);
+		glyph.horizBearingX = FtFontLoader::toPixels(ftGlyph.getMetrics().horiBearingX);
+		glyph.horizBearingY = FtFontLoader::toPixels(ftGlyph.getMetrics().horiBearingY);
+		glyph.horizAdvance = FtFontLoader::toPixels(ftGlyph.getMetrics().horiAdvance);
 	}
-}
 
+	//
+	// Calc texture matrices
+	//
+	int posX = 0;
+	int posY = 0;
 
-/// Copy one bitmap to another
-static void copyBitmap(const unsigned char* srcImg, const FT_Vector& srcSize, const FT_Vector& pos,
-                       Vec<uchar>& destImg, const FT_Vector& destSize)
-{
-	for(int i = 0; i < srcSize.y; i++)
+	// For all rows
+	for(uint i = 0; i < FtFontLoader::GLYPH_ROWS; i++)
 	{
-		for(int j = 0; j < srcSize.x; j++)
+		// For all columns
+		for(uint j = 0; j < FtFontLoader::GLYPH_COLUMNS; j++)
 		{
-			int jj = j + pos.x;
-			int ii = i + pos.y;
-			destImg[ii * destSize.x + jj] = srcImg[i * srcSize.x + j];
-		}
-	}
-}
+			Glyph& glyph = glyphs[i * FtFontLoader::GLYPH_COLUMNS + j];
 
+			// Set texture matrix
+			float scaleX = glyph.width / float(ft.getImageSize().x); // glyph width
+			float scaleY = glyph.height / float(ft.getImageSize().y); // glyph height
+			float tslX = posX / float(ft.getImageSize().x);
+			float tslY = (ft.getImageSize().y - glyph.height - posY) / float(ft.getImageSize().y);
 
-/// Compute the size of the image with all the glyphs
-static void computeImageSize(const Vec<FtGlyph>& glyphs, FT_Vector& size)
-{
-	size.x = 0;
-	size.y = 0;
+			glyph.textureMat = Mat3::getIdentity();
+			glyph.textureMat(0, 0) = scaleX;
+			glyph.textureMat(1, 1) = scaleY;
+			glyph.textureMat(0, 2) = tslX;
+			glyph.textureMat(1, 2) = tslY;
 
-	BOOST_FOREACH(const FtGlyph& glyph, glyphs)
-	{
-		// Inc the width
-		size.x += toPixels(glyph.metrics.width);
+			std::cout << glyph.textureMat << std::endl;
 
-		// Chose the max height
-		if(size.y < toPixels(glyph.metrics.height))
-		{
-			size.y = toPixels(glyph.metrics.height);
+			posX += glyph.width;
 		}
-	}
-}
-
-
-/// Given a filename and a font size create an image with all the glyphs
-static void createImage(const char* filename, const FT_Vector& fontSize,
-                        Vec<FtGlyph>& glyphs, Vec<uchar>& img, FT_Vector& imgSize)
-{
-	FT_Library library;
-	FT_Face face;
-	FT_Error error;
-
-	// Create lib
-	error = FT_Init_FreeType(&library);
-	if(error)
-	{
-		throw EXCEPTION("FT_Init_FreeType failed");
-	}
 
-	// Create face and set glyph size
-	error = FT_New_Face(library, filename, 0, &face);
-	FT_Set_Pixel_Sizes(face, fontSize.x, fontSize.y);
-
-	// Get all glyphs
-	getGlyphs(face, glyphs);
-
-	// Get final image size and create image buffer
-	computeImageSize(glyphs, imgSize);
-
-	size_t size = imgSize.x * imgSize.y * 2 * sizeof(uchar);
-	img.resize(size, 128);
-
-	// Draw all glyphs to the image
-	FT_Vector pos = {0, 0};
-	BOOST_FOREACH(FtGlyph& glyph, glyphs)
-	{
-		FT_Glyph_To_Bitmap(&glyph.glyph, FT_RENDER_MODE_NORMAL, 0, 0);
-		FT_BitmapGlyph bit = (FT_BitmapGlyph) glyph.glyph;
-
-		FT_Vector srcSize = {toPixels(glyph.metrics.width), toPixels(glyph.metrics.height)};
-
-		copyBitmap(bit->bitmap.buffer, srcSize, pos, img, imgSize);
-
-		pos.x += toPixels(glyph.metrics.width);
-	}
-
-	// Clean
-	BOOST_FOREACH(FtGlyph& glyph, glyphs)
-	{
-		FT_Done_Glyph(glyph.glyph);
-	}
-
-	FT_Done_Face(face);
-	FT_Done_FreeType(library);
-
-	//save_image(image, imgSize.x, imgSize.y);
-}
-
-
-/// Save image to TGA. For debuging purposes
-static void saveImage(const char* filename, const Vec<uchar>& buff, int w, int h)
-{
-	char tgaHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-	FILE* fp = fopen(filename, "wb");
-
-	fwrite(tgaHeader, 1, sizeof(tgaHeader), fp);
-
-	unsigned char header6[6];
-
-	header6[0] = w % 256;
-	header6[1] = w / 256;
-	header6[2] = h % 256;
-	header6[3] = h / 256;
-	header6[4] = 24;
-	header6[5] = 0;
-
-	fwrite(header6, 1, sizeof(header6), fp);
-
-	for(int i = h - 1; i > -1; i--)
-	{
-		for(int j = 0; j < w; j++)
-		{
-			fwrite(&buff[i * w + j], 1, sizeof(unsigned char), fp);
-			fwrite(&buff[i * w + j], 1, sizeof(unsigned char), fp);
-			fwrite(&buff[i * w + j], 1, sizeof(unsigned char), fp);
-		}
+		posX = 0;
+		posY += ft.getImageSize().y / FtFontLoader::GLYPH_ROWS;
 	}
 
-	fclose(fp);
-}
-
-
-//======================================================================================================================
-// create                                                                                                              =
-//======================================================================================================================
-void Font::create(const char* fontFilename, uint nominalWidth, uint NominalHeight)
-{
-	Vec<FtGlyph> glyphs;
-	Vec<uchar> img;
-	FT_Vector imgSize;
-	FT_Vector fontSize = {nominalWidth, NominalHeight};
-	createImage(fontFilename, fontSize, glyphs, img, imgSize);
-
-	saveImage("/tmp/test.tga", img, imgSize.x, imgSize.y);
+	//
+	// Create the texture
+	//
+	Texture::Initializer tinit;
+	tinit.width = ft.getImageSize().x;
+	tinit.height = ft.getImageSize().y;
+	tinit.internalFormat = GL_RED;
+	tinit.format = GL_RED;
+	tinit.type = GL_UNSIGNED_INT;
+	tinit.data = &ft.getImage()[0];
+	tinit.mipmapping = false;
+	tinit.filteringType = Texture::TFT_NEAREST;
+	tinit.anisotropyLevel = 0;
+
+	map.reset(new Texture());
+	map->create(tinit);
 }
 
 

+ 17 - 3
src/Ui/UiFont.h

@@ -13,25 +13,39 @@ class Texture;
 namespace Ui {
 
 
-/// @todo
+/// The font is device agnostic, all sizes are in actual pixels
 class Font
 {
 	public:
-		/// Constructor
+		/// Constructor @see create
 		Font(const char* fontFilename, uint nominalWidth, uint nominalHeight);
 
+		/// @name Accessors
+		/// @{
+		const Mat3& getGlyphTextureMatrix(char c) const {return glyphs[c - ' '].textureMat;}
+		uint getGlyphWidth(char c) const {return glyphs[c - ' '].width;}
+		uint getGlyphHeight(char c) const {return glyphs[c - ' '].height;}
+		/// @}
+
 	private:
 		struct Glyph
 		{
 			/// Transforms the default texture coordinates to the glyph's. The default are (1, 1), (0, 1), (0, 0),
 			/// (0, 1)
 			Mat3 textureMat;
-			float horizontalAdvance;
+			uint width;
+			uint height;
+			int horizBearingX;
+			int horizBearingY;
+			int horizAdvance;
 		};
 
 		std::auto_ptr<Texture> map; ///< The texture map that contains all the glyphs
 		boost::ptr_vector<Glyph> glyphs; ///< A set of glyphs from ' ' to ' ' + 128
 
+		/// @param[in] fontFilename The filename of the font to load
+		/// @param[in] nominalWidth The nominal glyph width in pixels
+		/// @param[in] nominalHeight The nominal glyph height in pixels
 		void create(const char* fontFilename, uint nominalWidth, uint NominalHeight);
 };
 

+ 3 - 17
src/Ui/UiFtFontLoader.cpp

@@ -9,9 +9,9 @@ namespace Ui {
 
 
 //======================================================================================================================
-// getGlyphs                                                                                                           =
+// getAllGlyphs                                                                                                        =
 //======================================================================================================================
-void FtFontLoader::getGlyphs()
+void FtFontLoader::getAllGlyphs()
 {
 	glyphs.resize(GLYPHS_NUM);
 
@@ -131,7 +131,7 @@ void FtFontLoader::createImage(const char* filename, const FT_Vector& fontSize)
 	}
 
 	// Get all glyphs
-	getGlyphs();
+	getAllGlyphs();
 
 	// Get final image size and create image buffer
 	computeImageSize();
@@ -149,20 +149,6 @@ void FtFontLoader::createImage(const char* filename, const FT_Vector& fontSize)
 		{
 			Glyph& glyph = glyphs[i * GLYPH_COLUMNS + j];
 
-			// Set texture matrix
-			float scaleX = toPixels(glyph.metrics.width) / float(imgSize.x); // glyph width
-			float scaleY = toPixels(glyph.metrics.height) / float(imgSize.y); // glyph height
-			float tslX = pos.x / float(imgSize.x);
-			float tslY = (imgSize.y - toPixels(glyph.metrics.height) - pos.y) / float(imgSize.y);
-
-			glyph.textureMat = Mat3::getIdentity();
-			glyph.textureMat(0, 0) = scaleX;
-			glyph.textureMat(1, 1) = scaleY;
-			glyph.textureMat(0, 2) = tslX;
-			glyph.textureMat(1, 2) = tslY;
-
-			std::cout << glyph.textureMat << std::endl;
-
 			// If not ' '
 			if(i != 0 || j != 0)
 			{

+ 26 - 11
src/Ui/UiFtFontLoader.h

@@ -7,15 +7,29 @@
 #include "Vec.h"
 #include "StdTypes.h"
 #include "Math.h"
+#include "Accessors.h"
 
 
 namespace Ui {
 
 
-/// A helper class that uses libfreetype to load glyphs from a font file and gather the metrics for each glyhp
+/// A helper class that uses libfreetype to load glyphs from a font file and gather the metrics for each glyph
 class FtFontLoader
 {
 	public:
+		/// Contains info about the glyphs
+		class Glyph
+		{
+			friend class FtFontLoader;
+
+			public:
+				GETTER_R(FT_Glyph_Metrics, metrics, getMetrics)
+
+			private:
+				FT_Glyph glyph;
+				FT_Glyph_Metrics metrics;
+		};
+
 		enum
 		{
 			GLYPHS_NUM = 128,
@@ -23,19 +37,22 @@ class FtFontLoader
 			GLYPH_ROWS = 8
 		};
 
+		/// One and only constructor
 		FtFontLoader(const char* filename, const FT_Vector& fontSize);
 
+		/// @name Accessors
+		/// @{
+		GETTER_R(Vec<uchar>, img, getImage)
+		GETTER_R(FT_Vector, imgSize, getImageSize)
+		GETTER_R(Vec<Glyph>, glyphs, getGlyphs)
+		/// @}
+
 		/// Save the image (img) to TGA. Its for debugging purposes
 		void saveImage(const char* filename) const;
 
-	private:
-		struct Glyph
-		{
-			FT_Glyph glyph;
-			FT_Glyph_Metrics metrics;
-			Mat3 textureMat;
-		};
+		static FT_Int toPixels(FT_Int a) {return a >> 6;}
 
+	private:
 		/// @name Data
 		/// @{
 		FT_Library library;
@@ -45,10 +62,8 @@ class FtFontLoader
 		FT_Vector imgSize;
 		/// @}
 
-		FT_Int toPixels(FT_Int a) {return a >> 6;}
-
 		/// Reads the face and extracts the glyphs
-		void getGlyphs();
+		void getAllGlyphs();
 
 		/// Copy one bitmap to img
 		void copyBitmap(const uchar* srcImg, const FT_Vector& srcSize, const FT_Vector& pos);

+ 2 - 1
unit-tests/Resources/Material.ut.cpp

@@ -29,6 +29,7 @@ TEST(MaterialTests, Test)
 		RsrcPtr<Material> mtl;
 		EXPECT_NO_THROW(mtl.loadRsrc("unit-tests/data/complex.mtl"));
 		EXPECT_EQ(mtl->getUserDefinedVars().size(), 6);
-		EXPECT_EQ(mtl->getUserDefinedVars()[3].getVec3(), Vec3(1.0, 2.0, -0.8));
+		Vec3 tmp = mtl->getUserDefinedVars()[3].get<Vec3>();
+		EXPECT_EQ(tmp, Vec3(1.0, 2.0, -0.8));
 	}
 }

+ 1 - 0
unit-tests/Scripting/ScriptingEngine.ut.cpp

@@ -2,6 +2,7 @@
 #include "ScriptingEngine.h"
 #include "Math.h"
 #include "Logger.h"
+#include "Globals.h"
 
 
 TEST(ScriptingTests, ScriptingEngine)

+ 7 - 0
unit-tests/Ui/UiFtFontLoader.ut.cpp

@@ -0,0 +1,7 @@
+#include <gtest/gtest.h>
+#include "UiFtFontLoader.h"
+
+
+TEST(UiTests, UiFtFontLoader)
+{
+}

+ 6 - 6
unit-tests/Util/Scanner.ut.cpp

@@ -10,11 +10,11 @@ TEST(ScannerTests, Numbers)
 	std::stringstream ss;	
 	ss << "12345678901234 1.12 0.00000000000001 0.01e1 1e- 10.123e-7 1ab";
 
-	std::auto_ptr<Scanner> scanner_;
+	std::auto_ptr<Scanner::Scanner> scanner_;
 	const Scanner::Token* token;
 	
-	EXPECT_NO_THROW(scanner_.reset(new Scanner(ss, "numbers")));
-	Scanner& scanner = *scanner_;
+	EXPECT_NO_THROW(scanner_.reset(new Scanner::Scanner(ss, "numbers")));
+	Scanner::Scanner& scanner = *scanner_;
 
 	// 12345678901234
 	EXPECT_NO_THROW(token = &scanner.getNextToken());
@@ -63,11 +63,11 @@ TEST(ScannerTests, Identifiers)
 	std::stringstream ss;	
 	ss << "1 la0_la ha\n_ha";
 
-	std::auto_ptr<Scanner> scanner_;
+	std::auto_ptr<Scanner::Scanner> scanner_;
 	const Scanner::Token* token;
 	
-	EXPECT_NO_THROW(scanner_.reset(new Scanner(ss, "identifiers")));
-	Scanner& scanner = *scanner_;
+	EXPECT_NO_THROW(scanner_.reset(new Scanner::Scanner(ss, "identifiers")));
+	Scanner::Scanner& scanner = *scanner_;
 	
 	// 1
 	EXPECT_NO_THROW(token = &scanner.getNextToken());

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 3
unit-tests/build/Makefile


+ 4 - 4
unit-tests/build/gen.cfg.py

@@ -1,14 +1,14 @@
-sourcePaths = walkDir("../../src")
+sourcePaths = walkDir("../../src", False)
 sourcePaths.extend(list(walkDir("../", True)))
 
 includePaths = ["./"]
 includePaths.extend(list(sourcePaths))
-includePaths.extend(["../../extern/include", "../../extern/include/bullet", "/usr/include/python2.6"])
+includePaths.extend(["../../extern/include", "../../extern/include/bullet", "/usr/include/python2.6", "/usr/include/freetype2"])
 
 executableName = "anki-unit-tests"
 
 compiler = "g++"
 
-compilerFlags = "-DDEBUG_ENABLED=1 -DPLATFORM_LINUX -DMATH_INTEL_SIMD -DREVISION=\\\"`svnversion -c ../..`\\\" -c -msse4 -pedantic-errors -pedantic -ansi -Wall -Wextra -W -Wno-long-long -pipe -g3 -pg -fsingle-precision-constant"
+compilerFlags = "-DPLATFORM_LINUX -DMATH_INTEL_SIMD -DREVISION=\\\"`svnversion -c ../..`\\\" -c -msse4 -pedantic-errors -pedantic -ansi -Wall -Wextra -W -Wno-long-long -pipe -pipe -pg -fsingle-precision-constant"
 
-linkerFlags = "-rdynamic -pg -L../../extern/lib-x86-64-linux -Wl,-Bstatic -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath -lGLEW -lGLU -Wl,-Bdynamic -lGL -ljpeg -lSDL -lpng -lpython2.6 -lboost_system -lboost_python -lboost_filesystem -lboost_thread -lgtest"
+linkerFlags = "-rdynamic -pg -L../../extern/lib-x86-64-linux -Wl,-Bstatic -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath -lGLEW -lGLU -Wl,-Bdynamic -lGL -ljpeg -lSDL -lpng -lpython2.6 -lboost_system -lboost_python -lboost_filesystem -lboost_thread -lfreetype -lgtest"

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov