pcbjam/tests/apps/standalone/regions/regions_test.cpp
Viktor Vaczi a26b40c063 Reorganize project structure for clarity
- Rename tests/wasm-app/ to tests/apps/ for brevity
- Move lib/gl_immediate_shim.js to wasm/shims/ (consolidates WASM files)
- Delete docs/ directory (outdated Nov 2024 research docs)
- Delete patches/ directory (already applied to fork submodules)
- Delete wasm/patches/ and wasm/config/ (empty/unused)
- Update all file references in scripts, configs, and documentation
- Update .gitignore for new tests/apps/ paths

Verified both build workflows pass:
- wxWidgets tests: 255 passed
- Docker KiCad build: completed successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 14:06:23 +01:00

235 lines
8.8 KiB
C++

// Region Clipping Test - Tests non-rectangular clipping regions
// Tests: wxRegion, wxDC::SetDeviceClippingRegion(), Union/Subtract/Intersect
#include "wx/wx.h"
#include "wx/dcmemory.h"
#include "wx/region.h"
class RegionsFrame : public wxFrame
{
public:
RegionsFrame() : wxFrame(nullptr, wxID_ANY, "Region Clipping Test",
wxDefaultPosition, wxSize(900, 700))
{
wxPanel* mainPanel = new wxPanel(this);
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
// Description
wxStaticText* desc = new wxStaticText(mainPanel, wxID_ANY,
"Tests non-rectangular region clipping.\n"
"Uses wxRegion with Union, Subtract, and Intersect operations.");
mainSizer->Add(desc, 0, wxALL, 5);
// Drawing panel
m_drawPanel = new wxPanel(mainPanel, wxID_ANY, wxDefaultPosition, wxSize(-1, 550));
m_drawPanel->SetBackgroundColour(*wxWHITE);
m_drawPanel->Bind(wxEVT_PAINT, &RegionsFrame::OnPaint, this);
mainSizer->Add(m_drawPanel, 1, wxEXPAND | wxALL, 5);
// Event log
mainSizer->Add(new wxStaticText(mainPanel, wxID_ANY, "Event Log"), 0, wxLEFT | wxTOP, 5);
m_log = new wxTextCtrl(mainPanel, wxID_ANY, "", wxDefaultPosition, wxSize(-1, 80),
wxTE_MULTILINE | wxTE_READONLY);
mainSizer->Add(m_log, 0, wxEXPAND | wxALL, 5);
mainPanel->SetSizer(mainSizer);
CreateStatusBar();
SetStatusText("Region clipping test app started");
Log("Region clipping test app started");
Log("Testing non-rectangular region clipping");
}
private:
void DrawTestPattern(wxDC& dc, int x, int y, int w, int h)
{
// Draw a gradient-like pattern that makes clipping visible
for (int i = 0; i < w; i += 5)
{
dc.SetPen(wxPen(wxColour(255 * i / w, 100, 255 - 255 * i / w)));
dc.DrawLine(x + i, y, x + i, y + h);
}
// Draw some shapes
dc.SetBrush(wxBrush(wxColour(255, 200, 0, 128)));
dc.SetPen(wxPen(*wxBLACK, 2));
dc.DrawCircle(x + w/2, y + h/2, w/3);
dc.SetBrush(wxBrush(wxColour(0, 200, 255, 128)));
dc.DrawRectangle(x + w/4, y + h/4, w/2, h/2);
}
void OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(m_drawPanel);
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
int y = 10;
const int boxWidth = 200;
const int boxHeight = 150;
const int spacing = 20;
dc.SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
// Row 1: Basic region types
// 1a: No clipping (reference)
dc.DrawText("No Clipping (reference)", 20, y);
y += 15;
DrawTestPattern(dc, 20, y, boxWidth, boxHeight);
// 1b: Single rectangle clipping
dc.DrawText("Single Rectangle", 20 + boxWidth + spacing, y - 15);
wxRegion singleRect(20 + boxWidth + spacing + 20, y + 20, boxWidth - 40, boxHeight - 40);
dc.SetDeviceClippingRegion(singleRect);
DrawTestPattern(dc, 20 + boxWidth + spacing, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 1c: Two rectangles (union)
dc.DrawText("Two Rectangles (Union)", 20 + (boxWidth + spacing) * 2, y - 15);
wxRegion twoRects;
twoRects.Union(wxRect(20 + (boxWidth + spacing) * 2, y, boxWidth / 2, boxHeight / 2));
twoRects.Union(wxRect(20 + (boxWidth + spacing) * 2 + boxWidth / 2, y + boxHeight / 2, boxWidth / 2, boxHeight / 2));
dc.SetDeviceClippingRegion(twoRects);
DrawTestPattern(dc, 20 + (boxWidth + spacing) * 2, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 1d: L-shaped region
dc.DrawText("L-Shape (Union)", 20 + (boxWidth + spacing) * 3, y - 15);
wxRegion lShape;
int lx = 20 + (boxWidth + spacing) * 3;
lShape.Union(wxRect(lx, y, boxWidth / 3, boxHeight)); // Vertical bar
lShape.Union(wxRect(lx, y + boxHeight * 2 / 3, boxWidth, boxHeight / 3)); // Horizontal bar
dc.SetDeviceClippingRegion(lShape);
DrawTestPattern(dc, lx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
y += boxHeight + 40;
// Row 2: Complex regions
// 2a: Cross shape
dc.DrawText("Cross (Two Rects)", 20, y);
y += 15;
wxRegion cross;
cross.Union(wxRect(20 + boxWidth / 3, y, boxWidth / 3, boxHeight)); // Vertical
cross.Union(wxRect(20, y + boxHeight / 3, boxWidth, boxHeight / 3)); // Horizontal
dc.SetDeviceClippingRegion(cross);
DrawTestPattern(dc, 20, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 2b: Checkerboard pattern (4 squares)
dc.DrawText("Checkerboard (4 Rects)", 20 + boxWidth + spacing, y - 15);
wxRegion checkerboard;
int cx = 20 + boxWidth + spacing;
int halfW = boxWidth / 2;
int halfH = boxHeight / 2;
checkerboard.Union(wxRect(cx, y, halfW, halfH));
checkerboard.Union(wxRect(cx + halfW, y + halfH, halfW, halfH));
dc.SetDeviceClippingRegion(checkerboard);
DrawTestPattern(dc, cx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 2c: Diagonal stripes (multiple rectangles)
dc.DrawText("Stripes (Multiple)", 20 + (boxWidth + spacing) * 2, y - 15);
wxRegion stripes;
int sx = 20 + (boxWidth + spacing) * 2;
int stripeW = boxWidth / 5;
for (int i = 0; i < 3; i++)
{
stripes.Union(wxRect(sx + i * stripeW * 2, y, stripeW, boxHeight));
}
dc.SetDeviceClippingRegion(stripes);
DrawTestPattern(dc, sx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 2d: Frame (subtract inner rect)
dc.DrawText("Frame (Subtract)", 20 + (boxWidth + spacing) * 3, y - 15);
wxRegion frame(20 + (boxWidth + spacing) * 3, y, boxWidth, boxHeight);
int fx = 20 + (boxWidth + spacing) * 3;
frame.Subtract(wxRect(fx + 30, y + 30, boxWidth - 60, boxHeight - 60));
dc.SetDeviceClippingRegion(frame);
DrawTestPattern(dc, fx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
y += boxHeight + 40;
// Row 3: More complex patterns
// 3a: Grid pattern
dc.DrawText("Grid (9 Rects)", 20, y);
y += 15;
wxRegion grid;
int cellW = boxWidth / 5;
int cellH = boxHeight / 5;
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
grid.Union(wxRect(20 + col * cellW * 2, y + row * cellH * 2, cellW, cellH));
}
}
dc.SetDeviceClippingRegion(grid);
DrawTestPattern(dc, 20, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 3b: T-shape
dc.DrawText("T-Shape", 20 + boxWidth + spacing, y - 15);
wxRegion tShape;
int tx = 20 + boxWidth + spacing;
tShape.Union(wxRect(tx, y, boxWidth, boxHeight / 3)); // Top bar
tShape.Union(wxRect(tx + boxWidth / 3, y, boxWidth / 3, boxHeight)); // Vertical stem
dc.SetDeviceClippingRegion(tShape);
DrawTestPattern(dc, tx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 3c: Corner rectangles
dc.DrawText("4 Corners", 20 + (boxWidth + spacing) * 2, y - 15);
wxRegion corners;
int cornx = 20 + (boxWidth + spacing) * 2;
int cornSize = boxWidth / 4;
corners.Union(wxRect(cornx, y, cornSize, cornSize)); // Top-left
corners.Union(wxRect(cornx + boxWidth - cornSize, y, cornSize, cornSize)); // Top-right
corners.Union(wxRect(cornx, y + boxHeight - cornSize, cornSize, cornSize)); // Bottom-left
corners.Union(wxRect(cornx + boxWidth - cornSize, y + boxHeight - cornSize, cornSize, cornSize)); // Bottom-right
dc.SetDeviceClippingRegion(corners);
DrawTestPattern(dc, cornx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
// 3d: Staircase
dc.DrawText("Staircase", 20 + (boxWidth + spacing) * 3, y - 15);
wxRegion stairs;
int stx = 20 + (boxWidth + spacing) * 3;
int stepW = boxWidth / 4;
int stepH = boxHeight / 4;
for (int i = 0; i < 4; i++)
{
stairs.Union(wxRect(stx + i * stepW, y + i * stepH, boxWidth - i * stepW, stepH));
}
dc.SetDeviceClippingRegion(stairs);
DrawTestPattern(dc, stx, y, boxWidth, boxHeight);
dc.DestroyClippingRegion();
}
void Log(const wxString& msg)
{
m_log->AppendText(msg + "\n");
}
wxPanel* m_drawPanel;
wxTextCtrl* m_log;
};
class RegionsApp : public wxApp
{
public:
virtual bool OnInit() override
{
RegionsFrame* frame = new RegionsFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(RegionsApp);