1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-27 00:58:36 +00:00

Move X11 font stuff to display-x11

This commit is contained in:
François Revol 2020-12-26 02:37:29 +01:00
parent 281097a2a5
commit 568de329ef
5 changed files with 236 additions and 189 deletions

View File

@ -108,6 +108,14 @@ class display_output_base {
virtual void begin_draw_stuff() {}
virtual void end_draw_stuff() {}
virtual void clear_text(int exposures) {}
// font stuff
virtual int font_height(int) { return 0; }
virtual int font_ascent(int) { return 0; }
virtual int font_descent(int) { return 0; }
virtual void setup_fonts(void) {}
virtual void set_font(int) {}
virtual void free_fonts(bool utf8) {}
virtual void load_fonts(bool utf8) {}
// tty interface

View File

@ -76,6 +76,57 @@ extern long current_color;
static int xft_dpi = -1;
#endif /* BUILD_XFT */
/* for x_fonts */
struct x_font_list {
XFontStruct *font;
XFontSet fontset;
#ifdef BUILD_XFT
XftFont *xftfont;
int font_alpha;
#endif
x_font_list()
: font(nullptr),
fontset(nullptr)
#ifdef BUILD_XFT
,
xftfont(nullptr),
font_alpha(0xffff)
#endif
{
}
};
static std::vector<x_font_list> x_fonts; /* indexed by selected_font */
#ifdef BUILD_XFT
namespace {
class xftalpha_setting : public conky::simple_config_setting<float> {
using Base = conky::simple_config_setting<float>;
protected:
void lua_setter(lua::state &l, bool init) override {
lua::stack_sentry s(l, -2);
Base::lua_setter(l, init);
if (init && out_to_x.get(*state)) {
x_fonts.resize(std::max(1, static_cast<int>(fonts.size())));
x_fonts[0].font_alpha = do_convert(l, -1).first * 0xffff;
}
++s;
}
public:
xftalpha_setting() : Base("xftalpha", 1.0, false) {}
};
xftalpha_setting xftalpha;
} // namespace
#endif /* BUILD_XFT */
static void X11_create_window();
struct _x11_stuff_s {
@ -538,17 +589,17 @@ int display_output_x11::calc_text_width(const char *s) {
XGlyphInfo gi;
if (utf8_mode.get(*state)) {
XftTextExtentsUtf8(display, fonts[selected_font].xftfont,
XftTextExtentsUtf8(display, x_fonts[selected_font].xftfont,
reinterpret_cast<const FcChar8 *>(s), slen, &gi);
} else {
XftTextExtents8(display, fonts[selected_font].xftfont,
XftTextExtents8(display, x_fonts[selected_font].xftfont,
reinterpret_cast<const FcChar8 *>(s), slen, &gi);
}
return gi.xOff;
}
#endif /* BUILD_XFT */
return XTextWidth(fonts[selected_font].font, s, slen);
return XTextWidth(x_fonts[selected_font].font, s, slen);
}
void display_output_x11::draw_string_at(int x, int y, const char *s, int w) {
@ -565,19 +616,19 @@ void display_output_x11::draw_string_at(int x, int y, const char *s, int w) {
c2.color.red = c.red;
c2.color.green = c.green;
c2.color.blue = c.blue;
c2.color.alpha = fonts[selected_font].font_alpha;
c2.color.alpha = x_fonts[selected_font].font_alpha;
if (utf8_mode.get(*state)) {
XftDrawStringUtf8(window.xftdraw, &c2, fonts[selected_font].xftfont, x, y,
reinterpret_cast<const XftChar8 *>(s), w);
XftDrawStringUtf8(window.xftdraw, &c2, x_fonts[selected_font].xftfont, x,
y, reinterpret_cast<const XftChar8 *>(s), w);
} else {
XftDrawString8(window.xftdraw, &c2, fonts[selected_font].xftfont, x, y,
XftDrawString8(window.xftdraw, &c2, x_fonts[selected_font].xftfont, x, y,
reinterpret_cast<const XftChar8 *>(s), w);
}
} else
#endif
{
if (utf8_mode.get(*state)) {
Xutf8DrawString(display, window.drawable, fonts[selected_font].fontset,
Xutf8DrawString(display, window.drawable, x_fonts[selected_font].fontset,
window.gc, x, y, s, w);
} else {
XDrawString(display, window.drawable, window.gc, x, y, s, w);
@ -656,7 +707,158 @@ void display_output_x11::clear_text(int exposures) {
}
}
void display_output_x11::load_fonts(bool utf8) { ::load_fonts(utf8); }
#ifdef BUILD_XFT
int display_output_x11::font_height(int f) {
assert(f < x_fonts.size());
if (use_xft.get(*state)) {
return x_fonts[f].xftfont->ascent + x_fonts[f].xftfont->descent;
} else {
return x_fonts[f].font->max_bounds.ascent +
x_fonts[f].font->max_bounds.descent;
}
}
int display_output_x11::font_ascent(int f) {
assert(f < x_fonts.size());
if (use_xft.get(*state)) {
return x_fonts[f].xftfont->ascent;
} else {
return x_fonts[f].font->max_bounds.ascent;
}
}
int display_output_x11::font_descent(int f) {
assert(f < x_fonts.size());
if (use_xft.get(*state)) {
return x_fonts[f].xftfont->descent;
} else {
return x_fonts[f].font->max_bounds.descent;
}
}
#else
int display_output_x11::font_height(int f) {
assert(f < x_fonts.size());
return x_fonts[f].font->max_bounds.ascent +
x_fonts[f].font->max_bounds.descent;
}
int display_output_x11::font_ascent(int f) {
assert(f < x_fonts.size());
return x_fonts[f].font->max_bounds.ascent;
}
int display_output_x11::font_descent(int f) {
assert(f < x_fonts.size());
return x_fonts[f].font->max_bounds.descent;
}
#endif
void display_output_x11::setup_fonts(void) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
if (window.xftdraw != nullptr) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = nullptr;
}
window.xftdraw = XftDrawCreate(display, window.drawable, window.visual,
window.colourmap);
}
#endif /* BUILD_XFT */
}
void display_output_x11::set_font(int f) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) { return; }
#endif /* BUILD_XFT */
if (x_fonts.size() > f && x_fonts[f].font != nullptr &&
window.gc != nullptr) {
XSetFont(display, window.gc, x_fonts[f].font->fid);
}
}
void display_output_x11::free_fonts(bool utf8) {
for (auto &font : x_fonts) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
/*
* Do we not need to close fonts with Xft? Unsure. Not freeing the
* fonts seems to incur a slight memory leak, but it also prevents
* a crash.
*
* XftFontClose(display, x_fonts[i].xftfont);
*/
} else
#endif /* BUILD_XFT */
{
if (font.font != nullptr) { XFreeFont(display, font.font); }
if (utf8 && (font.fontset != nullptr)) {
XFreeFontSet(display, font.fontset);
}
}
}
x_fonts.clear();
#ifdef BUILD_XFT
if (window.xftdraw != nullptr) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = nullptr;
}
#endif /* BUILD_XFT */
}
void display_output_x11::load_fonts(bool utf8) {
x_fonts.resize(fonts.size());
for (int i = 0; i < fonts.size(); i++) {
auto &font = fonts[i];
auto &xfont = x_fonts[i];
#ifdef BUILD_XFT
/* load Xft font */
if (use_xft.get(*state)) {
if (xfont.xftfont == nullptr) {
xfont.xftfont = XftFontOpenName(display, screen, font.name.c_str());
}
if (xfont.xftfont != nullptr) { continue; }
NORM_ERR("can't load Xft font '%s'", font.name.c_str());
if ((xfont.xftfont = XftFontOpenName(display, screen, "courier-12")) !=
nullptr) {
continue;
}
CRIT_ERR(nullptr, nullptr, "can't load Xft font '%s'", "courier-12");
continue;
}
#endif
if (utf8 && xfont.fontset == nullptr) {
char **missing;
int missingnum;
char *missingdrawn;
xfont.fontset = XCreateFontSet(display, font.name.c_str(), &missing,
&missingnum, &missingdrawn);
XFreeStringList(missing);
if (xfont.fontset == nullptr) {
NORM_ERR("can't load font '%s'", font.name.c_str());
xfont.fontset = XCreateFontSet(display, "fixed", &missing, &missingnum,
&missingdrawn);
if (xfont.fontset == nullptr) {
CRIT_ERR(nullptr, nullptr, "can't load font '%s'", "fixed");
}
}
}
/* load normal font */
if ((xfont.font == nullptr) &&
(xfont.font = XLoadQueryFont(display, font.name.c_str())) == nullptr) {
NORM_ERR("can't load font '%s'", font.name.c_str());
if ((xfont.font = XLoadQueryFont(display, "fixed")) == nullptr) {
CRIT_ERR(nullptr, nullptr, "can't load font '%s'", "fixed");
}
}
}
}
#endif /* BUILD_X11 */

