This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
#include "spdlog/fmt/bin_to_hex.h"
|
#include "spdlog/fmt/bin_to_hex.h"
|
||||||
|
|
||||||
// as long as DRYRUN is defined, no data is actually send to the printer, we need to save some tape ;)
|
// as long as DRYRUN is defined, no data is actually send to the printer, we need to save some tape ;)
|
||||||
//#define DRYRUN
|
#define DRYRUN
|
||||||
|
|
||||||
namespace ptprnt::printer {
|
namespace ptprnt::printer {
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ bool P700Printer::detachUsbDevice() {
|
|||||||
|
|
||||||
bool P700Printer::printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) {
|
bool P700Printer::printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) {
|
||||||
#ifdef DRYRUN
|
#ifdef DRYRUN
|
||||||
SPDLOG_DEBUG("DRYRUN enabled");
|
spdlog::debug("DRYRUN enabled");
|
||||||
for (unsigned int lineNo = 0; lineNo < bitmap.getHeight(); lineNo++) {
|
for (unsigned int lineNo = 0; lineNo < bitmap.getHeight(); lineNo++) {
|
||||||
auto line = bitmap.getLine(lineNo);
|
auto line = bitmap.getLine(lineNo);
|
||||||
auto monoLine = graphics::Monochrome(*line);
|
auto monoLine = graphics::Monochrome(*line);
|
||||||
@@ -158,26 +158,6 @@ bool P700Printer::printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool P700Printer::setText(const std::string& text) {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool P700Printer::setFont(const std::string& text) {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool P700Printer::setFontSize(uint8_t fontSize) {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool P700Printer::setHAlign(HAlignPosition hpos) {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool P700Printer::setVAlign(VAlignPosition vpos) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool P700Printer::print() {
|
bool P700Printer::print() {
|
||||||
send(p700::commands::LF);
|
send(p700::commands::LF);
|
||||||
send(p700::commands::FF);
|
send(p700::commands::FF);
|
||||||
@@ -201,7 +181,7 @@ bool P700Printer::send(const std::vector<uint8_t>& data) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
tx = data.size();
|
tx = data.size();
|
||||||
spdlog::info("USB raw data(len {}): {}", data.size(), spdlog::to_hex(data));
|
spdlog::trace("USB raw data(len {}): {}", data.size(), spdlog::to_hex(data));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (tx != static_cast<int>(data.size())) {
|
if (tx != static_cast<int>(data.size())) {
|
||||||
|
@@ -44,6 +44,9 @@ const cmd_T PRINTER_INFO{0x81};
|
|||||||
|
|
||||||
constexpr uint8_t MAX_TRIES_GET_STATUS = 10;
|
constexpr uint8_t MAX_TRIES_GET_STATUS = 10;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Remove Text-layout specific parts, add them to label
|
||||||
|
|
||||||
class P700Printer : public ::ptprnt::IPrinterDriver {
|
class P700Printer : public ::ptprnt::IPrinterDriver {
|
||||||
public:
|
public:
|
||||||
P700Printer() = default;
|
P700Printer() = default;
|
||||||
@@ -67,11 +70,6 @@ class P700Printer : public ::ptprnt::IPrinterDriver {
|
|||||||
[[nodiscard]] const PrinterStatus getPrinterStatus() override;
|
[[nodiscard]] const PrinterStatus getPrinterStatus() override;
|
||||||
bool attachUsbDevice(std::shared_ptr<libusbwrap::IUsbDevice> usbHndl) override;
|
bool attachUsbDevice(std::shared_ptr<libusbwrap::IUsbDevice> usbHndl) override;
|
||||||
bool detachUsbDevice() override;
|
bool detachUsbDevice() override;
|
||||||
bool setText(const std::string& text) override;
|
|
||||||
bool setFont(const std::string& text) override;
|
|
||||||
bool setFontSize(uint8_t fontSize) override;
|
|
||||||
bool setHAlign(HAlignPosition hpos) override;
|
|
||||||
bool setVAlign(VAlignPosition vpos) override;
|
|
||||||
bool printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) override;
|
bool printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) override;
|
||||||
bool print() override;
|
bool print() override;
|
||||||
|
|
||||||
|
@@ -16,12 +16,10 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include <cstdint>
|
#include "PtouchPrint.hpp"
|
||||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
|
|
||||||
#define SPDLOG_DEBUG_ON
|
|
||||||
#define SPDLOG_TRACE_ON
|
|
||||||
|
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/details/synchronous_factory.h>
|
#include <spdlog/details/synchronous_factory.h>
|
||||||
@@ -31,15 +29,16 @@
|
|||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "CLI/Option.hpp"
|
#include "CLI/Option.hpp"
|
||||||
#include "PrinterDriverFactory.hpp"
|
#include "PrinterDriverFactory.hpp"
|
||||||
#include "PtouchPrint.hpp"
|
|
||||||
#include "graphics/Bitmap.hpp"
|
|
||||||
#include "graphics/Label.hpp"
|
#include "graphics/Label.hpp"
|
||||||
|
#include "graphics/interface/ILabel.hpp"
|
||||||
#include "libusbwrap/UsbDeviceFactory.hpp"
|
#include "libusbwrap/UsbDeviceFactory.hpp"
|
||||||
|
|
||||||
namespace ptprnt {
|
namespace ptprnt {
|
||||||
@@ -98,37 +97,64 @@ int PtouchPrint::run() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& cmd : mCommands) {
|
auto label = graphics::Label();
|
||||||
switch (cmd.first) {
|
std::string labelText{};
|
||||||
|
|
||||||
|
for (const auto& [cmd, value] : mCommands) {
|
||||||
|
switch (cmd) {
|
||||||
case CliCmdType::Text:
|
case CliCmdType::Text:
|
||||||
spdlog::debug("Setting text to {}", cmd.second);
|
if (labelText.empty()) {
|
||||||
printer->setText(cmd.second);
|
labelText = value;
|
||||||
|
} else {
|
||||||
|
labelText = labelText + '\n' + value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CliCmdType::Font:;
|
case CliCmdType::Font:
|
||||||
spdlog::debug("Setting font to {}", cmd.second);
|
spdlog::debug("Setting font to {}", value);
|
||||||
printer->setFont(cmd.second);
|
label.setFontFamily(value);
|
||||||
break;
|
break;
|
||||||
case CliCmdType::FontSize:;
|
case CliCmdType::FontSize:
|
||||||
spdlog::debug("Setting font size to {}", cmd.second);
|
spdlog::debug("Setting font size to {}", std::stod(value));
|
||||||
printer->setFontSize(static_cast<uint8_t>(std::atoi(cmd.second.c_str())));
|
label.setFontSize(std::stod(value));
|
||||||
break;
|
break;
|
||||||
case CliCmdType::HAlign:;
|
case CliCmdType::HAlign:
|
||||||
spdlog::debug("[Not implemented] Setting text horizontal alignment to {}", cmd.second);
|
spdlog::debug("Setting text horizontal alignment to {}", value);
|
||||||
|
{
|
||||||
|
auto hPos = HALignPositionMap.find(value);
|
||||||
|
if (hPos == HALignPositionMap.end()) {
|
||||||
|
spdlog::warn("Invalid horizontal alignment specified!");
|
||||||
|
label.setHAlign(HAlignPosition::UNKNOWN);
|
||||||
|
} else {
|
||||||
|
label.setHAlign(hPos->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CliCmdType::VAlign:;
|
case CliCmdType::VAlign:
|
||||||
spdlog::debug("[Not implemented] Setting text vertical alignment to {}", cmd.second);
|
spdlog::debug("Setting text vertical alignment to {}", value);
|
||||||
|
{
|
||||||
|
auto vPos = VALignPositionMap.find(value);
|
||||||
|
if (vPos == VALignPositionMap.end()) {
|
||||||
|
spdlog::warn("Invalid verical alignment specified!");
|
||||||
|
label.setVAlign(VAlignPosition::UNKNOWN);
|
||||||
|
} else {
|
||||||
|
label.setVAlign(vPos->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CliCmdType::None:;
|
case CliCmdType::None:
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
default:
|
default:
|
||||||
spdlog::warn("This command is currently not supported.");
|
spdlog::warn("This command is currently not supported.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if (!printer->print()) {
|
if (!printer->print()) {
|
||||||
spdlog::error("An error occured while printing");
|
spdlog::error("An error occured while printing");
|
||||||
return -1;
|
return -1;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
label.create(labelText, 128);
|
||||||
|
label.writeToPng("./testlabel.png");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,23 +211,39 @@ void PtouchPrint::setupCliParser() {
|
|||||||
->each([this](std::string text) { mCommands.emplace_back(CliCmdType::Text, text); });
|
->each([this](std::string text) { mCommands.emplace_back(CliCmdType::Text, text); });
|
||||||
mApp.add_option("-f,--font", "Font used for the following text occurences")
|
mApp.add_option("-f,--font", "Font used for the following text occurences")
|
||||||
->group("Text printing ")
|
->group("Text printing ")
|
||||||
->multi_option_policy(CLI::MultiOptionPolicy::TakeAll)
|
->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst)
|
||||||
->trigger_on_parse()
|
->trigger_on_parse()
|
||||||
->each([this](std::string font) { mCommands.emplace_back(CliCmdType::Font, font); });
|
->each([this](std::string font) { mCommands.emplace_back(CliCmdType::Font, font); });
|
||||||
mApp.add_option("-s,--fontsize", "Font size of the following text occurences")
|
mApp.add_option("-s,--fontsize", "Font size of the following text occurences")
|
||||||
->group("Text printing ")
|
->group("Text printing ")
|
||||||
->multi_option_policy(CLI::MultiOptionPolicy::TakeAll)
|
->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst)
|
||||||
->trigger_on_parse()
|
->trigger_on_parse()
|
||||||
->each([this](std::string size) { mCommands.emplace_back(CliCmdType::FontSize, size); });
|
->each([this](std::string size) { mCommands.emplace_back(CliCmdType::FontSize, size); });
|
||||||
mApp.add_option("--valign", "Vertical alignment of the following text occurences")
|
mApp.add_option("--valign", "Vertical alignment of the following text occurences")
|
||||||
->group("Text printing ")
|
->group("Text printing ")
|
||||||
->multi_option_policy(CLI::MultiOptionPolicy::TakeAll)
|
->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst)
|
||||||
->trigger_on_parse()
|
->trigger_on_parse()
|
||||||
|
->transform([](std::string in) -> std::string {
|
||||||
|
std::unordered_set<std::string> validValignOptions{"top", "middle", "bottom"};
|
||||||
|
std::transform(in.begin(), in.end(), in.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
if (validValignOptions.find(in) == validValignOptions.end()) {
|
||||||
|
return {""};
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
})
|
||||||
->each([this](std::string valign) { mCommands.emplace_back(CliCmdType::VAlign, valign); });
|
->each([this](std::string valign) { mCommands.emplace_back(CliCmdType::VAlign, valign); });
|
||||||
mApp.add_option("--halign", "Vertical alignment of the following text occurences")
|
mApp.add_option("--halign", "Vertical alignment of the following text occurences")
|
||||||
->group("Text printing ")
|
->group("Text printing ")
|
||||||
->multi_option_policy(CLI::MultiOptionPolicy::TakeAll)
|
->multi_option_policy(CLI::MultiOptionPolicy::TakeFirst)
|
||||||
->trigger_on_parse()
|
->trigger_on_parse()
|
||||||
|
->transform([](std::string in) -> std::string {
|
||||||
|
std::unordered_set<std::string> validValignOptions{"left", "center", "right", "justify"};
|
||||||
|
std::transform(in.begin(), in.end(), in.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
if (validValignOptions.find(in) == validValignOptions.end()) {
|
||||||
|
return {""};
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
})
|
||||||
->each([this](std::string halign) { mCommands.emplace_back(CliCmdType::HAlign, halign); });
|
->each([this](std::string halign) { mCommands.emplace_back(CliCmdType::HAlign, halign); });
|
||||||
|
|
||||||
// Image options
|
// Image options
|
||||||
|
@@ -24,23 +24,23 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iostream> // remove me
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "pango/pango-context.h"
|
#include "graphics/interface/ILabel.hpp"
|
||||||
#include "pango/pango-font.h"
|
#include "pango/pango-font.h"
|
||||||
#include "pango/pango-fontmap.h"
|
|
||||||
#include "pango/pango-layout.h"
|
#include "pango/pango-layout.h"
|
||||||
#include "pango/pango-types.h"
|
#include "pango/pango-types.h"
|
||||||
#include "pango/pangocairo.h"
|
#include "pango/pangocairo.h"
|
||||||
|
|
||||||
namespace ptprnt::graphics {
|
namespace ptprnt::graphics {
|
||||||
Label::Label()
|
Label::Label()
|
||||||
: mPangoCtx(pango_font_map_create_context(pango_cairo_font_map_get_default())),
|
: mCairoCtx(cairo_create(mSurface)),
|
||||||
|
mPangoCtx(pango_cairo_create_context(mCairoCtx)),
|
||||||
mPangoLyt(pango_layout_new(mPangoCtx)),
|
mPangoLyt(pango_layout_new(mPangoCtx)),
|
||||||
mPangoFontDesc(pango_font_description_from_string("Noto sans 32")) {}
|
mFontMap(pango_cairo_font_map_new()) {}
|
||||||
|
|
||||||
std::vector<uint8_t> Label::getRaw() {
|
std::vector<uint8_t> Label::getRaw() {
|
||||||
assert(mSurface != nullptr);
|
assert(mSurface != nullptr);
|
||||||
@@ -63,29 +63,78 @@ int Label::getLayoutWidth() {
|
|||||||
return mLayoutWidth;
|
return mLayoutWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Label::create(const std::string& labelText, const uint16_t heightPixel) {
|
bool Label::create(PrintableText printableText, const uint16_t heightPixel) {
|
||||||
|
setFontFamily(printableText.fontFamily);
|
||||||
|
setFontSize(printableText.fontSize);
|
||||||
|
|
||||||
|
return create(printableText.text, heightPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Label::create(const std::string& labelText, const uint16_t heightPixel) {
|
||||||
mPrinterHeight = heightPixel;
|
mPrinterHeight = heightPixel;
|
||||||
pango_layout_set_single_paragraph_mode(mPangoLyt, true);
|
|
||||||
|
// TODO: we need to create a custom fontconfig here so that Noto Emoji does not load the systems default
|
||||||
|
// fontconfig here. For this, we need to create a PangoFcFontMap and a custom FcConfig
|
||||||
|
// see: https://docs.gtk.org/PangoFc/method.FontMap.set_config.html
|
||||||
|
// see: https://gist.github.com/CallumDev/7c66b3f9cf7a876ef75f
|
||||||
|
PangoFontDescription* regularFont = pango_font_description_new();
|
||||||
|
pango_font_description_set_size(regularFont, static_cast<int>(mFontSize * PANGO_SCALE));
|
||||||
|
pango_font_description_set_family(regularFont, mFontFamily.c_str());
|
||||||
|
//pango_layout_set_single_paragraph_mode(mPangoLyt, true); // this will force a single line in the label width width -1
|
||||||
pango_layout_set_height(mPangoLyt, getNumLines(labelText) * -1);
|
pango_layout_set_height(mPangoLyt, getNumLines(labelText) * -1);
|
||||||
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_CENTER);
|
pango_layout_set_font_description(mPangoLyt, regularFont);
|
||||||
pango_layout_set_font_description(mPangoLyt, mPangoFontDesc);
|
|
||||||
pango_context_load_font(mPangoCtx, mPangoFontDesc);
|
|
||||||
pango_layout_set_text(mPangoLyt, labelText.c_str(), static_cast<int>(labelText.length()));
|
pango_layout_set_text(mPangoLyt, labelText.c_str(), static_cast<int>(labelText.length()));
|
||||||
|
|
||||||
pango_layout_get_size(mPangoLyt, &mLayoutWidth, &mLayoutHeight);
|
// Set horizontal alignment
|
||||||
|
switch (mHAlign) {
|
||||||
|
case HAlignPosition::LEFT:
|
||||||
|
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_LEFT);
|
||||||
|
break;
|
||||||
|
case HAlignPosition::RIGHT:
|
||||||
|
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_RIGHT);
|
||||||
|
break;
|
||||||
|
case HAlignPosition::JUSTIFY:
|
||||||
|
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_LEFT); // not sure if needed
|
||||||
|
pango_layout_set_justify(mPangoLyt, true);
|
||||||
|
pango_layout_set_justify_last_line(mPangoLyt, true);
|
||||||
|
break;
|
||||||
|
case HAlignPosition::CENTER:
|
||||||
|
[[fallthrough]];
|
||||||
|
default:
|
||||||
|
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_CENTER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate label size for Cairo surface creation
|
||||||
|
pango_layout_get_size(mPangoLyt, &mLayoutWidth, &mLayoutHeight);
|
||||||
mLayoutWidth /= PANGO_SCALE;
|
mLayoutWidth /= PANGO_SCALE;
|
||||||
mLayoutHeight /= PANGO_SCALE;
|
mLayoutHeight /= PANGO_SCALE;
|
||||||
|
|
||||||
SPDLOG_DEBUG("Layout width: {}, height: {}", mLayoutWidth, mLayoutHeight);
|
spdlog::debug("Layout width: {}, height: {}", mLayoutWidth, mLayoutHeight);
|
||||||
|
|
||||||
mSurface = cairo_image_surface_create(CAIRO_FORMAT_A8, mLayoutWidth, mPrinterHeight);
|
mSurface = cairo_image_surface_create(CAIRO_FORMAT_A8, mLayoutWidth, mPrinterHeight);
|
||||||
cairo_t* cr = cairo_create(mSurface);
|
cairo_t* cr = cairo_create(mSurface);
|
||||||
|
|
||||||
|
// Adjust Cairo cursor position to respect the vertical alignment
|
||||||
|
switch (mVAlign) {
|
||||||
|
case VAlignPosition::TOP:
|
||||||
|
break;
|
||||||
|
case VAlignPosition::BOTTOM:
|
||||||
|
cairo_move_to(cr, 0.0, mPrinterHeight - mLayoutHeight);
|
||||||
|
break;
|
||||||
|
case VAlignPosition::MIDDLE:
|
||||||
|
cairo_move_to(cr, 0.0, (mPrinterHeight - mLayoutHeight) / 2);
|
||||||
|
[[fallthrough]];
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally show the layout on the Cairo surface
|
||||||
pango_cairo_show_layout(cr, mPangoLyt);
|
pango_cairo_show_layout(cr, mPangoLyt);
|
||||||
|
|
||||||
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
||||||
cairo_surface_flush(mSurface);
|
cairo_surface_flush(mSurface);
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Label::writeToPng(const std::string& file) {
|
void Label::writeToPng(const std::string& file) {
|
||||||
@@ -95,11 +144,31 @@ void Label::writeToPng(const std::string& file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Label::setFontSize(const double fontSize) {
|
||||||
|
mFontSize = fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setFontFamily(const std::string& fontFamily) {
|
||||||
|
mFontFamily = fontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setHAlign(HAlignPosition hAlign) {
|
||||||
|
mHAlign = hAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setVAlign(VAlignPosition vAlign) {
|
||||||
|
mVAlign = vAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setText(const std::string& text) {
|
||||||
|
mText = text;
|
||||||
|
}
|
||||||
|
|
||||||
Label::~Label() {
|
Label::~Label() {
|
||||||
SPDLOG_DEBUG("Image dtor...");
|
spdlog::debug("Image dtor...");
|
||||||
pango_font_description_free(mPangoFontDesc);
|
|
||||||
g_object_unref(mPangoCtx);
|
g_object_unref(mPangoCtx);
|
||||||
g_object_unref(mPangoLyt);
|
g_object_unref(mPangoLyt);
|
||||||
|
g_object_unref(mFontMap);
|
||||||
cairo_surface_destroy(mSurface);
|
cairo_surface_destroy(mSurface);
|
||||||
}
|
}
|
||||||
} // namespace ptprnt::graphics
|
} // namespace ptprnt::graphics
|
@@ -26,15 +26,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "pango/pango-font.h"
|
#include "graphics/interface/ILabel.hpp"
|
||||||
#include "pango/pango-types.h"
|
#include "pango/pango-types.h"
|
||||||
|
|
||||||
namespace ptprnt::graphics {
|
namespace ptprnt::graphics {
|
||||||
|
|
||||||
constexpr const char* DEFAULT_FONT_FAMILY = "sans";
|
class Label : public ILabel {
|
||||||
constexpr const uint8_t DEFAULT_FONT_SIZE = 32;
|
|
||||||
|
|
||||||
class Label {
|
|
||||||
public:
|
public:
|
||||||
Label();
|
Label();
|
||||||
~Label();
|
~Label();
|
||||||
@@ -44,20 +41,35 @@ class Label {
|
|||||||
Label(Label&&) = delete;
|
Label(Label&&) = delete;
|
||||||
Label& operator=(Label&&) = delete;
|
Label& operator=(Label&&) = delete;
|
||||||
|
|
||||||
std::vector<uint8_t> getRaw();
|
bool create(PrintableText printableText, const uint16_t heightPixel) override;
|
||||||
void create(const std::string& labelText, const uint16_t heightPixel);
|
bool create(const std::string& labelText, const uint16_t heightPixel) override;
|
||||||
void writeToPng(const std::string& file);
|
void writeToPng(const std::string& file);
|
||||||
int getLayoutWidth();
|
[[nodiscard]] int getLayoutWidth() override;
|
||||||
int getLayoutHeight();
|
[[nodiscard]] int getLayoutHeight() override;
|
||||||
|
[[nodiscard]] std::vector<uint8_t> getRaw() override;
|
||||||
|
void setFontSize(const double fontSize) override;
|
||||||
|
void setFontFamily(const std::string& fontFamily) override;
|
||||||
|
|
||||||
|
void setText(const std::string& text) override;
|
||||||
|
void setHAlign(HAlignPosition hpos) override;
|
||||||
|
void setVAlign(VAlignPosition vpos) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
uint8_t getNumLines(std::string_view str);
|
[[nodiscard]] uint8_t getNumLines(std::string_view str);
|
||||||
|
[[nodiscard]] PangoFontMap* createCustomFontMap();
|
||||||
// members
|
// members
|
||||||
|
// TODO: convert raw pointers here into std::unique_ptr with custom deleters, calling g_object_unref()
|
||||||
|
cairo_surface_t* mSurface{nullptr};
|
||||||
|
cairo_t* mCairoCtx{nullptr};
|
||||||
PangoContext* mPangoCtx{nullptr};
|
PangoContext* mPangoCtx{nullptr};
|
||||||
PangoLayout* mPangoLyt{nullptr};
|
PangoLayout* mPangoLyt{nullptr};
|
||||||
PangoFontDescription* mPangoFontDesc{nullptr};
|
PangoFontMap* mFontMap{nullptr};
|
||||||
cairo_surface_t* mSurface{nullptr};
|
double mFontSize{DEFAULT_FONT_SIZE};
|
||||||
|
std::string mFontFamily{DEFAULT_FONT_FAMILY};
|
||||||
|
HAlignPosition mHAlign = HAlignPosition::LEFT;
|
||||||
|
VAlignPosition mVAlign = VAlignPosition::MIDDLE;
|
||||||
|
std::string mText{""};
|
||||||
int mLayoutWidth = 0, mLayoutHeight = 0;
|
int mLayoutWidth = 0, mLayoutHeight = 0;
|
||||||
int mPrinterHeight = 0;
|
int mPrinterHeight = 0;
|
||||||
};
|
};
|
||||||
|
78
src/graphics/interface/ILabel.hpp
Normal file
78
src/graphics/interface/ILabel.hpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
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>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
constexpr const char* DEFAULT_FONT_FAMILY = "sans";
|
||||||
|
constexpr const double DEFAULT_FONT_SIZE = 32.0;
|
||||||
|
|
||||||
|
enum class HAlignPosition {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
LEFT = 1,
|
||||||
|
CENTER = 2,
|
||||||
|
RIGHT = 3,
|
||||||
|
JUSTIFY = 4,
|
||||||
|
};
|
||||||
|
const std::map<std::string, HAlignPosition> HALignPositionMap{{"", HAlignPosition::UNKNOWN},
|
||||||
|
{"left", HAlignPosition::LEFT},
|
||||||
|
{"center", HAlignPosition::CENTER},
|
||||||
|
{"right", HAlignPosition::RIGHT},
|
||||||
|
{"justify", HAlignPosition::JUSTIFY}};
|
||||||
|
|
||||||
|
enum class VAlignPosition {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
TOP = 1,
|
||||||
|
MIDDLE = 2,
|
||||||
|
BOTTOM = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<std::string, VAlignPosition> VALignPositionMap{{"", VAlignPosition::UNKNOWN},
|
||||||
|
{"top", VAlignPosition::TOP},
|
||||||
|
{"middle", VAlignPosition::MIDDLE},
|
||||||
|
{"bottom", VAlignPosition::BOTTOM}};
|
||||||
|
|
||||||
|
struct PrintableText {
|
||||||
|
std::string text{""};
|
||||||
|
std::string fontFamily{DEFAULT_FONT_FAMILY};
|
||||||
|
double fontSize{DEFAULT_FONT_SIZE};
|
||||||
|
HAlignPosition hAlign{HAlignPosition::LEFT};
|
||||||
|
VAlignPosition vAlign{VAlignPosition::MIDDLE};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ILabel {
|
||||||
|
public:
|
||||||
|
virtual ~ILabel() = default;
|
||||||
|
|
||||||
|
virtual bool create(PrintableText printableText, const uint16_t heightPixel) = 0;
|
||||||
|
virtual bool create(const std::string& labelText, const uint16_t heightPixel) = 0;
|
||||||
|
virtual std::vector<uint8_t> getRaw() = 0;
|
||||||
|
virtual int getLayoutWidth() = 0;
|
||||||
|
virtual int getLayoutHeight() = 0;
|
||||||
|
|
||||||
|
virtual void setText(const std::string& text) = 0;
|
||||||
|
virtual void setFontSize(const double fontSize) = 0;
|
||||||
|
virtual void setFontFamily(const std::string& fontFamily) = 0;
|
||||||
|
virtual void setHAlign(HAlignPosition hpos) = 0;
|
||||||
|
virtual void setVAlign(VAlignPosition vpos) = 0;
|
||||||
|
};
|
@@ -39,11 +39,6 @@ class IPrinterDriver {
|
|||||||
[[nodiscard]] virtual const PrinterStatus getPrinterStatus() = 0;
|
[[nodiscard]] virtual const PrinterStatus getPrinterStatus() = 0;
|
||||||
virtual bool attachUsbDevice(std::shared_ptr<libusbwrap::IUsbDevice> usbHndl) = 0;
|
virtual bool attachUsbDevice(std::shared_ptr<libusbwrap::IUsbDevice> usbHndl) = 0;
|
||||||
virtual bool detachUsbDevice() = 0;
|
virtual bool detachUsbDevice() = 0;
|
||||||
virtual bool setText(const std::string& text) = 0;
|
|
||||||
virtual bool setFont(const std::string& text) = 0;
|
|
||||||
virtual bool setFontSize(uint8_t fontSize) = 0;
|
|
||||||
virtual bool setHAlign(HAlignPosition hpos) = 0;
|
|
||||||
virtual bool setVAlign(VAlignPosition vpos) = 0;
|
|
||||||
virtual bool printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) = 0;
|
virtual bool printBitmap(const graphics::Bitmap<graphics::ALPHA8>& bitmap) = 0;
|
||||||
virtual bool print() = 0;
|
virtual bool print() = 0;
|
||||||
};
|
};
|
||||||
|
@@ -43,27 +43,4 @@ struct PrinterStatus {
|
|||||||
|
|
||||||
using cmd_T = std::vector<uint8_t>;
|
using cmd_T = std::vector<uint8_t>;
|
||||||
|
|
||||||
enum class HAlignPosition {
|
|
||||||
UNKNOWN = 0,
|
|
||||||
LEFT = 1,
|
|
||||||
CENTER = 2,
|
|
||||||
RIGHT = 3,
|
|
||||||
JUSTIFY = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class VAlignPosition {
|
|
||||||
UNKNOWN = 0,
|
|
||||||
TOP = 1,
|
|
||||||
MIDDLE = 2,
|
|
||||||
BOTTOM = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PrintableText {
|
|
||||||
std::string text{""};
|
|
||||||
std::string font{"Noto"};
|
|
||||||
uint8_t fontSize{0};
|
|
||||||
HAlignPosition hAlign{HAlignPosition::LEFT};
|
|
||||||
VAlignPosition vAlign{VAlignPosition::MIDDLE};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ptprnt
|
} // namespace ptprnt
|
Reference in New Issue
Block a user