mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 18:11:50 +01:00
Add support for pseudo monospace with a non-monospace (proportional) font.
This commit is contained in:
parent
2f0567b9ef
commit
aac6061671
@ -106,7 +106,7 @@ export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -j4 -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
@make --no-print-directory -j4 -C $(BUILD) -f $(CURDIR)/Makefile.currentDevkitPPC
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
|
@ -34,7 +34,7 @@ void InitFreeType(uint8_t* fontBuffer, FT_Long bufferSize)
|
||||
FT_New_Memory_Face(ftLibrary, (FT_Byte *)fontBuffer, bufferSize, 0, &ftFace);
|
||||
ftSlot = ftFace->glyph;
|
||||
|
||||
for(int i=0; i<50; i++)
|
||||
for(int i=0; i <= MAX_FONT_SIZE; i++)
|
||||
fontSystem[i] = NULL;
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ void ChangeFontSize(FT_UInt pixelSize)
|
||||
|
||||
void ClearFontData()
|
||||
{
|
||||
for(int i=0; i<50; i++)
|
||||
for(int i=0; i <= MAX_FONT_SIZE; i++)
|
||||
{
|
||||
if(fontSystem[i])
|
||||
delete fontSystem[i];
|
||||
@ -100,6 +100,12 @@ FreeTypeGX::FreeTypeGX(FT_UInt pixelSize, uint8_t vertexIndex)
|
||||
this->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
|
||||
this->ftPointSize = pixelSize;
|
||||
this->ftKerningEnabled = FT_HAS_KERNING(ftFace);
|
||||
if (ftFace->size) {
|
||||
this->ftMaxAdvanceX = ftFace->size->metrics.max_advance >> 6;
|
||||
}
|
||||
else {
|
||||
this->ftMaxAdvanceX = ftFace->max_advance_width >> 6;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,17 +397,17 @@ int16_t FreeTypeGX::getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format
|
||||
* @param textStyle Flags which specify any styling which should be applied to the rendered string.
|
||||
* @return The number of characters printed.
|
||||
*/
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle)
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color, uint16_t textStyle, int monoPercent)
|
||||
{
|
||||
uint16_t x_pos = x, printed = 0;
|
||||
uint16_t x_offset = 0, y_offset = 0;
|
||||
int16_t x_pos = x, printed = 0;
|
||||
int16_t x_offset = 0, y_offset = 0;
|
||||
GXTexObj glyphTexture;
|
||||
FT_Vector pairDelta;
|
||||
ftgxDataOffset offset;
|
||||
|
||||
if(textStyle & FTGX_JUSTIFY_MASK)
|
||||
{
|
||||
x_offset = this->getStyleOffsetWidth(this->getWidth(text), textStyle);
|
||||
x_offset = this->getStyleOffsetWidth(this->getWidth(text, textStyle, monoPercent), textStyle);
|
||||
}
|
||||
if(textStyle & FTGX_ALIGN_MASK)
|
||||
{
|
||||
@ -410,6 +416,11 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int x_diff = 0;
|
||||
int monoAdvanceX = 0;
|
||||
if (textStyle & FTGX_MONOSPACE_FAKE) {
|
||||
monoAdvanceX = (int)this->ftMaxAdvanceX * monoPercent / 100;
|
||||
}
|
||||
while (text[i])
|
||||
{
|
||||
ftgxCharData* glyphData = NULL;
|
||||
@ -424,16 +435,27 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
||||
|
||||
if (glyphData != NULL)
|
||||
{
|
||||
if (this->ftKerningEnabled && i)
|
||||
{
|
||||
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||
x_pos += pairDelta.x >> 6;
|
||||
if (textStyle & FTGX_MONOSPACE_FAKE) {
|
||||
x_diff = (monoAdvanceX - (int)glyphData->glyphAdvanceX) / 2;
|
||||
x_pos += x_diff;
|
||||
}
|
||||
else {
|
||||
if (this->ftKerningEnabled && i)
|
||||
{
|
||||
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||
x_pos += pairDelta.x >> 6;
|
||||
}
|
||||
}
|
||||
|
||||
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
this->copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, color);
|
||||
|
||||
x_pos += glyphData->glyphAdvanceX;
|
||||
if (textStyle & FTGX_MONOSPACE_FAKE) {
|
||||
x_pos += monoAdvanceX - x_diff;
|
||||
}
|
||||
else {
|
||||
x_pos += glyphData->glyphAdvanceX;
|
||||
}
|
||||
++printed;
|
||||
}
|
||||
++i;
|
||||
@ -442,7 +464,7 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
||||
if(textStyle & FTGX_STYLE_MASK)
|
||||
{
|
||||
this->getOffset(text, &offset);
|
||||
this->drawTextFeature(x + x_offset, y + y_offset, this->getWidth(text), &offset, textStyle, color);
|
||||
this->drawTextFeature(x + x_offset, y + y_offset, this->getWidth(text, textStyle, monoPercent), &offset, textStyle, color);
|
||||
}
|
||||
|
||||
return printed;
|
||||
@ -451,9 +473,9 @@ uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t *text, GXColor color
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color, uint16_t textStyle)
|
||||
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color, uint16_t textStyle, int monoPercent)
|
||||
{
|
||||
return this->drawText(x, y, (wchar_t *)text, color, textStyle);
|
||||
return this->drawText(x, y, (wchar_t *)text, color, textStyle, monoPercent);
|
||||
}
|
||||
|
||||
void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color)
|
||||
@ -476,12 +498,16 @@ void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataO
|
||||
* @param text NULL terminated string to calculate.
|
||||
* @return The width of the text string in pixels.
|
||||
*/
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t *text)
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t *text, uint16_t textStyle, int monoPercent)
|
||||
{
|
||||
uint16_t strWidth = 0;
|
||||
FT_Vector pairDelta;
|
||||
|
||||
int i = 0;
|
||||
int monoAdvanceX = 0;
|
||||
if (textStyle & FTGX_MONOSPACE_FAKE) {
|
||||
monoAdvanceX = (int)this->ftMaxAdvanceX * monoPercent / 100;
|
||||
}
|
||||
while (text[i])
|
||||
{
|
||||
ftgxCharData* glyphData = NULL;
|
||||
@ -496,13 +522,18 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text)
|
||||
|
||||
if (glyphData != NULL)
|
||||
{
|
||||
if (this->ftKerningEnabled && (i > 0))
|
||||
{
|
||||
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||
strWidth += pairDelta.x >> 6;
|
||||
if (textStyle & FTGX_MONOSPACE_FAKE) {
|
||||
strWidth += monoAdvanceX;
|
||||
}
|
||||
else {
|
||||
if (this->ftKerningEnabled && (i > 0))
|
||||
{
|
||||
FT_Get_Kerning(ftFace, this->fontData[text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta);
|
||||
strWidth += pairDelta.x >> 6;
|
||||
}
|
||||
|
||||
strWidth += glyphData->glyphAdvanceX;
|
||||
strWidth += glyphData->glyphAdvanceX;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
@ -513,9 +544,9 @@ uint16_t FreeTypeGX::getWidth(wchar_t *text)
|
||||
*
|
||||
* \overload
|
||||
*/
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t const *text)
|
||||
uint16_t FreeTypeGX::getWidth(wchar_t const *text, uint16_t textStyle, int monoPercent)
|
||||
{
|
||||
return this->getWidth((wchar_t *)text);
|
||||
return this->getWidth((wchar_t *)text, textStyle, monoPercent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +87,10 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
|
||||
|
||||
#define FTGX_STYLE_UNDERLINE 0x1000
|
||||
#define FTGX_STYLE_STRIKE 0x2000
|
||||
#define FTGX_STYLE_MASK 0xf000
|
||||
#define FTGX_STYLE_MASK 0x7000
|
||||
|
||||
#define FTGX_MONOSPACE_FAKE 0x8000
|
||||
#define FTGX_MONOSPACE_MASK 0x8000
|
||||
|
||||
#define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE 0X0001
|
||||
#define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_DECAL 0X0002
|
||||
@ -126,6 +129,7 @@ class FreeTypeGX {
|
||||
private:
|
||||
FT_UInt ftPointSize; /**< Requested size of the rendered font. */
|
||||
bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */
|
||||
uint16_t ftMaxAdvanceX;
|
||||
uint8_t vertexIndex; /**< Vertex format descriptor index. */
|
||||
uint32_t compatibilityMode; /**< Compatibility mode for default tev operations and vertex descriptors. */
|
||||
std::map<wchar_t, ftgxCharData> fontData; /**< Map which holds the glyph data structures for the corresponding characters. */
|
||||
@ -154,11 +158,11 @@ class FreeTypeGX {
|
||||
void setVertexFormat(uint8_t vertexIndex);
|
||||
void setCompatibilityMode(uint32_t compatibilityMode);
|
||||
|
||||
uint16_t drawText(int16_t x, int16_t y, wchar_t *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL);
|
||||
uint16_t drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL);
|
||||
uint16_t drawText(int16_t x, int16_t y, wchar_t *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL, int monospacePercentage = 100);
|
||||
uint16_t drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL, int monospacePercentage = 100);
|
||||
|
||||
uint16_t getWidth(wchar_t *text);
|
||||
uint16_t getWidth(wchar_t const *text);
|
||||
uint16_t getWidth(wchar_t *text, uint16_t textStyling = FTGX_NULL, int monospacePercentage = 100);
|
||||
uint16_t getWidth(wchar_t const *text, uint16_t textStyling = FTGX_NULL, int monospacePercentage = 100);
|
||||
uint16_t getHeight(wchar_t *text);
|
||||
uint16_t getHeight(wchar_t const *text);
|
||||
void getOffset(wchar_t *text, ftgxDataOffset* offset);
|
||||
|
@ -689,6 +689,7 @@ class GuiText : public GuiElement
|
||||
//!Sets the FreeTypeGX style attributes
|
||||
//!\param s Style attributes
|
||||
void SetStyle(u16 s);
|
||||
void SetPseudoMonospace(int monoPercentage);
|
||||
//!Sets the text alignment
|
||||
//!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE)
|
||||
//!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
|
||||
@ -711,6 +712,7 @@ class GuiText : public GuiElement
|
||||
int textScrollDelay; //!< Scrolling speed
|
||||
u16 style; //!< FreeTypeGX style attributes
|
||||
bool wrap; //!< Wrapping toggle
|
||||
int monoPercentage;
|
||||
};
|
||||
|
||||
//!Display, manage, and manipulate tooltips in the GUI
|
||||
|
@ -22,7 +22,6 @@ static u16 presetStyle = 0;
|
||||
#define TEXT_SCROLL_DELAY 8
|
||||
#define TEXT_SCROLL_INITIAL_DELAY 6
|
||||
|
||||
|
||||
static const char *gettext(const char *msg)
|
||||
{
|
||||
return msg;
|
||||
@ -73,6 +72,7 @@ GuiText::GuiText(const char * t)
|
||||
style = presetStyle;
|
||||
maxWidth = presetMaxWidth;
|
||||
wrap = false;
|
||||
monoPercentage = 100;
|
||||
textDynNum = 0;
|
||||
textScroll = SCROLL_NONE;
|
||||
textScrollPos = 0;
|
||||
@ -214,7 +214,7 @@ int GuiText::GetTextWidth()
|
||||
|
||||
currentSize = size;
|
||||
}
|
||||
return fontSystem[size]->getWidth(text);
|
||||
return fontSystem[size]->getWidth(text, style, monoPercentage);
|
||||
}
|
||||
|
||||
void GuiText::SetWrap(bool w, int width)
|
||||
@ -267,6 +267,12 @@ void GuiText::SetStyle(u16 s)
|
||||
style = s;
|
||||
}
|
||||
|
||||
void GuiText::SetPseudoMonospace(int monoPercentage)
|
||||
{
|
||||
style |= FTGX_MONOSPACE_FAKE;
|
||||
this->monoPercentage = monoPercentage;
|
||||
}
|
||||
|
||||
void GuiText::SetAlignment(int hor, int vert)
|
||||
{
|
||||
style = 0;
|
||||
@ -351,7 +357,7 @@ void GuiText::Draw()
|
||||
|
||||
if(maxWidth == 0)
|
||||
{
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style);
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), text, c, style, monoPercentage);
|
||||
this->UpdateEffects();
|
||||
return;
|
||||
}
|
||||
@ -377,7 +383,7 @@ void GuiText::Draw()
|
||||
|
||||
if(text[ch] == ' ' || ch == textlen-1)
|
||||
{
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[linenum]) > maxWidth)
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[linenum], style, monoPercentage) > maxWidth)
|
||||
{
|
||||
if(lastSpace >= 0)
|
||||
{
|
||||
@ -415,7 +421,7 @@ void GuiText::Draw()
|
||||
int top = this->GetTop() + voffset;
|
||||
|
||||
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, textDyn[i], c, style, monoPercentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -425,13 +431,13 @@ void GuiText::Draw()
|
||||
textDyn[0] = wcsdup(text);
|
||||
int len = wcslen(textDyn[0]);
|
||||
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0], style, monoPercentage) > maxWidth)
|
||||
textDyn[0][--len] = 0;
|
||||
}
|
||||
|
||||
if(textScroll == SCROLL_HORIZONTAL)
|
||||
{
|
||||
if(fontSystem[currentSize]->getWidth(text) > maxWidth && (FrameTimer % textScrollDelay == 0))
|
||||
if(fontSystem[currentSize]->getWidth(text, style, monoPercentage) > maxWidth && (FrameTimer % textScrollDelay == 0))
|
||||
{
|
||||
if(textScrollInitialDelay)
|
||||
{
|
||||
@ -457,22 +463,22 @@ void GuiText::Draw()
|
||||
dynlen += 2;
|
||||
}
|
||||
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[0], style, monoPercentage) > maxWidth)
|
||||
{
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0], style, monoPercentage) > maxWidth)
|
||||
textDyn[0][--dynlen] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0]) < maxWidth && dynlen+1 < textlen)
|
||||
while(fontSystem[currentSize]->getWidth(textDyn[0], style, monoPercentage) < maxWidth && dynlen+1 < textlen)
|
||||
{
|
||||
textDyn[0][dynlen] = text[i++];
|
||||
textDyn[0][++dynlen] = 0;
|
||||
}
|
||||
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[0]) > maxWidth)
|
||||
if(fontSystem[currentSize]->getWidth(textDyn[0], style, monoPercentage) > maxWidth)
|
||||
textDyn[0][dynlen-2] = 0;
|
||||
else
|
||||
textDyn[0][dynlen-1] = 0;
|
||||
@ -480,7 +486,7 @@ void GuiText::Draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn[0], c, style);
|
||||
fontSystem[currentSize]->drawText(this->GetLeft(), this->GetTop(), textDyn[0], c, style, monoPercentage);
|
||||
}
|
||||
this->UpdateEffects();
|
||||
}
|
||||
|
@ -395,10 +395,12 @@ void HomeMenu ()
|
||||
|
||||
GuiText cycleText(NULL, 20, (GXColor){255, 255, 255, 255});
|
||||
cycleText.SetPosition(-215, -180);
|
||||
cycleText.SetPseudoMonospace(70);
|
||||
updateCyclesText(&cycleText);
|
||||
|
||||
GuiText fskipText(NULL, 20, (GXColor){255, 255, 255, 255});
|
||||
fskipText.SetPosition(-45, -180);
|
||||
fskipText.SetPseudoMonospace(70);
|
||||
updateFskipText(&fskipText);
|
||||
|
||||
GuiText cycleDecBtnTxt("-", 24, (GXColor){0, 0, 0, 255});
|
||||
|
Loading…
Reference in New Issue
Block a user