about summary refs log tree commit diff
path: root/src/engine/client/text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/client/text.cpp')
-rw-r--r--src/engine/client/text.cpp160
1 files changed, 80 insertions, 80 deletions
diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp
index da91980d..b0896b92 100644
--- a/src/engine/client/text.cpp
+++ b/src/engine/client/text.cpp
@@ -36,7 +36,7 @@ static int aFontSizes[] = {8,9,10,11,12,13,14,15,16,17,18,19,20,36,64};
 struct CFontChar
 {
 	int m_ID;
-	
+
 	// these values are scaled to the pFont size
 	// width * font_size == real_size
 	float m_Width;
@@ -44,7 +44,7 @@ struct CFontChar
 	float m_OffsetX;
 	float m_OffsetY;
 	float m_AdvanceX;
-	
+
 	float m_aUvs[4];
 	int64 m_TouchTime;
 };
@@ -57,16 +57,16 @@ struct CFontSizeData
 	GLuint m_aTextures[2];
 	int m_TextureWidth;
 	int m_TextureHeight;
-	
+
 	int m_NumXChars;
 	int m_NumYChars;
-	
+
 	int m_CharMaxWidth;
 	int m_CharMaxHeight;
-	
+
 	CFontChar m_aCharacters[MAX_CHARACTERS*MAX_CHARACTERS];
-	
-	int m_CurrentCharacter;	
+
+	int m_CurrentCharacter;
 };
 
 class CFont
