Start refactoring printers into own directory

This commit is contained in:
2025-10-11 12:29:43 +02:00
parent 3dc5da6fc8
commit 0b8ff28a60
11 changed files with 271 additions and 177 deletions

View File

@@ -25,71 +25,85 @@
#include <vector>
namespace ptprnt::graphics {
Monochrome::Monochrome(const std::vector<uint8_t>& grayscale, uint32_t width, uint32_t height)
: mPixels(grayscale), mWidth(width), mHeight(height) {}
// Constructor from grayscale data
MonochromeData::MonochromeData(const std::vector<uint8_t>& grayscale, uint32_t width, uint32_t height,
Orientation orient)
: stride(0),
orientation(orient),
width(width),
height(height),
mPixels(grayscale),
mIsProcessed(false) {}
Monochrome::Monochrome(const std::span<uint8_t> grayscale, uint32_t width, uint32_t height)
: mPixels(grayscale.begin(), grayscale.end()), mWidth(width), mHeight(height) {}
MonochromeData::MonochromeData(const std::span<uint8_t> grayscale, uint32_t width, uint32_t height,
Orientation orient)
: stride(0),
orientation(orient),
width(width),
height(height),
mPixels(grayscale.begin(), grayscale.end()),
mIsProcessed(false) {}
void Monochrome::setThreshold(uint8_t threshhold) {
mThreshhold = threshhold;
void MonochromeData::setThreshold(uint8_t threshold) {
mThreshold = threshold;
mIsProcessed = false; // Mark as needing reprocessing
}
void Monochrome::invert(bool shouldInvert) {
void MonochromeData::invert(bool shouldInvert) {
mShouldInvert = shouldInvert;
mIsProcessed = false; // Mark as needing reprocessing
}
std::vector<uint8_t> Monochrome::get() {
// Calculate output size for packed format: (width + 7) / 8 bytes per row
uint32_t stride = (mWidth + 7) / 8;
size_t outputSize = stride * mHeight;
std::vector<uint8_t> outPixels(outputSize, 0);
MonochromeData MonochromeData::get() {
if (!mIsProcessed) {
processGrayscaleToMonochrome();
mIsProcessed = true;
}
// Pack pixels row by row for correct 2D layout
for (uint32_t y = 0; y < mHeight; ++y) {
for (uint32_t x = 0; x < mWidth; ++x) {
size_t pixelIndex = y * mWidth + x; // Row-major index in input
size_t byteIndex = y * stride + x / 8; // Byte index in packed output
size_t bitIndex = 7 - (x % 8); // MSB first
// Return a copy of the processed data
MonochromeData result;
result.bytes = bytes;
result.stride = stride;
result.orientation = orientation;
result.width = width;
result.height = height;
result.mIsProcessed = true;
return result;
}
// Convert grayscale pixel to bit based on threshold
bool pixelOn = mPixels[pixelIndex] > mThreshhold;
if (mShouldInvert) {
pixelOn = !pixelOn;
}
void MonochromeData::processGrayscaleToMonochrome() {
// Calculate stride based on packed monochrome data (1 bit per pixel, 8 pixels per byte)
stride = static_cast<uint32_t>((width + 7) / 8);
if (pixelOn) {
outPixels[byteIndex] |= (1 << bitIndex);
// Create the monochrome byte array
bytes.clear();
bytes.resize(stride * height, 0);
// Convert grayscale to monochrome
for (uint32_t y = 0; y < height; ++y) {
for (uint32_t x = 0; x < width; ++x) {
uint32_t pixelIndex = y * width + x;
if (pixelIndex < mPixels.size()) {
uint8_t pixelValue = mPixels[pixelIndex];
// Apply threshold
bool isSet = pixelValue >= mThreshold;
// Apply inversion if needed
if (mShouldInvert) {
isSet = !isSet;
}
// Set the bit in the monochrome data
if (isSet) {
setBit(x, y, true);
}
}
}
}
return outPixels;
}
void Monochrome::visualize() {
auto mono = get();
for (unsigned char pix : mono) {
std::cout << ((pix & (1 << 7)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 6)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 5)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 4)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 3)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 2)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 1)) == 0 ? "." : "x");
std::cout << ((pix & (1 << 0)) == 0 ? "." : "x");
}
std::cout << std::endl;
}
MonochromeData Monochrome::getMonochromeData() {
auto processedBytes = get();
// Calculate stride based on packed monochrome data (1 bit per pixel, 8 pixels per byte)
auto stride = static_cast<uint32_t>((mWidth + 7) / 8);
return {std::move(processedBytes), stride, Orientation::LANDSCAPE, mWidth, mHeight};
}
// MonochromeData transformation methods implementation
// Transformation methods implementation
void MonochromeData::transformTo(Orientation targetOrientation) {
if (orientation == targetOrientation) {
return; // No transformation needed
@@ -151,7 +165,7 @@ void MonochromeData::setBit(uint32_t x, uint32_t y, bool value) {
}
std::vector<uint8_t> MonochromeData::createRotatedData(Orientation targetOrientation) const {
uint32_t newWidth, newHeight;
uint32_t newWidth = 0, newHeight = 0;
// Determine new dimensions
switch (targetOrientation) {
@@ -182,8 +196,8 @@ std::vector<uint8_t> MonochromeData::createRotatedData(Orientation targetOrienta
// Copy pixels with appropriate transformation
for (uint32_t y = 0; y < height; ++y) {
for (uint32_t x = 0; x < width; ++x) {
bool pixel = getBit(x, y);
uint32_t newX, newY;
bool pixel = getBit(x, y);
uint32_t newX = 0, newY = 0;
switch (targetOrientation) {
case Orientation::LANDSCAPE: