#include using namespace std; #include "Options.h" #include "DisplayBase.h" #include "TextRendererPangoFT2.h" PangoFontMap* TextRendererPangoFT2::fontMap_ = NULL; TextRendererPangoFT2::TextRendererPangoFT2(DisplayBase *display) : TextRenderer(display), direction_(PANGO_DIRECTION_LTR) { g_type_init(); // There is a memory leak in the pango library. This can be // minimized by making the fontMap_ member static. // See http://bugzilla.gnome.org/show_bug.cgi?id=143542 if (fontMap_ == NULL) fontMap_ = pango_ft2_font_map_new(); int dpiX = 100; int dpiY = 100; pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontMap_), dpiX, dpiY); context_ = pango_ft2_font_map_create_context(PANGO_FT2_FONT_MAP(fontMap_)); pango_context_set_language(context_, pango_language_from_string ("en_US")); pango_context_set_base_dir(context_, direction_); fontDescription_ = pango_font_description_new(); Options *options = Options::getInstance(); Font(options->Font()); FontSize(options->FontSize()); layout_ = pango_layout_new(context_); pango_layout_set_width(layout_, -1); // Don't wrap lines } TextRendererPangoFT2::~TextRendererPangoFT2() { g_object_unref(layout_); pango_font_description_free(fontDescription_); g_object_unref(context_); // g_object_unref(fontMap_); pango_ft2_shutdown_display(); } void TextRendererPangoFT2::Font(const string &font) { pango_font_description_set_family(fontDescription_, font.c_str()); pango_font_description_set_style(fontDescription_, PANGO_STYLE_NORMAL); pango_font_description_set_variant(fontDescription_, PANGO_VARIANT_NORMAL); pango_font_description_set_weight(fontDescription_, PANGO_WEIGHT_NORMAL); pango_font_description_set_stretch(fontDescription_, PANGO_STRETCH_NORMAL); } void TextRendererPangoFT2::FontSize(const int size) { pango_font_description_set_size(fontDescription_, size * PANGO_SCALE); } int TextRendererPangoFT2::FontHeight() const { int returnVal = 0; PangoRectangle rect; pango_layout_get_extents(layout_, NULL, &rect); returnVal = static_cast (1.5 * PANGO_PIXELS(pango_font_description_get_size(fontDescription_))); return(returnVal); } void TextRendererPangoFT2::DrawText(const int x, const int y, const unsigned char color[3]) { FT_Bitmap bitmap; int textWidth, textHeight; TextBox(textWidth, textHeight); unsigned char *buffer = new unsigned char[textWidth * textHeight]; memset(buffer, 0, textWidth * textHeight); bitmap.rows = textHeight; bitmap.width = textWidth; bitmap.pitch = bitmap.width; bitmap.buffer = buffer; bitmap.num_grays = 256; bitmap.pixel_mode = ft_pixel_mode_grays; pango_ft2_render_layout(&bitmap, layout_, 0, 0); for (int j = 0; j < bitmap.rows; j++) { int istart = j * bitmap.width; for (int k = 0; k < bitmap.width; k++) { if (bitmap.buffer[istart + k]) { const double opacity = bitmap.buffer[istart + k]/255.0; display_->setPixel(x + k, y + j - textHeight, color, opacity); } } } delete [] buffer; } void TextRendererPangoFT2::SetText(const std::string &text) { pango_layout_set_text(layout_, text.c_str(), text.size()); pango_layout_set_alignment(layout_, PANGO_ALIGN_LEFT); pango_layout_set_font_description(layout_, fontDescription_); } void TextRendererPangoFT2::FreeText() { } void TextRendererPangoFT2::TextBox(int &textWidth, int &textHeight) { PangoRectangle rect; pango_layout_get_extents(layout_, NULL, &rect); textWidth = PANGO_PIXELS(rect.width); textHeight = PANGO_PIXELS(rect.height); }