Add an auxiliary font reader class to reduce code repetition

This commit is contained in:
mniip
2018-05-01 02:21:34 +03:00
parent ff27d69424
commit 9d927cbd6f
6 changed files with 88 additions and 101 deletions

2
src/graphics/Font.cpp Normal file
View File

@@ -0,0 +1,2 @@
#define INCLUDE_FONTDATA
#include "font.h"

43
src/graphics/Font.h Normal file
View File

@@ -0,0 +1,43 @@
#include <cstddef>
#include "common/String.h"
#include "font.h"
class FontReader
{
unsigned char *pointer;
int width;
int pixels;
int data;
inline FontReader(unsigned char *_pointer):
pointer(_pointer + 1),
width(*_pointer),
pixels(0),
data(0)
{}
public:
inline FontReader(String::value_type ch):
FontReader(ch <= 0xFF ? &font_data[font_ptrs[ch]] : &font_data[0])
{
}
inline int GetWidth() const
{
return width;
}
inline int NextPixel()
{
if(!pixels)
{
data = *(pointer++);
pixels = 4;
}
int old = data;
pixels--;
data >>= 2;
return old & 0x3;
}
};

View File

@@ -5,8 +5,7 @@
#include "Config.h" #include "Config.h"
#include "Misc.h" #include "Misc.h"
#include "Graphics.h" #include "Graphics.h"
#define INCLUDE_FONTDATA #include "Font.h"
#include "font.h"
#ifdef HIGH_QUALITY_RESAMPLE #ifdef HIGH_QUALITY_RESAMPLE
#include "resampler/resampler.h" #include "resampler/resampler.h"
#endif #endif
@@ -86,64 +85,31 @@ void VideoBuffer::Resize(int width, int height, bool resample, bool fixedRatio)
} }
} }
int VideoBuffer::SetCharacter(int x, int y, int c, int r, int g, int b, int a) int VideoBuffer::SetCharacter(int x, int y, String::value_type c, int r, int g, int b, int a)
{ {
int i, j, w, bn = 0, ba = 0; FontReader reader(c);
unsigned char *rp = font_data + font_ptrs[c]; for (int j = -2; j < FONT_H - 2; j++)
w = *(rp++); for (int i = 0; i < reader.GetWidth(); i++)
for (j=-2; j<FONT_H-2; j++) SetPixel(x + i, y + j, r, g, b, reader.NextPixel() * a / 3);
for (i=0; i<w; i++) return x + reader.GetWidth();
{
if (!bn)
{
ba = *(rp++);
bn = 8;
}
SetPixel(x+i, y+j, r, g, b, ((ba&3)*a)/3);
ba >>= 2;
bn -= 2;
}
return x + w;
} }
int VideoBuffer::BlendCharacter(int x, int y, int c, int r, int g, int b, int a) int VideoBuffer::BlendCharacter(int x, int y, String::value_type c, int r, int g, int b, int a)
{ {
int i, j, w, bn = 0, ba = 0; FontReader reader(c);
unsigned char *rp = font_data + font_ptrs[c]; for (int j = -2; j < FONT_H - 2; j++)
w = *(rp++); for (int i = 0; i < reader.GetWidth(); i++)
for (j=-2; j<FONT_H-2; j++) BlendPixel(x + i, y + j, r, g, b, reader.NextPixel() * a / 3);
for (i=0; i<w; i++) return x + reader.GetWidth();
{
if (!bn)
{
ba = *(rp++);
bn = 8;
}
BlendPixel(x+i, y+j, r, g, b, ((ba&3)*a)/3);
ba >>= 2;
bn -= 2;
}
return x + w;
} }
int VideoBuffer::AddCharacter(int x, int y, int c, int r, int g, int b, int a) int VideoBuffer::AddCharacter(int x, int y, String::value_type c, int r, int g, int b, int a)
{ {
int i, j, w, bn = 0, ba = 0; FontReader reader(c);
unsigned char *rp = font_data + font_ptrs[c]; for (int j = -2; j < FONT_H - 2; j++)
w = *(rp++); for (int i = 0; i < reader.GetWidth(); i++)
for (j=-2; j<FONT_H-2; j++) AddPixel(x + i, y + j, r, g, b, reader.NextPixel() * a / 3);
for (i=0; i<w; i++) return x + reader.GetWidth();
{
if (!bn)
{
ba = *(rp++);
bn = 8;
}
AddPixel(x+i, y+j, r, g, b, ((ba&3)*a)/3);
ba >>= 2;
bn -= 2;
}
return x + w;
} }
VideoBuffer::~VideoBuffer() VideoBuffer::~VideoBuffer()
@@ -582,14 +548,14 @@ int Graphics::textwidth(String str)
s+=3; s+=3;
continue; continue;
} }
x += font_data[font_ptrs[*s]]; x += FontReader(*s).GetWidth();
} }
return x-1; return x-1;
} }
int Graphics::CharWidth(String::value_type c) int Graphics::CharWidth(String::value_type c)
{ {
return font_data[font_ptrs[(int)c]]; return FontReader(c).GetWidth();
} }
int Graphics::textnwidth(String str, int n) int Graphics::textnwidth(String str, int n)
@@ -610,7 +576,7 @@ int Graphics::textnwidth(String str, int n)
s+=3; s+=3;
continue; continue;
} }
x += font_data[font_ptrs[*s]]; x += FontReader(*s).GetWidth();
n--; n--;
} }
return x-1; return x-1;
@@ -638,7 +604,7 @@ void Graphics::textnpos(String str, int n, int w, int *cx, int *cy)
if (!n) { if (!n) {
break; break;
} }
x += font_data[font_ptrs[*s]]; x += FontReader(*s).GetWidth();
if (x>=w) if (x>=w)
{ {
x = 0; x = 0;
@@ -668,7 +634,7 @@ int Graphics::textwidthx(String str, int w)
s+=3; s+=3;
continue; continue;
} }
cw = font_data[font_ptrs[*s]]; cw = FontReader(*s).GetWidth();
if (x+(cw/2) >= w) if (x+(cw/2) >= w)
break; break;
x += cw; x += cw;
@@ -702,7 +668,7 @@ int Graphics::PositionAtCharIndex(String str, int charIndex, int & positionX, in
charIndex-=4; charIndex-=4;
continue; continue;
} }
x += font_data[font_ptrs[*s]]; x += FontReader(*s).GetWidth();
charIndex--; charIndex--;
} }
positionX = x; positionX = x;
@@ -732,7 +698,7 @@ int Graphics::CharIndexAtPosition(String str, int positionX, int positionY)
charIndex+=4; charIndex+=4;
continue; continue;
} }
cw = font_data[font_ptrs[*s]]; cw = FontReader(*s).GetWidth();
if ((x+(cw/2) >= positionX && y+FONT_H >= positionY) || y > positionY) if ((x+(cw/2) >= positionX && y+FONT_H >= positionY) || y > positionY)
break; break;
x += cw; x += cw;
@@ -778,7 +744,7 @@ int Graphics::textwrapheight(String str, int width)
} }
else else
{ {
cw = font_data[font_ptrs[*s]]; cw = FontReader(*s).GetWidth();
if (x+cw>=width) if (x+cw>=width)
{ {
x = 0; x = 0;
@@ -821,7 +787,7 @@ void Graphics::textsize(String str, int & width, int & height)
} }
else else
{ {
cWidth += font_data[font_ptrs[*s]]; cWidth += FontReader(*s).GetWidth();
if(cWidth>lWidth) if(cWidth>lWidth)
lWidth = cWidth; lWidth = cWidth;
} }

View File

@@ -84,9 +84,9 @@ public:
b = 255; b = 255;
Buffer[y*(Width)+x] = PIXRGB(r,g,b); Buffer[y*(Width)+x] = PIXRGB(r,g,b);
} }
int SetCharacter(int x, int y, int c, int r, int g, int b, int a); int SetCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
int BlendCharacter(int x, int y, int c, int r, int g, int b, int a); int BlendCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
int AddCharacter(int x, int y, int c, int r, int g, int b, int a); int AddCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
~VideoBuffer(); ~VideoBuffer();
}; };

