/** * Render Targets Scenario * * Tests GAL render target concepts: * - SetTarget() / GetTarget() * - ClearTarget() * - HasTarget() * * NOTE: In this test harness context, we don't switch targets mid-frame * as that requires specific compositor setup. Instead, we demonstrate * the concept visually and test the API availability. * * RENDER_TARGET values: * - TARGET_CACHED: Main rendering target (persistent) * - TARGET_NONCACHED: Auxiliary target (cleared each frame) * - TARGET_OVERLAY: Overlay items (cleared each frame) * - TARGET_TEMP: Temporary target for special operations */ #include #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif namespace GALTest { using KIGFX::COLOR4D; using KIGFX::GAL; using KIGFX::RENDER_TARGET; using KIGFX::TARGET_CACHED; using KIGFX::TARGET_NONCACHED; using KIGFX::TARGET_OVERLAY; using KIGFX::TARGET_TEMP; void RenderRenderTargets(GAL* gal, int width, int height) { // All drawing to the default target (NONCACHED in test harness) // Background grid gal->SetLayerDepth(100); gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.2, 0.2, 0.25, 0.4)); for (int x = 0; x < width; x += 30) { gal->DrawLine(VECTOR2D(x, 0), VECTOR2D(x, height)); } for (int y = 0; y < height; y += 30) { gal->DrawLine(VECTOR2D(0, y), VECTOR2D(width, y)); } // Visual representation of render target concept // Show boxes representing each target type double boxW = 160; double boxH = 200; double startX = 40; double startY = 50; double spacing = 180; // Box 1: CACHED (persistent content) gal->SetLayerDepth(50); gal->SetIsFill(true); gal->SetIsStroke(false); gal->SetFillColor(COLOR4D(0.15, 0.3, 0.15, 1.0)); gal->DrawRectangle(VECTOR2D(startX, startY), VECTOR2D(startX + boxW, startY + boxH)); // Static PCB elements (what would go in cached) gal->SetFillColor(COLOR4D(0.7, 0.5, 0.2, 1.0)); gal->DrawSegment(VECTOR2D(startX + 20, startY + 50), VECTOR2D(startX + boxW - 20, startY + 50), 6); gal->DrawSegment(VECTOR2D(startX + 20, startY + 100), VECTOR2D(startX + boxW - 20, startY + 100), 6); gal->DrawSegment(VECTOR2D(startX + 20, startY + 150), VECTOR2D(startX + boxW - 20, startY + 150), 6); gal->SetFillColor(COLOR4D(0.8, 0.6, 0.3, 1.0)); gal->DrawCircle(VECTOR2D(startX + 40, startY + 50), 12); gal->DrawCircle(VECTOR2D(startX + boxW - 40, startY + 50), 12); gal->DrawCircle(VECTOR2D(startX + 40, startY + 100), 12); gal->DrawCircle(VECTOR2D(startX + boxW - 40, startY + 100), 12); gal->DrawCircle(VECTOR2D(startX + 40, startY + 150), 12); gal->DrawCircle(VECTOR2D(startX + boxW - 40, startY + 150), 12); // Frame gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(3.0); gal->SetStrokeColor(COLOR4D(0.3, 0.6, 0.3, 1.0)); gal->DrawRectangle(VECTOR2D(startX, startY), VECTOR2D(startX + boxW, startY + boxH)); // Label gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.5, 0.8, 0.5, 0.8)); gal->DrawRectangle(VECTOR2D(startX + 20, startY + boxH + 10), VECTOR2D(startX + boxW - 20, startY + boxH + 25)); // Box 2: NONCACHED (dynamic content) double box2X = startX + spacing; gal->SetLayerDepth(50); gal->SetIsFill(true); gal->SetIsStroke(false); gal->SetFillColor(COLOR4D(0.3, 0.25, 0.1, 1.0)); gal->DrawRectangle(VECTOR2D(box2X, startY), VECTOR2D(box2X + boxW, startY + boxH)); // Dynamic elements (selection highlights, moving items) gal->SetFillColor(COLOR4D(1.0, 1.0, 0.2, 0.4)); gal->DrawRectangle(VECTOR2D(box2X + 30, startY + 40), VECTOR2D(box2X + boxW - 30, startY + 80)); gal->SetFillColor(COLOR4D(0.2, 0.8, 0.2, 0.6)); gal->DrawRectangle(VECTOR2D(box2X + 50, startY + 90), VECTOR2D(box2X + boxW - 50, startY + 140)); // Movement arrows gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(2.0); gal->SetStrokeColor(COLOR4D(1.0, 0.5, 0.0, 0.8)); gal->DrawLine(VECTOR2D(box2X + 80, startY + 160), VECTOR2D(box2X + 80, startY + 180)); gal->DrawLine(VECTOR2D(box2X + 80, startY + 180), VECTOR2D(box2X + 70, startY + 170)); gal->DrawLine(VECTOR2D(box2X + 80, startY + 180), VECTOR2D(box2X + 90, startY + 170)); // Frame gal->SetLineWidth(3.0); gal->SetStrokeColor(COLOR4D(0.8, 0.7, 0.2, 1.0)); gal->DrawRectangle(VECTOR2D(box2X, startY), VECTOR2D(box2X + boxW, startY + boxH)); // Label gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.9, 0.8, 0.3, 0.8)); gal->DrawRectangle(VECTOR2D(box2X + 20, startY + boxH + 10), VECTOR2D(box2X + boxW - 20, startY + boxH + 25)); // Box 3: OVERLAY (crosshairs, measurements) double box3X = startX + spacing * 2; gal->SetLayerDepth(50); gal->SetIsFill(true); gal->SetIsStroke(false); gal->SetFillColor(COLOR4D(0.15, 0.15, 0.25, 1.0)); gal->DrawRectangle(VECTOR2D(box3X, startY), VECTOR2D(box3X + boxW, startY + boxH)); // Crosshair overlay gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(1.0, 1.0, 1.0, 0.8)); double crossX = box3X + boxW / 2; double crossY = startY + boxH / 2; gal->DrawLine(VECTOR2D(box3X + 10, crossY), VECTOR2D(box3X + boxW - 10, crossY)); gal->DrawLine(VECTOR2D(crossX, startY + 10), VECTOR2D(crossX, startY + boxH - 10)); // Measurement line gal->SetStrokeColor(COLOR4D(0.3, 1.0, 1.0, 0.9)); gal->SetLineWidth(2.0); gal->DrawLine(VECTOR2D(box3X + 30, startY + 160), VECTOR2D(box3X + boxW - 30, startY + 160)); gal->SetIsFill(true); gal->SetFillColor(COLOR4D(0.3, 1.0, 1.0, 0.9)); gal->DrawCircle(VECTOR2D(box3X + 30, startY + 160), 4); gal->DrawCircle(VECTOR2D(box3X + boxW - 30, startY + 160), 4); // Frame gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(3.0); gal->SetStrokeColor(COLOR4D(0.4, 0.4, 0.8, 1.0)); gal->DrawRectangle(VECTOR2D(box3X, startY), VECTOR2D(box3X + boxW, startY + boxH)); // Label gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.5, 0.5, 0.9, 0.8)); gal->DrawRectangle(VECTOR2D(box3X + 20, startY + boxH + 10), VECTOR2D(box3X + boxW - 20, startY + boxH + 25)); // Box 4: TEMP (special operations) double box4X = startX + spacing * 3; gal->SetLayerDepth(50); gal->SetIsFill(true); gal->SetIsStroke(false); gal->SetFillColor(COLOR4D(0.25, 0.15, 0.25, 1.0)); gal->DrawRectangle(VECTOR2D(box4X, startY), VECTOR2D(box4X + boxW, startY + boxH)); // Temporary rendering (drag preview, etc) gal->SetFillColor(COLOR4D(0.8, 0.3, 0.8, 0.5)); gal->DrawRectangle(VECTOR2D(box4X + 40, startY + 60), VECTOR2D(box4X + boxW - 40, startY + 120)); // Dotted outline showing "ghost" position gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(1.0, 0.5, 1.0, 0.6)); // Draw dashed rectangle manually for (int i = 0; i < 10; i++) { double x1 = box4X + 40 + i * 8; double x2 = x1 + 5; if (x2 > box4X + boxW - 40) x2 = box4X + boxW - 40; gal->DrawLine(VECTOR2D(x1, startY + 140), VECTOR2D(x2, startY + 140)); gal->DrawLine(VECTOR2D(x1, startY + 180), VECTOR2D(x2, startY + 180)); } // Frame gal->SetLineWidth(3.0); gal->SetStrokeColor(COLOR4D(0.7, 0.3, 0.7, 1.0)); gal->DrawRectangle(VECTOR2D(box4X, startY), VECTOR2D(box4X + boxW, startY + boxH)); // Label gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.8, 0.4, 0.8, 0.8)); gal->DrawRectangle(VECTOR2D(box4X + 20, startY + boxH + 10), VECTOR2D(box4X + boxW - 20, startY + boxH + 25)); // Bottom: API demonstration - HasTarget results double apiY = 340; gal->SetLayerDepth(40); // Check target availability (these are API calls) bool hasCached = gal->HasTarget(TARGET_CACHED); bool hasNoncached = gal->HasTarget(TARGET_NONCACHED); bool hasOverlay = gal->HasTarget(TARGET_OVERLAY); bool hasTemp = gal->HasTarget(TARGET_TEMP); // Show results visually gal->SetIsFill(true); gal->SetIsStroke(false); // Label area gal->SetFillColor(COLOR4D(0.15, 0.15, 0.18, 1.0)); gal->DrawRectangle(VECTOR2D(40, apiY), VECTOR2D(760, apiY + 100)); // Indicator for each target double indicatorY = apiY + 50; double indicatorSpacing = 180; // CACHED indicator gal->SetFillColor(hasCached ? COLOR4D(0.2, 0.9, 0.2, 1.0) : COLOR4D(0.9, 0.2, 0.2, 1.0)); gal->DrawCircle(VECTOR2D(startX + boxW / 2, indicatorY), 15); // NONCACHED indicator gal->SetFillColor(hasNoncached ? COLOR4D(0.2, 0.9, 0.2, 1.0) : COLOR4D(0.9, 0.2, 0.2, 1.0)); gal->DrawCircle(VECTOR2D(startX + spacing + boxW / 2, indicatorY), 15); // OVERLAY indicator gal->SetFillColor(hasOverlay ? COLOR4D(0.2, 0.9, 0.2, 1.0) : COLOR4D(0.9, 0.2, 0.2, 1.0)); gal->DrawCircle(VECTOR2D(startX + spacing * 2 + boxW / 2, indicatorY), 15); // TEMP indicator gal->SetFillColor(hasTemp ? COLOR4D(0.2, 0.9, 0.2, 1.0) : COLOR4D(0.9, 0.2, 0.2, 1.0)); gal->DrawCircle(VECTOR2D(startX + spacing * 3 + boxW / 2, indicatorY), 15); // Frame around API section gal->SetIsFill(false); gal->SetIsStroke(true); gal->SetLineWidth(2.0); gal->SetStrokeColor(COLOR4D(0.4, 0.4, 0.5, 0.8)); gal->DrawRectangle(VECTOR2D(40, apiY), VECTOR2D(760, apiY + 100)); // Bottom: GetTarget demonstration RENDER_TARGET currentTarget = gal->GetTarget(); (void)currentTarget; // Used - shows API works // Label for current target gal->SetLineWidth(1.0); gal->SetStrokeColor(COLOR4D(0.5, 0.5, 0.6, 0.8)); gal->DrawRectangle(VECTOR2D(40, apiY + 70), VECTOR2D(300, apiY + 85)); } } // namespace GALTest