mirror of
https://github.com/dborth/fceugx.git
synced 2025-01-24 14:31:10 +01:00
much saner and more optimized font drawing
This commit is contained in:
parent
0597f37b58
commit
5098d92c03
@ -662,9 +662,10 @@ class GuiText : public GuiElement
|
|||||||
void Draw();
|
void Draw();
|
||||||
protected:
|
protected:
|
||||||
GXColor color; //!< Font color
|
GXColor color; //!< Font color
|
||||||
wchar_t* text; //!< Unicode text value
|
wchar_t* text; //!< Translated Unicode text value
|
||||||
wchar_t* textDyn; //!< Wrapped text value
|
wchar_t *textDyn[20]; //!< Text value, if max width, scrolling, or wrapping enabled
|
||||||
char * origText; //!< Original text data
|
int textDynNum; //!< Number of text lines
|
||||||
|
char * origText; //!< Original text data (English)
|
||||||
int size; //!< Font size
|
int size; //!< Font size
|
||||||
int maxWidth; //!< Maximum width of the generated text object (for text wrapping)
|
int maxWidth; //!< Maximum width of the generated text object (for text wrapping)
|
||||||
int textScroll; //!< Scrolling toggle
|
int textScroll; //!< Scrolling toggle
|
||||||
|
@ -109,7 +109,7 @@ GuiFileBrowser::GuiFileBrowser(int w, int h)
|
|||||||
fileListText[i] = new GuiText(NULL, 20, (GXColor){0, 0, 0, 0xff});
|
fileListText[i] = new GuiText(NULL, 20, (GXColor){0, 0, 0, 0xff});
|
||||||
fileListText[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
|
fileListText[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
|
||||||
fileListText[i]->SetPosition(5,0);
|
fileListText[i]->SetPosition(5,0);
|
||||||
fileListText[i]->SetMaxWidth(450);
|
fileListText[i]->SetMaxWidth(380);
|
||||||
|
|
||||||
fileListBg[i] = new GuiImage(bgFileSelectionEntry);
|
fileListBg[i] = new GuiImage(bgFileSelectionEntry);
|
||||||
fileListIcon[i] = NULL;
|
fileListIcon[i] = NULL;
|
||||||
|
@ -35,7 +35,7 @@ GuiText::GuiText(const char * t, int s, GXColor c)
|
|||||||
style = FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE;
|
style = FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE;
|
||||||
maxWidth = 0;
|
maxWidth = 0;
|
||||||
wrap = false;
|
wrap = false;
|
||||||
textDyn = NULL;
|
textDynNum = 0;
|
||||||
textScroll = SCROLL_NONE;
|
textScroll = SCROLL_NONE;
|
||||||
textScrollPos = 0;
|
textScrollPos = 0;
|
||||||
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
@ -64,7 +64,7 @@ GuiText::GuiText(const char * t)
|
|||||||
style = presetStyle;
|
style = presetStyle;
|
||||||
maxWidth = presetMaxWidth;
|
maxWidth = presetMaxWidth;
|
||||||
wrap = false;
|
wrap = false;
|
||||||
textDyn = NULL;
|
textDynNum = 0;
|
||||||
textScroll = SCROLL_NONE;
|
textScroll = SCROLL_NONE;
|
||||||
textScrollPos = 0;
|
textScrollPos = 0;
|
||||||
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
@ -89,8 +89,12 @@ GuiText::~GuiText()
|
|||||||
free(origText);
|
free(origText);
|
||||||
if(text)
|
if(text)
|
||||||
delete[] text;
|
delete[] text;
|
||||||
if(textDyn)
|
|
||||||
delete[] textDyn;
|
if(textDynNum > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i < textDynNum; i++)
|
||||||
|
delete[] textDyn[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiText::SetText(const char * t)
|
void GuiText::SetText(const char * t)
|
||||||
@ -99,12 +103,16 @@ void GuiText::SetText(const char * t)
|
|||||||
free(origText);
|
free(origText);
|
||||||
if(text)
|
if(text)
|
||||||
delete[] text;
|
delete[] text;
|
||||||
if(textDyn)
|
|
||||||
delete[] textDyn;
|
if(textDynNum > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i < textDynNum; i++)
|
||||||
|
delete[] textDyn[i];
|
||||||
|
}
|
||||||
|
|
||||||
origText = NULL;
|
origText = NULL;
|
||||||
text = NULL;
|
text = NULL;
|
||||||
textDyn = NULL;
|
textDynNum = 0;
|
||||||
textScrollPos = 0;
|
textScrollPos = 0;
|
||||||
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
|
||||||
@ -133,12 +141,26 @@ void GuiText::SetFontSize(int s)
|
|||||||
void GuiText::SetMaxWidth(int width)
|
void GuiText::SetMaxWidth(int width)
|
||||||
{
|
{
|
||||||
maxWidth = width;
|
maxWidth = width;
|
||||||
|
|
||||||
|
if(textDynNum > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i < textDynNum; i++)
|
||||||
|
delete[] textDyn[i];
|
||||||
|
}
|
||||||
|
textDynNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiText::SetWrap(bool w, int width)
|
void GuiText::SetWrap(bool w, int width)
|
||||||
{
|
{
|
||||||
wrap = w;
|
wrap = w;
|
||||||
maxWidth = width;
|
maxWidth = width;
|
||||||
|
|
||||||
|
if(textDynNum > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i < textDynNum; i++)
|
||||||
|
delete[] textDyn[i];
|
||||||
|
}
|
||||||
|
textDynNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiText::SetScroll(int s)
|
void GuiText::SetScroll(int s)
|
||||||
@ -146,11 +168,13 @@ void GuiText::SetScroll(int s)
|
|||||||
if(textScroll == s)
|
if(textScroll == s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(textDyn)
|
if(textDynNum > 0)
|
||||||
{
|
{
|
||||||
delete[] textDyn;
|
for(int i=0; i < textDynNum; i++)
|
||||||
textDyn = NULL;
|
delete[] textDyn[i];
|
||||||
}
|
}
|
||||||
|
textDynNum = 0;
|
||||||
|
|
||||||
textScroll = s;
|
textScroll = s;
|
||||||
textScrollPos = 0;
|
textScrollPos = 0;
|
||||||
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
@ -209,6 +233,13 @@ void GuiText::ResetText()
|
|||||||
delete[] text;
|
delete[] text;
|
||||||
|
|
||||||
text = charToWideChar(gettext(origText));
|
text = charToWideChar(gettext(origText));
|
||||||
|
|
||||||
|
if(textDynNum > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i < textDynNum; i++)
|
||||||
|
delete[] textDyn[i];
|
||||||
|
}
|
||||||
|
textDynNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,130 +268,119 @@ void GuiText::Draw()
|
|||||||
fontSystem[newSize] = new FreeTypeGX(newSize);
|
fontSystem[newSize] = new FreeTypeGX(newSize);
|
||||||
currentSize = newSize;
|
currentSize = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 maxChar;
|
|
||||||
|
|
||||||
if(maxWidth == 0)
|
if(maxWidth == 0)
|
||||||
{
|
{
|
||||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
|
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
|
||||||
goto done;
|
this->UpdateEffects();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxChar = int((float((maxWidth<<1))) / (float(newSize))); // approximate
|
u32 maxChar = maxWidth*2.5 / (float)newSize; // approximate
|
||||||
|
u32 textlen = wcslen(text);
|
||||||
|
|
||||||
if(wrap)
|
if(wrap)
|
||||||
{
|
{
|
||||||
int lineheight = newSize + 6;
|
if(textDynNum == 0)
|
||||||
int txtlen = wcslen(text);
|
|
||||||
int i = 0;
|
|
||||||
int ch = 0;
|
|
||||||
int linenum = 0;
|
|
||||||
int lastSpace = -1;
|
|
||||||
int lastSpaceIndex = -1;
|
|
||||||
wchar_t * textrow[20];
|
|
||||||
|
|
||||||
while(ch < txtlen)
|
|
||||||
{
|
{
|
||||||
if(i == 0)
|
u32 n = 0, ch = 0;
|
||||||
textrow[linenum] = new wchar_t[txtlen + 1];
|
int linenum = 0;
|
||||||
|
int lastSpace = -1;
|
||||||
|
int lastSpaceIndex = -1;
|
||||||
|
|
||||||
textrow[linenum][i] = text[ch];
|
while(ch < textlen && linenum < 20)
|
||||||
textrow[linenum][i+1] = 0;
|
|
||||||
|
|
||||||
if(text[ch] == ' ' || ch == txtlen-1)
|
|
||||||
{
|
{
|
||||||
if(wcslen(textrow[linenum]) >= maxChar)
|
if(n == 0)
|
||||||
|
textDyn[linenum] = new wchar_t[textlen + 1];
|
||||||
|
|
||||||
|
textDyn[linenum][n] = text[ch];
|
||||||
|
textDyn[linenum][n+1] = 0;
|
||||||
|
|
||||||
|
if(text[ch] == ' ' || ch == textlen-1)
|
||||||
{
|
{
|
||||||
if(lastSpace >= 0)
|
if(wcslen(textDyn[linenum]) >= maxChar)
|
||||||
{
|
{
|
||||||
textrow[linenum][lastSpaceIndex] = 0; // discard space, and everything after
|
if(lastSpace >= 0)
|
||||||
ch = lastSpace; // go backwards to the last space
|
{
|
||||||
lastSpace = -1; // we have used this space
|
textDyn[linenum][lastSpaceIndex] = 0; // discard space, and everything after
|
||||||
lastSpaceIndex = -1;
|
ch = lastSpace; // go backwards to the last space
|
||||||
|
lastSpace = -1; // we have used this space
|
||||||
|
lastSpaceIndex = -1;
|
||||||
|
}
|
||||||
|
++linenum;
|
||||||
|
n = -1;
|
||||||
|
}
|
||||||
|
else if(ch == textlen-1)
|
||||||
|
{
|
||||||
|
++linenum;
|
||||||
}
|
}
|
||||||
++linenum;
|
|
||||||
i = -1;
|
|
||||||
}
|
}
|
||||||
else if(ch == txtlen-1)
|
if(text[ch] == ' ' && n >= 0)
|
||||||
{
|
{
|
||||||
++linenum;
|
lastSpace = ch;
|
||||||
|
lastSpaceIndex = n;
|
||||||
}
|
}
|
||||||
|
++ch;
|
||||||
|
++n;
|
||||||
}
|
}
|
||||||
if(text[ch] == ' ' && i >= 0)
|
textDynNum = linenum;
|
||||||
{
|
|
||||||
lastSpace = ch;
|
|
||||||
lastSpaceIndex = i;
|
|
||||||
}
|
|
||||||
++ch;
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lineheight = newSize + 6;
|
||||||
int voffset = 0;
|
int voffset = 0;
|
||||||
|
|
||||||
if(alignmentVert == ALIGN_MIDDLE)
|
if(alignmentVert == ALIGN_MIDDLE)
|
||||||
voffset = (lineheight >> 1) * (1-linenum);
|
voffset = (lineheight >> 1) * (1-textDynNum);
|
||||||
|
|
||||||
int left = this->GetLeft();
|
int left = this->GetLeft();
|
||||||
int top = this->GetTop() + voffset;
|
int top = this->GetTop() + voffset;
|
||||||
|
|
||||||
for(i=0; i < linenum; ++i)
|
for(int i=0; i < textDynNum; ++i)
|
||||||
{
|
fontSystem[currentSize]->drawText(left, top+i*lineheight, textDyn[i], c, style);
|
||||||
fontSystem[currentSize]->drawText(left, top+i*lineheight, textrow[i], c, style);
|
|
||||||
delete[] textrow[i];
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if(textScroll == SCROLL_HORIZONTAL)
|
|
||||||
{
|
{
|
||||||
char *tmpText = strdup(gettext(origText));
|
if(textDynNum == 0)
|
||||||
char *tmpText2 = strdup(tmpText);
|
|
||||||
int textlen = strlen(tmpText);
|
|
||||||
|
|
||||||
if(textlen > maxChar && (FrameTimer % textScrollDelay == 0))
|
|
||||||
{
|
{
|
||||||
if(textScrollInitialDelay)
|
textDynNum = 1;
|
||||||
|
textDyn[0] = wcsdup(text);
|
||||||
|
|
||||||
|
if(textlen > maxChar)
|
||||||
|
textDyn[0][maxChar] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(textScroll == SCROLL_HORIZONTAL)
|
||||||
|
{
|
||||||
|
if(textlen > maxChar && (FrameTimer % textScrollDelay == 0))
|
||||||
{
|
{
|
||||||
--textScrollInitialDelay;
|
if(textScrollInitialDelay)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++textScrollPos;
|
|
||||||
if(textScrollPos > textlen-1)
|
|
||||||
{
|
{
|
||||||
textScrollPos = 0;
|
--textScrollInitialDelay;
|
||||||
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
strncpy(tmpText, &tmpText2[textScrollPos], maxChar-1);
|
|
||||||
tmpText[maxChar-1] = 0;
|
|
||||||
|
|
||||||
int dynlen = strlen(tmpText);
|
|
||||||
|
|
||||||
if(dynlen+2 < maxChar)
|
|
||||||
{
|
{
|
||||||
tmpText[dynlen] = ' ';
|
++textScrollPos;
|
||||||
tmpText[dynlen+1] = ' ';
|
if((u32)textScrollPos > textlen-1)
|
||||||
strncat(&tmpText[dynlen+2], tmpText2, maxChar - dynlen - 2);
|
{
|
||||||
|
textScrollPos = 0;
|
||||||
|
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcsncpy(textDyn[0], &text[textScrollPos], maxChar-1);
|
||||||
|
textDyn[maxChar-1] = 0;
|
||||||
|
|
||||||
|
u32 dynlen = wcslen(textDyn[0]);
|
||||||
|
|
||||||
|
if(dynlen+2 < maxChar)
|
||||||
|
{
|
||||||
|
textDyn[0][dynlen] = ' ';
|
||||||
|
textDyn[0][dynlen+1] = ' ';
|
||||||
|
wcsncat(&textDyn[0][dynlen+2], text, maxChar - dynlen - 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(textDyn) delete[] textDyn;
|
|
||||||
textDyn = charToWideChar(tmpText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tmpText);
|
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn[0], c, style);
|
||||||
free(tmpText2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!textDyn)
|
|
||||||
{
|
|
||||||
char *tmpText = strdup(gettext(origText));
|
|
||||||
if(strlen(tmpText) > maxChar)
|
|
||||||
tmpText[maxChar] = 0;
|
|
||||||
textDyn = charToWideChar(tmpText);
|
|
||||||
free(tmpText);
|
|
||||||
}
|
|
||||||
|
|
||||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn, c, style);
|
|
||||||
done:
|
|
||||||
this->UpdateEffects();
|
this->UpdateEffects();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user