Skip to content

Commit

Permalink
Windows UWP: Enable color emoji rendering through DirectWrite
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Aug 6, 2023
1 parent 5533d5e commit ab685be
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
3 changes: 1 addition & 2 deletions Common/Render/Text/draw_text_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x,
if (text.empty())
return;

bool emoji = AnyEmojiInString(text.c_str(), text.size());

CacheKey key{ std::string(str), fontHash_ };
target.Flush(true);

Expand All @@ -263,6 +261,7 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x,
entry->lastUsedFrame = frameCount_;
} else {
DataFormat texFormat = use4444Format_ ? Draw::DataFormat::R4G4B4A4_UNORM_PACK16 : Draw::DataFormat::R8_UNORM;
bool emoji = AnyEmojiInString(text.c_str(), text.size());
if (emoji) {
texFormat = Draw::DataFormat::R8G8B8A8_UNORM;
}
Expand Down
15 changes: 12 additions & 3 deletions Common/Render/Text/draw_text_uwp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ void TextDrawerUWP::DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStrin

m_d2dContext->BeginDraw();
m_d2dContext->Clear();
m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush);
m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush, texFormat == Draw::DataFormat::R8G8B8A8_UNORM ? D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT : D2D1_DRAW_TEXT_OPTIONS_NONE);
m_d2dContext->EndDraw();

layout->Release();
Expand All @@ -395,11 +395,15 @@ void TextDrawerUWP::DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStrin
// because we need white. Well, we could using swizzle, but not all our backends support that.
if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) {
bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t));
bool swap = texFormat == Draw::DataFormat::R8G8B8A8_UNORM;
uint32_t *bitmapData32 = (uint32_t *)&bitmapData[0];
for (int y = 0; y < entry.bmHeight; y++) {
uint32_t *bmpLine = (uint32_t *)&map.bits[map.pitch * y];
for (int x = 0; x < entry.bmWidth; x++) {
uint8_t bAlpha = (uint8_t)(map.bits[map.pitch * y + x * 4] & 0xff);
bitmapData32[entry.bmWidth * y + x] = (bAlpha << 24) | 0x00ffffff;
uint32_t v = bmpLine[x];
if (swap)
v = (v & 0xFF00FF00) | ((v >> 16) & 0xFF) | ((v << 16) & 0xFF0000);
bitmapData32[entry.bmWidth * y + x] = v;
}
}
} else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16 || texFormat == Draw::DataFormat::R4G4B4A4_UNORM_PACK16) {
Expand Down Expand Up @@ -451,6 +455,7 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo
entry->lastUsedFrame = frameCount_;
} else {
DataFormat texFormat;

// For our purposes these are equivalent, so just choose the supported one. D3D can emulate them.
if (draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16) & FMT_TEXTURE)
texFormat = Draw::DataFormat::A4R4G4B4_UNORM_PACK16;
Expand All @@ -459,6 +464,10 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo
else
texFormat = Draw::DataFormat::R8G8B8A8_UNORM;

bool emoji = AnyEmojiInString(key.text.c_str(), key.text.size());
if (emoji)
texFormat = Draw::DataFormat::R8G8B8A8_UNORM;

entry = new TextStringEntry();

// Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format
Expand Down
2 changes: 1 addition & 1 deletion UI/MiscScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ void LogoScreen::render() {
int ppsspp_org_y = bounds.h / 2 + 130;
dc.DrawText("www.ppsspp.org", bounds.centerX(), ppsspp_org_y, textColor, ALIGN_CENTER);

#if !PPSSPP_PLATFORM(UWP)
#if !PPSSPP_PLATFORM(UWP) || defined(_DEBUG)
// Draw the graphics API, except on UWP where it's always D3D11
std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME);
#ifdef _DEBUG
Expand Down

0 comments on commit ab685be

Please sign in to comment.