Merge pull request #9218 from hrydgard/fix-smallwindow

Fix smallwindow mode
This commit is contained in:
Henrik Rydgård 2017-01-17 19:07:22 +07:00 committed by GitHub
commit ac2df14aa2
6 changed files with 96 additions and 53 deletions

View File

@ -130,22 +130,40 @@ bool Core_GetPowerSaving() {
return powerSaving;
}
#ifdef _WIN32
static int ScreenDPI() {
HDC screenDC = GetDC(nullptr);
int dotsPerInch = GetDeviceCaps(screenDC, LOGPIXELSY);
ReleaseDC(nullptr, screenDC);
return dotsPerInch;
}
#endif
static bool IsWindowSmall(int pixelWidth, int pixelHeight) {
// Can't take this from config as it will not be set if windows is maximized.
int w = (int)(pixelWidth * g_dpi_scale);
int h = (int)(pixelHeight * g_dpi_scale);
return g_Config.IsPortrait() ? (h < 480 + 80) : (w < 480 + 80);
}
// TODO: Feels like this belongs elsewhere.
bool UpdateScreenScale(int width, int height, bool smallWindow) {
bool UpdateScreenScale(int width, int height) {
bool smallWindow;
#ifdef _WIN32
// Use legacy DPI handling, because we still compile as XP compatible we don't get the new SDK, unless
// we do unholy tricks.
HDC screenDC = GetDC(nullptr);
double hPixelsPerInch = GetDeviceCaps(screenDC, LOGPIXELSY);
ReleaseDC(nullptr, screenDC);
g_dpi = hPixelsPerInch;
g_dpi = ScreenDPI();
g_dpi_scale = 96.0f / g_dpi;
#else
g_dpi = 96;
g_dpi_scale = 1.0f;
#endif
smallWindow = IsWindowSmall(width, height);
if (smallWindow) {
g_dpi /= 2;
g_dpi_scale *= 2.0f;
}
pixel_in_dps = 1.0f / g_dpi_scale;
int new_dp_xres = width * g_dpi_scale;

View File

@ -47,7 +47,7 @@ bool Core_IsInactive();
void Core_WaitInactive();
void Core_WaitInactive(int milliseconds);
bool UpdateScreenScale(int width, int height, bool smallWindow);
bool UpdateScreenScale(int width, int height);
// Don't run the core when minimized etc.
void Core_NotifyWindowHidden(bool hidden);

View File

@ -273,7 +273,7 @@ void GameSettingsScreen::CreateViews() {
static const char *quality[] = { "Low", "Medium", "High"};
PopupMultiChoice *beziersChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iSplineBezierQuality, gr->T("LowCurves", "Spline/Bezier curves quality"), quality, 0, ARRAY_SIZE(quality), gr->GetName(), screenManager()));
beziersChoice->OnChoice.Add([=](EventParams &e) {
if (&g_Config.iSplineBezierQuality != 0) {
if (g_Config.iSplineBezierQuality != 0) {
settingInfo_->Show(gr->T("LowCurves Tip", "This option will significantly improve/reduce the quality of rendered splines and bezier curves"), e.v);
}
return UI::EVENT_CONTINUE;

View File

@ -204,15 +204,6 @@ namespace MainWindow
rcOuter.top = g_Config.iWindowY;
}
static bool IsWindowSmall() {
// Can't take this from config as it will not be set if windows is maximized.
RECT rc;
GetWindowRect(hwndMain, &rc);
int width = (int)((rc.right - rc.left) * g_dpi_scale);
int height = (int)((rc.bottom - rc.top) * g_dpi_scale);
return g_Config.IsPortrait() ? (height < 480 + 80) : (width < 480 + 80);
}
void SetWindowSize(int zoom) {
AssertCurrentThreadName("Main");
RECT rc, rcOuter;
@ -281,7 +272,7 @@ namespace MainWindow
PSP_CoreParameter().pixelHeight = height;
}
if (UpdateScreenScale(width, height, IsWindowSmall())) {
if (UpdateScreenScale(width, height)) {
NativeMessageReceived("gpu resized", "");
}

View File

@ -41,8 +41,32 @@ enum {
MAX_TEXT_HEIGHT = 512
};
struct TextDrawerFontContext {
class TextDrawerFontContext {
public:
~TextDrawerFontContext() {
Destroy();
}
void Create() {
if (hFont) {
Destroy();
}
// TODO: Should the 72 really be 96? Oh well...
int nHeight = -MulDiv(height, g_dpi, 72);
hFont = CreateFont(nHeight, 0, 0, 0, bold, 0,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
VARIABLE_PITCH, fname.c_str());
}
void Destroy() {
DeleteObject(hFont);
hFont = 0;
}
HFONT hFont;
std::wstring fname;
int height;
int bold;
};
struct TextDrawerContext {
@ -55,6 +79,7 @@ TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(nullpt
// These probably shouldn't be state.
fontScaleX_ = 1.0f;
fontScaleY_ = 1.0f;
last_dpi_scale_ = g_dpi_scale;
ctx_ = new TextDrawerContext();
ctx_->hDC = CreateCompatibleDC(NULL);
@ -75,22 +100,12 @@ TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(nullpt
}
TextDrawer::~TextDrawer() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
ClearCache();
for (auto iter = fontMap_.begin(); iter != fontMap_.end(); ++iter) {
DeleteObject(iter->second->hFont);
delete iter->second;
}
fontMap_.clear();
DeleteObject(ctx_->hbmBitmap);
DeleteDC(ctx_->hDC);
delete ctx_;
}
@ -112,17 +127,12 @@ uint32_t TextDrawer::SetFont(const char *fontName, int size, int flags) {
fname = L"Tahoma";
TextDrawerFontContext *font = new TextDrawerFontContext();
font->bold = FW_LIGHT;
font->height = size;
font->fname = fname;
font->Create();
float textScale = 1.0f;
// TODO: Should the 72 really be 96? Oh well...
INT nHeight = -MulDiv( size, (INT)(GetDeviceCaps(ctx_->hDC, LOGPIXELSY) * textScale), 72 );
int dwBold = FW_LIGHT; ///FW_BOLD
font->hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
VARIABLE_PITCH, fname.c_str());
fontMap_[fontHash] = font;
fontMap_[fontHash] = std::unique_ptr<TextDrawerFontContext>(font);
fontHash_ = fontHash;
return fontHash;
}
@ -296,6 +306,12 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
target.Flush(true);
}
void TextDrawer::RecreateFonts() {
for (auto &iter : fontMap_) {
iter.second->Create();
}
}
#else
TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(NULL) {
@ -304,12 +320,7 @@ TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(NULL)
}
TextDrawer::~TextDrawer() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
ClearCache();
}
uint32_t TextDrawer::SetFont(const char *fontName, int size, int flags) {
@ -340,6 +351,10 @@ void TextDrawer::SetFont(uint32_t fontHandle) {
}
void TextDrawer::RecreateFonts() {
}
void TextDrawer::MeasureString(const char *str, float *w, float *h) {
MeasureString(str, strlen(str), w, h);
}
@ -441,6 +456,15 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
#endif
void TextDrawer::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawer::WrapString(std::string &out, const char *str, float maxW) {
TextDrawerWordWrapper wrapper(this, str, maxW);
out = wrapper.Wrapped();
@ -476,7 +500,14 @@ void TextDrawer::DrawStringRect(DrawBuffer &target, const char *str, const Bound
void TextDrawer::OncePerFrame() {
frameCount_++;
// Use a prime number to reduce clashing with other rhythms
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
if (g_dpi_scale != last_dpi_scale_) {
last_dpi_scale_ = g_dpi_scale;
ClearCache();
RecreateFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {

View File

@ -46,7 +46,7 @@ enum {
// Internal struct but all details in .cpp file (pimpl to avoid pulling in excessive headers here)
struct TextDrawerContext;
struct TextDrawerFontContext;
class TextDrawerFontContext;
class TextDrawer {
public:
@ -68,21 +68,24 @@ public:
private:
Draw::DrawContext *thin3d_;
void ClearCache();
void RecreateFonts(); // On DPI change
void WrapString(std::string &out, const char *str, float maxWidth);
int frameCount_;
float fontScaleX_;
float fontScaleY_;
float last_dpi_scale_;
TextDrawerContext *ctx_;
#ifdef USING_QT_UI
#if defined(USING_QT_UI)
std::map<uint32_t, QFont *> fontMap_;
#else
std::map<uint32_t, TextDrawerFontContext *> fontMap_;
#elif defined(_WIN32)
std::map<uint32_t, std::unique_ptr<TextDrawerFontContext>> fontMap_;
#endif
uint32_t fontHash_;
// The key is the CityHash of the string xor the fontHash_.
std::map<uint32_t, std::unique_ptr<TextStringEntry> > cache_;
std::map<uint32_t, std::unique_ptr<TextMeasureEntry> > sizeCache_;
std::map<uint32_t, std::unique_ptr<TextStringEntry>> cache_;
std::map<uint32_t, std::unique_ptr<TextMeasureEntry>> sizeCache_;
};