Skip to content

Commit

Permalink
Improved DPI awareness
Browse files Browse the repository at this point in the history
  • Loading branch information
aardappel committed Apr 6, 2017
1 parent 186b07d commit 7ede87a
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ struct Document {
if (image.trefc) {
fos.Write("I", 1);
sos.WriteDouble(image.display_scale);
wxImage im = image.bm.ConvertToImage();
wxImage im = image.bm_orig.ConvertToImage();
im.SaveFile(fos, wxBITMAP_TYPE_PNG);
image.savedindex = realindex++;
}
Expand Down
37 changes: 31 additions & 6 deletions src/myapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,38 @@ struct MyApp : wxApp {
#ifdef __WXMSW__
// wxWidgets should really be doing this itself, but it doesn't (or expects you to
// want to use a manifest), so we have to call it ourselves.
typedef BOOL (*SetProcessDPIAwareFunc)();
auto udll = LoadLibrary(L"User32.dll");
if (udll) {
auto f = (SetProcessDPIAwareFunc)GetProcAddress(udll, "SetProcessDPIAware");
if (f) f();
FreeLibrary(udll);
#ifndef DPI_ENUMS_DECLARED
typedef enum PROCESS_DPI_AWARENESS
{
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
#endif

typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void);
typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
HMODULE shcore = LoadLibraryA("Shcore.dll");
SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness = NULL;
if (shcore) {
SetProcessDpiAwareness =
(SETPROCESSDPIAWARENESS_T)GetProcAddress(shcore, "SetProcessDpiAwareness");
}
HMODULE user32 = LoadLibraryA("User32.dll");
SETPROCESSDPIAWARE_T SetProcessDPIAware = NULL;
if (user32) {
SetProcessDPIAware =
(SETPROCESSDPIAWARE_T)GetProcAddress(user32, "SetProcessDPIAware");
}

if (SetProcessDpiAwareness) {
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
} else if (SetProcessDPIAware) {
SetProcessDPIAware();
}

if (user32) FreeLibrary(user32);
if (shcore) FreeLibrary(shcore);
#endif

locale.Init();
Expand Down
14 changes: 8 additions & 6 deletions src/myframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ struct MyFrame : wxFrame {
csf = GetContentScaleFactor();
wxLogMessage(L"content scale: %f", csf);
#ifdef __WXMSW__
// On Windows, I get csf == 3 on my 4K screen. With this factor set, bitmaps display
// At their same physical sizes as when TreeSheets was a non-DPI-aware app, and
// extra resolution is used.
// On Windows, I get csf == 1.25, as indicated in the display properties.
// With this factor set, bitmaps display. At their same physical sizes as when
// TreeSheets was a non-DPI-aware app, and extra resolution is used.
#endif
#ifdef __WXMAC__
// Typically csf == 2 on a retina mac. But on the mac, unlike Windows, image rendering
Expand Down Expand Up @@ -135,6 +135,7 @@ struct MyFrame : wxFrame {
// FIXME: what is the correct way to exit?
}
foldicon = wxBitmap(foldiconi);
ScaleBitmap(foldicon, csf / 3.0, foldicon);

if (sys->singletray)
tbi.Connect(wxID_ANY, wxEVT_TASKBAR_LEFT_UP,
Expand Down Expand Up @@ -587,15 +588,16 @@ struct MyFrame : wxFrame {

wxString iconpath =
GetPath(iconset ? L"images/webalys/toolbar/" : L"images/nuvola/toolbar/");
tb->SetToolBitmapSize((iconset ? wxSize(18, 18) : wxSize(22, 22)) * csf);
auto sz = (iconset ? wxSize(18, 18) : wxSize(22, 22)) * csf;
tb->SetToolBitmapSize(sz);

double sc = iconset ? 1.0 : 22.0 / 48.0;

auto AddTBIcon = [&](const wxChar *name, int action, wxString file) {
wxBitmap bm;
if (bm.LoadFile(file, wxBITMAP_TYPE_PNG)) {
auto ns = bm.GetSize() * csf * sc;
bm = wxBitmap(bm.ConvertToImage().Scale(ns.GetX(), ns.GetY(), wxIMAGE_QUALITY_HIGH));
auto ns = csf * sc;
ScaleBitmap(bm, ns, bm);
/*
wxBitmap sbm;
sbm.CreateScaled(bm.GetWidth() / csf, bm.GetHeight() / csf, bm.GetDepth(), csf);
Expand Down
22 changes: 15 additions & 7 deletions src/mywxtools.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ struct ImagePopup : wxVListBoxComboPopup {
};

struct ImageDropdown : wxOwnerDrawnComboBox {
Vector<wxBitmap *> bitmaps; // FIXME: delete these somewhere
// FIXME: delete these somewhere
Vector<wxBitmap *> bitmaps_display;
wxArrayString as;
double csf;
const int image_space = 22;
Expand All @@ -137,9 +138,11 @@ struct ImageDropdown : wxOwnerDrawnComboBox {
csf = _csf;
wxString f = wxFindFirstFile(path + L"*.*");
while (!f.empty()) {
wxBitmap *bm = new wxBitmap();
if (bm->LoadFile(f, wxBITMAP_TYPE_PNG)) {
bitmaps.push() = bm;
wxBitmap bm;
if (bm.LoadFile(f, wxBITMAP_TYPE_PNG)) {
auto dbm = new wxBitmap();
ScaleBitmap(bm, csf / dd_icon_res_scale, *dbm);
bitmaps_display.push() = dbm;
as.Add(f);
}
f = wxFindNextFile();
Expand All @@ -159,8 +162,13 @@ struct ImageDropdown : wxOwnerDrawnComboBox {
}

void OnDrawItem(wxDC &dc, const wxRect &rect, int item, int flags) const {
auto bm = bitmaps[item];
sys->ImageDraw(bm, dc, rect.x + 3 * csf, rect.y + 3 * csf,
bm->GetWidth() * csf / dd_icon_res_scale, bm->GetHeight() * csf / dd_icon_res_scale);
auto bm = bitmaps_display[item];
sys->ImageDraw(bm, dc, rect.x + 3 * csf, rect.y + 3 * csf);
}
};

static void ScaleBitmap(const wxBitmap &src, double sc, wxBitmap &dest) {
dest = wxBitmap(src.ConvertToImage().Scale(src.GetWidth() * sc, src.GetHeight() * sc,
wxIMAGE_QUALITY_HIGH));
}

35 changes: 18 additions & 17 deletions src/system.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

struct Image {
wxBitmap bm;
wxBitmap bm_orig;
wxBitmap bm_display;

int trefc;
int savedindex;
Expand All @@ -12,11 +13,18 @@ struct Image {
// This is all relative to GetContentScalingFactor.
double display_scale;

Image(wxBitmap _bm, int _cs, double _sc) : bm(_bm), checksum(_cs), display_scale(_sc) {}
Image(wxBitmap _bm, int _cs, double _sc) : bm_orig(_bm), checksum(_cs), display_scale(_sc) {}

void Scale(double sc) {
bm = wxBitmap(bm.ConvertToImage().Scale(bm.GetWidth() * sc, bm.GetHeight() * sc,
wxIMAGE_QUALITY_HIGH));
ScaleBitmap(bm_orig, sc, bm_orig);
bm_display = wxNullBitmap;
}

wxBitmap &Display() {
if (!bm_display.IsOk()) {
ScaleBitmap(bm_orig, 1.0 / display_scale * sys->frame->csf, bm_display);
}
return bm_display;
}
};

Expand Down Expand Up @@ -537,20 +545,13 @@ struct System {
return imagelist.size() - 1;
}

void ImageSize(const std::pair<wxBitmap *, double> &bs, int &xs, int &ys) {
if (!bs.first) return;
xs = bs.first->GetWidth() * frame->csf / bs.second;
ys = bs.first->GetHeight() * frame->csf / bs.second;
void ImageSize(wxBitmap *bm, int &xs, int &ys) {
if (!bm) return;
xs = bm->GetWidth();
ys = bm->GetHeight();
}

void ImageDraw(wxBitmap *bm, wxDC &dc, int x, int y,
int xs, int ys) {
double xscale = xs / (double)bm->GetWidth();
double yscale = ys / (double)bm->GetHeight();
double prevx, prevy;
dc.GetUserScale(&prevx, &prevy);
dc.SetUserScale(xscale * prevx, yscale * prevy);
dc.DrawBitmap(*bm, x / xscale, y / yscale);
dc.SetUserScale(prevx, prevy);
void ImageDraw(wxBitmap *bm, wxDC &dc, int x, int y) {
dc.DrawBitmap(*bm, x, y);
}
};
12 changes: 5 additions & 7 deletions src/text.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ struct Text {
WasEdited();
}

std::pair<wxBitmap *, double> DisplayImage() {
wxBitmap * DisplayImage() {
return cell->grid && cell->grid->folded
? std::make_pair(&sys->frame->foldicon, 3.0)
: (image
? std::make_pair(&image->bm, image->display_scale)
: std::make_pair(nullptr, 1.0));
? &sys->frame->foldicon
: (image ? &image->Display() : nullptr);
}

size_t EstimatedMemoryUse() {
Expand Down Expand Up @@ -181,8 +179,8 @@ struct Text {
if (!cell->tiny) sys->ImageSize(DisplayImage(), ixs, iys);

if (ixs && iys) {
sys->ImageDraw(DisplayImage().first, dc, bx + 1 + g_margin_extra,
by + (cell->tys - iys) / 2 + g_margin_extra, ixs, iys);
sys->ImageDraw(DisplayImage(), dc, bx + 1 + g_margin_extra,
by + (cell->tys - iys) / 2 + g_margin_extra);
ixs += 2;
iys += 2;
}
Expand Down

0 comments on commit 7ede87a

Please sign in to comment.