mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-26 11:56:16 +02:00
ASFont: access font pixels efficiently.
Previous commit ensures that the font surface is always 32 bpp. Therefore we can read font pixels directly through a pointer.
This commit is contained in:
parent
41e6e4693e
commit
a382a425a9
@ -8,39 +8,6 @@
|
|||||||
|
|
||||||
#define SFONTPLUS_CHARSET "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¿ÀÁÈÉÌÍÒÓÙÚÝÄËÏÖÜŸÂÊÎÔÛÅÃÕÑÆÇČĎĚĽĹŇÔŘŔŠŤŮŽàáèéìíòóùúýäëïöüÿâêîôûåãõñæçčďěľĺňôřŕšťžůðßÐÞþАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяØøąćęłńśżźĄĆĘŁŃŚŻŹ"
|
#define SFONTPLUS_CHARSET "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¿ÀÁÈÉÌÍÒÓÙÚÝÄËÏÖÜŸÂÊÎÔÛÅÃÕÑÆÇČĎĚĽĹŇÔŘŔŠŤŮŽàáèéìíòóùúýäëïöüÿâêîôûåãõñæçčďěľĺňôřŕšťžůðßÐÞþАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяØøąćęłńśżźĄĆĘŁŃŚŻŹ"
|
||||||
|
|
||||||
Uint32 ASFont::getPixel(Sint32 x, Sint32 y) {
|
|
||||||
assert(x>=0);
|
|
||||||
assert(x<surface->w);
|
|
||||||
assert(y>=0);
|
|
||||||
assert(y<surface->h);
|
|
||||||
|
|
||||||
Uint32 Bpp = surface->format->BytesPerPixel;
|
|
||||||
|
|
||||||
// Get the pixel
|
|
||||||
switch(Bpp) {
|
|
||||||
case 1:
|
|
||||||
return *((Uint8 *)surface->pixels + y * surface->pitch + x);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
return *((Uint16 *)surface->pixels + y * surface->pitch/2 + x);
|
|
||||||
break;
|
|
||||||
case 3: { // Format/endian independent
|
|
||||||
Uint8 *bits = ((Uint8 *)surface->pixels)+y*surface->pitch+x*Bpp;
|
|
||||||
Uint8 r, g, b;
|
|
||||||
r = *((bits)+surface->format->Rshift/8);
|
|
||||||
g = *((bits)+surface->format->Gshift/8);
|
|
||||||
b = *((bits)+surface->format->Bshift/8);
|
|
||||||
return SDL_MapRGB(surface->format, r, g, b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
return *((Uint32 *)surface->pixels + y * surface->pitch/4 + x);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASFont::ASFont(const std::string &fontImagePath)
|
ASFont::ASFont(const std::string &fontImagePath)
|
||||||
: characters(SFONTPLUS_CHARSET)
|
: characters(SFONTPLUS_CHARSET)
|
||||||
{
|
{
|
||||||
@ -73,41 +40,53 @@ ASFont::ASFont(const std::string &fontImagePath)
|
|||||||
surface = SDL_ConvertSurface(buf, &format32, SDL_SRCALPHA);
|
surface = SDL_ConvertSurface(buf, &format32, SDL_SRCALPHA);
|
||||||
SDL_FreeSurface(buf);
|
SDL_FreeSurface(buf);
|
||||||
}
|
}
|
||||||
|
assert(surface->format->BytesPerPixel == 4);
|
||||||
|
|
||||||
Uint32 pink = SDL_MapRGB(surface->format, 255,0,255);
|
|
||||||
unsigned c = 0;
|
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
for (unsigned x=0; x<(unsigned)surface->w && c<characters.length(); x++) {
|
|
||||||
if (getPixel(x,0) == pink) {
|
// Determine character widths.
|
||||||
|
Uint32 pink = SDL_MapRGB(surface->format, 255, 0, 255);
|
||||||
|
Uint32 *topLine = static_cast<Uint32 *>(surface->pixels);
|
||||||
|
const unsigned width = surface->w;
|
||||||
|
unsigned x = 0;
|
||||||
|
unsigned c = 0;
|
||||||
|
while (c < characters.length()) {
|
||||||
|
while (x < width && topLine[x] != pink) x++;
|
||||||
unsigned startx = x;
|
unsigned startx = x;
|
||||||
charpos.push_back(x);
|
|
||||||
|
|
||||||
x++;
|
x++;
|
||||||
while (x<(unsigned)surface->w && getPixel(x,0) == pink) x++;
|
while (x < width && topLine[x] == pink) x++;
|
||||||
charpos.push_back(x);
|
|
||||||
|
|
||||||
//utf8 characters
|
charpos.push_back(startx);
|
||||||
if (c>0 && utf8Code(characters[c-1])) {
|
charpos.push_back(x);
|
||||||
|
if (c > 0 && utf8Code(characters[c - 1])) {
|
||||||
|
// UTF8 character
|
||||||
charpos.push_back(startx);
|
charpos.push_back(startx);
|
||||||
charpos.push_back(x);
|
charpos.push_back(x);
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
SDL_UnlockSurface(surface);
|
// Scan height of "0" glyph.
|
||||||
Uint32 colKey = getPixel(0,surface->h-1);
|
std::string::size_type pos = characters.find("0") * 2;
|
||||||
std::string::size_type pos = characters.find("0")*2;
|
SDL_Rect srcrect = {
|
||||||
SDL_Rect srcrect = {charpos[pos], 1, charpos[pos+2] - charpos[pos], surface->h - 1};
|
charpos[pos], 1, charpos[pos + 2] - charpos[pos], surface->h - 1
|
||||||
|
};
|
||||||
|
const unsigned alphaMask = surface->format->Amask;
|
||||||
unsigned y = srcrect.h;
|
unsigned y = srcrect.h;
|
||||||
bool nonKeyFound = false;
|
bool nonTransparentFound = false;
|
||||||
while (y-- > 0 && !nonKeyFound) {
|
while (!nonTransparentFound && y-- > 0) {
|
||||||
unsigned x = srcrect.w;
|
Uint32 *line = reinterpret_cast<Uint32 *>(
|
||||||
while (x-- > 0 && !nonKeyFound)
|
reinterpret_cast<Uint8 *>(surface->pixels)
|
||||||
nonKeyFound = getPixel(x+srcrect.x,y+srcrect.y) != colKey;
|
+ (srcrect.y + y) * surface->pitch
|
||||||
|
);
|
||||||
|
for (unsigned x = 0; !nonTransparentFound && x < srcrect.w; x++) {
|
||||||
|
nonTransparentFound = (line[srcrect.x + x] & alphaMask) != 0;
|
||||||
}
|
}
|
||||||
lineHeight = y+1;
|
}
|
||||||
|
lineHeight = y + 1;
|
||||||
|
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASFont::~ASFont() {
|
ASFont::~ASFont() {
|
||||||
|
@ -35,7 +35,6 @@ public:
|
|||||||
void write(Surface* surface, const std::string& text, int x, int y, HAlign halign = HAlignLeft, VAlign valign = VAlignTop);
|
void write(Surface* surface, const std::string& text, int x, int y, HAlign halign = HAlignLeft, VAlign valign = VAlignTop);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Uint32 getPixel(Sint32 x, Sint32 y);
|
|
||||||
void write(SDL_Surface *surface, const std::string &text, int x, int y);
|
void write(SDL_Surface *surface, const std::string &text, int x, int y);
|
||||||
void write(SDL_Surface *surface, const std::string &text, int x, int y, HAlign halign);
|
void write(SDL_Surface *surface, const std::string &text, int x, int y, HAlign halign);
|
||||||
void write(SDL_Surface *surface, const std::string &text, int x, int y, HAlign halign, VAlign valign);
|
void write(SDL_Surface *surface, const std::string &text, int x, int y, HAlign halign, VAlign valign);
|
||||||
|
Loading…
Reference in New Issue
Block a user