105 lines
3.2 KiB
C++
105 lines
3.2 KiB
C++
/*
|
|
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/>.
|
|
|
|
*/
|
|
|
|
#include "graphics/Label.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <spdlog/spdlog.h>
|
|
|
|
#include <cassert>
|
|
#include <cstddef>
|
|
#include <iostream> // remove me
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "cairo.h"
|
|
#include "pango/pango-context.h"
|
|
#include "pango/pango-font.h"
|
|
#include "pango/pango-fontmap.h"
|
|
#include "pango/pango-layout.h"
|
|
#include "pango/pango-types.h"
|
|
#include "pango/pangocairo.h"
|
|
|
|
namespace ptprnt::graphics {
|
|
Label::Label()
|
|
: mPangoCtx(pango_font_map_create_context(pango_cairo_font_map_get_default())),
|
|
mPangoLyt(pango_layout_new(mPangoCtx)),
|
|
mPangoFontDesc(pango_font_description_from_string("Noto sans 32")) {}
|
|
|
|
std::vector<uint8_t> Label::getRaw() {
|
|
assert(mSurface != nullptr);
|
|
size_t len = mPrinterHeight * mLayoutWidth;
|
|
|
|
cairo_surface_flush(mSurface);
|
|
auto data = cairo_image_surface_get_data(mSurface);
|
|
return {data, data + len};
|
|
}
|
|
|
|
uint8_t Label::getNumLines(std::string_view strv) {
|
|
return std::count(strv.begin(), strv.end(), '\n');
|
|
}
|
|
|
|
int Label::getLayoutHeight() {
|
|
return mLayoutHeight;
|
|
}
|
|
|
|
int Label::getLayoutWidth() {
|
|
return mLayoutWidth;
|
|
}
|
|
|
|
void Label::create(const std::string& labelText, const uint16_t heightPixel) {
|
|
mPrinterHeight = heightPixel;
|
|
pango_layout_set_single_paragraph_mode(mPangoLyt, true);
|
|
pango_layout_set_height(mPangoLyt, getNumLines(labelText) * -1);
|
|
pango_layout_set_alignment(mPangoLyt, PANGO_ALIGN_CENTER);
|
|
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_get_size(mPangoLyt, &mLayoutWidth, &mLayoutHeight);
|
|
|
|
mLayoutWidth /= PANGO_SCALE;
|
|
mLayoutHeight /= PANGO_SCALE;
|
|
|
|
SPDLOG_DEBUG("Layout width: {}, height: {}", mLayoutWidth, mLayoutHeight);
|
|
|
|
mSurface = cairo_image_surface_create(CAIRO_FORMAT_A8, mLayoutWidth, mPrinterHeight);
|
|
cairo_t* cr = cairo_create(mSurface);
|
|
pango_cairo_show_layout(cr, mPangoLyt);
|
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
|
cairo_surface_flush(mSurface);
|
|
cairo_destroy(cr);
|
|
}
|
|
|
|
void Label::writeToPng(const std::string& file) {
|
|
if (mSurface) {
|
|
cairo_surface_flush(mSurface);
|
|
cairo_surface_write_to_png(mSurface, file.c_str());
|
|
}
|
|
}
|
|
|
|
Label::~Label() {
|
|
SPDLOG_DEBUG("Image dtor...");
|
|
pango_font_description_free(mPangoFontDesc);
|
|
g_object_unref(mPangoCtx);
|
|
g_object_unref(mPangoLyt);
|
|
cairo_surface_destroy(mSurface);
|
|
}
|
|
} // namespace ptprnt::graphics
|