/** * BITMAP_BASE Test Patterns for GAL Test * * Provides helper functions to create wxImage test patterns that can be * used with KiCad's real BITMAP_BASE class for testing DrawBitmap(). * * Usage: * wxImage img = CreateCheckerboardImage(64, 64); * BITMAP_BASE bitmap; * bitmap.SetImage(img); * gal->DrawBitmap(bitmap); */ #ifndef BITMAP_BASE_STUB_H #define BITMAP_BASE_STUB_H #include #include #include #include //============================================================================= // Image pattern generation functions //============================================================================= /** * Create a solid color image */ inline wxImage CreateSolidImage(int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; data[idx + 0] = r; data[idx + 1] = g; data[idx + 2] = b; alpha[y * width + x] = a; } } return img; } /** * Create a checkerboard pattern image */ inline wxImage CreateCheckerboardImage(int width, int height, int squareSize = 8, uint8_t r1 = 255, uint8_t g1 = 255, uint8_t b1 = 255, uint8_t r2 = 0, uint8_t g2 = 0, uint8_t b2 = 0) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; bool isLight = ((x / squareSize) + (y / squareSize)) % 2 == 0; if (isLight) { data[idx + 0] = r1; data[idx + 1] = g1; data[idx + 2] = b1; } else { data[idx + 0] = r2; data[idx + 1] = g2; data[idx + 2] = b2; } alpha[y * width + x] = 255; } } return img; } /** * Create a horizontal gradient image */ inline wxImage CreateGradientHImage(int width, int height, uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; float t = (float)x / (width - 1); data[idx + 0] = (uint8_t)(r1 + t * (r2 - r1)); data[idx + 1] = (uint8_t)(g1 + t * (g2 - g1)); data[idx + 2] = (uint8_t)(b1 + t * (b2 - b1)); alpha[y * width + x] = 255; } } return img; } /** * Create a vertical gradient image */ inline wxImage CreateGradientVImage(int width, int height, uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); for (int y = 0; y < height; y++) { float t = (float)y / (height - 1); for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; data[idx + 0] = (uint8_t)(r1 + t * (r2 - r1)); data[idx + 1] = (uint8_t)(g1 + t * (g2 - g1)); data[idx + 2] = (uint8_t)(b1 + t * (b2 - b1)); alpha[y * width + x] = 255; } } return img; } /** * Create a radial gradient image */ inline wxImage CreateRadialGradientImage(int width, int height, uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); float cx = width / 2.0f; float cy = height / 2.0f; float maxDist = std::sqrt(cx * cx + cy * cy); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; float dx = x - cx; float dy = y - cy; float dist = std::sqrt(dx * dx + dy * dy); float t = std::min(1.0f, dist / maxDist); data[idx + 0] = (uint8_t)(r1 + t * (r2 - r1)); data[idx + 1] = (uint8_t)(g1 + t * (g2 - g1)); data[idx + 2] = (uint8_t)(b1 + t * (b2 - b1)); alpha[y * width + x] = 255; } } return img; } /** * Create a striped pattern image */ inline wxImage CreateStripedImage(int width, int height, int stripeWidth, bool horizontal, uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; int pos = horizontal ? y : x; bool isFirst = (pos / stripeWidth) % 2 == 0; if (isFirst) { data[idx + 0] = r1; data[idx + 1] = g1; data[idx + 2] = b1; } else { data[idx + 0] = r2; data[idx + 1] = g2; data[idx + 2] = b2; } alpha[y * width + x] = 255; } } return img; } /** * Create a "K" logo-style image (simplified KiCad logo) */ inline wxImage CreateKiCadLogoImage(int width, int height, uint8_t bgR = 30, uint8_t bgG = 60, uint8_t bgB = 30, uint8_t fgR = 255, uint8_t fgG = 200, uint8_t fgB = 50) { wxImage img(width, height); img.InitAlpha(); unsigned char* data = img.GetData(); unsigned char* alpha = img.GetAlpha(); // Fill background for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = (y * width + x) * 3; data[idx + 0] = bgR; data[idx + 1] = bgG; data[idx + 2] = bgB; alpha[y * width + x] = 255; } } // Draw a simplified "K" shape int centerX = width / 2; int centerY = height / 2; int thickness = std::max(2, std::min(width, height) / 8); int halfH = height / 3; int halfW = width / 3; // Vertical bar of K for (int y = centerY - halfH; y <= centerY + halfH; y++) { if (y < 0 || y >= height) continue; for (int dx = -thickness/2; dx <= thickness/2; dx++) { int x = centerX - halfW/2 + dx; if (x < 0 || x >= width) continue; int idx = (y * width + x) * 3; data[idx + 0] = fgR; data[idx + 1] = fgG; data[idx + 2] = fgB; } } // Upper diagonal of K for (int i = 0; i <= halfH; i++) { int y = centerY - i; int x = centerX - halfW/2 + (halfW * i / halfH); if (y < 0 || y >= height) continue; for (int dy = -thickness/2; dy <= thickness/2; dy++) { for (int dx = -thickness/2; dx <= thickness/2; dx++) { int py = y + dy; int px = x + dx; if (py < 0 || py >= height) continue; if (px < 0 || px >= width) continue; int idx = (py * width + px) * 3; data[idx + 0] = fgR; data[idx + 1] = fgG; data[idx + 2] = fgB; } } } // Lower diagonal of K for (int i = 0; i <= halfH; i++) { int y = centerY + i; int x = centerX - halfW/2 + (halfW * i / halfH); if (y < 0 || y >= height) continue; for (int dy = -thickness/2; dy <= thickness/2; dy++) { for (int dx = -thickness/2; dx <= thickness/2; dx++) { int py = y + dy; int px = x + dx; if (py < 0 || py >= height) continue; if (px < 0 || px >= width) continue; int idx = (py * width + px) * 3; data[idx + 0] = fgR; data[idx + 1] = fgG; data[idx + 2] = fgB; } } } return img; } /** * Add a border to an existing image */ inline void AddBorderToImage(wxImage& img, int borderWidth, uint8_t r, uint8_t g, uint8_t b) { int width = img.GetWidth(); int height = img.GetHeight(); unsigned char* data = img.GetData(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { bool isBorder = (x < borderWidth || x >= width - borderWidth || y < borderWidth || y >= height - borderWidth); if (isBorder) { int idx = (y * width + x) * 3; data[idx + 0] = r; data[idx + 1] = g; data[idx + 2] = b; } } } } //============================================================================= // Factory functions to create BITMAP_BASE with test patterns //============================================================================= /** * Create a BITMAP_BASE with checkerboard pattern */ inline std::unique_ptr CreateCheckerboardBitmap(int width, int height, int squareSize = 8) { auto bitmap = std::make_unique(); wxImage img = CreateCheckerboardImage(width, height, squareSize); bitmap->SetImage(img); return bitmap; } /** * Create a BITMAP_BASE with horizontal gradient (red to blue) */ inline std::unique_ptr CreateGradientBitmap(int width, int height) { auto bitmap = std::make_unique(); wxImage img = CreateGradientHImage(width, height, 255, 50, 50, 50, 50, 255); bitmap->SetImage(img); return bitmap; } /** * Create a BITMAP_BASE with KiCad logo pattern */ inline std::unique_ptr CreateKiCadLogoBitmap(int width, int height) { auto bitmap = std::make_unique(); wxImage img = CreateKiCadLogoImage(width, height); AddBorderToImage(img, 2, 200, 150, 50); bitmap->SetImage(img); return bitmap; } /** * Create a BITMAP_BASE with radial gradient */ inline std::unique_ptr CreateRadialBitmap(int width, int height) { auto bitmap = std::make_unique(); wxImage img = CreateRadialGradientImage(width, height, 255, 255, 200, 50, 50, 150); bitmap->SetImage(img); return bitmap; } /** * Create a BITMAP_BASE with stripes */ inline std::unique_ptr CreateStripedBitmap(int width, int height, bool horizontal = true) { auto bitmap = std::make_unique(); wxImage img = CreateStripedImage(width, height, 8, horizontal, 100, 150, 200, 200, 100, 50); bitmap->SetImage(img); return bitmap; } #endif // BITMAP_BASE_STUB_H