@@ -82,7 +82,7 @@ class CTextRender : public IEngineTextRender
 {
 	IGraphics *m_pGraphics;
 	IGraphics *Graphics() { return m_pGraphics; }
-	
+
 	int WordLength(const char *pText)
 	{
 		int s = 1;
@@ -106,13 +106,13 @@ class CTextRender : public IEngineTextRender
 	float m_TextOutlineG;
 	float m_TextOutlineB;
 	float m_TextOutlineA;
-	
+
 	int m_FontTextureFormat;
 
 	CFont *m_pDefaultFont;
 
 	FT_Library m_FTLibrary;
-	
+
 	int GetFontSizeIndex(int Pixelsize)
 	{
 		for(unsigned i = 0; i < NUM_FONT_SIZES; i++)
@@ -120,18 +120,18 @@ class CTextRender : public IEngineTextRender
 			if(aFontSizes[i] >= Pixelsize)
 				return i;
 		}
-		
+
 		return NUM_FONT_SIZES-1;
 	}
-	
+
 
 
 	void Grow(unsigned char *pIn, unsigned char *pOut, int w, int h)
 	{
-		for(int y = 0; y < h; y++) 
-			for(int x = 0; x < w; x++) 
-			{ 
-				int c = pIn[y*w+x]; 
+		for(int y = 0; y < h; y++)
+			for(int x = 0; x < w; x++)
+			{
+				int c = pIn[y*w+x];
 
 				for(int sy = -1; sy <= 1; sy++)
 					for(int sx = -1; sx <= 1; sx++)
@@ -142,7 +142,7 @@ class CTextRender : public IEngineTextRender
 						{
 							int Index = GetY*w+GetX;
 							if(pIn[Index] > c)
-								c = pIn[Index]; 
+								c = pIn[Index];
 						}
 					}
 
@@ -157,18 +157,18 @@ class CTextRender : public IEngineTextRender
 		int Height = CharHeight*Ychars;
 		void *pMem = mem_alloc(Width*Height, 1);
 		mem_zero(pMem, Width*Height);
-		
+
 		if(pSizeData->m_aTextures[0] == 0)
 			glGenTextures(2, pSizeData->m_aTextures);
 		else
 			FontMemoryUsage -= pSizeData->m_TextureWidth*pSizeData->m_TextureHeight*2;
-		
+
 		pSizeData->m_NumXChars = Xchars;
 		pSizeData->m_NumYChars = Ychars;
 		pSizeData->m_TextureWidth = Width;
 		pSizeData->m_TextureHeight = Height;
 		pSizeData->m_CurrentCharacter = 0;
-		
+
 		for(int i = 0; i < 2; i++)
 		{
 			glBindTexture(GL_TEXTURE_2D, pSizeData->m_aTextures[i]);
@@ -177,9 +177,9 @@ class CTextRender : public IEngineTextRender
 			glTexImage2D(GL_TEXTURE_2D, 0, m_FontTextureFormat, Width, Height, 0, m_FontTextureFormat, GL_UNSIGNED_BYTE, pMem);
 			FontMemoryUsage += Width*Height;
 		}
-		
+
 		dbg_msg("", "pFont memory usage: %d", FontMemoryUsage);
-		
+
 		mem_free(pMem);
 	}
 
@@ -198,43 +198,43 @@ class CTextRender : public IEngineTextRender
 			pSizeData->m_NumXChars <<= 1;
 		else
 			pSizeData->m_NumYChars <<= 1;
-		InitTexture(pSizeData, pSizeData->m_CharMaxWidth, pSizeData->m_CharMaxHeight, pSizeData->m_NumXChars, pSizeData->m_NumYChars);		
+		InitTexture(pSizeData, pSizeData->m_CharMaxWidth, pSizeData->m_CharMaxHeight, pSizeData->m_NumXChars, pSizeData->m_NumYChars);
 	}
-	
-	
+
+
 	// TODO: Refactor: move this into a pFont class
 	void InitIndex(CFont *pFont, int Index)
 	{
 		CFontSizeData *pSizeData = &pFont->m_aSizes[Index];
-		
+
 		pSizeData->m_FontSize = aFontSizes[Index];
 		FT_Set_Pixel_Sizes(pFont->m_FtFace, 0, pSizeData->m_FontSize);
-		
+
 		int OutlineThickness = AdjustOutlineThicknessToFontSize(1, pSizeData->m_FontSize);
-			
+
 		{
 			unsigned GlyphIndex;
 			int MaxH = 0;
 			int MaxW = 0;
-			
+
 			int Charcode = FT_Get_First_Char(pFont->m_FtFace, &GlyphIndex);
 			while(GlyphIndex != 0)
-			{   
+			{
 				// do stuff
 				FT_Load_Glyph(pFont->m_FtFace, GlyphIndex, FT_LOAD_DEFAULT);
-				
+
 				if(pFont->m_FtFace->glyph->metrics.width > MaxW) MaxW = pFont->m_FtFace->glyph->metrics.width; // ignore_convention
 				if(pFont->m_FtFace->glyph->metrics.height > MaxH) MaxH = pFont->m_FtFace->glyph->metrics.height; // ignore_convention
 				Charcode = FT_Get_Next_Char(pFont->m_FtFace, Charcode, &GlyphIndex);
 			}
-			
+
 			MaxW = (MaxW>>6)+2+OutlineThickness*2;
 			MaxH = (MaxH>>6)+2+OutlineThickness*2;
-			
+
 			for(pSizeData->m_CharMaxWidth = 1; pSizeData->m_CharMaxWidth < MaxW; pSizeData->m_CharMaxWidth <<= 1);
 			for(pSizeData->m_CharMaxHeight = 1; pSizeData->m_CharMaxHeight < MaxH; pSizeData->m_CharMaxHeight <<= 1);
 		}
-		
+
 		//dbg_msg("pFont", "init size %d, texture size %d %d", pFont->sizes[index].font_size, w, h);
 		//FT_New_Face(m_FTLibrary, "data/fonts/vera.ttf", 0, &pFont->ft_face);
 		InitTexture(pSizeData, pSizeData->m_CharMaxWidth, pSizeData->m_CharMaxHeight, 8, 8);
@@ -253,7 +253,7 @@ class CTextRender : public IEngineTextRender
 	{
 		int x = (SlotID%pSizeData->m_NumXChars) * (pSizeData->m_TextureWidth/pSizeData->m_NumXChars);
 		int y = (SlotID/pSizeData->m_NumXChars) * (pSizeData->m_TextureHeight/pSizeData->m_NumYChars);
-		
+
 		glBindTexture(GL_TEXTURE_2D, pSizeData->m_aTextures[Texnum]);
 		glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
 			pSizeData->m_TextureWidth/pSizeData->m_NumXChars,
@@ -284,13 +284,13 @@ class CTextRender : public IEngineTextRender
 				if(pSizeData->m_aCharacters[i].m_TouchTime < pSizeData->m_aCharacters[Oldest].m_TouchTime)
 					Oldest = i;
 			}
-			
+
 			if(time_get()-pSizeData->m_aCharacters[Oldest].m_TouchTime < time_freq())
 			{
 				IncreaseTextureSize(pSizeData);
 				return GetSlot(pSizeData);
 			}
-			
+
 			return Oldest;
 		}
 	}
@@ -315,12 +315,12 @@ class CTextRender : public IEngineTextRender
 		}
 
 		pBitmap = &pFont->m_FtFace->glyph->bitmap; // ignore_convention
