mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
UI: Support a second texture for just fonts.
Will still allow using fonts between both.
This commit is contained in:
parent
593241b50f
commit
eb81d5b30b
7 changed files with 91 additions and 36 deletions
|
@ -14,11 +14,10 @@
|
|||
#include "Common/Log.h"
|
||||
#include "Common/StringUtils.h"
|
||||
|
||||
DrawBuffer::DrawBuffer() : count_(0), atlas(0) {
|
||||
DrawBuffer::DrawBuffer() {
|
||||
verts_ = new Vertex[MAX_VERTS];
|
||||
fontscalex = 1.0f;
|
||||
fontscaley = 1.0f;
|
||||
inited_ = false;
|
||||
}
|
||||
|
||||
DrawBuffer::~DrawBuffer() {
|
||||
|
@ -482,7 +481,9 @@ float AtlasWordWrapper::MeasureWidth(const char *str, size_t bytes) {
|
|||
}
|
||||
|
||||
void DrawBuffer::MeasureTextCount(FontID font, const char *text, int count, float *w, float *h) {
|
||||
const AtlasFont *atlasfont = atlas->getFont(font);
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
atlasfont = atlas->getFont(font);
|
||||
if (!atlasfont) {
|
||||
*w = 0.0f;
|
||||
*h = 0.0f;
|
||||
|
@ -533,7 +534,9 @@ void DrawBuffer::MeasureTextRect(FontID font_id, const char *text, int count, co
|
|||
std::string toMeasure = std::string(text, count);
|
||||
int wrap = align & (FLAG_WRAP_TEXT | FLAG_ELLIPSIZE_TEXT);
|
||||
if (wrap) {
|
||||
const AtlasFont *font = atlas->getFont(font_id);
|
||||
const AtlasFont *font = fontAtlas_->getFont(font_id);
|
||||
if (!font)
|
||||
font = atlas->getFont(font_id);
|
||||
if (!font) {
|
||||
*w = 0.0f;
|
||||
*h = 0.0f;
|
||||
|
@ -582,7 +585,9 @@ void DrawBuffer::DrawTextRect(FontID font, const char *text, float x, float y, f
|
|||
|
||||
std::string toDraw = text;
|
||||
int wrap = align & (FLAG_WRAP_TEXT | FLAG_ELLIPSIZE_TEXT);
|
||||
const AtlasFont *atlasfont = atlas->getFont(font);
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
atlasfont = atlas->getFont(font);
|
||||
if (wrap && atlasfont) {
|
||||
AtlasWordWrapper wrapper(*atlasfont, fontscalex, toDraw.c_str(), w, wrap);
|
||||
toDraw = wrapper.Wrapped();
|
||||
|
@ -624,7 +629,9 @@ void DrawBuffer::DrawText(FontID font, const char *text, float x, float y, Color
|
|||
}
|
||||
}
|
||||
|
||||
const AtlasFont *atlasfont = atlas->getFont(font);
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
atlasfont = atlas->getFont(font);
|
||||
if (!atlasfont)
|
||||
return;
|
||||
unsigned int cval;
|
||||
|
|
|
@ -110,6 +110,10 @@ public:
|
|||
atlas = _atlas;
|
||||
}
|
||||
const Atlas *GetAtlas() const { return atlas; }
|
||||
void SetFontAtlas(const Atlas *_atlas) {
|
||||
fontAtlas_ = _atlas;
|
||||
}
|
||||
const Atlas *GetFontAtlas() const { return fontAtlas_; }
|
||||
bool MeasureImage(ImageID atlas_image, float *w, float *h);
|
||||
void DrawImage(ImageID atlas_image, float x, float y, float scale, Color color = COLOR(0xFFFFFF), int align = ALIGN_TOPLEFT);
|
||||
|
||||
|
@ -189,18 +193,18 @@ private:
|
|||
float alpha_ = 1.0f;
|
||||
std::vector<float> alphaStack_;
|
||||
|
||||
Draw::DrawContext *draw_;
|
||||
Draw::Buffer *vbuf_;
|
||||
Draw::Pipeline *pipeline_;
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
Draw::Buffer *vbuf_ = nullptr;
|
||||
Draw::Pipeline *pipeline_ = nullptr;
|
||||
|
||||
Vertex *verts_;
|
||||
int count_;
|
||||
const Atlas *atlas;
|
||||
int count_ = 0;
|
||||
const Atlas *atlas = nullptr;
|
||||
const Atlas *fontAtlas_ = nullptr;
|
||||
|
||||
bool inited_;
|
||||
float fontscalex;
|
||||
float fontscaley;
|
||||
bool inited_ = false;
|
||||
float fontscalex = 1.0f;
|
||||
float fontscaley = 1.0f;
|
||||
|
||||
float curZ_ = 0.0f;
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ void UIContext::BeginFrame() {
|
|||
if (!uitexture_) {
|
||||
uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM, false);
|
||||
_dbg_assert_msg_(uitexture_, "Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
|
||||
if (!fontTexture_) {
|
||||
fontTexture_ = CreateTextureFromFile(draw_, "font_atlas.zim", ImageFileType::ZIM, false);
|
||||
if (!fontTexture_)
|
||||
WARN_LOG(SYSTEM, "Failed to load font_atlas.zim");
|
||||
}
|
||||
}
|
||||
uidrawbufferTop_->SetCurZ(0.0f);
|
||||
uidrawbuffer_->SetCurZ(0.0f);
|
||||
|
@ -70,6 +75,14 @@ void UIContext::RebindTexture() const {
|
|||
draw_->BindTexture(0, uitexture_->GetTexture());
|
||||
}
|
||||
|
||||
void UIContext::BindFontTexture() const {
|
||||
// Fall back to the UI texture, in case they have an old atlas.
|
||||
if (fontTexture_)
|
||||
draw_->BindTexture(0, fontTexture_->GetTexture());
|
||||
else if (uitexture_)
|
||||
draw_->BindTexture(0, uitexture_->GetTexture());
|
||||
}
|
||||
|
||||
void UIContext::Flush() {
|
||||
if (uidrawbuffer_) {
|
||||
uidrawbuffer_->Flush();
|
||||
|
@ -190,14 +203,22 @@ void UIContext::MeasureTextRect(const UI::FontStyle &style, float scaleX, float
|
|||
|
||||
void UIContext::DrawText(const char *str, float x, float y, uint32_t color, int align) {
|
||||
if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) {
|
||||
// Use the font texture if this font is in that texture instead.
|
||||
bool useFontTexture = Draw()->GetFontAtlas()->getFont(fontStyle_->atlasFont) != nullptr;
|
||||
if (useFontTexture) {
|
||||
Flush();
|
||||
BindFontTexture();
|
||||
}
|
||||
float sizeFactor = (float)fontStyle_->sizePts / 24.0f;
|
||||
Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor);
|
||||
Draw()->DrawText(fontStyle_->atlasFont, str, x, y, color, align);
|
||||
if (useFontTexture)
|
||||
Flush();
|
||||
} else {
|
||||
textDrawer_->SetFontScale(fontScaleX_, fontScaleY_);
|
||||
textDrawer_->DrawString(*Draw(), str, x, y, color, align);
|
||||
RebindTexture();
|
||||
}
|
||||
RebindTexture();
|
||||
}
|
||||
|
||||
void UIContext::DrawTextShadow(const char *str, float x, float y, uint32_t color, int align) {
|
||||
|
@ -208,17 +229,25 @@ void UIContext::DrawTextShadow(const char *str, float x, float y, uint32_t color
|
|||
|
||||
void UIContext::DrawTextRect(const char *str, const Bounds &bounds, uint32_t color, int align) {
|
||||
if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) {
|
||||
// Use the font texture if this font is in that texture instead.
|
||||
bool useFontTexture = Draw()->GetFontAtlas()->getFont(fontStyle_->atlasFont) != nullptr;
|
||||
if (useFontTexture) {
|
||||
Flush();
|
||||
BindFontTexture();
|
||||
}
|
||||
float sizeFactor = (float)fontStyle_->sizePts / 24.0f;
|
||||
Draw()->SetFontScale(fontScaleX_ * sizeFactor, fontScaleY_ * sizeFactor);
|
||||
Draw()->DrawTextRect(fontStyle_->atlasFont, str, bounds.x, bounds.y, bounds.w, bounds.h, color, align);
|
||||
if (useFontTexture)
|
||||
Flush();
|
||||
} else {
|
||||
textDrawer_->SetFontScale(fontScaleX_, fontScaleY_);
|
||||
Bounds rounded = bounds;
|
||||
rounded.x = floorf(rounded.x);
|
||||
rounded.y = floorf(rounded.y);
|
||||
textDrawer_->DrawStringRect(*Draw(), str, rounded, color, align);
|
||||
RebindTexture();
|
||||
}
|
||||
RebindTexture();
|
||||
}
|
||||
|
||||
void UIContext::DrawTextShadowRect(const char *str, const Bounds &bounds, uint32_t color, int align) {
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
void Flush();
|
||||
|
||||
void RebindTexture() const;
|
||||
void BindFontTexture() const;
|
||||
|
||||
// TODO: Support transformed bounds using stencil
|
||||
void PushScissor(const Bounds &bounds);
|
||||
|
@ -112,6 +113,7 @@ private:
|
|||
Draw::Pipeline *ui_pipeline_ = nullptr;
|
||||
Draw::Pipeline *ui_pipeline_notex_ = nullptr;
|
||||
std::unique_ptr<ManagedTexture> uitexture_;
|
||||
std::unique_ptr<ManagedTexture> fontTexture_;
|
||||
|
||||
DrawBuffer *uidrawbuffer_ = nullptr;
|
||||
DrawBuffer *uidrawbufferTop_ = nullptr;
|
||||
|
|
|
@ -77,15 +77,14 @@ struct Style {
|
|||
};
|
||||
|
||||
struct FontStyle {
|
||||
FontStyle() : atlasFont(0), sizePts(0), flags(0) {}
|
||||
FontStyle(const char *name, int size) : atlasFont(0), fontName(name), sizePts(size), flags(0) {}
|
||||
FontStyle(FontID atlasFnt, const char *name, int size) : atlasFont(atlasFnt), fontName(name), sizePts(size), flags(0) {}
|
||||
FontStyle() {}
|
||||
FontStyle(FontID atlasFnt, const char *name, int size) : atlasFont(atlasFnt), fontName(name), sizePts(size) {}
|
||||
|
||||
FontID atlasFont;
|
||||
FontID atlasFont{ nullptr };
|
||||
// For native fonts:
|
||||
std::string fontName;
|
||||
int sizePts;
|
||||
int flags;
|
||||
int sizePts = 0;
|
||||
int flags = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1154,6 +1154,8 @@ static void DrawCrashDump(UIContext *ctx) {
|
|||
sysName.c_str(), sysVersion, GetCompilerABI()
|
||||
);
|
||||
|
||||
if (ctx->Draw()->GetFontAtlas()->getFont(ubuntu24))
|
||||
ctx->BindFontTexture();
|
||||
ctx->Draw()->SetFontScale(.7f, .7f);
|
||||
ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF);
|
||||
y += 140;
|
||||
|
@ -1205,6 +1207,8 @@ BREAK
|
|||
CheatsInEffect() ? "Y" : "N", HLEPlugins::HasEnabled() ? "Y" : "N");
|
||||
|
||||
ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF);
|
||||
ctx->Flush();
|
||||
ctx->RebindTexture();
|
||||
}
|
||||
|
||||
static void DrawAudioDebugStats(DrawBuffer *draw2d, const Bounds &bounds) {
|
||||
|
|
|
@ -132,8 +132,8 @@
|
|||
// The new UI framework, for initialization
|
||||
|
||||
static UI::Theme ui_theme;
|
||||
|
||||
Atlas g_ui_atlas;
|
||||
static Atlas g_ui_atlas;
|
||||
static Atlas g_font_atlas;
|
||||
|
||||
#if PPSSPP_ARCH(ARM) && defined(__ANDROID__)
|
||||
#include "../../android/jni/ArmEmitterTest.h"
|
||||
|
@ -900,6 +900,22 @@ static void UIThemeInit() {
|
|||
void RenderOverlays(UIContext *dc, void *userdata);
|
||||
bool CreateGlobalPipelines();
|
||||
|
||||
static void LoadAtlasMetadata(Atlas &metadata, const char *filename, bool required) {
|
||||
size_t atlas_data_size = 0;
|
||||
if (!metadata.IsMetadataLoaded()) {
|
||||
const uint8_t *atlas_data = VFSReadFile(filename, &atlas_data_size);
|
||||
bool load_success = atlas_data != nullptr && metadata.Load(atlas_data, atlas_data_size);
|
||||
if (!load_success) {
|
||||
if (required)
|
||||
ERROR_LOG(G3D, "Failed to load %s - graphics will be broken", filename);
|
||||
else
|
||||
WARN_LOG(G3D, "Failed to load %s", filename);
|
||||
// Stumble along with broken visuals instead of dying...
|
||||
}
|
||||
delete[] atlas_data;
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
INFO_LOG(SYSTEM, "NativeInitGraphics");
|
||||
|
||||
|
@ -914,20 +930,14 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Load the atlas.
|
||||
size_t atlas_data_size = 0;
|
||||
if (!g_ui_atlas.IsMetadataLoaded()) {
|
||||
const uint8_t *atlas_data = VFSReadFile("ui_atlas.meta", &atlas_data_size);
|
||||
bool load_success = atlas_data != nullptr && g_ui_atlas.Load(atlas_data, atlas_data_size);
|
||||
if (!load_success) {
|
||||
ERROR_LOG(G3D, "Failed to load ui_atlas.meta - graphics will be broken.");
|
||||
// Stumble along with broken visuals instead of dying.
|
||||
}
|
||||
delete[] atlas_data;
|
||||
}
|
||||
// Load any missing atlas.
|
||||
LoadAtlasMetadata(g_ui_atlas, "ui_atlas.meta", true);
|
||||
LoadAtlasMetadata(g_font_atlas, "font_atlas.meta", g_ui_atlas.num_fonts == 0);
|
||||
|
||||
ui_draw2d.SetAtlas(&g_ui_atlas);
|
||||
ui_draw2d.SetFontAtlas(&g_font_atlas);
|
||||
ui_draw2d_front.SetAtlas(&g_ui_atlas);
|
||||
ui_draw2d_front.SetFontAtlas(&g_font_atlas);
|
||||
|
||||
UIThemeInit();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue