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:
parent
281097a2a5
commit
568de329ef
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
171
src/fonts.cc
171
src/fonts.cc
@ -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
|
||||
|
19
src/fonts.h
19
src/fonts.h
@ -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) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user