View File

@ -71,6 +71,13 @@ class display_output_x11 : public display_output_base {
virtual void end_draw_stuff();
virtual void clear_text(int exposures);
virtual int font_height(int);
virtual int font_ascent(int);
virtual int font_descent(int);
virtual void setup_fonts(void);
virtual void set_font(int);
virtual void free_fonts(bool utf8);
virtual void load_fonts(bool utf8);
// X11-specific

View File

@ -28,6 +28,7 @@
*/
#include "fonts.h"
#include "display-output.hh"
#include "logging.h"
unsigned int selected_font = 0;
@ -53,55 +54,14 @@ conky::simple_config_setting<std::string> font_template[10] = {
{"font0", ""}, {"font1", ""}, {"font2", ""}, {"font3", ""}, {"font4", ""},
{"font5", ""}, {"font6", ""}, {"font7", ""}, {"font8", ""}, {"font9", ""}};
#ifdef BUILD_XFT
namespace {
class xftalpha_setting : public conky::simple_config_setting<float> {
using Base = conky::simple_config_setting<float>;
protected:
void lua_setter(lua::state &l, bool init) override {
lua::stack_sentry s(l, -2);
Base::lua_setter(l, init);
if (init && out_to_x.get(*state)) {
fonts[0].font_alpha = do_convert(l, -1).first * 0xffff;
}
++s;
}
public:
xftalpha_setting() : Base("xftalpha", 1.0, false) {}
};
xftalpha_setting xftalpha;
} // namespace
#endif /* BUILD_XFT */
void set_font() {
#ifdef BUILD_XFT
if (use_xft.get(*state)) { return; }
#endif /* BUILD_XFT */
if (fonts.size() > selected_font && fonts[selected_font].font != nullptr &&
window.gc != nullptr) {
XSetFont(display, window.gc, fonts[selected_font].font->fid);
}
if (selected_font >= fonts.size()) return;
for (auto output : display_outputs()) output->set_font(selected_font);
}
void setup_fonts() {
DBGP2("setting up fonts");
if (!out_to_x.get(*state)) { return; }
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
if (window.xftdraw != nullptr) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = nullptr;
}
window.xftdraw = XftDrawCreate(display, window.drawable, window.visual,
window.colourmap);
}
#endif /* BUILD_XFT */
for (auto output : display_outputs()) output->setup_fonts();
set_font();
}
@ -114,140 +74,27 @@ int add_font(const char *data_in) {
}
void free_fonts(bool utf8) {
if (!out_to_x.get(*state)) { return; }
for (auto &font : fonts) {
#ifdef BUILD_XFT
if (use_xft.get(*state)) {
/*
* Do we not need to close fonts with Xft? Unsure. Not freeing the
* fonts seems to incur a slight memory leak, but it also prevents
* a crash.
*
* XftFontClose(display, fonts[i].xftfont);
*/
} else
#endif /* BUILD_XFT */
{
if (font.font != nullptr) { XFreeFont(display, font.font); }
if (utf8 && (font.fontset != nullptr)) {
XFreeFontSet(display, font.fontset);
}
}
}
for (auto output : display_outputs()) output->free_fonts(utf8);
fonts.clear();
selected_font = 0;
#ifdef BUILD_XFT
if (window.xftdraw != nullptr) {
XftDrawDestroy(window.xftdraw);
window.xftdraw = nullptr;
}
#endif /* BUILD_XFT */
}
void load_fonts(bool utf8) {
DBGP2("loading fonts");
if (!out_to_x.get(*state)) { return; }
for (auto &font : fonts) {
#ifdef BUILD_XFT
/* load Xft font */
if (use_xft.get(*state)) {
if (font.xftfont == nullptr) {
font.xftfont = XftFontOpenName(display, screen, font.name.c_str());
}
if (font.xftfont != nullptr) { continue; }
NORM_ERR("can't load Xft font '%s'", font.name.c_str());
if ((font.xftfont = XftFontOpenName(display, screen, "courier-12")) !=
nullptr) {
continue;
}
CRIT_ERR(nullptr, nullptr, "can't load Xft font '%s'", "courier-12");
continue;
}
#endif
if (utf8 && font.fontset == nullptr) {
char **missing;
int missingnum;
char *missingdrawn;
font.fontset = XCreateFontSet(display, font.name.c_str(), &missing,
&missingnum, &missingdrawn);
XFreeStringList(missing);
if (font.fontset == nullptr) {
NORM_ERR("can't load font '%s'", font.name.c_str());
font.fontset = XCreateFontSet(display, "fixed", &missing, &missingnum,
&missingdrawn);
if (font.fontset == nullptr) {
CRIT_ERR(nullptr, nullptr, "can't load font '%s'", "fixed");
}
}
}
/* load normal font */
if ((font.font == nullptr) &&
(font.font = XLoadQueryFont(display, font.name.c_str())) == nullptr) {
NORM_ERR("can't load font '%s'", font.name.c_str());
if ((font.font = XLoadQueryFont(display, "fixed")) == nullptr) {
CRIT_ERR(nullptr, nullptr, "can't load font '%s'", "fixed");
}
}
}
for (auto output : display_outputs()) output->load_fonts(utf8);
}
#ifdef BUILD_XFT
int font_height() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
if (use_xft.get(*state)) {
return fonts[selected_font].xftfont->ascent +
fonts[selected_font].xftfont->descent;
} else {
return fonts[selected_font].font->max_bounds.ascent +
fonts[selected_font].font->max_bounds.descent;
}
return display_output()->font_height(selected_font);
}
int font_ascent() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
if (use_xft.get(*state)) {
return fonts[selected_font].xftfont->ascent;
} else {
return fonts[selected_font].font->max_bounds.ascent;
}
return display_output()->font_ascent(selected_font);
}
int font_descent() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
if (use_xft.get(*state)) {
return fonts[selected_font].xftfont->descent;
} else {
return fonts[selected_font].font->max_bounds.descent;
}
return display_output()->font_descent(selected_font);
}
#else
int font_height() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
return fonts[selected_font].font->max_bounds.ascent +
fonts[selected_font].font->max_bounds.descent;
}
int font_ascent() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
return fonts[selected_font].font->max_bounds.ascent;
}
int font_descent() {
if (!out_to_x.get(*state)) { return 0; }
assert(selected_font < fonts.size());
return fonts[selected_font].font->max_bounds.descent;
}
#endif

View File

@ -37,25 +37,8 @@
/* for fonts */
struct font_list {
std::string name;
XFontStruct *font;
XFontSet fontset;
#ifdef BUILD_XFT
XftFont *xftfont;
int font_alpha;
#endif
font_list()
: name(),
font(nullptr),
fontset(nullptr)
#ifdef BUILD_XFT
,
xftfont(nullptr),
font_alpha(0xffff)
#endif
{
}
font_list() : name() {}
};
/* direct access to registered fonts (FIXME: bad encapsulation) */