mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
127 lines
3.2 KiB
C++
127 lines
3.2 KiB
C++
#include <CtrlCore/CtrlCore.h>
|
|
|
|
#ifdef GUI_GTK
|
|
|
|
#include <cairo/cairo-ft.h>
|
|
|
|
// #include <freetype2/freetype/ftoutln.h>
|
|
|
|
namespace Upp {
|
|
|
|
#define LLOG(x)
|
|
|
|
FcPattern *CreateFcPattern(Font font);
|
|
FT_Face FTFace(Font fnt, String *rpath = NULL);
|
|
|
|
struct FontSysData {
|
|
cairo_scaled_font_t *scaled_font;
|
|
bool colorimg = false;
|
|
Sizef colorimg_size;
|
|
|
|
void Init(Font font, int angle);
|
|
~FontSysData() { cairo_scaled_font_destroy(scaled_font); }
|
|
};
|
|
|
|
void FontSysData::Init(Font font, int angle)
|
|
{
|
|
LLOG("FontSysData::Init " << font << ", " << angle);
|
|
Std(font);
|
|
|
|
FcPattern *p = CreateFcPattern(font);
|
|
cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(p);
|
|
FcPatternDestroy(p);
|
|
|
|
cairo_matrix_t font_matrix[1], ctm[1];
|
|
cairo_matrix_init_identity(ctm);
|
|
|
|
int fh = font.GetHeight();
|
|
|
|
cairo_matrix_init_scale(font_matrix, fh, fh);
|
|
|
|
if(angle)
|
|
cairo_matrix_rotate(font_matrix, -angle * M_PI / 1800);
|
|
|
|
if(font.IsItalic() && !(FTFace(font)->style_flags & FT_STYLE_FLAG_ITALIC)) { // Synthetic italic
|
|
cairo_matrix_t shear[1];
|
|
cairo_matrix_init_identity(shear);
|
|
shear->xy = -0.165;
|
|
cairo_matrix_multiply(font_matrix, shear, font_matrix);
|
|
}
|
|
|
|
cairo_font_options_t *opt = cairo_font_options_create();
|
|
scaled_font = cairo_scaled_font_create(font_face, font_matrix, ctm, opt);
|
|
|
|
cairo_font_options_destroy(opt);
|
|
cairo_font_face_destroy(font_face);
|
|
}
|
|
|
|
struct FontDataSysMaker : LRUCache<FontSysData, Tuple2<Font, int> >::Maker {
|
|
Font font;
|
|
int angle;
|
|
|
|
virtual Tuple2<Font, int> Key() const { return MakeTuple(font, angle); }
|
|
virtual int Make(FontSysData& object) const { object.Init(font, angle); return 1; }
|
|
};
|
|
|
|
int gtk_antialias = -1; // These are not really used with GTK backed.....
|
|
int gtk_hinting = -1;
|
|
String gtk_hintstyle;
|
|
String gtk_rgba;
|
|
|
|
void SystemDraw::FlushText()
|
|
{
|
|
if(textcache.GetCount() == 0)
|
|
return;
|
|
static LRUCache<FontSysData, Tuple2<Font, int> > cache;
|
|
FontDataSysMaker m;
|
|
m.font = textfont;
|
|
m.angle = textangle;
|
|
FontSysData& sf = cache.Get(m);
|
|
|
|
cairo_set_scaled_font(cr, sf.scaled_font);
|
|
SetColor(textink);
|
|
|
|
Buffer<cairo_glyph_t> gs(textcache.GetCount());
|
|
for(int i = 0; i < textcache.GetCount(); i++) {
|
|
cairo_glyph_t& g = gs[i];
|
|
g.index = textcache[i].index;
|
|
g.x = textcache[i].x;
|
|
g.y = textcache[i].y;
|
|
}
|
|
|
|
cairo_show_glyphs(cr, gs, textcache.GetCount());
|
|
|
|
cache.Shrink(INT_MAX, 128);
|
|
|
|
textcache.Clear();
|
|
}
|
|
|
|
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
|
{
|
|
GuiLock __;
|
|
|
|
if(textcache.GetCount() && (font != textfont || ink != textink || angle != textangle))
|
|
FlushText();
|
|
|
|
textfont = font;
|
|
textink = ink;
|
|
textangle = angle;
|
|
|
|
int ascent = font.GetAscent();
|
|
double sina = 0;
|
|
double cosa = 1;
|
|
if(angle)
|
|
Draw::SinCos(angle, sina, cosa);
|
|
int xpos = 0;
|
|
for(int i = 0; i < n; i++) {
|
|
TextGlyph& g = textcache.Add();
|
|
g.index = GetGlyphInfo(font, text[i]).glyphi;
|
|
g.x = int(x + cosa * xpos + sina * ascent);
|
|
g.y = int(y + cosa * ascent - sina * xpos);
|
|
xpos += dx ? dx[i] : font[text[i]];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|