فهرست منبع

Added support for non-antialiased font rendering

Marko Pintera 12 سال پیش
والد
کامیت
5d477cd8a7

+ 1 - 0
BansheeEngine/Source/BsEngineGUI.cpp

@@ -55,6 +55,7 @@ namespace BansheeEngine
 				vector<CamelotFramework::UINT32>::type fontSizes;
 				vector<CamelotFramework::UINT32>::type fontSizes;
 				fontSizes.push_back(DefaultFontSize);
 				fontSizes.push_back(DefaultFontSize);
 				importOptions->setFontSizes(fontSizes);
 				importOptions->setFontSizes(fontSizes);
+				importOptions->setAntialiasing(false);
 			}
 			}
 
 
 			font = Importer::instance().import(DefaultFontPath, fontImportOptions);
 			font = Importer::instance().import(DefaultFontPath, fontImportOptions);

+ 3 - 0
CamelotCore/Include/CmFontImportOptions.h

@@ -15,10 +15,12 @@ namespace CamelotFramework
 		void addCharIndexRange(UINT32 from, UINT32 to);
 		void addCharIndexRange(UINT32 from, UINT32 to);
 		void clearCharIndexRanges();
 		void clearCharIndexRanges();
 		void setDPI(UINT32 dpi) { mDPI = dpi; }
 		void setDPI(UINT32 dpi) { mDPI = dpi; }
+		void setAntialiasing(bool enabled) { mAntialiasing = enabled; }
 
 
 		vector<UINT32>::type getFontSizes() const { return mFontSizes; }
 		vector<UINT32>::type getFontSizes() const { return mFontSizes; }
 		vector<std::pair<UINT32, UINT32>>::type getCharIndexRanges() const { return mCharIndexRanges; }
 		vector<std::pair<UINT32, UINT32>>::type getCharIndexRanges() const { return mCharIndexRanges; }
 		UINT32 getDPI() const { return mDPI; }
 		UINT32 getDPI() const { return mDPI; }
+		bool getAntialiasing() const { return mAntialiasing; }
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								SERIALIZATION                      		*/
 		/* 								SERIALIZATION                      		*/
@@ -32,5 +34,6 @@ namespace CamelotFramework
 		vector<UINT32>::type mFontSizes;
 		vector<UINT32>::type mFontSizes;
 		vector<std::pair<UINT32, UINT32>>::type mCharIndexRanges;
 		vector<std::pair<UINT32, UINT32>>::type mCharIndexRanges;
 		UINT32 mDPI;
 		UINT32 mDPI;
+		bool mAntialiasing;
 	};
 	};
 }
 }

+ 1 - 1
CamelotCore/Source/CmFontImportOptions.cpp

@@ -4,7 +4,7 @@
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
 	FontImportOptions::FontImportOptions()
 	FontImportOptions::FontImportOptions()
-		:mDPI(96)
+		:mDPI(72), mAntialiasing(true)
 	{
 	{
 		mCharIndexRanges.push_back(std::make_pair(33, 166)); // Most used ASCII characters
 		mCharIndexRanges.push_back(std::make_pair(33, 166)); // Most used ASCII characters
 	}
 	}

+ 44 - 15
CamelotFontImporter/Source/CmFontImporter.cpp

@@ -47,7 +47,7 @@ namespace CamelotFramework
 
 
 	HResource FontImporter::import(const String& filePath, ConstImportOptionsPtr importOptions)
 	HResource FontImporter::import(const String& filePath, ConstImportOptionsPtr importOptions)
 	{
 	{
-		const FontImportOptions* gpuProgImportOptions = static_cast<const FontImportOptions*>(importOptions.get());
+		const FontImportOptions* fontImportOptions = static_cast<const FontImportOptions*>(importOptions.get());
 
 
 		FT_Library library;
 		FT_Library library;
 
 
@@ -67,9 +67,13 @@ namespace CamelotFramework
 			CM_EXCEPT(InternalErrorException, "Failed to load font file: " + filePath + ". Unknown error.");
 			CM_EXCEPT(InternalErrorException, "Failed to load font file: " + filePath + ". Unknown error.");
 		}
 		}
 
 
-		vector<std::pair<UINT32, UINT32>>::type charIndexRanges = gpuProgImportOptions->getCharIndexRanges();
-		vector<UINT32>::type fontSizes = gpuProgImportOptions->getFontSizes();
-		UINT32 dpi = gpuProgImportOptions->getDPI();
+		vector<std::pair<UINT32, UINT32>>::type charIndexRanges = fontImportOptions->getCharIndexRanges();
+		vector<UINT32>::type fontSizes = fontImportOptions->getFontSizes();
+		UINT32 dpi = fontImportOptions->getDPI();
+
+		FT_Int32 loadFlags = FT_LOAD_RENDER;
+		if(!fontImportOptions->getAntialiasing())
+			loadFlags |= FT_LOAD_TARGET_MONO | FT_LOAD_NO_AUTOHINT;
 
 
 		vector<FontData>::type dataPerSize;
 		vector<FontData>::type dataPerSize;
 		for(size_t i = 0; i < fontSizes.size(); i++)
 		for(size_t i = 0; i < fontSizes.size(); i++)
