wasm: validate kicad hi-dpi scaling

This commit is contained in:
Viktor Vaczi 2026-03-22 12:48:05 +01:00
commit a49ed49d5d
12 changed files with 490 additions and 30 deletions

View file

@ -146,7 +146,8 @@ all: minimal_test.html \
$(S)/maximize/maximize_test.html \
$(S)/earlysize/earlysize_test.html \
$(S)/threadpool/threadpool_test.html \
$(S)/logerror/logerror_test.html
$(S)/logerror/logerror_test.html \
$(S)/retinascale/retinascale_test.html
# Main test app (uses GL)
minimal_test.o: minimal_test.cpp
@ -493,8 +494,17 @@ earlysize: $(S)/earlysize/earlysize_test.html
threadpool: $(S)/threadpool/threadpool_test.html
logerror: $(S)/logerror/logerror_test.html
# Retina/HiDPI scaling test
$(S)/retinascale/retinascale_test.o: $(S)/retinascale/retinascale_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/retinascale/retinascale_test.html: $(S)/retinascale/retinascale_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
retinascale: $(S)/retinascale/retinascale_test.html
clean:
rm -f minimal_test.o minimal_test.html minimal_test.js minimal_test.wasm
rm -f $(S)/*/*.o $(S)/*/*.html $(S)/*/*.js $(S)/*/*.wasm
.PHONY: all clean menu clipboard filedialog layout aui toolbar grid dialog timer tree dataview htmlwin stc print dnd propgrid pickers collapsible listctrl infobar dataviewvirtual auinotebook wizard gridedit calendar gridrenderers printpreview bitmapbuttons specialized validators ownerdrawn popup xml wasmedge fontenum textdecor bitmask regions maximize earlysize threadpool logerror
.PHONY: all clean menu clipboard filedialog layout aui toolbar grid dialog timer tree dataview htmlwin stc print dnd propgrid pickers collapsible listctrl infobar dataviewvirtual auinotebook wizard gridedit calendar gridrenderers printpreview bitmapbuttons specialized validators ownerdrawn popup xml wasmedge fontenum textdecor bitmask regions maximize earlysize threadpool logerror retinascale

View file

@ -79,11 +79,10 @@
var canvas = document.createElement('canvas');
canvas.id = 'canvas';
canvas.style.display = 'none';
// Set both CSS display size and internal pixel resolution
// wx.js owns the backing-store size via setWindowRect(); keep the HTML
// shell responsible only for the CSS size.
var width = window.innerWidth;
var height = window.innerHeight;
canvas.width = width;
canvas.height = height;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
canvas.oncontextmenu = function() { event.preventDefault(); };

View file

@ -0,0 +1,109 @@
// Retina/HiDPI Scaling Test
// Verifies that bitmaps render at correct logical pixel sizes regardless of
// display scale factor. Icons should appear the same size on 1x and 2x displays.
#include "wx/wx.h"
#include "wx/dcmemory.h"
// Create a colored icon bitmap at the given size with scaleFactor=1.0
// (matching how KiCad creates toolbar icons via KiScaledBitmap)
wxBitmap CreateTestIcon(const wxColour& color, int size)
{
wxBitmap bmp(size, size);
wxMemoryDC dc(bmp);
dc.SetBackground(wxBrush(wxColour(240, 240, 240)));
dc.Clear();
dc.SetPen(wxPen(*wxBLACK, 1));
dc.SetBrush(wxBrush(color));
dc.DrawRectangle(1, 1, size - 2, size - 2);
// Draw a diagonal cross to make scaling visible
dc.SetPen(wxPen(color, 2));
dc.DrawLine(2, 2, size - 2, size - 2);
dc.DrawLine(size - 2, 2, 2, size - 2);
return bmp;
}
class RetinaScaleFrame : public wxFrame
{
public:
RetinaScaleFrame() : wxFrame(nullptr, wxID_ANY, "Retina Scale Test",
wxDefaultPosition, wxSize(800, 600))
{
// Log scale factor info
double contentSF = GetContentScaleFactor();
double dpiSF = GetDPIScaleFactor();
wxLogMessage("ContentScaleFactor: %.1f, DPIScaleFactor: %.1f", contentSF, dpiSF);
wxPanel* panel = new wxPanel(this);
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
// Create a toolbar with icons at different sizes
wxToolBar* toolbar = CreateToolBar();
toolbar->SetName("toolbar");
wxBitmap icon16 = CreateTestIcon(*wxRED, 16);
wxBitmap icon24 = CreateTestIcon(*wxBLUE, 24);
wxBitmap icon32 = CreateTestIcon(*wxGREEN, 32);
toolbar->AddTool(1001, "Icon16", icon16, "16px icon");
toolbar->AddTool(1002, "Icon24", icon24, "24px icon");
toolbar->AddTool(1003, "Icon32", icon32, "32px icon");
toolbar->Realize();
// Info label
wxString info = wxString::Format(
"Scale: content=%.1f dpi=%.1f\n"
"Icons should be 16, 24, 32 logical pixels wide respectively.\n"
"Below: bitmap buttons with the same icons for comparison.",
contentSF, dpiSF);
wxStaticText* label = new wxStaticText(panel, wxID_ANY, info);
label->SetName("info");
mainSizer->Add(label, 0, wxALL, 10);
// Bitmap buttons row for comparison
wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
wxBitmapButton* btn16 = new wxBitmapButton(panel, wxID_ANY, icon16);
btn16->SetName("btn16");
btnSizer->Add(btn16, 0, wxALL, 5);
wxBitmapButton* btn24 = new wxBitmapButton(panel, wxID_ANY, icon24);
btn24->SetName("btn24");
btnSizer->Add(btn24, 0, wxALL, 5);
wxBitmapButton* btn32 = new wxBitmapButton(panel, wxID_ANY, icon32);
btn32->SetName("btn32");
btnSizer->Add(btn32, 0, wxALL, 5);
mainSizer->Add(btnSizer, 0, wxLEFT, 5);
// Reference line: a static text showing expected sizes
wxStaticText* refLabel = new wxStaticText(panel, wxID_ANY,
"If scaling is correct, the red icon above should be ~16px, "
"blue ~24px, green ~32px (logical pixels).");
refLabel->SetName("reference");
mainSizer->Add(refLabel, 0, wxALL, 10);
panel->SetSizer(mainSizer);
wxLogMessage("RetinaScaleFrame created successfully");
}
};
class RetinaScaleApp : public wxApp
{
public:
bool OnInit() override
{
RetinaScaleFrame* frame = new RetinaScaleFrame();
frame->Show(true);
return true;
}
};
wxIMPLEMENT_APP(RetinaScaleApp);