-		
+
 		// fetch slot
 		SlotID = GetSlot(pSizeData);
 		if(SlotID < 0)
 			return -1;
-		
+
 		// adjust spacing
 		int OutlineThickness = AdjustOutlineThicknessToFontSize(1, pSizeData->m_FontSize);
 		x += OutlineThickness;
@@ -337,7 +337,7 @@ class CTextRender : public IEngineTextRender
 		}
 		else if(pBitmap->pixel_mode == FT_PIXEL_MODE_MONO) // ignore_convention
 		{
-			for(py = 0; py < pBitmap->rows; py++)  // ignore_convention
+			for(py = 0; py < pBitmap->rows; py++) // ignore_convention
 				for(px = 0; px < pBitmap->width; px++) // ignore_convention
 				{
 					if(pBitmap->buffer[py*pBitmap->pitch+px/8]&(1<<(7-(px%8)))) // ignore_convention
@@ -345,13 +345,13 @@ class CTextRender : public IEngineTextRender
 				}
 		}
 
-		if(0) for(py = 0; py < SlotW; py++) 
-			for(px = 0; px < SlotH; px++) 
+		if(0) for(py = 0; py < SlotW; py++)
+			for(px = 0; px < SlotH; px++)
 				ms_aGlyphData[py*SlotW+px] = 255;
-		
+
 		// upload the glyph
 		UploadGlyph(pSizeData, 0, SlotID, Chr, ms_aGlyphData);
-		
+
 		if(OutlineThickness == 1)
 		{
 			Grow(ms_aGlyphData, ms_aGlyphDataOutlined, SlotW, SlotH);
@@ -366,7 +366,7 @@ class CTextRender : public IEngineTextRender
 			}
 			UploadGlyph(pSizeData, 1, SlotID, Chr, ms_aGlyphData);
 		}
-		
+
 		// set char info
 		{
 			CFontChar *pFontchr = &pSizeData->m_aCharacters[SlotID];
@@ -375,27 +375,27 @@ class CTextRender : public IEngineTextRender
 			float Vscale = 1.0f/pSizeData->m_TextureHeight;
 			int Height = pBitmap->rows + OutlineThickness*2 + 2; // ignore_convention
 			int Width = pBitmap->width + OutlineThickness*2 + 2; // ignore_convention
-			
+
 			pFontchr->m_ID = Chr;
 			pFontchr->m_Height = Height * Scale;
 			pFontchr->m_Width = Width * Scale;
 			pFontchr->m_OffsetX = (pFont->m_FtFace->glyph->bitmap_left-1) * Scale; // ignore_convention
 			pFontchr->m_OffsetY = (pSizeData->m_FontSize - pFont->m_FtFace->glyph->bitmap_top) * Scale; // ignore_convention
 			pFontchr->m_AdvanceX = (pFont->m_FtFace->glyph->advance.x>>6) * Scale; // ignore_convention
-			
+
 			pFontchr->m_aUvs[0] = (SlotID%pSizeData->m_NumXChars) / (float)(pSizeData->m_NumXChars);
 			pFontchr->m_aUvs[1] = (SlotID/pSizeData->m_NumXChars) / (float)(pSizeData->m_NumYChars);
 			pFontchr->m_aUvs[2] = pFontchr->m_aUvs[0] + Width*Uscale;
 			pFontchr->m_aUvs[3] = pFontchr->m_aUvs[1] + Height*Vscale;
 		}
