TextAsset::Size TextAsset::computeSizeOfText(cairo_t* cairoContext, const std::string textString, int bounds, PangoFontDescription* font, Rect* tight, float* lineHeightOut) { PangoLayout* layout = pango_cairo_create_layout(cairoContext); // Kerning PangoAttrList* attr_list = pango_attr_list_new(); PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern)); pango_attr_list_insert(attr_list, spacing_attr); pango_layout_set_attributes(layout, attr_list); pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION); pango_layout_set_text(layout, textString.c_str(), (int)textString.length()); pango_layout_set_alignment(layout, _alignment); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); const Size maxTextureSize(bounds, 1024); pango_layout_set_width(layout, pango_units_from_double(maxTextureSize.width)); pango_layout_set_height(layout, pango_units_from_double(maxTextureSize.height)); pango_layout_set_font_description(layout, font); applyLeading(cairoContext, layout, font); PangoRectangle estimateSize; PangoRectangle ink; pango_layout_get_pixel_extents(layout, &ink, &estimateSize); // If the text is right or center aligned the offsets will contain all the // leading space. We ignore that for the size because drawText will draw // in the larger box. The tight box below will get the offsets so we know // where to draw so the text lands in the same tight box. Size res(estimateSize.width, estimateSize.height); if (tight != NULL) { float lineHeight; float xHeight = charHeight(cairoContext, font, 'x', &lineHeight); if (lineHeightOut != NULL) { *lineHeightOut = lineHeight; } const float capHeight = charHeight(cairoContext, font, 'Y'); const float ascender = pango_units_to_double(pango_layout_get_baseline(layout)); const float topSpace = ascender - capHeight; const float bottomSpace = MAX(lineHeight - ascender - (capHeight - xHeight), 0); if (res.height > topSpace + bottomSpace) { *tight = Rect(estimateSize.x, estimateSize.y + topSpace, res.width, res.height - topSpace - bottomSpace); } else { *tight = Rect(0, 0, res.width, res.height); } } g_object_unref(layout); return res; }
ttext::ttext() : #if PANGO_VERSION_CHECK(1,22,0) context_(pango_font_map_create_context(pango_cairo_font_map_get_default())), #else context_(pango_cairo_font_map_create_context(( reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))), #endif layout_(pango_layout_new(context_)), rect_(), surface_(), #ifdef SDL_GPU texture_(), #endif text_(), markedup_text_(false), link_aware_(false), link_color_(), font_class_(font::FONT_SANS_SERIF), font_size_(14), font_style_(STYLE_NORMAL), foreground_color_(0xFFFFFFFF), // solid white maximum_width_(-1), characters_per_line_(0), maximum_height_(-1), ellipse_mode_(PANGO_ELLIPSIZE_END), alignment_(PANGO_ALIGN_LEFT), maximum_length_(std::string::npos), calculation_dirty_(true), length_(0), surface_dirty_(true), surface_buffer_(nullptr) { // With 72 dpi the sizes are the same as with SDL_TTF so hardcoded. pango_cairo_context_set_resolution(context_, 72.0); pango_layout_set_ellipsize(layout_, ellipse_mode_); pango_layout_set_alignment(layout_, alignment_); pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR); /* * Set the pango spacing a bit bigger since the default is deemed to small * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832 */ pango_layout_set_spacing(layout_, 2 * PANGO_SCALE); cairo_font_options_t *fo = cairo_font_options_create(); cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON); #ifdef _WIN32 // Cairo on Windows (at least the latest available version from gtk.org // as of 2014-02-22, version 1.10.2) has issues with ClearType resulting // in glitchy anti-aliasing with CAIRO_ANTIALIAS_SUBPIXEL or // CAIRO_ANTIALIAS_DEFAULT, but not CAIRO_ANTIALIAS_GRAY, so we use that // as a workaround until the Windows package is updated to use a newer // version of Cairo (see Wesnoth bug #21648). cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); #endif pango_cairo_context_set_font_options(context_, fo); cairo_font_options_destroy(fo); }
static void _tristatebutton_size_request(GtkWidget *widget, GtkRequisition *requisition) { g_return_if_fail(widget != NULL); g_return_if_fail(DTGTK_IS_TRISTATEBUTTON(widget)); g_return_if_fail(requisition != NULL); /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); g_object_unref(layout); requisition->width = pw + DT_PIXEL_APPLY_DPI(4); requisition->height = ph + DT_PIXEL_APPLY_DPI(4); } else { requisition->width = requisition->height = DT_PIXEL_APPLY_DPI(24); } }
static PyObject * _pango_cairo_layout_set_resolution(PyObject *self, PyObject *args) { PangoLayout *layout; double res; if (!PyArg_ParseTuple(args, "ld", &layout, &res)) return NULL; pango_cairo_context_set_resolution(pango_layout_get_context(layout), res); Py_RETURN_NONE; }
ttext::ttext() : #if PANGO_VERSION_CHECK(1,22,0) context_(pango_font_map_create_context(pango_cairo_font_map_get_default())), #else context_(pango_cairo_font_map_create_context(( reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))), #endif layout_(pango_layout_new(context_)), rect_(), surface_(), text_(), markedup_text_(false), link_aware_(false), link_color_(), font_class_(font::FONT_SANS_SERIF), font_size_(14), font_style_(STYLE_NORMAL), foreground_color_(0xFFFFFFFF), // solid white maximum_width_(-1), characters_per_line_(0), maximum_height_(-1), ellipse_mode_(PANGO_ELLIPSIZE_END), alignment_(PANGO_ALIGN_LEFT), maximum_length_(std::string::npos), calculation_dirty_(true), length_(0), surface_dirty_(true), surface_buffer_(nullptr) { // With 72 dpi the sizes are the same as with SDL_TTF so hardcoded. pango_cairo_context_set_resolution(context_, 72.0); pango_layout_set_ellipsize(layout_, ellipse_mode_); pango_layout_set_alignment(layout_, alignment_); pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR); /* * Set the pango spacing a bit bigger since the default is deemed to small * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832 */ pango_layout_set_spacing(layout_, 4 * PANGO_SCALE); cairo_font_options_t *fo = cairo_font_options_create(); cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON); cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_DEFAULT); pango_cairo_context_set_font_options(context_, fo); cairo_font_options_destroy(fo); }
static void lsm_dom_view_set_cairo_context (LsmDomView *view, cairo_t *cairo) { PangoContext *context; cairo_font_options_t *font_options; const cairo_font_options_t *current_font_options; cairo_surface_t *surface; cairo_surface_type_t type; g_return_if_fail (LSM_IS_DOM_VIEW (view)); if (view->cairo == cairo) return; if (view->cairo != NULL) { cairo_destroy (view->cairo); g_object_unref (view->pango_layout); } if (cairo == NULL) { view->cairo = NULL; view->pango_layout = NULL; return; } cairo_reference (cairo); view->cairo = cairo; view->pango_layout = pango_cairo_create_layout (cairo); surface = cairo_get_target (cairo); type = cairo_surface_get_type (surface); view->is_vector = (type == CAIRO_SURFACE_TYPE_SVG || type == CAIRO_SURFACE_TYPE_PDF || type == CAIRO_SURFACE_TYPE_PS); context = pango_layout_get_context (view->pango_layout); pango_cairo_context_set_resolution (context, 72); current_font_options = pango_cairo_context_get_font_options (context); if (current_font_options == NULL) font_options = cairo_font_options_create (); else font_options = cairo_font_options_copy (current_font_options); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); pango_cairo_context_set_font_options (context, font_options); cairo_font_options_destroy (font_options); }
// Returns the PangoFont structure corresponding to the closest available font // in the font map. Note that if the font is wholly missing, this could // correspond to a completely different font family and face. PangoFont* PangoFontInfo::ToPangoFont() const { InitFontconfig(); PangoFontMap* font_map = pango_cairo_font_map_get_default(); PangoContext* context = pango_context_new(); pango_cairo_context_set_resolution(context, resolution_); pango_context_set_font_map(context, font_map); PangoFont* font = NULL; { DISABLE_HEAP_LEAK_CHECK; font = pango_font_map_load_font(font_map, context, desc_); } g_object_unref(context); return font; }
void TextAsset::drawText(cairo_t* cairoContext, const std::string& textString, const Rect& rect, PangoFontDescription* inFontDescription, bool outlineEnabled) { cairo_move_to(cairoContext, rect.x, rect.y); PangoLayout* layout = pango_cairo_create_layout(cairoContext); // Kerning PangoAttrList* attr_list = pango_attr_list_new(); PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern)); pango_attr_list_insert(attr_list, spacing_attr); pango_layout_set_attributes(layout, attr_list); pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION); pango_layout_set_text(layout, textString.c_str(), textString.length()); pango_layout_set_font_description(layout, inFontDescription); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_width(layout, pango_units_from_double(rect.size.width + WIDTH_PADDING)); pango_layout_set_height(layout, pango_units_from_double(rect.size.height + HEIGHT_PADDING)); pango_layout_set_alignment(layout, _alignment); applyLeading(cairoContext, layout, inFontDescription); pango_cairo_show_layout(cairoContext, layout); // Core Text defines positive outline width values as stroke only if (_outlineThickness <= 0.0f) { cairo_fill_preserve(cairoContext); } // Outline if (outlineEnabled && _outlineThickness != 0.0f) { const float outlineThickness = (fabsf(_outlineThickness) / 100.0f) * _fontSize * CLIENT_TO_SERVER_SCALE; cairo_set_source_rgba(cairoContext, _outlineColor.red, _outlineColor.green, _outlineColor.blue, _outlineColor.alpha); pango_cairo_layout_path(cairoContext, layout); cairo_set_line_width(cairoContext, outlineThickness); cairo_stroke(cairoContext); } else { cairo_new_path(cairoContext); } g_object_unref(layout); }
PangoLayout* TextView::initPango(cairo_t* cr, Text* t) { PangoLayout* layout = pango_cairo_create_layout(cr); // Additional Feature: add autowrap and text field size for // the next xournal release (with new fileformat...) // pango_layout_set_wrap pango_cairo_context_set_resolution(pango_layout_get_context(layout), textDpi); pango_cairo_update_layout(cr, layout); pango_context_set_matrix(pango_layout_get_context(layout), NULL); updatePangoFont(layout, t); return layout; }
int FontHeightWithContextReal(cairo_t* c, PangoFontDescription* fontDesc, int dpi) { int height; PangoContext* pc = pango_cairo_create_context(c); pango_cairo_context_set_resolution(pc, dpi); PangoLayout *layout = pango_layout_new(pc); pango_layout_set_text(layout, "Ayg中", -1); pango_layout_set_font_description(layout, fontDesc); pango_layout_get_pixel_size(layout, NULL, &height); g_object_unref(layout); g_object_unref(pc); return height; }
void StringSizeStrict(const char* str, const char* font, int fontSize, int dpi, int* w, int* h) { if (!str || str[0] == 0) { if (w) *w = 0; if (h) *h = 0; return; } if (!fcitx_utf8_check_string(str)) { if (w) *w = 0; if (h) *h = 0; return; } cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 10, 10); cairo_t *c = cairo_create(surface); SetFontContext(c, font, fontSize, dpi); #ifdef _ENABLE_PANGO PangoRectangle rect; PangoContext* pc = pango_cairo_create_context(c); pango_cairo_context_set_resolution(pc, dpi); PangoLayout *layout = pango_layout_new(pc); pango_layout_set_text(layout, str, -1); pango_layout_set_font_description(layout, fontDesc); pango_layout_get_pixel_extents(layout, &rect, NULL); if (w) *w = rect.width; if (h) *h = rect.height; g_object_unref(layout); #else cairo_text_extents_t extents; cairo_text_extents(c, str, &extents); if (w) *w = extents.width; if (h) *h = extents.height; #endif ResetFontContext(); cairo_destroy(c); cairo_surface_destroy(surface); }
static void style_updated (GtkWidget *widget, void *user_data) { GdkDisplay *gdkdisplay; GdkScreen *gdkscreen; WnckScreen *screen; PangoContext *context = (PangoContext *) user_data; gdkdisplay = gdk_display_get_default (); gdkscreen = gdk_display_get_default_screen (gdkdisplay); screen = wnck_screen_get_default (); update_style (widget); pango_cairo_context_set_resolution (context, gdk_screen_get_resolution (gdkscreen)); decorations_changed (screen); }
static void lsm_dom_view_init (LsmDomView *view) { PangoFontMap *font_map; PangoContext *pango_context; cairo_font_options_t *font_options; view->resolution_ppi = LSM_DOM_VIEW_DEFAULT_RESOLUTION; view->viewport_pt.x = 0; view->viewport_pt.y = 0; view->viewport_pt.width = LSM_DOM_VIEW_DEFAULT_VIEWBOX_WIDTH; view->viewport_pt.height = LSM_DOM_VIEW_DEFAULT_VIEWBOX_HEIGHT; view->font_description = pango_font_description_new (); font_map = pango_cairo_font_map_get_default (); #if PANGO_VERSION_CHECK(1,22,0) pango_context = pango_font_map_create_context (font_map); #else pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (font_map)); #endif pango_cairo_context_set_resolution (pango_context, 72.0); view->measure_pango_layout = pango_layout_new (pango_context); font_options = cairo_font_options_create (); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); pango_cairo_context_set_font_options (pango_context, font_options); cairo_font_options_destroy (font_options); g_object_unref (pango_context); view->pango_layout = NULL; view->cairo = NULL; view->is_vector = FALSE; }
/** * gdk_pango_context_get_for_screen: * @screen: the #GdkScreen for which the context is to be created. * * Creates a #PangoContext for @screen. * * The context must be freed when you're finished with it. * * When using GTK+, normally you should use gtk_widget_get_pango_context() * instead of this function, to get the appropriate context for * the widget you intend to render text onto. * * The newly created context will have the default font options * (see #cairo_font_options_t) for the screen; if these options * change it will not be updated. Using gtk_widget_get_pango_context() * is more convenient if you want to keep a context around and track * changes to the screen's font rendering settings. * * Return value: (transfer full): a new #PangoContext for @screen * * Since: 2.2 **/ PangoContext * gdk_pango_context_get_for_screen (GdkScreen *screen) { PangoFontMap *fontmap; PangoContext *context; const cairo_font_options_t *options; double dpi; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); fontmap = pango_cairo_font_map_get_default (); context = pango_font_map_create_context (fontmap); options = gdk_screen_get_font_options (screen); pango_cairo_context_set_font_options (context, options); dpi = gdk_screen_get_resolution (screen); pango_cairo_context_set_resolution (context, dpi); return context; }
void OutputStringWithContextReal(cairo_t * c, PangoFontDescription* desc, int dpi, const char *str, int x, int y) { if (!str || str[0] == 0) return; if (!fcitx_utf8_check_string(str)) return; cairo_save(c); PangoContext *pc = pango_cairo_create_context(c); pango_cairo_context_set_resolution(pc, dpi); PangoLayout *layout = pango_layout_new(pc); pango_layout_set_text(layout, str, -1); pango_layout_set_font_description(layout, desc); cairo_move_to(c, x, y); pango_cairo_show_layout(c, layout); cairo_restore(c); g_object_unref(layout); g_object_unref(pc); }
void StringSizeWithContextReal(cairo_t * c, PangoFontDescription* fontDesc, int dpi, const char *str, int* w, int* h) { if (!str || str[0] == 0) { if (w) *w = 0; if (h) *h = 0; return; } if (!fcitx_utf8_check_string(str)) { if (w) *w = 0; if (h) *h = 0; return; } PangoContext *pc = pango_cairo_create_context(c); pango_cairo_context_set_resolution(pc, dpi); PangoLayout *layout = pango_layout_new(pc); pango_layout_set_text(layout, str, -1); pango_layout_set_font_description(layout, fontDesc); pango_layout_get_pixel_size(layout, w, h); g_object_unref(layout); g_object_unref(pc); }
static void schgui_cairo_drafter_draw_text(SchGUICairoDrafter *drafter, const struct _SchText *text) { if (text != NULL) { int visible; sch_text_get_visible(text, &visible); if (visible) { SchGUICairoDrafterPrivate *privat = SCHGUI_CAIRO_DRAFTER_GET_PRIVATE(drafter); if (privat->cairo != NULL) { PangoLayout *layout; SchMultiline *multiline = sch_text_get_multiline(text); int point_size = sch_text_get_size(text); float height; int alignment; cairo_font_options_t *options; PangoContext *context; int baseline; PangoLayoutIter *iter; int index; int show; SchGUIDrawingCfgColor color; int enabled; sch_text_get_color(text, &index); enabled = schgui_drawing_cfg_get_color(privat->config, index, &color); if (enabled) { if (0) /* show ink rect */ { GeomBounds bounds; int success; success = schgui_cairo_drafter_text_bounds(drafter, text, &bounds); if (success) { cairo_set_source_rgb(privat->cairo, 1.0, 0, 0); cairo_move_to(privat->cairo, bounds.min_x, bounds.min_y); cairo_line_to(privat->cairo, bounds.max_x, bounds.min_y); cairo_stroke(privat->cairo); cairo_set_source_rgb(privat->cairo, 0.75, 0, 0); cairo_move_to(privat->cairo, bounds.max_x, bounds.min_y); cairo_line_to(privat->cairo, bounds.max_x, bounds.max_y); cairo_line_to(privat->cairo, bounds.min_x, bounds.max_y); cairo_line_to(privat->cairo, bounds.min_x, bounds.min_y); //cairo_close_path(privat->cairo); cairo_stroke(privat->cairo); cairo_set_source_rgb(privat->cairo, 0, 0, 0); } cairo_set_source_rgb(privat->cairo, 0, 0, 1.0); cairo_new_sub_path(privat->cairo); cairo_arc(privat->cairo, sch_text_get_x(text), sch_text_get_y(text), 10, 0, 2 * M_PI); cairo_stroke(privat->cairo); cairo_set_source_rgb(privat->cairo, 0, 0, 0); } cairo_save(privat->cairo); height = 1000 * point_size / 72; layout = pango_cairo_create_layout(privat->cairo); pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936); // context = pango_layout_get_context(layout); // options = cairo_font_options_create (); // cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); // cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_MEDIUM); // pango_cairo_context_set_font_options (context, options); // cairo_font_options_destroy (options); cairo_set_source_rgb(privat->cairo, color.red, color.green, color.blue); pango_font_description_set_size(privat->desc, point_size * PANGO_SCALE ); pango_layout_set_spacing(layout, 40000); pango_layout_set_font_description(layout, privat->desc); sch_text_get_show(text, &show); pango_layout_set_markup(layout, sch_multiline_peek_markup(multiline, show), -1); PangoFontMetrics *metrics = pango_context_get_metrics( pango_layout_get_context(layout), privat->desc, NULL ); cairo_move_to(privat->cairo, sch_text_get_x(text), sch_text_get_y(text)); cairo_rotate(privat->cairo, M_PI * sch_text_get_angle(text) / 180); cairo_scale(privat->cairo, 1, -1); baseline = pango_layout_get_baseline(layout); alignment = sch_text_get_alignment(text); #if 1 switch (alignment) { case 2: case 5: case 8: /* upper */ //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE)); //cairo_rel_move_to(privat->cairo, 0, height); break; case 1: case 4: case 7: /* center */ cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE)); cairo_rel_move_to(privat->cairo, 0, height); cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(2 * privat->zoom * PANGO_SCALE)); cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline) - 1)/(2 * privat->zoom * PANGO_SCALE)); break; case 0: case 3: case 6: default: /* lower */ //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(privat->zoom * PANGO_SCALE)); //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline)-1)/(privat->zoom * PANGO_SCALE)); //cairo_rel_move_to(privat->cairo, 0, -pango_layout_get_spacing(layout) * (sch_multiline_lines(multiline)-1)/ PANGO_SCALE); iter = pango_layout_get_iter(layout); while (!pango_layout_iter_at_last_line(iter)) { pango_layout_iter_next_line(iter); } cairo_rel_move_to(privat->cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE); pango_layout_iter_free(iter); } #endif //g_debug("Ascent: %d", pango_font_metrics_get_ascent(metrics)); //g_debug("Descent: %d", pango_font_metrics_get_descent(metrics)); //g_debug("Spacing: %d", pango_layout_get_spacing(layout)); //g_debug("Font size: %d", pango_font_description_get_size(privat->desc)); //g_debug("Baseline %d", pango_layout_get_baseline(layout)); pango_font_metrics_unref(metrics); pango_cairo_show_layout(privat->cairo, layout); cairo_restore(privat->cairo); g_object_unref(layout); } } } } }
static void schgui_cairo_text_draw(SchGUICairoDrawItem *item, cairo_t *cairo) { if (cairo != NULL) { SchGUICairoTextPrivate *privat = SCHGUI_CAIRO_TEXT_GET_PRIVATE(item); if (privat != NULL) { PangoLayout *layout = pango_cairo_create_layout(cairo); if (layout != NULL) { PangoLayoutIter *iter; int width; cairo_save(cairo); cairo_set_source_rgba(cairo, privat->red, privat->green, privat->blue, privat->alpha); pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936); pango_layout_set_spacing(layout, 40000); pango_layout_set_font_description(layout, privat->font_desc); pango_layout_set_markup(layout, privat->markup, -1); cairo_move_to(cairo, privat->x, privat->y); cairo_rotate(cairo, privat->angle); cairo_scale(cairo, 1, -1); switch (privat->alignment) { case 2: case 5: case 8: /* upper */ break; case 1: case 4: case 7: /* center */ iter = pango_layout_get_iter(layout); while (!pango_layout_iter_at_last_line(iter)) { pango_layout_iter_next_line(iter); } cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE / 2); pango_layout_iter_free(iter); break; case 0: case 3: case 6: default: /* lower */ iter = pango_layout_get_iter(layout); while (!pango_layout_iter_at_last_line(iter)) { pango_layout_iter_next_line(iter); } cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE); pango_layout_iter_free(iter); } switch (privat->alignment) { case 3: case 4: case 5: /* center */ pango_layout_get_size(layout, &width, NULL); cairo_rel_move_to(cairo, -width / PANGO_SCALE / 2, 0); break; case 6: case 7: case 8: pango_layout_get_size(layout, &width, NULL); cairo_rel_move_to(cairo, -width / PANGO_SCALE, 0); /* right */ break; case 0: case 1: case 2: default: /* left */ ; } pango_cairo_show_layout(cairo, layout); cairo_restore(cairo); g_object_unref(layout); } } } }
static boolean pango_textlayout(textpara_t * para, char **fontpath) { static char buf[1024]; /* returned in fontpath, only good until next call */ static PangoFontMap *fontmap; static PangoContext *context; static PangoFontDescription *desc; static char *fontname; static double fontsize; static gv_font_map* gv_fmap; char *fnt, *psfnt = NULL; PangoLayout *layout; PangoRectangle logical_rect; cairo_font_options_t* options; PangoFont *font; #ifdef ENABLE_PANGO_MARKUP PangoAttrList *attrs; GError *error = NULL; int flags; #endif char *text; double textlayout_scale; if (!context) { fontmap = pango_cairo_font_map_new(); gv_fmap = get_font_mapping(fontmap); context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap)); options=cairo_font_options_create(); cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY); cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON); cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR); pango_cairo_context_set_font_options(context, options); pango_cairo_context_set_resolution(context, FONT_DPI); cairo_font_options_destroy(options); g_object_unref(fontmap); } if (!fontname || strcmp(fontname, para->fontname) != 0 || fontsize != para->fontsize) { fontname = para->fontname; fontsize = para->fontsize; pango_font_description_free (desc); if (para->postscript_alias) { psfnt = fnt = gv_fmap[para->postscript_alias->xfig_code].gv_font; if(!psfnt) psfnt = fnt = pango_psfontResolve (para->postscript_alias); } else fnt = fontname; desc = pango_font_description_from_string(fnt); /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */ pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE)); if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) { /* -v support */ const char *fontclass; fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font)); buf[0] = '\0'; if (psfnt) { strcat(buf, "(ps:pango "); strcat(buf, psfnt); strcat(buf, ") "); } strcat(buf, "("); strcat(buf, fontclass); strcat(buf, ") "); #ifdef HAVE_PANGO_FC_FONT_LOCK_FACE if (strcmp(fontclass, "PangoCairoFcFont") == 0) { FT_Face face; PangoFcFont *fcfont; FT_Stream stream; FT_StreamDesc streamdesc; fcfont = PANGO_FC_FONT(font); face = pango_fc_font_lock_face(fcfont); if (face) { strcat(buf, "\""); strcat(buf, face->family_name); strcat(buf, ", "); strcat(buf, face->style_name); strcat(buf, "\" "); stream = face->stream; if (stream) { streamdesc = stream->pathname; if (streamdesc.pointer) strcat(buf, (char*)streamdesc.pointer); else strcat(buf, "*no pathname available*"); } else strcat(buf, "*no stream available*"); } pango_fc_font_unlock_face(fcfont); } else #endif { PangoFontDescription *tdesc; char *tfont; tdesc = pango_font_describe(font); tfont = pango_font_description_to_string(tdesc); strcat(buf, "\""); strcat(buf, tfont); strcat(buf, "\" "); g_free(tfont); } *fontpath = buf; } } #ifdef ENABLE_PANGO_MARKUP if ((para->font) && (flags = para->font->flags)) { char* markup = N_NEW(strlen(para->str) + sizeof(FULL_MARKUP), char); strcpy(markup,"<span"); if (flags & HTML_BF) strcat(markup," weight=\"bold\""); if (flags & HTML_IF) strcat(markup," style=\"italic\""); if (flags & HTML_UL) strcat(markup," underline=\"single\""); strcat (markup,">"); if (flags & HTML_SUP) strcat(markup,"<sup>"); if (flags & HTML_SUB) strcat(markup,"<sub>"); strcat (markup,para->str); if (flags & HTML_SUB) strcat(markup,"</sub>"); if (flags & HTML_SUP) strcat(markup,"</sup>"); strcat (markup,"</span>"); if (!pango_parse_markup (markup, -1, 0, &attrs, &text, NULL, &error)) { fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message); text = para->str; attrs = NULL; } free (markup); }
static gboolean _button_draw(GtkWidget *widget, cairo_t *cr) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_BUTTON(widget), FALSE); GtkStateFlags state = gtk_widget_get_state_flags(widget); GdkRGBA bg_color, fg_color; GtkStyleContext *context = gtk_widget_get_style_context(widget); gtk_style_context_get_background_color(context, state, &bg_color); gtk_style_context_get_color(context, state, &fg_color); /* update paint flags depending of states */ int flags = DTGTK_BUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* prelight */ if(state & GTK_STATE_FLAG_PRELIGHT) flags |= CPF_PRELIGHT; else flags &= ~CPF_PRELIGHT; /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } /* begin cairo drawing */ GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent */ if((flags & CPF_STYLE_FLAT)) { if(flags & CPF_PRELIGHT) { cairo_rectangle(cr, 0, 0, width, height); gdk_cairo_set_source_rgba(cr, &bg_color); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { /* draw default boxed button */ gtk_render_background(context, cr, 0, 0, width, height); if(!(flags & CPF_DO_NOT_USE_BORDER)) gtk_render_frame(context, cr, 0, 0, width, height); } gdk_cairo_set_source_rgba(cr, &fg_color); /* draw icon */ if(DTGTK_BUTTON(widget)->icon) { int icon_width = text ? height - (border * 2) : width - (border * 2); int icon_height = height - (border * 2); if(icon_width > 0 && icon_height > 0) { if(text) DTGTK_BUTTON(widget) ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags); else DTGTK_BUTTON(widget) ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags); } } /* draw label */ if(text) { int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0)); if(DTGTK_BUTTON(widget)->icon) lx += width; cairo_move_to(cr, lx, ly); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return FALSE; }
cairo_surface_t* render_text_to_surface (gchar* text, gint width, gint height, const cairo_font_options_t* font_opts, gdouble dpi) { cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc; PangoLayout* layout; // sanity check if (!text || width <= 0 || height <= 0) return NULL; // create surface surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) return NULL; // create context cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } // clear context cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // layout = pango_cairo_create_layout (cr); desc = pango_font_description_new (); pango_font_description_set_size (desc, 12 * PANGO_SCALE); pango_font_description_set_family_static (desc, "Candara"); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_height (layout, height * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); // print and layout string (pango-wise) pango_layout_set_text (layout, text, -1); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts); pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi); pango_layout_context_changed (layout); // draw pango-text to our cairo-context cairo_move_to (cr, 0.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); // this call leaks 3803 bytes, I've no idea how to fix that pango_cairo_show_layout (cr, layout); // clean up g_object_unref (layout); cairo_destroy (cr); return surface; }
static gboolean _tristatebutton_expose(GtkWidget *widget, GdkEventExpose *event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_TRISTATEBUTTON(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style = gtk_widget_get_style(widget); int state = gtk_widget_get_state(widget); /* fix text style */ for(int i = 0; i < 5; i++) style->text[i] = style->fg[i]; /* fetch flags */ int flags = DTGTK_TRISTATEBUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* update active state paint flag */ gboolean active = DTGTK_TRISTATEBUTTON(widget)->state > 0; if(active) flags |= CPF_ACTIVE; else flags &= ~(CPF_ACTIVE); /* begin cairo drawing */ cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(widget)); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int x = allocation.x; int y = allocation.y; int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent nor flat styled */ if((flags & CPF_STYLE_FLAT)) { if(state != GTK_STATE_NORMAL) { cairo_rectangle(cr, x, y, width, height); cairo_set_source_rgba(cr, style->bg[state].red / 65535.0, style->bg[state].green / 65535.0, style->bg[state].blue / 65535.0, 0.5); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { cairo_rectangle(cr, x, y, width, height); float rs = 1.0, gs = 1.0, bs = 1.0; if(DTGTK_TRISTATEBUTTON(widget)->state == 1) rs = gs = bs = 3.0; else if(DTGTK_TRISTATEBUTTON(widget)->state == 2) rs = 3.0; cairo_set_source_rgba(cr, (style->bg[state].red / 65535.0) * rs, (style->bg[state].green / 65535.0) * gs, (style->bg[state].blue / 65535.0) * bs, 0.5); cairo_fill(cr); } /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } cairo_set_source_rgb(cr, style->fg[state].red / 65535.0, style->fg[state].green / 65535.0, style->fg[state].blue / 65535.0); /* draw button image if any */ GtkWidget *image = gtk_button_get_image(GTK_BUTTON(widget)); if(image) { GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); if(pixbuf) { /* Draw the pixbuf */ gint pbw = gdk_pixbuf_get_width(pixbuf); gint pbh = gdk_pixbuf_get_height(pixbuf); gdk_cairo_set_source_pixbuf(cr, pixbuf, allocation.x + ((allocation.width / 2) - (pbw / 2)), allocation.y + ((allocation.height / 2) - (pbh / 2))); cairo_paint(cr); } } /* draw icon */ if(DTGTK_TRISTATEBUTTON(widget)->icon) { // if (flags & CPF_IGNORE_FG_STATE) // state = GTK_STATE_NORMAL; if(text) DTGTK_TRISTATEBUTTON(widget) ->icon(cr, x + border, y + border, height - (border * 2), height - (border * 2), flags); else DTGTK_TRISTATEBUTTON(widget) ->icon(cr, x + border, y + border, width - (border * 2), height - (border * 2), flags); } /* draw label */ if(text) { int lx = x + DT_PIXEL_APPLY_DPI(2), ly = y + ((height / 2.0) - (ph / 2.0)); cairo_translate(cr, lx, ly); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } cairo_destroy(cr); return FALSE; }
static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE); GtkDarktableToggleButton *button = DTGTK_TOGGLEBUTTON(widget); GtkStateFlags state = gtk_widget_get_state_flags(widget); GdkRGBA bg_color, fg_color; GtkStyleContext *context = gtk_widget_get_style_context(widget); if(button->icon_flags & CPF_CUSTOM_BG) bg_color = button->bg; else gtk_style_context_get_background_color(context, state, &bg_color); if(button->icon_flags & CPF_CUSTOM_FG) fg_color = button->fg; else gtk_style_context_get_color(context, state, &fg_color); /* fetch flags */ int flags = DTGTK_TOGGLEBUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* update active state paint flag */ gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if(active) flags |= CPF_ACTIVE; else flags &= ~(CPF_ACTIVE); /* prelight */ if(state & GTK_STATE_FLAG_PRELIGHT) flags |= CPF_PRELIGHT; else flags &= ~CPF_PRELIGHT; /* begin cairo drawing */ GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent nor flat styled */ if((flags & CPF_STYLE_FLAT)) { if(flags & CPF_PRELIGHT || flags & CPF_ACTIVE) { cairo_rectangle(cr, 0, 0, width, height); gdk_cairo_set_source_rgba(cr, &bg_color); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { /* draw default boxed button */ gtk_render_background(context, cr, 0, 0, width, height); if(!(flags & CPF_DO_NOT_USE_BORDER)) gtk_render_frame(context, cr, 0, 0, width, height); } /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } gdk_cairo_set_source_rgba(cr, &fg_color); /* draw icon */ if(DTGTK_TOGGLEBUTTON(widget)->icon) { // if (flags & CPF_IGNORE_FG_STATE) // state = GTK_STATE_NORMAL; int icon_width = text ? height - (border * 2) : width - (border * 2); int icon_height = height - (border * 2); if(icon_width > 0 && icon_height > 0) { if(text) DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags); else DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags); } } /* draw label */ if(text) { int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0)); // if (DTGTK_TOGGLEBUTTON (widget)->icon) lx += width; // GdkRectangle t={x,y,x+width,y+height}; // gtk_paint_layout(style,gtk_widget_get_window(widget), // state,TRUE,&t,widget,"togglebutton",lx,ly,layout); cairo_translate(cr, lx, ly); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return FALSE; }
static boolean pango_textlayout(textspan_t * span, char **fontpath) { static char buf[1024]; /* returned in fontpath, only good until next call */ static PangoFontMap *fontmap; static PangoContext *context; static PangoFontDescription *desc; static char *fontname; static double fontsize; static gv_font_map* gv_fmap; char *fnt, *psfnt = NULL; PangoLayout *layout; PangoRectangle logical_rect; cairo_font_options_t* options; PangoFont *font; #ifdef ENABLE_PANGO_MARKUP PangoAttrList *attrs; GError *error = NULL; int flags; #endif char *text; double textlayout_scale; PostscriptAlias *pA; if (!context) { fontmap = pango_cairo_font_map_new(); gv_fmap = get_font_mapping(fontmap); #ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT context = pango_font_map_create_context (fontmap); #else context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap)); #endif options=cairo_font_options_create(); cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY); cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON); cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR); pango_cairo_context_set_font_options(context, options); pango_cairo_context_set_resolution(context, FONT_DPI); cairo_font_options_destroy(options); g_object_unref(fontmap); } if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) { fontname = span->font->name; fontsize = span->font->size; pango_font_description_free (desc); pA = span->font->postscript_alias; if (pA) { psfnt = fnt = gv_fmap[pA->xfig_code].gv_font; if(!psfnt) psfnt = fnt = pango_psfontResolve (pA); } else fnt = fontname; desc = pango_font_description_from_string(fnt); /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */ pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE)); if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) { /* -v support */ const char *fontclass; fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font)); buf[0] = '\0'; if (psfnt) { strcat(buf, "(ps:pango "); strcat(buf, psfnt); strcat(buf, ") "); } strcat(buf, "("); strcat(buf, fontclass); strcat(buf, ") "); #ifdef HAVE_PANGO_FC_FONT_LOCK_FACE if (strcmp(fontclass, "PangoCairoFcFont") == 0) { FT_Face face; PangoFcFont *fcfont; FT_Stream stream; FT_StreamDesc streamdesc; fcfont = PANGO_FC_FONT(font); face = pango_fc_font_lock_face(fcfont); if (face) { strcat(buf, "\""); strcat(buf, face->family_name); strcat(buf, ", "); strcat(buf, face->style_name); strcat(buf, "\" "); stream = face->stream; if (stream) { streamdesc = stream->pathname; if (streamdesc.pointer) strcat(buf, (char*)streamdesc.pointer); else strcat(buf, "*no pathname available*"); } else strcat(buf, "*no stream available*"); } pango_fc_font_unlock_face(fcfont); } else #endif { PangoFontDescription *tdesc; char *tfont; tdesc = pango_font_describe(font); tfont = pango_font_description_to_string(tdesc); strcat(buf, "\""); strcat(buf, tfont); strcat(buf, "\" "); g_free(tfont); } *fontpath = buf; } } #ifdef ENABLE_PANGO_MARKUP if ((span->font) && (flags = span->font->flags)) { unsigned char buf[BUFSIZ]; agxbuf xb; agxbinit(&xb, BUFSIZ, buf); agxbput(&xb,"<span"); if (flags & HTML_BF) agxbput(&xb," weight=\"bold\""); if (flags & HTML_IF) agxbput(&xb," style=\"italic\""); if (flags & HTML_UL) agxbput(&xb," underline=\"single\""); if (flags & HTML_S) agxbput(&xb," strikethrough=\"true\""); agxbput (&xb,">"); if (flags & HTML_SUP) agxbput(&xb,"<sup>"); if (flags & HTML_SUB) agxbput(&xb,"<sub>"); agxbput (&xb,xml_string0(span->str, TRUE)); if (flags & HTML_SUB) agxbput(&xb,"</sub>"); if (flags & HTML_SUP) agxbput(&xb,"</sup>"); agxbput (&xb,"</span>"); if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) { fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message); text = span->str; attrs = NULL; } agxbfree (&xb); } else { text = span->str; attrs = NULL; } #else text = span->str; #endif layout = pango_layout_new (context); span->layout = (void *)layout; /* layout free with textspan - see labels.c */ span->free_layout = pango_free_layout; /* function for freeing pango layout */ pango_layout_set_text (layout, text, -1); pango_layout_set_font_description (layout, desc); #ifdef ENABLE_PANGO_MARKUP if (attrs) pango_layout_set_attributes (layout, attrs); #endif pango_layout_get_extents (layout, NULL, &logical_rect); /* if pango doesn't like the font then it sets width=0 but height = garbage */ if (logical_rect.width == 0) logical_rect.height = 0; textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE); span->size.x = (int)(logical_rect.width * textlayout_scale + 1); /* round up so that width/height are never too small */ span->size.y = (int)(logical_rect.height * textlayout_scale + 1); /* FIXME -- Horrible kluge !!! */ /* For now we are using pango for single line blocks only. * The logical_rect.height seems to be too high from the font metrics on some platforms. * Use an assumed height based on the point size. */ span->size.y = (int)(span->font->size * 1.1 + .5); /* The y offset from baseline to 0,0 of the bitmap representation */ #if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1) span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale; #else { /* do it the hard way on rhel5/centos5 */ PangoLayoutIter *iter = pango_layout_get_iter (layout); span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale; } #endif /* The distance below midline for y centering of text strings */ span->yoffset_centerline = 0.2 * span->font->size; if (logical_rect.width == 0) return FALSE; return TRUE; }