View File

@@ -1,5 +1,5 @@
#include "Graphics.h" #include "Graphics.h"
#include "font.h" #include "Font.h"
#include "common/tpt-thread.h" #include "common/tpt-thread.h"
#ifdef OGLI #ifdef OGLI

View File

@@ -1,5 +1,5 @@
#include "font.h"
#include <cmath> #include <cmath>
#include "Font.h"
int PIXELMETHODS_CLASS::drawtext_outline(int x, int y, String s, int r, int g, int b, int a) int PIXELMETHODS_CLASS::drawtext_outline(int x, int y, String s, int r, int g, int b, int a)
{ {
@@ -105,44 +105,20 @@ int PIXELMETHODS_CLASS::drawtext(int x, int y, String str, int r, int g, int b,
int PIXELMETHODS_CLASS::drawchar(int x, int y, String::value_type c, int r, int g, int b, int a) int PIXELMETHODS_CLASS::drawchar(int x, int y, String::value_type c, int r, int g, int b, int a)
{ {
int i, j, w, bn = 0, ba = 0; FontReader reader(c);
unsigned char *rp = font_data + font_ptrs[c]; for (int j = -2; j < FONT_H - 2; j++)
w = *(rp++); for (int i = 0; i < reader.GetWidth(); i++)
for (j=-2; j<FONT_H-2; j++) blendpixel(x + i, y + j, r, g, b, reader.NextPixel() * a / 3);
for (i=0; i<w; i++) return x + reader.GetWidth();
{
if (!bn)
{
ba = *(rp++);
bn = 8;
}
blendpixel(x+i, y+j, r, g, b, ((ba&3)*a)/3);
ba >>= 2;
bn -= 2;
}
return x + w;
} }
int PIXELMETHODS_CLASS::addchar(int x, int y, String::value_type c, int r, int g, int b, int a) int PIXELMETHODS_CLASS::addchar(int x, int y, String::value_type c, int r, int g, int b, int a)
{ {
int i, j, w, bn = 0, ba = 0; FontReader reader(c);
unsigned char *rp = font_data + font_ptrs[c]; for (int j = -2; j < FONT_H - 2; j++)
w = *(rp++); for (int i = 0; i < reader.GetWidth(); i++)
for (j=-2; j<FONT_H-2; j++) addpixel(x + i, y + j, r, g, b, reader.NextPixel() * a / 3);
for (i=0; i<w; i++) return x + reader.GetWidth();
{
if (!bn)
{
ba = *(rp++);
bn = 8;
}
{
addpixel(x+i, y+j, r, g, b, ((ba&3)*a)/3);
}
ba >>= 2;
bn -= 2;
}
return x + w;
} }
TPT_INLINE void PIXELMETHODS_CLASS::xor_pixel(int x, int y) TPT_INLINE void PIXELMETHODS_CLASS::xor_pixel(int x, int y)