-		
+
 		return SlotID;
 	}
 
 	CFontChar *GetChar(CFont *pFont, CFontSizeData *pSizeData, int Chr)
 	{
 		CFontChar *pFontchr = NULL;
-		
+
 		// search for the character
 		// TODO: remove this linear search
 		int i;
@@ -407,7 +407,7 @@ class CTextRender : public IEngineTextRender
 				break;
 			}
 		}
-		
+
 		// check if we need to render the character
 		if(!pFontchr)
 		{
@@ -415,12 +415,12 @@ class CTextRender : public IEngineTextRender
 			if(Index >= 0)
 				pFontchr = &pSizeData->m_aCharacters[Index];
 		}
-		
+
 		// touch the character
 		// TODO: don't call time_get here
 		if(pFontchr)
 			pFontchr->m_TouchTime = time_get();
-			
+
 		return pFontchr;
 	}
 
@@ -436,8 +436,8 @@ class CTextRender : public IEngineTextRender
 		FT_Get_Kerning(pFont->m_FtFace, Left, Right, FT_KERNING_DEFAULT, &Kerning);
 		return (Kerning.x>>6);
 	}
-	
-	
+
+
 public:
 	CTextRender()
 	{
@@ -457,21 +457,21 @@ public:
 		// GL_LUMINANCE can be good for debugging
 		m_FontTextureFormat = GL_ALPHA;
 	}
-		
+
 	virtual void Init()
 	{
 		m_pGraphics = Kernel()->RequestInterface<IGraphics>();
 		FT_Init_FreeType(&m_FTLibrary);
 	}
-			
+
 
 	virtual CFont *LoadFont(const char *pFilename)
 	{
 		CFont *pFont = (CFont *)mem_alloc(sizeof(CFont), 1);
-		
+
 		mem_zero(pFont, sizeof(*pFont));
 		str_copy(pFont->m_aFilename, pFilename, sizeof(pFont->m_aFilename));
-		
+
 		if(FT_New_Face(m_FTLibrary, pFont->m_aFilename, 0, &pFont->m_FtFace))
 		{
 			mem_free(pFont);
@@ -480,7 +480,7 @@ public:
 
 		for(unsigned i = 0; i < NUM_FONT_SIZES; i++)
 			pFont->m_aSizes[i].m_FontSize = -1;
-		
+
 		dbg_msg("textrender", "loaded pFont from '%s'", pFilename);
 		return pFont;
 	};
@@ -495,8 +495,8 @@ public:
 		dbg_msg("textrender", "default pFont set %p", pFont);
 		m_pDefaultFont = pFont;
 	}
-		
-		
+
+
 	virtual void SetCursor(CTextCursor *pCursor, float x, float y, float FontSize, int Flags)
 	{
 		mem_zero(pCursor, sizeof(*pCursor));
@@ -510,8 +510,8 @@ public:
 		pCursor->m_Flags = Flags;
 		pCursor->m_CharCount = 0;
 	}
-	
-		
+
+
 	virtual void Text(void *pFontSetV, float x, float y, float Size, const char *pText, int MaxWidth)
 	{
 		CTextCursor Cursor;
@@ -527,7 +527,7 @@ public:
 		TextEx(&Cursor, pText, Length);
 		return Cursor.m_X;
 	}
