1 #include "config.h"
2
3 #include "ypaint.h"
4 #include "yprefs.h"
5 #include "yfontcache.h"
6
7 #include <string.h>
8 #include "ytrace.h"
9
10 #ifdef CONFIG_XFREETYPE
11 extern YFontBase* getXftFont(const char* name);
12 extern YFontBase* getXftFontXlfd(const char* name);
13 extern YFontBase* getXftDefault(const char* name);
14 #endif
15 #ifdef CONFIG_COREFONTS
16 extern YFontBase* getCoreFont(const char* name);
17 extern YFontBase* getCoreDefault(const char* name);
18 #endif
19
20 YFontCache fontCache;
21
show(bool busy,const char * kind,const char * inst)22 void YTraceFont::show(bool busy, const char* kind, const char* inst) {
23 char detail[128];
24 if (base) {
25 snprintf(detail, sizeof detail, " ascent=%d,descent=%d",
26 base->ascent(), base->descent());
27 } else {
28 *detail = '\0';
29 }
30 tlog("%s open: %s%s", kind, inst, detail);
31 }
32
loadFont(fontloader loader,const char * name)33 void YFont::loadFont(fontloader loader, const char* name) {
34 base = fontCache.lookup(name);
35 if (base == nullptr) {
36 base = loader(name);
37 if (base) {
38 YTraceFont trace(name, base);
39 fontCache.store(name, base);
40 }
41 }
42 }
43
operator =(YFontName & name)44 YFont YFont::operator=(YFontName& name) {
45 base = nullptr;
46
47 for (bool tf : { true, false }) {
48 #ifdef CONFIG_XFREETYPE
49 if (tf == fontPreferFreetype) {
50 if (base == nullptr && name.haveXft()) {
51 loadFont(getXftFont, name.xftName());
52 }
53 if (base == nullptr && name.haveCore()) {
54 loadFont(getXftFontXlfd, name.coreName());
55 }
56 }
57 #endif
58 #ifdef CONFIG_COREFONTS
59 if (tf) {
60 if (base == nullptr && name.haveCore()) {
61 loadFont(getCoreFont, name.coreName());
62 }
63 }
64 #endif
65 }
66 #ifdef CONFIG_XFREETYPE
67 if (base == nullptr) {
68 loadFont(getXftDefault,
69 name.haveXft() ? name.xftName() :
70 name.haveCore() ? name.coreName() : "");
71 }
72 #endif
73 #ifdef CONFIG_COREFONTS
74 if (base == nullptr) {
75 loadFont(getCoreDefault, name.haveCore() ? name.coreName() : "");
76 }
77 #endif
78
79 #ifndef CONFIG_XFREETYPE
80 #ifndef CONFIG_COREFONTS
81 if (ONCE)
82 warn("Neither XFT fonts nor X11 core fonts are configured!");
83 #endif
84 #endif
85
86 return *this;
87 }
88
multilineTabPos(const char * str) const89 int YFontBase::multilineTabPos(const char *str) const {
90 int tabPos(0);
91
92 for (const char * end(strchr(str, '\n')); end;
93 str = end + 1, end = strchr(str, '\n'))
94 {
95 int const len(end - str);
96 const char * tab((const char *) memchr(str, '\t', len));
97
98 if (tab) tabPos = max(tabPos, textWidth(str, tab - str));
99 }
100
101 const char * tab(strchr(str, '\t'));
102 if (tab) tabPos = max(tabPos, textWidth(str, tab - str));
103
104 return tabPos ? tabPos + textWidth(".|", 2) : 0;
105 }
106
multilineAlloc(const char * str) const107 YDimension YFontBase::multilineAlloc(const char *str) const {
108 const unsigned tabPos(multilineTabPos(str));
109 YDimension alloc(0, ascent());
110
111 for (const char * end(strchr(str, '\n')); end;
112 str = end + 1, end = strchr(str, '\n'))
113 {
114 int const len(end - str);
115 const char * tab((const char *) memchr(str, '\t', len));
116
117 alloc.w = max(tab ? tabPos + textWidth(tab + 1, end - tab - 1)
118 : textWidth(str, len), alloc.w);
119 alloc.h+= height();
120 }
121
122 const char * tab(strchr(str, '\t'));
123 alloc.w = max(alloc.w, tab ? tabPos + textWidth(tab + 1) : textWidth(str));
124
125 return alloc;
126 }
127
ellipsis() const128 const char* YFontBase::ellipsis() const {
129 const unsigned utf32ellipsis = 0x2026;
130 static const char utf8ellipsis[] = "\xe2\x80\xa6";
131 return showEllipsis && supports(utf32ellipsis) ? utf8ellipsis : "...";
132 }
133
clearFontCache()134 void clearFontCache() {
135 fontCache.clear();
136 }
137
138 // vim: set sw=4 ts=4 et:
139