@@ -87,7 +91,7 @@ namespace CamelotFramework
 			{
 			{
 				for(UINT32 charIdx = iter->first; charIdx <= iter->second; charIdx++)
 				for(UINT32 charIdx = iter->first; charIdx <= iter->second; charIdx++)
 				{
 				{
-					error = FT_Load_Char(face, (FT_ULong)charIdx, FT_LOAD_RENDER);
+					error = FT_Load_Char(face, (FT_ULong)charIdx, loadFlags);
 
 
 					if(error)
 					if(error)
 						CM_EXCEPT(InternalErrorException, "Failed to load a character");
 						CM_EXCEPT(InternalErrorException, "Failed to load a character");
@@ -105,7 +109,7 @@ namespace CamelotFramework
 
 
 			// Add missing glyph
 			// Add missing glyph
 			{
 			{
-				error = FT_Load_Glyph(face, (FT_ULong)0, FT_LOAD_RENDER);
+				error = FT_Load_Glyph(face, (FT_ULong)0, loadFlags);
 
 
 				if(error)
 				if(error)
 					CM_EXCEPT(InternalErrorException, "Failed to load a character");
 					CM_EXCEPT(InternalErrorException, "Failed to load a character");
@@ -132,6 +136,7 @@ namespace CamelotFramework
 			{
 			{
 				UINT32 bufferSize = pageIter->width * pageIter->height * 2;
 				UINT32 bufferSize = pageIter->width * pageIter->height * 2;
 
 
+				// TODO - I don't actually need a 2 channel texture
 				PixelData pixelData(pageIter->width, pageIter->height, 1, PF_R8G8);
 				PixelData pixelData(pageIter->width, pageIter->height, 1, PF_R8G8);
 
 
 				pixelData.allocateInternalBuffer();
 				pixelData.allocateInternalBuffer();
@@ -152,11 +157,11 @@ namespace CamelotFramework
 					{
 					{
 						charIdx = seqIdxToCharIdx[(UINT32)elementIdx];
 						charIdx = seqIdxToCharIdx[(UINT32)elementIdx];
 
 
-						error = FT_Load_Char(face, charIdx, FT_LOAD_RENDER);
+						error = FT_Load_Char(face, charIdx, loadFlags);
 					}
 					}
 					else
 					else
 					{
 					{
-						error = FT_Load_Glyph(face, 0, FT_LOAD_RENDER);
+						error = FT_Load_Glyph(face, 0, loadFlags);
 					}
 					}
 
 
 					if(error)
 					if(error)
@@ -169,17 +174,41 @@ namespace CamelotFramework
 
 
 					UINT8* sourceBuffer = slot->bitmap.buffer;
 					UINT8* sourceBuffer = slot->bitmap.buffer;
 					UINT8* dstBuffer = pixelBuffer + (curElement.output.y * pageIter->width * 2) + curElement.output.x * 2;
 					UINT8* dstBuffer = pixelBuffer + (curElement.output.y * pageIter->width * 2) + curElement.output.x * 2;
-					for(INT32 bitmapRow = 0; bitmapRow < slot->bitmap.rows; bitmapRow++)
+
+					if(slot->bitmap.pixel_mode == ft_pixel_mode_grays)
 					{
 					{
-						for(INT32 bitmapColumn = 0; bitmapColumn < slot->bitmap.width; bitmapColumn++)
+						for(INT32 bitmapRow = 0; bitmapRow < slot->bitmap.rows; bitmapRow++)
 						{
 						{
-							dstBuffer[bitmapColumn * 2 + 0] = sourceBuffer[bitmapColumn];
-							dstBuffer[bitmapColumn * 2 + 1] = sourceBuffer[bitmapColumn];
+							for(INT32 bitmapColumn = 0; bitmapColumn < slot->bitmap.width; bitmapColumn++)
+							{
+								dstBuffer[bitmapColumn * 2 + 0] = sourceBuffer[bitmapColumn];
+								dstBuffer[bitmapColumn * 2 + 1] = sourceBuffer[bitmapColumn];
+							}
+
+							dstBuffer += pageIter->width * 2;
+							sourceBuffer += slot->bitmap.pitch;
 						}
 						}
+					}
+					else if(slot->bitmap.pixel_mode == ft_pixel_mode_mono)
+					{
+						// 8 pixels are packed into a byte, so do some unpacking
+						for(INT32 bitmapRow = 0; bitmapRow < slot->bitmap.rows; bitmapRow++)
+						{
+							for(INT32 bitmapColumn = 0; bitmapColumn < slot->bitmap.width; bitmapColumn++)
+							{
+								UINT8 srcValue = sourceBuffer[bitmapColumn >> 3];
+								UINT8 dstValue = (srcValue & (128 >> (bitmapColumn & 7))) != 0 ? 255 : 0;
+
+								dstBuffer[bitmapColumn * 2 + 0] = dstValue;
+								dstBuffer[bitmapColumn * 2 + 1] = dstValue;
+							}
 
 
-						dstBuffer += pageIter->width * 2;
-						sourceBuffer += slot->bitmap.pitch;
+							dstBuffer += pageIter->width * 2;
+							sourceBuffer += slot->bitmap.pitch;
+						}
 					}
 					}
+					else
+						CM_EXCEPT(InternalErrorException, "Unsupported pixel mode for a FreeType bitmap.");
 
 
 					// Store character information
 					// Store character information
 					CHAR_DESC charDesc;
 					CHAR_DESC charDesc;
@@ -256,7 +285,7 @@ namespace CamelotFramework
 			fontData.fontDesc.lineHeight = lineHeight;
 			fontData.fontDesc.lineHeight = lineHeight;
 
 
 			// Get space size
 			// Get space size
-			error = FT_Load_Char(face, 32, FT_LOAD_RENDER);
+			error = FT_Load_Char(face, 32, loadFlags);
 
 
 			if(error)
 			if(error)
 				CM_EXCEPT(InternalErrorException, "Failed to load a character");
 				CM_EXCEPT(InternalErrorException, "Failed to load a character");