-	
+
 	virtual int TextLineCount(void *pFontSetV, float Size, const char *pText, float LineWidth)
 	{
 		CTextCursor Cursor;
@@ -552,12 +552,12 @@ public:
 		m_TextOutlineB = b;
 		m_TextOutlineA = a;
 	}
-	
+
 	virtual void TextEx(CTextCursor *pCursor, const char *pText, int Length)
 	{
 		CFont *pFont = pCursor->m_pFont;
 		CFontSizeData *pSizeData = NULL;
-		
+
 		//dbg_msg("textrender", "rendering text '%s'", text);
 
 		float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
@@ -576,7 +576,7 @@ public:
 
 		// to correct coords, convert to screen coords, round, and convert back
 		Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
-		
+
 		FakeToScreenX = (Graphics()->ScreenWidth()/(ScreenX1-ScreenX0));
 		FakeToScreenY = (Graphics()->ScreenHeight()/(ScreenY1-ScreenY0));
 		ActualX = (int)(pCursor->m_X * FakeToScreenX);
@@ -592,7 +592,7 @@ public:
 		// fetch pFont data
 		if(!pFont)
 			pFont = m_pDefaultFont;
-		
+
 		if(!pFont)
 			return;
 
@@ -600,11 +600,11 @@ public:
 		RenderSetup(pFont, ActualSize);
 
 		float Scale = 1/pSizeData->m_FontSize;
-		
+
 		// set length
 		if(Length < 0)
 			Length = str_length(pText);
-			
+
 		pEnd = pText + Length;
 
 		// if we don't want to render, we can just skip the first outline pass
@@ -649,7 +649,7 @@ public:
 					Compare.m_Flags &= ~TEXTFLAG_RENDER;
 					Compare.m_LineWidth = -1;
 					TextEx(&Compare, pText, Wlen);
-					
+
 					if(Compare.m_X-DrawX > pCursor->m_LineWidth)
 					{
 						// word can't be fitted in one line, cut it
@@ -659,11 +659,11 @@ public:
 						Cutter.m_Y = DrawY;
 						Cutter.m_Flags &= ~TEXTFLAG_RENDER;
 						Cutter.m_Flags |= TEXTFLAG_STOP_AT_END;
-						
+
 						TextEx(&Cutter, (const char *)pCurrent, Wlen);
 						Wlen = Cutter.m_CharCount;
 						NewLine = 1;
-						
+
 						if(Wlen <= 3) // if we can't place 3 chars of the word on this line, take the next
 							Wlen = 0;
 					}
@@ -672,10 +672,10 @@ public:
 						NewLine = 1;
 						Wlen = 0;
 					}
-					
+
 					pBatchEnd = pCurrent + Wlen;
 				}
-				
+
 				const char *pTmp = pCurrent;
 				int NextCharacter = str_utf8_decode(&pTmp);
 				while(pCurrent < pBatchEnd)
@@ -683,7 +683,7 @@ public:
 					int Character = NextCharacter;
 					pCurrent = pTmp;
 					NextCharacter = str_utf8_decode(&pTmp);
-					
+
 					if(Character == '\n')
 					{
 						DrawX = pCursor->m_StartX;
@@ -718,14 +718,14 @@ public:
 						pCursor->m_CharCount++;
 					}
 				}
-				
+
 				if(NewLine)
 				{
 					DrawX = pCursor->m_StartX;
 					DrawY += Size;
 					GotNewLine = 1;
 					DrawX = (int)(DrawX * FakeToScreenX) / FakeToScreenX; // realign
-					DrawY = (int)(DrawY * FakeToScreenY) / FakeToScreenY;				
+					DrawY = (int)(DrawY * FakeToScreenY) / FakeToScreenY;
 					++LineCount;
 				}
 			}
@@ -736,11 +736,11 @@ public:
 
 		pCursor->m_X = DrawX;
 		pCursor->m_LineCount = LineCount;
-		
+
 		if(GotNewLine)
 			pCursor->m_Y = DrawY;
 	}
-	
+
 };
 
 IEngineTextRender *CreateEngineTextRender() { return new CTextRender; }