5 Commits

Author SHA1 Message Date
7437d79393 Update copyright
All checks were successful
Build ptprnt / build (push) Successful in 3m41s
2025-10-12 22:04:29 +02:00
5f673b7d57 Printing not flipped
All checks were successful
Build ptprnt / build (push) Successful in 3m37s
2025-10-12 21:46:24 +02:00
58287202d8 printing but flipped 2025-10-12 21:20:17 +02:00
ae22feed4f Add meson options 2025-10-12 12:56:29 +02:00
652e687fb0 Add a trace mode for usb tracing 2025-10-12 12:56:09 +02:00
27 changed files with 278 additions and 48 deletions

View File

@@ -35,6 +35,15 @@ incdir = include_directories('src')
subdir('src')
# Build arguments
cpp_args = ['-DPROJ_VERSION="' + meson.project_version() + '"']
# USB trace mode option (for debugging without sending to hardware)
if get_option('usb_trace_only')
cpp_args += ['-DUSB_TRACE_ONLY']
message('USB_TRACE_ONLY enabled: USB data will be logged but not sent to device')
endif
ptprnt_exe = executable(
'ptprnt',
'src/main.cpp',
@@ -42,7 +51,7 @@ ptprnt_exe = executable(
dependencies: [usb_dep, log_dep, fmt_dep, pangocairo_dep, cli11_dep],
include_directories: incdir,
sources: [ptprnt_srcs],
cpp_args: ['-DPROJ_VERSION="' + meson.project_version() + '"'],
cpp_args: cpp_args,
)

4
meson_options.txt Normal file
View File

@@ -0,0 +1,4 @@
option('usb_trace_only',
type: 'boolean',
value: false,
description: 'Enable USB trace mode: log USB data without sending to device (saves label tape during debugging)')

View File

@@ -1,3 +1,22 @@
/*
ptrnt - print labels on linux
Copyright (C) 2024-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "PrinterDriverFactory.hpp"
#include <algorithm>

View File

@@ -1,6 +1,26 @@
/*
ptrnt - print labels on linux
Copyright (C) 2024-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <memory>
#include <vector>
#include <string>
#include <vector>
#include "interface/IPrinterDriver.hpp"
#include "libusbwrap/LibUsbTypes.hpp"
@@ -45,4 +65,4 @@ class PrinterDriverFactory {
private:
};
}
} // namespace ptprnt

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -55,7 +55,10 @@ int PtouchPrint::init(int argc, char** argv) {
return -1;
}
if (mVerboseFlag) {
// Set log level based on flags
if (mTraceFlag) {
setupLogger(spdlog::level::trace);
} else if (mVerboseFlag) {
setupLogger(spdlog::level::debug);
} else {
setupLogger(spdlog::level::warn);
@@ -263,6 +266,7 @@ void PtouchPrint::setupCliParser() {
// General options
mApp.add_flag("-v,--verbose", mVerboseFlag, "Enable verbose output");
mApp.add_flag("--trace", mTraceFlag, "Enable trace output (shows USB communication)");
mApp.add_flag("-V,--version", printVersion, "Prints the ptprnt's version");
// Printer selection

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -60,6 +60,7 @@ class PtouchPrint {
// CLI flags and options
bool mVerboseFlag = false;
bool mTraceFlag = false;
std::string mPrinterSelection = "auto";
bool mListDriversFlag = false;
};

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2024-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2024 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2024 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2024 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2024 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2023-2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,3 +1,22 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023-2024 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <sys/types.h>

View File

@@ -1,3 +1,22 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
@@ -9,8 +28,8 @@
namespace libusbwrap {
class IUsbDeviceFactory {
public:
virtual ~IUsbDeviceFactory() = default;
virtual std::vector<std::unique_ptr<IUsbDevice>> findAllDevices() = 0;
virtual ~IUsbDeviceFactory() = default;
virtual std::vector<std::unique_ptr<IUsbDevice>> findAllDevices() = 0;
virtual std::vector<std::unique_ptr<IUsbDevice>> findDevices(uint16_t vid, uint16_t pid) = 0;
};
} // namespace libusbwrap

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2022-2023 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -127,42 +127,51 @@ bool P700Printer::printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap)
}
bool P700Printer::printMonochromeData(const graphics::MonochromeData& data) {
// Send initialization sequence
// The INITIALIZE command needs to be sent as a 128-byte packet with ESC @ at the end
std::vector<uint8_t> initCmd(128, 0x00);
initCmd[126] = p700::commands::INITIALIZE[0]; // ESC
initCmd[127] = p700::commands::INITIALIZE[1]; // @
send(initCmd);
send(p700::commands::RASTER_START);
std::vector<uint8_t> rastercmd(4);
rastercmd[0] = 0x47;
rastercmd[1] = 0x00; // size +1
rastercmd[2] = 0x00;
rastercmd[3] = 0x00; // size -1
// Status is already queried in getPrinterStatus()
send(p700::commands::PRINT_MODE);
send(p700::commands::AUTO_STATUS);
send(p700::commands::MODE_SETTING);
// Process data column by column for the printer
for (uint32_t col = 0; col < data.width; col++) {
std::vector<uint8_t> columnData;
// Send raster data row by row in reverse order (bottom to top)
// The printer feeds tape as it prints, so first row sent appears at the end
for (int row = data.height - 1; row >= 0; row--) {
std::vector<uint8_t> rowData;
// Extract column data bit by bit
for (uint32_t row = 0; row < data.height; row += 8) {
// Extract row data byte by byte
for (uint32_t col = 0; col < data.width; col += 8) {
uint8_t byte = 0;
for (int bit = 0; bit < 8 && (row + bit) < data.height; bit++) {
if (data.getBit(col, row + bit)) {
for (int bit = 0; bit < 8 && (col + bit) < data.width; bit++) {
if (data.getBit(col + bit, row)) {
byte |= (1 << (7 - bit));
}
}
columnData.push_back(byte);
rowData.push_back(byte);
}
// Build raster line command: G + length_high + 0x00 + length_low + data
std::vector<uint8_t> buf;
buf.insert(buf.begin(), rastercmd.begin(), rastercmd.end());
buf.insert(std::next(buf.begin(), 4), columnData.begin(), columnData.end());
buf[1] = columnData.size() + 1;
buf[3] = columnData.size() - 1;
buf.push_back(0x47); // 'G' command
buf.push_back((rowData.size() + 1) & 0xFF); // length + 1 (low byte)
buf.push_back(0x00); // high byte (always 0 for our data size)
buf.push_back((rowData.size() - 1) & 0xFF); // length - 1
buf.insert(buf.end(), rowData.begin(), rowData.end());
if (!send(buf)) {
spdlog::error("Error sending buffer to printer");
break;
spdlog::error("Error sending raster line {} to printer", row);
return false;
}
}
// Send print finalization commands
send(p700::commands::EJECT);
return true;
}
@@ -178,7 +187,8 @@ bool P700Printer::printLabel(std::unique_ptr<graphics::ILabel> label) {
// Transform to portrait orientation for printing
monoData.transformTo(graphics::Orientation::PORTRAIT);
spdlog::debug("Label surface is {}x{}, transformed to portrait", label->getWidth(), label->getHeight());
spdlog::debug("Label surface was {}x{}, after transform to portrait: {}x{}", label->getWidth(), label->getHeight(),
monoData.width, monoData.height);
return printMonochromeData(monoData);
}
@@ -197,6 +207,11 @@ bool P700Printer::send(const std::vector<uint8_t>& data) {
return false;
}
spdlog::trace("USB Tx → 0x02 {:03d} bytes: {:Xn}", data.size(), spdlog::to_hex(data));
#ifdef USB_TRACE_ONLY
// Trace mode: Log the data that would be sent without actually sending it
return true;
#else
int tx = 0;
if (!mUsbHndl->bulkTransfer(0x02, data, &tx, 0)) {
@@ -211,6 +226,7 @@ bool P700Printer::send(const std::vector<uint8_t>& data) {
}
return true;
#endif
}
bool P700Printer::init() {

View File

@@ -1,6 +1,6 @@
/*
ptrnt - print labels on linux
Copyright (C) 2023 Moritz Martinius
Copyright (C) 2025 Moritz Martinius
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,7 +32,11 @@
namespace ptprnt::printer {
namespace p700::commands {
const cmd_T GET_STATUS{0x1b, 0x69, 0x53};
const cmd_T INITIALIZE{0x1b, 0x40}; // ESC @ - Initialize
const cmd_T GET_STATUS{0x1b, 0x69, 0x53}; // ESC i S - Status query
const cmd_T PRINT_MODE{0x4d, 0x02}; // M 0x02 - Print mode
const cmd_T AUTO_STATUS{0x1b, 0x69, 0x61, 0x01}; // ESC i a - Auto status
const cmd_T MODE_SETTING{0x1b, 0x69, 0x4d, 0x40}; // ESC i M @ - Advanced mode
const cmd_T RASTER_START{0x1b, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const cmd_T INFO{0x1b, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const cmd_T PACKBITSON{0x02};

115
update_copyright.sh Executable file
View File

@@ -0,0 +1,115 @@
#!/bin/bash
# update_copyright.sh
# Updates copyright year ranges in a source file based on git history
#
# Usage: ./update_copyright.sh [--dry-run] <file>
#
# Examples:
# # Update a single file
# ./update_copyright.sh src/main.cpp
#
# # Dry-run on a single file
# ./update_copyright.sh --dry-run src/main.cpp
#
# # Update all C++ files using find -exec
# find src \( -name "*.cpp" -o -name "*.hpp" \) -exec ./update_copyright.sh {} \;
#
# # Dry-run on all C++ files
# find src \( -name "*.cpp" -o -name "*.hpp" \) -exec ./update_copyright.sh --dry-run {} \;
set -e
# Check for dry-run flag
DRY_RUN=false
FILE=""
if [ "$1" = "--dry-run" ]; then
DRY_RUN=true
FILE="$2"
elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
grep "^#" "$0" | sed 's/^# \?//'
exit 0
else
FILE="$1"
fi
# Check if file argument provided
if [ -z "$FILE" ]; then
echo "Error: No file specified"
echo "Usage: $0 [--dry-run] <file>"
echo "Run '$0 --help' for more information"
exit 1
fi
# Check if file exists
if [ ! -f "$FILE" ]; then
echo "Error: File not found: $FILE"
exit 1
fi
# Get the repository root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# Copyright holder name
COPYRIGHT_HOLDER="Moritz Martinius"
# Function to get first and last commit years for a file
get_years_for_file() {
local file="$1"
# Get the year of the first commit that touched this file
first_year=$(git log --follow --format=%ad --date=format:%Y --reverse "$file" 2>/dev/null | head -1)
# Get the year of the last commit that touched this file
last_year=$(git log --follow --format=%ad --date=format:%Y -1 "$file" 2>/dev/null)
# If file is not in git, use current year
if [ -z "$first_year" ]; then
first_year=$(date +%Y)
last_year=$(date +%Y)
fi
echo "$first_year $last_year"
}
# Get years from git history
read -r first_year last_year <<< "$(get_years_for_file "$FILE")"
# Determine the copyright year string
if [ "$first_year" = "$last_year" ]; then
year_string="$first_year"
else
year_string="$first_year-$last_year"
fi
# Check if file has a copyright notice
if ! grep -q "Copyright (C)" "$FILE"; then
echo "No copyright notice found in $FILE, skipping"
exit 0
fi
if [ "$DRY_RUN" = true ]; then
# Just show what would be changed
current_year=$(grep "Copyright (C)" "$FILE" | sed -n 's/.*Copyright (C) \([0-9]\{4\}\(-[0-9]\{4\}\)\?\).*/\1/p' | head -1)
if [ "$current_year" != "$year_string" ]; then
echo "Would update $FILE: $current_year$year_string"
else
echo "No change needed for $FILE (already $year_string)"
fi
else
# Update the copyright line
# Matches patterns like "Copyright (C) 2023 Moritz Martinius" or "Copyright (C) 2023-2024 Moritz Martinius"
# Handle variable whitespace between year and name
# Get current year from file for comparison
current_year=$(grep "Copyright (C)" "$FILE" | sed -n 's/.*Copyright (C) \([0-9]\{4\}\(-[0-9]\{4\}\)\?\).*/\1/p' | head -1)
if [ "$current_year" = "$year_string" ]; then
echo "No changes needed for $FILE (already $year_string)"
else
sed -i "s/Copyright (C) [0-9]\{4\}\(-[0-9]\{4\}\)\? \+$COPYRIGHT_HOLDER/Copyright (C) $year_string $COPYRIGHT_HOLDER/" "$FILE"
echo "✓ Updated $FILE: $current_year$year_string"
fi
fi