mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
*CtrlCore: Fixed font rendering issue with NOGTK flag
git-svn-id: svn://ultimatepp.org/upp/trunk@3587 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
2dd98b6c29
commit
18bf33ed6c
1 changed files with 251 additions and 251 deletions
|
|
@ -1,251 +1,251 @@
|
|||
#include "CtrlCore.h"
|
||||
|
||||
#ifdef GUI_X11
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x)
|
||||
#define LLOG(x)
|
||||
|
||||
int gtk_antialias = -1;
|
||||
int gtk_hinting;
|
||||
String gtk_hintstyle;
|
||||
String gtk_rgba;
|
||||
|
||||
XftFont *CreateXftFont(Font font, int angle)
|
||||
{
|
||||
LTIMING("CreateXftFont");
|
||||
XftFont *xftfont;
|
||||
double sina, cosa;
|
||||
Std(font);
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = max(GetStdFontCy(), 10);
|
||||
String face = font.GetFaceName();
|
||||
FcPattern *p = FcPatternCreate();
|
||||
FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face);
|
||||
FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? 110 : 0);
|
||||
FcPatternAddInteger(p, FC_PIXEL_SIZE, hg);
|
||||
FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? 200 : 100);
|
||||
FcPatternAddBool(p, FC_MINSPACE, 1);
|
||||
if(angle) {
|
||||
FcMatrix mx;
|
||||
Draw::SinCos(angle, sina, cosa);
|
||||
mx.xx = cosa;
|
||||
mx.xy = -sina;
|
||||
mx.yx = sina;
|
||||
mx.yy = cosa;
|
||||
FcPatternAddMatrix(p, FC_MATRIX, &mx);
|
||||
}
|
||||
FcResult result;
|
||||
FcPattern *m = XftFontMatch(Xdisplay, Xscreenno, p, &result);
|
||||
if(font.IsNonAntiAliased() || gtk_antialias >= 0) {
|
||||
FcPatternDel(m, FC_ANTIALIAS);
|
||||
FcPatternAddBool(m, FC_ANTIALIAS,
|
||||
font.IsNonAntiAliased() ? FcFalse : gtk_antialias ? FcTrue : FcFalse);
|
||||
}
|
||||
if(gtk_hinting >= 0) {
|
||||
FcPatternDel(m, FC_HINTING);
|
||||
FcPatternAddBool(m, FC_HINTING, gtk_hinting);
|
||||
}
|
||||
const char *hs[] = { "hintnone", "hintslight", "hintmedium", "hintfull" };
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(gtk_hintstyle == hs[i]) {
|
||||
FcPatternDel(m, FC_HINT_STYLE);
|
||||
FcPatternAddInteger(m, FC_HINT_STYLE, i);
|
||||
}
|
||||
const char *rgba[] = { "_", "rgb", "bgr", "vrgb", "vbgr" };
|
||||
for(int i = 0; i < __countof(rgba); i++)
|
||||
if(gtk_rgba == rgba[i]) {
|
||||
FcPatternDel(m, FC_RGBA);
|
||||
FcPatternAddInteger(m, FC_RGBA, i);
|
||||
}
|
||||
xftfont = XftFontOpenPattern(Xdisplay, m);
|
||||
FcPatternDestroy(p);
|
||||
return xftfont;
|
||||
}
|
||||
|
||||
#define FONTCACHE 37
|
||||
|
||||
struct XftEntry {
|
||||
Font font;
|
||||
int angle;
|
||||
XftFont *xftfont;
|
||||
};
|
||||
|
||||
XftFont *GetXftFont(Font fnt, int angle)
|
||||
{
|
||||
static XftEntry cache[FONTCACHE];
|
||||
ONCELOCK {
|
||||
for(int i = 0; i < FONTCACHE; i++)
|
||||
cache[i].font.Height(-30000);
|
||||
}
|
||||
XftEntry be;
|
||||
be = cache[0];
|
||||
for(int i = 0; i < FONTCACHE; i++) {
|
||||
XftEntry e = cache[i];
|
||||
if(i)
|
||||
cache[i] = be;
|
||||
if(e.font == fnt && e.angle == angle) {
|
||||
if(i)
|
||||
cache[0] = e;
|
||||
return e.xftfont;
|
||||
}
|
||||
be = e;
|
||||
}
|
||||
if(be.xftfont) {
|
||||
XftFontClose(Xdisplay, be.xftfont);
|
||||
}
|
||||
be.font = fnt;
|
||||
be.angle = angle;
|
||||
be.xftfont = CreateXftFont(fnt, angle);
|
||||
cache[0] = be;
|
||||
return be.xftfont;
|
||||
}
|
||||
|
||||
CommonFontInfo XftGetFontInfoSys(Font font)
|
||||
{
|
||||
CommonFontInfo fi;
|
||||
String path;
|
||||
XftFont *xftfont = GetXftFont(font, 0);
|
||||
if(xftfont) {
|
||||
fi.ascent = (int16)xftfont->ascent;
|
||||
fi.descent = (int16)xftfont->descent;
|
||||
fi.height = fi.ascent + fi.descent;
|
||||
fi.lineheight = (int16)xftfont->height;
|
||||
fi.external = 0;
|
||||
fi.internal = 0;
|
||||
fi.overhang = 0;
|
||||
fi.maxwidth = (int16)xftfont->max_advance_width;
|
||||
fi.avewidth = fi.maxwidth;
|
||||
fi.default_char = '?';
|
||||
fi.fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH;
|
||||
|
||||
char *fn = NULL;
|
||||
XftPatternGetString(xftfont->pattern, XFT_FILE, 0, &fn);
|
||||
if(fn && strlen(fn) < 250)
|
||||
strcpy(fi.path, fn);
|
||||
}
|
||||
return fi;
|
||||
}
|
||||
|
||||
GlyphInfo XftGetGlyphInfoSys(Font font, int chr)
|
||||
{
|
||||
wchar h = chr;
|
||||
XGlyphInfo info;
|
||||
XftTextExtents16(Xdisplay, GetXftFont(font, 0), &h, 1, &info);
|
||||
GlyphInfo gi;
|
||||
gi.width = info.xOff;
|
||||
gi.lspc = -info.x;
|
||||
gi.rspc = info.xOff - info.width + info.x;
|
||||
return gi;
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
// extern FT_Face (*FTFaceXft)(Font fnt, String *rpath);
|
||||
extern CommonFontInfo (*GetFontInfoSysXft)(Font font);
|
||||
extern GlyphInfo (*GetGlyphInfoSysXft)(Font font, int chr);
|
||||
// FTFaceXft = XftFTFace;
|
||||
GetFontInfoSysXft = XftGetFontInfoSys;
|
||||
GetGlyphInfoSysXft = XftGetGlyphInfoSys;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx) {
|
||||
GuiLock __;
|
||||
LTIMING("DrawText");
|
||||
LLOG("DrawText " << ToUtf8(WString(text, n)) << " color:" << ink << " font:" << font);
|
||||
//TODO - X11 seems to crash when displaying too long strings (?)
|
||||
int ox = x + actual_offset.x;
|
||||
int oy = y + actual_offset.y;
|
||||
SetForeground(ink);
|
||||
XftColor c;
|
||||
c.color.red = ink.GetR() << 8;
|
||||
c.color.green = ink.GetG() << 8;
|
||||
c.color.blue = ink.GetB() << 8;
|
||||
c.color.alpha = 0xffff;
|
||||
c.pixel = GetXPixel(ink.GetR(), ink.GetG(), ink.GetB());
|
||||
XftFont *xftfont = GetXftFont(font, angle);
|
||||
Size offset = Point(0, 0);
|
||||
double sina, cosa;
|
||||
int ascent = font.Info().GetAscent();
|
||||
if(angle) {
|
||||
SinCos(angle, sina, cosa);
|
||||
offset.cx = fround(ascent * sina);
|
||||
offset.cy = fround(ascent * cosa);
|
||||
}
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = 10;
|
||||
int underline_thickness = max(hg / 20, 1);
|
||||
int underline_position = max(hg / 15, int(font.Info().GetDescent() > 0));
|
||||
if(angle) {
|
||||
int xpos = 0;
|
||||
for(int i = 0; i < n; i++) {
|
||||
wchar h = text[i];
|
||||
XftDrawString16(xftdraw, &c, xftfont,
|
||||
int(ox + xpos * cosa + offset.cx),
|
||||
int(oy - xpos * sina + offset.cy),
|
||||
(FcChar16 *)&h, 1);
|
||||
xpos += dx ? dx[i] : lastFont[text[i]];
|
||||
}
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
x += offset.cx;
|
||||
y += offset.cy;
|
||||
if(font.IsUnderline())
|
||||
DrawLine(
|
||||
int(x + underline_position * sina),
|
||||
int(y + underline_position * cosa),
|
||||
int(x + xpos * cosa + underline_position * sina),
|
||||
int(y - xpos * sina + underline_position * cosa),
|
||||
underline_thickness,
|
||||
ink
|
||||
);
|
||||
if(font.IsStrikeout()) {
|
||||
int p = 2 * ascent / 3;
|
||||
DrawLine(
|
||||
int(x + p * sina),
|
||||
int(y + p * cosa),
|
||||
int(x + xpos * cosa + p * sina),
|
||||
int(y - xpos * sina + p * cosa),
|
||||
underline_thickness,
|
||||
ink
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(dx) {
|
||||
int xpos = ox;
|
||||
Buffer<XftCharSpec> ch(n);
|
||||
for(int i = 0; i < n; i++) {
|
||||
ch[i].ucs4 = text[i];
|
||||
ch[i].x = xpos;
|
||||
ch[i].y = oy + ascent;
|
||||
xpos += dx[i];
|
||||
}
|
||||
XftDrawCharSpec(xftdraw, &c, xftfont, ch, n);
|
||||
}
|
||||
else
|
||||
XftDrawString16(xftdraw, &c, xftfont, ox, oy + ascent,
|
||||
(FcChar16 *)text, n);
|
||||
LLOG("XftColor: r=" << c.color.red << ", g=" << c.color.green << ", b=" << c.color.blue
|
||||
<< ", alpha=" << c.color.alpha << ", pixel=" << FormatIntHex(c.pixel));
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
int cx;
|
||||
if(dx && n > 0) {
|
||||
cx = 0;
|
||||
Sum(cx, dx, dx + n - 1);
|
||||
cx += lastFont[text[n - 1]];
|
||||
}
|
||||
else
|
||||
cx = GetTextSize(text, font, n).cx;
|
||||
if(font.IsUnderline())
|
||||
DrawRect(x, y + ascent + underline_position, cx, underline_thickness, ink);
|
||||
if(font.IsStrikeout())
|
||||
DrawRect(x, y + 2 * ascent / 3, cx, underline_thickness, ink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
#include "CtrlCore.h"
|
||||
|
||||
#ifdef GUI_X11
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x)
|
||||
#define LLOG(x)
|
||||
|
||||
int gtk_antialias = -1;
|
||||
int gtk_hinting = -1;
|
||||
String gtk_hintstyle;
|
||||
String gtk_rgba;
|
||||
|
||||
XftFont *CreateXftFont(Font font, int angle)
|
||||
{
|
||||
LTIMING("CreateXftFont");
|
||||
XftFont *xftfont;
|
||||
double sina, cosa;
|
||||
Std(font);
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = max(GetStdFontCy(), 10);
|
||||
String face = font.GetFaceName();
|
||||
FcPattern *p = FcPatternCreate();
|
||||
FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face);
|
||||
FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? 110 : 0);
|
||||
FcPatternAddInteger(p, FC_PIXEL_SIZE, hg);
|
||||
FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? 200 : 100);
|
||||
FcPatternAddBool(p, FC_MINSPACE, 1);
|
||||
if(angle) {
|
||||
FcMatrix mx;
|
||||
Draw::SinCos(angle, sina, cosa);
|
||||
mx.xx = cosa;
|
||||
mx.xy = -sina;
|
||||
mx.yx = sina;
|
||||
mx.yy = cosa;
|
||||
FcPatternAddMatrix(p, FC_MATRIX, &mx);
|
||||
}
|
||||
FcResult result;
|
||||
FcPattern *m = XftFontMatch(Xdisplay, Xscreenno, p, &result);
|
||||
if(font.IsNonAntiAliased() || gtk_antialias >= 0) {
|
||||
FcPatternDel(m, FC_ANTIALIAS);
|
||||
FcPatternAddBool(m, FC_ANTIALIAS,
|
||||
font.IsNonAntiAliased() ? FcFalse : gtk_antialias ? FcTrue : FcFalse);
|
||||
}
|
||||
if(gtk_hinting >= 0) {
|
||||
FcPatternDel(m, FC_HINTING);
|
||||
FcPatternAddBool(m, FC_HINTING, gtk_hinting);
|
||||
}
|
||||
const char *hs[] = { "hintnone", "hintslight", "hintmedium", "hintfull" };
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(gtk_hintstyle == hs[i]) {
|
||||
FcPatternDel(m, FC_HINT_STYLE);
|
||||
FcPatternAddInteger(m, FC_HINT_STYLE, i);
|
||||
}
|
||||
const char *rgba[] = { "_", "rgb", "bgr", "vrgb", "vbgr" };
|
||||
for(int i = 0; i < __countof(rgba); i++)
|
||||
if(gtk_rgba == rgba[i]) {
|
||||
FcPatternDel(m, FC_RGBA);
|
||||
FcPatternAddInteger(m, FC_RGBA, i);
|
||||
}
|
||||
xftfont = XftFontOpenPattern(Xdisplay, m);
|
||||
FcPatternDestroy(p);
|
||||
return xftfont;
|
||||
}
|
||||
|
||||
#define FONTCACHE 37
|
||||
|
||||
struct XftEntry {
|
||||
Font font;
|
||||
int angle;
|
||||
XftFont *xftfont;
|
||||
};
|
||||
|
||||
XftFont *GetXftFont(Font fnt, int angle)
|
||||
{
|
||||
static XftEntry cache[FONTCACHE];
|
||||
ONCELOCK {
|
||||
for(int i = 0; i < FONTCACHE; i++)
|
||||
cache[i].font.Height(-30000);
|
||||
}
|
||||
XftEntry be;
|
||||
be = cache[0];
|
||||
for(int i = 0; i < FONTCACHE; i++) {
|
||||
XftEntry e = cache[i];
|
||||
if(i)
|
||||
cache[i] = be;
|
||||
if(e.font == fnt && e.angle == angle) {
|
||||
if(i)
|
||||
cache[0] = e;
|
||||
return e.xftfont;
|
||||
}
|
||||
be = e;
|
||||
}
|
||||
if(be.xftfont) {
|
||||
XftFontClose(Xdisplay, be.xftfont);
|
||||
}
|
||||
be.font = fnt;
|
||||
be.angle = angle;
|
||||
be.xftfont = CreateXftFont(fnt, angle);
|
||||
cache[0] = be;
|
||||
return be.xftfont;
|
||||
}
|
||||
|
||||
CommonFontInfo XftGetFontInfoSys(Font font)
|
||||
{
|
||||
CommonFontInfo fi;
|
||||
String path;
|
||||
XftFont *xftfont = GetXftFont(font, 0);
|
||||
if(xftfont) {
|
||||
fi.ascent = (int16)xftfont->ascent;
|
||||
fi.descent = (int16)xftfont->descent;
|
||||
fi.height = fi.ascent + fi.descent;
|
||||
fi.lineheight = (int16)xftfont->height;
|
||||
fi.external = 0;
|
||||
fi.internal = 0;
|
||||
fi.overhang = 0;
|
||||
fi.maxwidth = (int16)xftfont->max_advance_width;
|
||||
fi.avewidth = fi.maxwidth;
|
||||
fi.default_char = '?';
|
||||
fi.fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH;
|
||||
|
||||
char *fn = NULL;
|
||||
XftPatternGetString(xftfont->pattern, XFT_FILE, 0, &fn);
|
||||
if(fn && strlen(fn) < 250)
|
||||
strcpy(fi.path, fn);
|
||||
}
|
||||
return fi;
|
||||
}
|
||||
|
||||
GlyphInfo XftGetGlyphInfoSys(Font font, int chr)
|
||||
{
|
||||
wchar h = chr;
|
||||
XGlyphInfo info;
|
||||
XftTextExtents16(Xdisplay, GetXftFont(font, 0), &h, 1, &info);
|
||||
GlyphInfo gi;
|
||||
gi.width = info.xOff;
|
||||
gi.lspc = -info.x;
|
||||
gi.rspc = info.xOff - info.width + info.x;
|
||||
return gi;
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
// extern FT_Face (*FTFaceXft)(Font fnt, String *rpath);
|
||||
extern CommonFontInfo (*GetFontInfoSysXft)(Font font);
|
||||
extern GlyphInfo (*GetGlyphInfoSysXft)(Font font, int chr);
|
||||
// FTFaceXft = XftFTFace;
|
||||
GetFontInfoSysXft = XftGetFontInfoSys;
|
||||
GetGlyphInfoSysXft = XftGetGlyphInfoSys;
|
||||
}
|
||||
|
||||
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx) {
|
||||
GuiLock __;
|
||||
LTIMING("DrawText");
|
||||
LLOG("DrawText " << ToUtf8(WString(text, n)) << " color:" << ink << " font:" << font);
|
||||
//TODO - X11 seems to crash when displaying too long strings (?)
|
||||
int ox = x + actual_offset.x;
|
||||
int oy = y + actual_offset.y;
|
||||
SetForeground(ink);
|
||||
XftColor c;
|
||||
c.color.red = ink.GetR() << 8;
|
||||
c.color.green = ink.GetG() << 8;
|
||||
c.color.blue = ink.GetB() << 8;
|
||||
c.color.alpha = 0xffff;
|
||||
c.pixel = GetXPixel(ink.GetR(), ink.GetG(), ink.GetB());
|
||||
XftFont *xftfont = GetXftFont(font, angle);
|
||||
Size offset = Point(0, 0);
|
||||
double sina, cosa;
|
||||
int ascent = font.Info().GetAscent();
|
||||
if(angle) {
|
||||
SinCos(angle, sina, cosa);
|
||||
offset.cx = fround(ascent * sina);
|
||||
offset.cy = fround(ascent * cosa);
|
||||
}
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = 10;
|
||||
int underline_thickness = max(hg / 20, 1);
|
||||
int underline_position = max(hg / 15, int(font.Info().GetDescent() > 0));
|
||||
if(angle) {
|
||||
int xpos = 0;
|
||||
for(int i = 0; i < n; i++) {
|
||||
wchar h = text[i];
|
||||
XftDrawString16(xftdraw, &c, xftfont,
|
||||
int(ox + xpos * cosa + offset.cx),
|
||||
int(oy - xpos * sina + offset.cy),
|
||||
(FcChar16 *)&h, 1);
|
||||
xpos += dx ? dx[i] : lastFont[text[i]];
|
||||
}
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
x += offset.cx;
|
||||
y += offset.cy;
|
||||
if(font.IsUnderline())
|
||||
DrawLine(
|
||||
int(x + underline_position * sina),
|
||||
int(y + underline_position * cosa),
|
||||
int(x + xpos * cosa + underline_position * sina),
|
||||
int(y - xpos * sina + underline_position * cosa),
|
||||
underline_thickness,
|
||||
ink
|
||||
);
|
||||
if(font.IsStrikeout()) {
|
||||
int p = 2 * ascent / 3;
|
||||
DrawLine(
|
||||
int(x + p * sina),
|
||||
int(y + p * cosa),
|
||||
int(x + xpos * cosa + p * sina),
|
||||
int(y - xpos * sina + p * cosa),
|
||||
underline_thickness,
|
||||
ink
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(dx) {
|
||||
int xpos = ox;
|
||||
Buffer<XftCharSpec> ch(n);
|
||||
for(int i = 0; i < n; i++) {
|
||||
ch[i].ucs4 = text[i];
|
||||
ch[i].x = xpos;
|
||||
ch[i].y = oy + ascent;
|
||||
xpos += dx[i];
|
||||
}
|
||||
XftDrawCharSpec(xftdraw, &c, xftfont, ch, n);
|
||||
}
|
||||
else
|
||||
XftDrawString16(xftdraw, &c, xftfont, ox, oy + ascent,
|
||||
(FcChar16 *)text, n);
|
||||
LLOG("XftColor: r=" << c.color.red << ", g=" << c.color.green << ", b=" << c.color.blue
|
||||
<< ", alpha=" << c.color.alpha << ", pixel=" << FormatIntHex(c.pixel));
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
int cx;
|
||||
if(dx && n > 0) {
|
||||
cx = 0;
|
||||
Sum(cx, dx, dx + n - 1);
|
||||
cx += lastFont[text[n - 1]];
|
||||
}
|
||||
else
|
||||
cx = GetTextSize(text, font, n).cx;
|
||||
if(font.IsUnderline())
|
||||
DrawRect(x, y + ascent + underline_position, cx, underline_thickness, ink);
|
||||
if(font.IsStrikeout())
|
||||
DrawRect(x, y + 2 * ascent / 3, cx, underline_thickness, ink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue