diff --git a/include/cairo/context.hpp b/include/cairo/context.hpp index a10bf3fa..87b222e1 100644 --- a/include/cairo/context.hpp +++ b/include/cairo/context.hpp @@ -102,15 +102,6 @@ namespace cairo { return *this; } - context& operator<<(const displace& d) { - cairo_set_operator(m_c, CAIRO_OPERATOR_SOURCE); - cairo_set_source_surface(m_c, cairo_get_target(m_c), d.x - d.w, d.y); - cairo_rectangle(m_c, d.x - d.w, d.y, d.x + d.dx, d.y + d.dy); - cairo_fill(m_c); - cairo_surface_flush(cairo_get_target(m_c)); - return *this; - } - context& operator<<(const translate& d) { cairo_translate(m_c, d.x, d.y); return *this; @@ -200,8 +191,8 @@ namespace cairo { save(); { + cairo_set_operator(m_c, t.bg_operator); *this << t.bg; - cairo_set_operator(m_c, static_cast(t.bg_operator)); cairo_rectangle(m_c, t.bg_rect.x + *t.x_advance, t.bg_rect.y + *t.y_advance, t.bg_rect.w + extents.x_advance, t.bg_rect.h); cairo_fill(m_c); @@ -239,8 +230,6 @@ namespace cairo { chars.erase(chars.begin(), ++chars.begin()); } - // *this << abspos{x, y}; - return *this; } @@ -345,8 +334,8 @@ namespace cairo { context& snap(double* x, double* y) { cairo_user_to_device(m_c, x, y); - *x = ((int)*x + 0.5); - *y = ((int)*y + 0.5); + *x = static_cast(*x + 0.5); + *y = static_cast(*y + 0.5); return *this; } diff --git a/include/cairo/types.hpp b/include/cairo/types.hpp index 56525e63..dc4fb087 100644 --- a/include/cairo/types.hpp +++ b/include/cairo/types.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "common.hpp" POLYBAR_NS @@ -33,14 +35,6 @@ namespace cairo { double y2; double w; }; - struct displace { - double x; - double y; - double w; - double h; - double dx; - double dy; - }; struct translate { double x; double y; @@ -64,7 +58,7 @@ namespace cairo { string contents; int font; unsigned int bg; - int bg_operator; + cairo_operator_t bg_operator; rect bg_rect; double *x_advance; double *y_advance; diff --git a/include/cairo/utils.hpp b/include/cairo/utils.hpp index 33b74892..5db3a145 100644 --- a/include/cairo/utils.hpp +++ b/include/cairo/utils.hpp @@ -1,11 +1,9 @@ #pragma once -#include +#include #include -#include #include "common.hpp" -#include "utils/string.hpp" POLYBAR_NS @@ -16,21 +14,10 @@ namespace cairo { */ class device_lock { public: - explicit device_lock(cairo_device_t* device) { - auto status = cairo_device_acquire(device); - if (status == CAIRO_STATUS_SUCCESS) { - m_device = device; - } - } - ~device_lock() { - cairo_device_release(m_device); - } - operator bool() const { - return m_device != nullptr; - } - operator cairo_device_t*() const { - return m_device; - } + explicit device_lock(cairo_device_t* device); + ~device_lock(); + operator bool() const; + operator cairo_device_t*() const; private: cairo_device_t* m_device{nullptr}; @@ -42,16 +29,9 @@ namespace cairo { */ class ft_face_lock { public: - explicit ft_face_lock(cairo_scaled_font_t* font) : m_font(font) { - m_face = cairo_ft_scaled_font_lock_face(m_font); - } - ~ft_face_lock() { - cairo_ft_scaled_font_unlock_face(m_font); - } - - operator FT_Face() const { - return m_face; - } + explicit ft_face_lock(cairo_scaled_font_t* font); + ~ft_face_lock(); + operator FT_Face() const; private: cairo_scaled_font_t* m_font; @@ -63,8 +43,7 @@ namespace cairo { * and details on where its position in the source string */ struct unicode_character { - explicit unicode_character() : codepoint(0), offset(0), length(0) {} - + explicit unicode_character(); unsigned long codepoint; int offset; int length; @@ -74,128 +53,17 @@ namespace cairo { /** * @see */ - cairo_operator_t str2operator(const string& mode, cairo_operator_t fallback) { - if (mode.empty()) { - return fallback; - } - static std::map modes; - if (modes.empty()) { - modes["clear"s] = CAIRO_OPERATOR_CLEAR; - modes["source"s] = CAIRO_OPERATOR_SOURCE; - modes["over"s] = CAIRO_OPERATOR_OVER; - modes["in"s] = CAIRO_OPERATOR_IN; - modes["out"s] = CAIRO_OPERATOR_OUT; - modes["atop"s] = CAIRO_OPERATOR_ATOP; - modes["dest"s] = CAIRO_OPERATOR_DEST; - modes["dest-over"s] = CAIRO_OPERATOR_DEST_OVER; - modes["dest-in"s] = CAIRO_OPERATOR_DEST_IN; - modes["dest-out"s] = CAIRO_OPERATOR_DEST_OUT; - modes["dest-atop"s] = CAIRO_OPERATOR_DEST_ATOP; - modes["xor"s] = CAIRO_OPERATOR_XOR; - modes["add"s] = CAIRO_OPERATOR_ADD; - modes["saturate"s] = CAIRO_OPERATOR_SATURATE; - modes["multiply"s] = CAIRO_OPERATOR_MULTIPLY; - modes["screen"s] = CAIRO_OPERATOR_SCREEN; - modes["overlay"s] = CAIRO_OPERATOR_OVERLAY; - modes["darken"s] = CAIRO_OPERATOR_DARKEN; - modes["lighten"s] = CAIRO_OPERATOR_LIGHTEN; - modes["color-dodge"s] = CAIRO_OPERATOR_COLOR_DODGE; - modes["color-burn"s] = CAIRO_OPERATOR_COLOR_BURN; - modes["hard-light"s] = CAIRO_OPERATOR_HARD_LIGHT; - modes["soft-light"s] = CAIRO_OPERATOR_SOFT_LIGHT; - modes["difference"s] = CAIRO_OPERATOR_DIFFERENCE; - modes["exclusion"s] = CAIRO_OPERATOR_EXCLUSION; - modes["hsl-hue"s] = CAIRO_OPERATOR_HSL_HUE; - modes["hsl-saturation"s] = CAIRO_OPERATOR_HSL_SATURATION; - modes["hsl-color"s] = CAIRO_OPERATOR_HSL_COLOR; - modes["hsl-luminosity"s] = CAIRO_OPERATOR_HSL_LUMINOSITY; - } - auto it = modes.find(mode); - return it != modes.end() ? it->second : fallback; - } + cairo_operator_t str2operator(const string& mode, cairo_operator_t fallback); /** * @brief Create a UCS-4 codepoint from a utf-8 encoded string */ - bool utf8_to_ucs4(const unsigned char* src, unicode_charlist& result_list) { - if (!src) { - return false; - } - const unsigned char* first = src; - while (*first) { - int len = 0; - unsigned long result = 0; - if ((*first >> 7) == 0) { - len = 1; - result = *first; - } else if ((*first >> 5) == 6) { - len = 2; - result = *first & 31; - } else if ((*first >> 4) == 14) { - len = 3; - result = *first & 15; - } else if ((*first >> 3) == 30) { - len = 4; - result = *first & 7; - } else { - return false; - } - const unsigned char* next; - for (next = first + 1; *next && ((*next >> 6) == 2) && (next - first < len); next++) { - result = result << 6; - result |= *next & 63; - } - unicode_character uc_char; - uc_char.codepoint = result; - uc_char.offset = first - src; - uc_char.length = next - first; - result_list.push_back(uc_char); - first = next; - } - return true; - } + bool utf8_to_ucs4(const unsigned char* src, unicode_charlist& result_list); /** * @brief Convert a UCS-4 codepoint to a utf-8 encoded string */ - size_t ucs4_to_utf8(char* utf8, unsigned int ucs) { - if (ucs <= 0x7f) { - *utf8 = ucs; - return 1; - } else if (ucs <= 0x07ff) { - *(utf8++) = ((ucs >> 6) & 0xff) | 0xc0; - *utf8 = (ucs & 0x3f) | 0x80; - return 2; - } else if (ucs <= 0xffff) { - *(utf8++) = ((ucs >> 12) & 0x0f) | 0xe0; - *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; - *utf8 = (ucs & 0x3f) | 0x80; - return 3; - } else if (ucs <= 0x1fffff) { - *(utf8++) = ((ucs >> 18) & 0x07) | 0xf0; - *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; - *utf8 = (ucs & 0x3f) | 0x80; - return 4; - } else if (ucs <= 0x03ffffff) { - *(utf8++) = ((ucs >> 24) & 0x03) | 0xf8; - *(utf8++) = ((ucs >> 18) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; - *utf8 = (ucs & 0x3f) | 0x80; - return 5; - } else if (ucs <= 0x7fffffff) { - *(utf8++) = ((ucs >> 30) & 0x01) | 0xfc; - *(utf8++) = ((ucs >> 24) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 18) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; - *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; - *utf8 = (ucs & 0x3f) | 0x80; - return 6; - } else { - return 0; - } - } + size_t ucs4_to_utf8(char* utf8, unsigned int ucs); } } diff --git a/src/cairo/utils.cpp b/src/cairo/utils.cpp new file mode 100644 index 00000000..b58e4309 --- /dev/null +++ b/src/cairo/utils.cpp @@ -0,0 +1,176 @@ +#include + +#include "cairo/utils.hpp" + +POLYBAR_NS + +namespace cairo { + namespace utils { + + // implementation : device_lock {{{ + + device_lock::device_lock(cairo_device_t* device) { + auto status = cairo_device_acquire(device); + if (status == CAIRO_STATUS_SUCCESS) { + m_device = device; + } + } + device_lock::~device_lock() { + cairo_device_release(m_device); + } + device_lock::operator bool() const { + return m_device != nullptr; + } + device_lock::operator cairo_device_t*() const { + return m_device; + } + + // }}} + // implementation : ft_face_lock {{{ + + ft_face_lock::ft_face_lock(cairo_scaled_font_t* font) : m_font(font) { + m_face = cairo_ft_scaled_font_lock_face(m_font); + } + ft_face_lock::~ft_face_lock() { + cairo_ft_scaled_font_unlock_face(m_font); + } + ft_face_lock::operator FT_Face() const { + return m_face; + } + + // }}} + // implementation : unicode_character {{{ + + unicode_character::unicode_character() : codepoint(0), offset(0), length(0) {} + + // }}} + + /** + * @see + */ + cairo_operator_t str2operator(const string& mode, cairo_operator_t fallback) { + if (mode.empty()) { + return fallback; + } + static std::map modes; + if (modes.empty()) { + modes["clear"s] = CAIRO_OPERATOR_CLEAR; + modes["source"s] = CAIRO_OPERATOR_SOURCE; + modes["over"s] = CAIRO_OPERATOR_OVER; + modes["in"s] = CAIRO_OPERATOR_IN; + modes["out"s] = CAIRO_OPERATOR_OUT; + modes["atop"s] = CAIRO_OPERATOR_ATOP; + modes["dest"s] = CAIRO_OPERATOR_DEST; + modes["dest-over"s] = CAIRO_OPERATOR_DEST_OVER; + modes["dest-in"s] = CAIRO_OPERATOR_DEST_IN; + modes["dest-out"s] = CAIRO_OPERATOR_DEST_OUT; + modes["dest-atop"s] = CAIRO_OPERATOR_DEST_ATOP; + modes["xor"s] = CAIRO_OPERATOR_XOR; + modes["add"s] = CAIRO_OPERATOR_ADD; + modes["saturate"s] = CAIRO_OPERATOR_SATURATE; + modes["multiply"s] = CAIRO_OPERATOR_MULTIPLY; + modes["screen"s] = CAIRO_OPERATOR_SCREEN; + modes["overlay"s] = CAIRO_OPERATOR_OVERLAY; + modes["darken"s] = CAIRO_OPERATOR_DARKEN; + modes["lighten"s] = CAIRO_OPERATOR_LIGHTEN; + modes["color-dodge"s] = CAIRO_OPERATOR_COLOR_DODGE; + modes["color-burn"s] = CAIRO_OPERATOR_COLOR_BURN; + modes["hard-light"s] = CAIRO_OPERATOR_HARD_LIGHT; + modes["soft-light"s] = CAIRO_OPERATOR_SOFT_LIGHT; + modes["difference"s] = CAIRO_OPERATOR_DIFFERENCE; + modes["exclusion"s] = CAIRO_OPERATOR_EXCLUSION; + modes["hsl-hue"s] = CAIRO_OPERATOR_HSL_HUE; + modes["hsl-saturation"s] = CAIRO_OPERATOR_HSL_SATURATION; + modes["hsl-color"s] = CAIRO_OPERATOR_HSL_COLOR; + modes["hsl-luminosity"s] = CAIRO_OPERATOR_HSL_LUMINOSITY; + } + auto it = modes.find(mode); + return it != modes.end() ? it->second : fallback; + } + + /** + * @brief Create a UCS-4 codepoint from a utf-8 encoded string + */ + bool utf8_to_ucs4(const unsigned char* src, unicode_charlist& result_list) { + if (!src) { + return false; + } + const unsigned char* first = src; + while (*first) { + int len = 0; + unsigned long result = 0; + if ((*first >> 7) == 0) { + len = 1; + result = *first; + } else if ((*first >> 5) == 6) { + len = 2; + result = *first & 31; + } else if ((*first >> 4) == 14) { + len = 3; + result = *first & 15; + } else if ((*first >> 3) == 30) { + len = 4; + result = *first & 7; + } else { + return false; + } + const unsigned char* next; + for (next = first + 1; *next && ((*next >> 6) == 2) && (next - first < len); next++) { + result = result << 6; + result |= *next & 63; + } + unicode_character uc_char; + uc_char.codepoint = result; + uc_char.offset = first - src; + uc_char.length = next - first; + result_list.push_back(uc_char); + first = next; + } + return true; + } + + /** + * @brief Convert a UCS-4 codepoint to a utf-8 encoded string + */ + size_t ucs4_to_utf8(char* utf8, unsigned int ucs) { + if (ucs <= 0x7f) { + *utf8 = ucs; + return 1; + } else if (ucs <= 0x07ff) { + *(utf8++) = ((ucs >> 6) & 0xff) | 0xc0; + *utf8 = (ucs & 0x3f) | 0x80; + return 2; + } else if (ucs <= 0xffff) { + *(utf8++) = ((ucs >> 12) & 0x0f) | 0xe0; + *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; + *utf8 = (ucs & 0x3f) | 0x80; + return 3; + } else if (ucs <= 0x1fffff) { + *(utf8++) = ((ucs >> 18) & 0x07) | 0xf0; + *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; + *utf8 = (ucs & 0x3f) | 0x80; + return 4; + } else if (ucs <= 0x03ffffff) { + *(utf8++) = ((ucs >> 24) & 0x03) | 0xf8; + *(utf8++) = ((ucs >> 18) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; + *utf8 = (ucs & 0x3f) | 0x80; + return 5; + } else if (ucs <= 0x7fffffff) { + *(utf8++) = ((ucs >> 30) & 0x01) | 0xfc; + *(utf8++) = ((ucs >> 24) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 18) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 12) & 0x3f) | 0x80; + *(utf8++) = ((ucs >> 6) & 0x3f) | 0x80; + *utf8 = (ucs & 0x3f) | 0x80; + return 6; + } else { + return 0; + } + } + } +} + +POLYBAR_NS_END