wip(refactor): Cairo drawing
This commit is contained in:
parent
452afcdc68
commit
a59e115622
@ -11,6 +11,7 @@
|
|||||||
#include "cairo/utils.hpp"
|
#include "cairo/utils.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "components/logger.hpp"
|
#include "components/logger.hpp"
|
||||||
|
#include "components/types.hpp"
|
||||||
#include "errors.hpp"
|
#include "errors.hpp"
|
||||||
#include "utils/color.hpp"
|
#include "utils/color.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@ -63,6 +64,9 @@ namespace cairo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context& operator<<(const abspos& p) {
|
context& operator<<(const abspos& p) {
|
||||||
|
if (p.clear) {
|
||||||
|
cairo_new_path(m_c);
|
||||||
|
}
|
||||||
cairo_move_to(m_c, p.x, p.y);
|
cairo_move_to(m_c, p.x, p.y);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -117,8 +121,24 @@ namespace cairo {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context& operator<<(const rounded_corners& c) {
|
||||||
|
double radius = c.radius / 1.0;
|
||||||
|
double d = M_PI / 180.0;
|
||||||
|
cairo_new_sub_path(m_c);
|
||||||
|
cairo_arc(m_c, c.x + c.w - radius, c.y + radius, radius, -90 * d, 0 * d);
|
||||||
|
cairo_arc(m_c, c.x + c.w - radius, c.y + c.h - radius, radius, 0 * d, 90 * d);
|
||||||
|
cairo_arc(m_c, c.x + radius, c.y + c.h - radius, radius, 90 * d, 180 * d);
|
||||||
|
cairo_arc(m_c, c.x + radius, c.y + radius, radius, 180 * d, 270 * d);
|
||||||
|
cairo_close_path(m_c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
context& operator<<(const textblock& t) {
|
context& operator<<(const textblock& t) {
|
||||||
// Sort the fontlist so that the preferred font is tested first
|
double x, y;
|
||||||
|
position(&x, &y);
|
||||||
|
|
||||||
|
// Sort the fontlist so that the
|
||||||
|
// preferred font gets prioritized
|
||||||
auto& fns = m_fonts;
|
auto& fns = m_fonts;
|
||||||
std::sort(fns.begin(), fns.end(), [&](const unique_ptr<font>& a, const unique_ptr<font>&) {
|
std::sort(fns.begin(), fns.end(), [&](const unique_ptr<font>& a, const unique_ptr<font>&) {
|
||||||
if (t.fontindex > 0 && std::distance(fns.begin(), std::find(fns.begin(), fns.end(), a)) == t.fontindex - 1) {
|
if (t.fontindex > 0 && std::distance(fns.begin(), std::find(fns.begin(), fns.end(), a)) == t.fontindex - 1) {
|
||||||
@ -147,18 +167,56 @@ namespace cairo {
|
|||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->use(m_c);
|
// encapsulate the vert. centering
|
||||||
|
save();
|
||||||
|
{
|
||||||
|
*this << abspos{x, y};
|
||||||
|
|
||||||
cairo_text_extents_t extents;
|
f->use();
|
||||||
f->textwidth(utf8, &extents);
|
|
||||||
|
|
||||||
save(); // encapsulate the y pos update
|
cairo_text_extents_t extents;
|
||||||
*this << relpos{0.0, extents.height / 2.0 - f->extents().descent + f->offset()};
|
f->textwidth(utf8, &extents);
|
||||||
f->render(subset);
|
double dx{0.0}, dy{0.0};
|
||||||
|
|
||||||
|
if (t.align == alignment::CENTER) {
|
||||||
|
dx -= extents.x_advance / 2.0;
|
||||||
|
|
||||||
|
save();
|
||||||
|
{
|
||||||
|
cairo_rectangle(m_c, x, y, extents.x_advance / 2.0, extents.height);
|
||||||
|
auto pattern = cairo_pattern_create_rgba(1.0, 0.0, 0.0, 0.0);
|
||||||
|
cairo_set_source(m_c, pattern);
|
||||||
|
cairo_translate(m_c, dx, 0.0);
|
||||||
|
cairo_set_operator(m_c, CAIRO_OPERATOR_DEST);
|
||||||
|
cairo_fill(m_c);
|
||||||
|
cairo_pattern_destroy(pattern);
|
||||||
|
}
|
||||||
|
restore();
|
||||||
|
} else if (t.align == alignment::RIGHT) {
|
||||||
|
dx -= extents.x_advance;
|
||||||
|
|
||||||
|
save();
|
||||||
|
{
|
||||||
|
cairo_rectangle(m_c, x, y, extents.x_advance, extents.height);
|
||||||
|
auto pattern = cairo_pattern_create_rgba(0.0, 0.0, 0.0, 0.0);
|
||||||
|
cairo_set_source(m_c, pattern);
|
||||||
|
cairo_set_operator(m_c, CAIRO_OPERATOR_DEST);
|
||||||
|
cairo_translate(m_c, dx, 0.0);
|
||||||
|
cairo_fill(m_c);
|
||||||
|
cairo_pattern_destroy(pattern);
|
||||||
|
}
|
||||||
|
restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fontextents = f->extents();
|
||||||
|
f->render(subset, x + dx,
|
||||||
|
y + dy - (extents.height / 2.0 + extents.y_bearing + fontextents.descent) + f->offset());
|
||||||
|
position(&x, nullptr);
|
||||||
|
x += dx;
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
restore();
|
restore();
|
||||||
|
|
||||||
*this << relpos{extents.width, 0.0};
|
|
||||||
|
|
||||||
chars.erase(chars.begin(), end);
|
chars.erase(chars.begin(), end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -179,6 +237,8 @@ namespace cairo {
|
|||||||
chars.erase(chars.begin(), ++chars.begin());
|
chars.erase(chars.begin(), ++chars.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*this << abspos{x, y};
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,11 +257,11 @@ namespace cairo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context& restore(bool restore_point = true) {
|
context& restore(bool restore_point = true) {
|
||||||
|
cairo_restore(m_c);
|
||||||
if (restore_point) {
|
if (restore_point) {
|
||||||
*this << abspos{m_points.front().first, m_points.front().first};
|
*this << abspos{m_points.front().first, m_points.front().first};
|
||||||
m_points.pop_front();
|
m_points.pop_front();
|
||||||
}
|
}
|
||||||
cairo_restore(m_c);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,8 +275,12 @@ namespace cairo {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
context& fill() {
|
context& fill(bool preserve = false) {
|
||||||
cairo_fill(m_c);
|
if (preserve) {
|
||||||
|
cairo_fill_preserve(m_c);
|
||||||
|
} else {
|
||||||
|
cairo_fill(m_c);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,10 +295,11 @@ namespace cairo {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
context& position(double* x, double* y) {
|
context& position(double* x, double* y = nullptr) {
|
||||||
*x = 0.0;
|
|
||||||
*y = 0.0;
|
|
||||||
if (cairo_has_current_point(m_c)) {
|
if (cairo_has_current_point(m_c)) {
|
||||||
|
double x_, y_;
|
||||||
|
x = x != nullptr ? x : &x_;
|
||||||
|
y = y != nullptr ? y : &y_;
|
||||||
cairo_get_current_point(m_c, x, y);
|
cairo_get_current_point(m_c, x, y);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -63,25 +63,23 @@ namespace cairo {
|
|||||||
class font {
|
class font {
|
||||||
public:
|
public:
|
||||||
explicit font(cairo_t* cairo, double offset) : m_cairo(cairo), m_offset(offset) {}
|
explicit font(cairo_t* cairo, double offset) : m_cairo(cairo), m_offset(offset) {}
|
||||||
virtual ~font() {};
|
virtual ~font(){};
|
||||||
|
|
||||||
virtual string name() const = 0;
|
virtual string name() const = 0;
|
||||||
virtual string file() const = 0;
|
virtual string file() const = 0;
|
||||||
virtual double offset() const = 0;
|
virtual double offset() const = 0;
|
||||||
virtual double size() const = 0;
|
virtual double size() const = 0;
|
||||||
|
|
||||||
virtual void use(cairo_t* c) {
|
virtual cairo_font_extents_t extents() = 0;
|
||||||
cairo_set_font_face(c, cairo_font_face_reference(m_font_face));
|
|
||||||
|
virtual void use() {
|
||||||
|
cairo_set_font_face(m_cairo, cairo_font_face_reference(m_font_face));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t match(unicode_charlist& charlist) = 0;
|
virtual size_t match(unicode_charlist& charlist) = 0;
|
||||||
virtual size_t render(const string& text) = 0;
|
virtual size_t render(const string& text, double x = 0.0, double y = 0.0, bool reverse = false) = 0;
|
||||||
virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0;
|
virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0;
|
||||||
|
|
||||||
cairo_font_extents_t extents() const {
|
|
||||||
return m_extents;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cairo_t* m_cairo;
|
cairo_t* m_cairo;
|
||||||
cairo_font_face_t* m_font_face{nullptr};
|
cairo_font_face_t* m_font_face{nullptr};
|
||||||
@ -111,7 +109,7 @@ namespace cairo {
|
|||||||
throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status));
|
throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = make_unique<details::ft_face_lock>(cairo_scaled_font_reference(m_scaled));
|
auto lock = make_unique<details::ft_face_lock>(m_scaled);
|
||||||
auto face = static_cast<FT_Face>(*lock);
|
auto face = static_cast<FT_Face>(*lock);
|
||||||
|
|
||||||
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) {
|
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) {
|
||||||
@ -121,6 +119,8 @@ namespace cairo {
|
|||||||
} else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) {
|
} else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
~font_fc() override {
|
~font_fc() override {
|
||||||
@ -132,6 +132,11 @@ namespace cairo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_font_extents_t extents() override {
|
||||||
|
cairo_scaled_font_extents(m_scaled, &m_extents);
|
||||||
|
return m_extents;
|
||||||
|
}
|
||||||
|
|
||||||
string name() const override {
|
string name() const override {
|
||||||
return property("family");
|
return property("family");
|
||||||
}
|
}
|
||||||
@ -157,12 +162,12 @@ namespace cairo {
|
|||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
void use(cairo_t* c) override {
|
void use() override {
|
||||||
cairo_set_scaled_font(c, cairo_scaled_font_reference(m_scaled));
|
cairo_set_scaled_font(m_cairo, m_scaled);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t match(unicode_charlist& charlist) override {
|
size_t match(unicode_charlist& charlist) override {
|
||||||
auto lock = make_unique<details::ft_face_lock>(cairo_scaled_font_reference(m_scaled));
|
auto lock = make_unique<details::ft_face_lock>(m_scaled);
|
||||||
auto face = static_cast<FT_Face>(*lock);
|
auto face = static_cast<FT_Face>(*lock);
|
||||||
size_t available_chars = 0;
|
size_t available_chars = 0;
|
||||||
for (auto&& c : charlist) {
|
for (auto&& c : charlist) {
|
||||||
@ -176,20 +181,22 @@ namespace cairo {
|
|||||||
return available_chars;
|
return available_chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t render(const string& text) override {
|
size_t render(const string& text, double x = 0.0, double y = 0.0, bool reverse = false) override {
|
||||||
double x, y;
|
|
||||||
cairo_get_current_point(m_cairo, &x, &y);
|
|
||||||
|
|
||||||
cairo_glyph_t* glyphs{nullptr};
|
cairo_glyph_t* glyphs{nullptr};
|
||||||
cairo_text_cluster_t* clusters{nullptr};
|
cairo_text_cluster_t* clusters{nullptr};
|
||||||
cairo_text_cluster_flags_t cf{};
|
cairo_text_cluster_flags_t cf{};
|
||||||
int nglyphs = 0, nclusters = 0;
|
int nglyphs = 0, nclusters = 0;
|
||||||
|
|
||||||
|
if (reverse) {
|
||||||
|
cf = CAIRO_TEXT_CLUSTER_FLAG_BACKWARD;
|
||||||
|
}
|
||||||
|
|
||||||
string utf8 = string(text);
|
string utf8 = string(text);
|
||||||
auto status = cairo_scaled_font_text_to_glyphs(cairo_scaled_font_reference(m_scaled), x, y, utf8.c_str(),
|
auto status = cairo_scaled_font_text_to_glyphs(
|
||||||
utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
||||||
|
|
||||||
if (status != CAIRO_STATUS_SUCCESS) {
|
if (status != CAIRO_STATUS_SUCCESS) {
|
||||||
throw application_error(sstream() << "cairo_scaled_font_status()" << cairo_status_to_string(status));
|
throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
@ -201,18 +208,36 @@ namespace cairo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes) {
|
if (bytes && bytes < text.size()) {
|
||||||
|
cairo_glyph_free(glyphs);
|
||||||
|
cairo_text_cluster_free(clusters);
|
||||||
|
|
||||||
utf8 = text.substr(0, bytes);
|
utf8 = text.substr(0, bytes);
|
||||||
cairo_scaled_font_text_to_glyphs(
|
auto status = cairo_scaled_font_text_to_glyphs(
|
||||||
m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);
|
||||||
cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
|
|
||||||
|
if (status != CAIRO_STATUS_SUCCESS) {
|
||||||
|
throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes) {
|
||||||
|
cairo_text_extents_t extents{};
|
||||||
|
cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents);
|
||||||
|
cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
|
||||||
|
cairo_rel_move_to(m_cairo, extents.x_advance, 0.0);
|
||||||
|
// cairo_glyph_path(m_cairo, glyphs, nglyphs);
|
||||||
|
cairo_fill_preserve(m_cairo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_glyph_free(glyphs);
|
||||||
|
cairo_text_cluster_free(clusters);
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void textwidth(const string& text, cairo_text_extents_t* extents) override {
|
void textwidth(const string& text, cairo_text_extents_t* extents) override {
|
||||||
cairo_scaled_font_text_extents(cairo_scaled_font_reference(m_scaled), text.c_str(), extents);
|
cairo_scaled_font_text_extents(m_scaled, text.c_str(), extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
|
enum class alignment;
|
||||||
|
|
||||||
namespace cairo {
|
namespace cairo {
|
||||||
struct abspos {
|
struct abspos {
|
||||||
double x;
|
double x;
|
||||||
double y;
|
double y;
|
||||||
|
bool clear{true};
|
||||||
};
|
};
|
||||||
struct relpos {
|
struct relpos {
|
||||||
double x;
|
double x;
|
||||||
@ -37,9 +40,18 @@ namespace cairo {
|
|||||||
vector<unsigned int> steps;
|
vector<unsigned int> steps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rounded_corners {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double w;
|
||||||
|
double h;
|
||||||
|
double radius;
|
||||||
|
};
|
||||||
|
|
||||||
struct textblock {
|
struct textblock {
|
||||||
|
alignment align;
|
||||||
string contents;
|
string contents;
|
||||||
unsigned char fontindex;
|
int fontindex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,7 @@ struct bar_settings {
|
|||||||
|
|
||||||
std::unordered_map<edge, border_settings, enum_hash> borders{};
|
std::unordered_map<edge, border_settings, enum_hash> borders{};
|
||||||
|
|
||||||
|
double radius{0.0};
|
||||||
int spacing{0};
|
int spacing{0};
|
||||||
string separator{};
|
string separator{};
|
||||||
|
|
||||||
|
@ -136,6 +136,7 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const
|
|||||||
m_opts.spacing = m_conf.get(bs, "spacing", m_opts.spacing);
|
m_opts.spacing = m_conf.get(bs, "spacing", m_opts.spacing);
|
||||||
m_opts.separator = m_conf.get(bs, "separator", ""s);
|
m_opts.separator = m_conf.get(bs, "separator", ""s);
|
||||||
m_opts.locale = m_conf.get(bs, "locale", ""s);
|
m_opts.locale = m_conf.get(bs, "locale", ""s);
|
||||||
|
m_opts.radius = m_conf.get(bs, "radius", m_opts.radius);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto padding = m_conf.get<decltype(m_opts.padding.left)>(bs, "module-padding");
|
auto padding = m_conf.get<decltype(m_opts.padding.left)>(bs, "module-padding");
|
||||||
|
@ -256,8 +256,8 @@ void renderer::flush() {
|
|||||||
/**
|
/**
|
||||||
* Reserve space at given edge
|
* Reserve space at given edge
|
||||||
*/
|
*/
|
||||||
void renderer::reserve_space(edge side, unsigned short int w) {
|
void renderer::reserve_space(edge side, unsigned int w) {
|
||||||
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<unsigned char>(side), w);
|
m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast<int>(side), w);
|
||||||
|
|
||||||
m_cleararea.side = side;
|
m_cleararea.side = side;
|
||||||
m_cleararea.size = w;
|
m_cleararea.size = w;
|
||||||
@ -295,6 +295,16 @@ void renderer::fill_background() {
|
|||||||
m_context->save();
|
m_context->save();
|
||||||
*m_context << m_compositing_background;
|
*m_context << m_compositing_background;
|
||||||
|
|
||||||
|
if (m_bar.radius != 0.0) {
|
||||||
|
// clang-format off
|
||||||
|
*m_context << cairo::rounded_corners{
|
||||||
|
static_cast<double>(m_rect.x),
|
||||||
|
static_cast<double>(m_rect.y),
|
||||||
|
static_cast<double>(m_rect.width),
|
||||||
|
static_cast<double>(m_rect.height), m_bar.radius};
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_bar.background_steps.empty()) {
|
if (!m_bar.background_steps.empty()) {
|
||||||
m_log.trace_x("renderer: gradient background (steps=%lu)", m_bar.background_steps.size());
|
m_log.trace_x("renderer: gradient background (steps=%lu)", m_bar.background_steps.size());
|
||||||
*m_context << cairo::linear_gradient{0.0, 0.0 + m_rect.y, 0.0, 0.0 + m_rect.height, m_bar.background_steps};
|
*m_context << cairo::linear_gradient{0.0, 0.0 + m_rect.y, 0.0, 0.0 + m_rect.height, m_bar.background_steps};
|
||||||
@ -303,7 +313,12 @@ void renderer::fill_background() {
|
|||||||
*m_context << m_bar.background;
|
*m_context << m_bar.background;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_context->paint();
|
if (m_bar.radius != 0.0) {
|
||||||
|
m_context->fill();
|
||||||
|
} else {
|
||||||
|
m_context->paint();
|
||||||
|
}
|
||||||
|
|
||||||
m_context->restore();
|
m_context->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,8 +326,8 @@ void renderer::fill_background() {
|
|||||||
* Fill overline color
|
* Fill overline color
|
||||||
*/
|
*/
|
||||||
void renderer::fill_overline(double x, double w) {
|
void renderer::fill_overline(double x, double w) {
|
||||||
if (m_bar.overline.size && m_attributes.test(static_cast<unsigned char>(attribute::OVERLINE))) {
|
if (m_bar.overline.size && m_attributes.test(static_cast<int>(attribute::OVERLINE))) {
|
||||||
m_log.trace_x("renderer: overline(x=%i, w=%i)", x, w);
|
m_log.trace_x("renderer: overline(x=%f, w=%f)", x, w);
|
||||||
m_context->save();
|
m_context->save();
|
||||||
*m_context << m_compositing_overline;
|
*m_context << m_compositing_overline;
|
||||||
*m_context << m_color_overline;
|
*m_context << m_color_overline;
|
||||||
@ -326,8 +341,8 @@ void renderer::fill_overline(double x, double w) {
|
|||||||
* Fill underline color
|
* Fill underline color
|
||||||
*/
|
*/
|
||||||
void renderer::fill_underline(double x, double w) {
|
void renderer::fill_underline(double x, double w) {
|
||||||
if (m_bar.underline.size && m_attributes.test(static_cast<unsigned char>(attribute::UNDERLINE))) {
|
if (m_bar.underline.size && m_attributes.test(static_cast<int>(attribute::UNDERLINE))) {
|
||||||
m_log.trace_x("renderer: underline(x=%i, w=%i)", x, w);
|
m_log.trace_x("renderer: underline(x=%f, w=%f)", x, w);
|
||||||
m_context->save();
|
m_context->save();
|
||||||
*m_context << m_compositing_underline;
|
*m_context << m_compositing_underline;
|
||||||
*m_context << m_color_underline;
|
*m_context << m_color_underline;
|
||||||
@ -382,21 +397,15 @@ void renderer::fill_borders() {
|
|||||||
void renderer::draw_text(const string& contents) {
|
void renderer::draw_text(const string& contents) {
|
||||||
m_log.trace_x("renderer: text(%s)", contents.c_str());
|
m_log.trace_x("renderer: text(%s)", contents.c_str());
|
||||||
|
|
||||||
cairo_text_extents_t extents;
|
|
||||||
cairo_text_extents(*m_context, contents.c_str(), &extents);
|
|
||||||
|
|
||||||
if (!extents.width) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo::abspos origin{static_cast<double>(m_rect.x), static_cast<double>(m_rect.y)};
|
cairo::abspos origin{static_cast<double>(m_rect.x), static_cast<double>(m_rect.y)};
|
||||||
|
origin.y += m_rect.height / 2.0;
|
||||||
|
|
||||||
if (m_alignment == alignment::CENTER) {
|
if (m_alignment == alignment::CENTER) {
|
||||||
origin.x += m_rect.width / 2.0 - extents.width / 2.0;
|
origin.x += m_rect.width / 2.0;
|
||||||
adjust_clickable_areas(extents.width / 2.0);
|
// adjust_clickable_areas(extents.width / 2.0);
|
||||||
} else if (m_alignment == alignment::RIGHT) {
|
} else if (m_alignment == alignment::RIGHT) {
|
||||||
origin.x += m_rect.width - extents.width;
|
origin.x += m_rect.width;
|
||||||
adjust_clickable_areas(extents.width);
|
// adjust_clickable_areas(extents.width);
|
||||||
} else {
|
} else {
|
||||||
origin.x += m_x;
|
origin.x += m_x;
|
||||||
}
|
}
|
||||||
@ -410,24 +419,16 @@ void renderer::draw_text(const string& contents) {
|
|||||||
// m_context->restore();
|
// m_context->restore();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
origin.y += m_rect.height / 2.0;
|
|
||||||
|
|
||||||
m_context->save();
|
m_context->save();
|
||||||
*m_context << origin;
|
*m_context << origin;
|
||||||
*m_context << m_compositing_foreground;
|
*m_context << m_compositing_foreground;
|
||||||
*m_context << m_color_foreground;
|
*m_context << m_color_foreground;
|
||||||
*m_context << cairo::textblock{contents, m_fontindex};
|
*m_context << cairo::textblock{m_alignment, contents, m_fontindex};
|
||||||
m_context->position(&m_x, &m_y);
|
m_context->position(&m_x, &m_y);
|
||||||
m_context->restore();
|
m_context->restore();
|
||||||
|
|
||||||
// if (m_alignment == alignment::CENTER) {
|
fill_underline(origin.x, m_x - origin.x);
|
||||||
// m_x += extents.width / 2.0;
|
fill_overline(origin.x, m_x - origin.x);
|
||||||
// } else {
|
|
||||||
// m_x += extents.width;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fill_underline(origin.x, m_x - origin.x);
|
|
||||||
// fill_overline(origin.x, m_x - origin.x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -450,7 +451,7 @@ void renderer::highlight_clickable_areas() {
|
|||||||
map<alignment, int> hint_num{};
|
map<alignment, int> hint_num{};
|
||||||
for (auto&& action : m_actions) {
|
for (auto&& action : m_actions) {
|
||||||
if (!action.active) {
|
if (!action.active) {
|
||||||
unsigned char n = hint_num.find(action.align)->second++;
|
int n = hint_num.find(action.align)->second++;
|
||||||
double x = action.start_x + n * DEBUG_HINTS_OFFSET_X;
|
double x = action.start_x + n * DEBUG_HINTS_OFFSET_X;
|
||||||
double y = m_bar.pos.y + m_rect.y + n * DEBUG_HINTS_OFFSET_Y;
|
double y = m_bar.pos.y + m_rect.y + n * DEBUG_HINTS_OFFSET_Y;
|
||||||
double w = action.width();
|
double w = action.width();
|
||||||
@ -513,27 +514,28 @@ bool renderer::on(const signals::parser::change_alignment& evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::offset_pixel& evt) {
|
bool renderer::on(const signals::parser::offset_pixel& evt) {
|
||||||
m_x += evt.cast();
|
(void)evt;
|
||||||
|
// m_x += evt.cast();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::attribute_set& evt) {
|
bool renderer::on(const signals::parser::attribute_set& evt) {
|
||||||
m_attributes.set(static_cast<unsigned char>(evt.cast()), true);
|
m_attributes.set(static_cast<int>(evt.cast()), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::attribute_unset& evt) {
|
bool renderer::on(const signals::parser::attribute_unset& evt) {
|
||||||
m_attributes.set(static_cast<unsigned char>(evt.cast()), false);
|
m_attributes.set(static_cast<int>(evt.cast()), false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::attribute_toggle& evt) {
|
bool renderer::on(const signals::parser::attribute_toggle& evt) {
|
||||||
m_attributes.flip(static_cast<unsigned char>(evt.cast()));
|
m_attributes.flip(static_cast<int>(evt.cast()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::action_begin& evt) {
|
bool renderer::on(const signals::parser::action_begin& evt) {
|
||||||
(void) evt;
|
(void)evt;
|
||||||
// auto a = evt.cast();
|
// auto a = evt.cast();
|
||||||
// action_block action{};
|
// action_block action{};
|
||||||
// action.button = a.button == mousebtn::NONE ? mousebtn::LEFT : a.button;
|
// action.button = a.button == mousebtn::NONE ? mousebtn::LEFT : a.button;
|
||||||
@ -546,9 +548,9 @@ bool renderer::on(const signals::parser::action_begin& evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool renderer::on(const signals::parser::action_end& evt) {
|
bool renderer::on(const signals::parser::action_end& evt) {
|
||||||
(void) evt;
|
(void)evt;
|
||||||
// auto btn = evt.cast();
|
// auto btn = evt.cast();
|
||||||
// short int clickable_width = 0;
|
// int clickable_width = 0;
|
||||||
// for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
|
// for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) {
|
||||||
// if (action->active && action->align == m_alignment && action->button == btn) {
|
// if (action->active && action->align == m_alignment && action->button == btn) {
|
||||||
// switch (action->align) {
|
// switch (action->align) {
|
||||||
|
@ -101,7 +101,7 @@ void tray_client::reconfigure(int x, int y) const {
|
|||||||
/**
|
/**
|
||||||
* Respond to client resize requests
|
* Respond to client resize requests
|
||||||
*/
|
*/
|
||||||
void tray_client::configure_notify(short int x, short int y) const {
|
void tray_client::configure_notify(int x, int y) const {
|
||||||
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t, 32_z>();
|
auto notify = memory_util::make_malloc_ptr<xcb_configure_notify_event_t, 32_z>();
|
||||||
notify->response_type = XCB_CONFIGURE_NOTIFY;
|
notify->response_type = XCB_CONFIGURE_NOTIFY;
|
||||||
notify->event = m_window;
|
notify->event = m_window;
|
||||||
|
Loading…
Reference in New Issue
Block a user