31 #include "pedigree/native/graphics/Graphics.h" 34 #include FT_FREETYPE_H 36 #include <cairo/cairo-ft.h> 37 #include <cairo/cairo.h> 39 #include <pango/pangocairo.h> 44 PangoFontDescription *m_FontDesc;
49 cairo_t *pCairo,
size_t requestedSize,
const char *pFilename,
bool bCache,
51 : m_CellWidth(0), m_CellHeight(0), m_Baseline(requestedSize),
55 m_FontLibraries->m_FontDesc = pango_font_description_from_string(pFilename);
56 m_FontLibraries->m_Cairo = pCairo;
58 PangoFontMetrics *metrics = 0;
59 PangoFontMap *fontmap = pango_cairo_font_map_get_default();
60 PangoContext *context = pango_font_map_create_context(fontmap);
61 pango_context_set_font_description(context, m_FontLibraries->m_FontDesc);
63 pango_context_get_metrics(context, m_FontLibraries->m_FontDesc, NULL);
64 g_object_unref(context);
67 pango_font_metrics_get_approximate_char_width(metrics) / PANGO_SCALE;
68 m_CellHeight = (pango_font_metrics_get_ascent(metrics) +
69 pango_font_metrics_get_descent(metrics)) /
71 m_Baseline = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
73 klog(LOG_INFO,
"metrics: %dx%d", m_CellWidth, m_CellHeight);
75 pango_font_metrics_unref(metrics);
78 m_FontLibraries->m_Iconv = iconv_open(
"UTF-8",
"UTF-32LE");
79 if (m_FontLibraries->m_Iconv == (iconv_t) -1)
82 LOG_WARNING,
"TUI: Font instance couldn't create iconv (%s)",
86 for (uint32_t c = 32; c < 127; ++c)
94 iconv_close(m_FontLibraries->m_Iconv);
97 for (std::map<uint32_t, char *>::iterator it = m_ConversionCache.begin();
98 it != m_ConversionCache.end(); ++it)
103 pango_font_description_free(m_FontLibraries->m_FontDesc);
105 delete m_FontLibraries;
110 uint32_t f, uint32_t b,
bool bBack,
bool bBold,
bool bItalic,
114 const char *convertOut = precache(c);
118 LOG_WARNING,
"TUI: Character '%x' was not able to be precached?",
124 return render(convertOut, x, y, f, b, bBack, bBold, bItalic, bUnderline);
128 const char *s,
size_t x,
size_t y, uint32_t f, uint32_t b,
bool bBack,
129 bool bBold,
bool bItalic,
bool bUnderline)
131 PangoAttrList *attrs = pango_attr_list_new();
134 PangoAttribute *attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
135 pango_attr_list_insert(attrs, attr);
139 PangoAttribute *attr = pango_attr_style_new(PANGO_STYLE_OBLIQUE);
140 pango_attr_list_insert(attrs, attr);
144 PangoAttribute *attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
145 pango_attr_list_insert(attrs, attr);
148 cairo_save(m_FontLibraries->m_Cairo);
149 PangoLayout *layout = pango_cairo_create_layout(m_FontLibraries->m_Cairo);
150 pango_layout_set_attributes(layout, attrs);
151 pango_layout_set_font_description(layout, m_FontLibraries->m_FontDesc);
152 pango_layout_set_text(
154 pango_attr_list_unref(attrs);
156 int width = 0, height = 0;
157 pango_layout_get_size(layout, &width, &height);
158 if ((width < 0) || (height < 0))
164 width /= PANGO_SCALE;
165 height /= PANGO_SCALE;
169 cairo_set_operator(m_FontLibraries->m_Cairo, CAIRO_OPERATOR_SOURCE);
170 cairo_set_source_rgba(
171 m_FontLibraries->m_Cairo, ((b >> 16) & 0xFF) / 256.0,
172 ((b >> 8) & 0xFF) / 256.0, ((b) &0xFF) / 256.0, 0.8);
176 m_CellWidth >
static_cast<size_t>(width) ? m_CellWidth : width;
178 m_CellHeight >
static_cast<size_t>(height) ? m_CellHeight : height;
179 cairo_rectangle(m_FontLibraries->m_Cairo, x, y, fillW, fillH);
180 cairo_fill(m_FontLibraries->m_Cairo);
183 cairo_set_operator(m_FontLibraries->m_Cairo, CAIRO_OPERATOR_OVER);
184 cairo_set_source_rgba(
185 m_FontLibraries->m_Cairo, ((f >> 16) & 0xFF) / 256.0,
186 ((f >> 8) & 0xFF) / 256.0, ((f) &0xFF) / 256.0, 1.0);
188 cairo_move_to(m_FontLibraries->m_Cairo, x, y);
189 pango_cairo_show_layout(m_FontLibraries->m_Cairo, layout);
191 g_object_unref(layout);
192 cairo_restore(m_FontLibraries->m_Cairo);
197 const char *Font::precache(uint32_t c)
199 if (m_FontLibraries->m_Iconv == (iconv_t) -1)
201 klog(LOG_WARNING,
"TUI: Font instance with bad iconv.");
206 std::map<uint32_t, char *>::iterator it = m_ConversionCache.find(c);
207 if (it == m_ConversionCache.end())
210 iconv(m_FontLibraries->m_Iconv, 0, 0, 0, 0);
213 uint32_t utf32[] = {c, 0};
214 char *utf32_c = (
char *) utf32;
215 char *out =
new char[100];
217 size_t utf32_len = 8;
218 size_t out_len = 100;
220 m_FontLibraries->m_Iconv, &utf32_c, &utf32_len, &out_c, &out_len);
222 if (res == ((
size_t) -1))
226 "TUI: Font::render couldn't convert input UTF-32 %x", c);
231 m_ConversionCache[c] = out;
243 void Font::updateCairo(cairo_t *pCairo)
245 m_FontLibraries->m_Cairo = pCairo;
Font(cairo_t *pCairo, size_t requestedSize, const char *pFilename, bool bCache, size_t nWidth)