From 01598df990c458f55d5d56f52889338f08dac302 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sat, 9 Nov 2002 15:48:44 +0000 Subject: [PATCH] Fourth try to add pang_x.cpp git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17779 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/x11/pango_x.cpp | 276 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 src/x11/pango_x.cpp diff --git a/src/x11/pango_x.cpp b/src/x11/pango_x.cpp new file mode 100644 index 0000000000..17108cf60b --- /dev/null +++ b/src/x11/pango_x.cpp @@ -0,0 +1,276 @@ +/** + * This file gets included from dcclient.cpp and implements + * the X11 interface to Pango. + * Copyright (C) Owen Taylor and Robert Roebling. + */ + +/* Declaration */ + +void +x11_draw_glyphs( Drawable drawable, + GC gc, + PangoFont *font, + int x, + int y, + PangoGlyphString *glyphs); + +void +x11_draw_layout_line_with_colors( Drawable drawable, + GC gc, + int x, + int y, + PangoLayoutLine *line, + XColor *foreground, + XColor *background); + +void +x11_draw_layout_with_colors( Drawable drawable, + GC gc, + int x, + int y, + PangoLayout *layout, + XColor *foreground, + XColor *background); + +void +x11_draw_layout( Drawable drawable, + GC gc, + int x, + int y, + PangoLayout *layout); + +void +x11_pango_get_item_properties( PangoItem *item, + PangoUnderline *uline, + gboolean *strikethrough, + gint *rise, + PangoColor *fg_color, + gboolean *fg_set, + PangoColor *bg_color, + gboolean *bg_set, + gboolean *shape_set, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + +/* Implementation */ + +void +x11_draw_glyphs( Drawable drawable, + GC gc, + PangoFont *font, + int x, + int y, + PangoGlyphString *glyphs) +{ + if (PANGO_XFT_IS_FONT (font)) + { + pango_xft_picture_render( wxGlobalDisplay(), drawable, drawable, font, glyphs, x, y ); + } + else + { + pango_x_render( wxGlobalDisplay(), drawable, gc, font, glyphs, x, y ); + } +} + +void +x11_draw_layout_line_with_colors( Drawable drawable, + GC gc, + int x, + int y, + PangoLayoutLine *line, + XColor *foreground, + XColor *background) +{ + PangoRectangle overall_rect; + PangoRectangle logical_rect; + PangoRectangle ink_rect; + PangoContext *context; + gint x_off = 0; + gint rise = 0; + + context = pango_layout_get_context (line->layout); + + pango_layout_line_get_extents (line,NULL, &overall_rect); + + GSList *tmp_list = line->runs; + while (tmp_list) + { + PangoUnderline uline = PANGO_UNDERLINE_NONE; + PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data; + PangoColor fg_color, bg_color; + gboolean strike, fg_set, bg_set, shape_set; + gint risen_y; + + tmp_list = tmp_list->next; + + x11_pango_get_item_properties (run->item, &uline, + &strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set, + &shape_set, &ink_rect, &logical_rect); + + /* we subtract the rise because X coordinates are upside down */ + risen_y = y - rise / PANGO_SCALE; + + if (!shape_set) + { + if (uline == PANGO_UNDERLINE_NONE) + pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect); + else + pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect); + } + +#if 0 + XDrawRectangle( drawable, gc, TRUE, + x + (x_off + logical_rect.x) / PANGO_SCALE, + risen_y + overall_rect.y / PANGO_SCALE, + logical_rect.width / PANGO_SCALE, + overall_rect.height / PANGO_SCALE); +#endif + + if (!shape_set) + { + int gx = x + x_off / PANGO_SCALE; + int gy = risen_y; + + x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs); + } + + if (uline == PANGO_UNDERLINE_SINGLE) + { + XDrawLine( wxGlobalDisplay(), drawable, gc, + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, + risen_y + 1, + x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, + risen_y + 1); + } + + x_off += logical_rect.width; + } +} + +void +x11_draw_layout_with_colors( Drawable drawable, + GC gc, + int x, + int y, + PangoLayout *layout, + XColor *foreground, + XColor *background) +{ + PangoLayoutIter *iter = pango_layout_get_iter (layout); + + do + { + PangoLayoutLine *line = pango_layout_iter_get_line (iter); + + PangoRectangle logical_rect; + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); + + int baseline = pango_layout_iter_get_baseline (iter); + + x11_draw_layout_line_with_colors( drawable, gc, + x + logical_rect.x / PANGO_SCALE, + y + baseline / PANGO_SCALE, + line, + foreground, + background); + + } while (pango_layout_iter_next_line (iter)); + + pango_layout_iter_free (iter); +} + +void +x11_draw_layout( Drawable drawable, + GC gc, + int x, + int y, + PangoLayout *layout) +{ + wxCHECK_RET( layout, wxT("No layout") ); + + x11_draw_layout_with_colors (drawable, gc, x, y, layout, NULL, NULL); +} + +void +x11_pango_get_item_properties( PangoItem *item, + PangoUnderline *uline, + gboolean *strikethrough, + gint *rise, + PangoColor *fg_color, + gboolean *fg_set, + PangoColor *bg_color, + gboolean *bg_set, + gboolean *shape_set, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + GSList *tmp_list = item->analysis.extra_attrs; + + if (strikethrough) + *strikethrough = FALSE; + + if (fg_set) + *fg_set = FALSE; + + if (bg_set) + *bg_set = FALSE; + + if (shape_set) + *shape_set = FALSE; + + if (rise) + *rise = 0; + + while (tmp_list) + { + PangoAttribute *attr = (PangoAttribute *) tmp_list->data; + + switch (attr->klass->type) + { + case PANGO_ATTR_UNDERLINE: + if (uline) + *uline = (PangoUnderline) ((PangoAttrInt *)attr)->value; + break; + + case PANGO_ATTR_STRIKETHROUGH: + if (strikethrough) + *strikethrough = ((PangoAttrInt *)attr)->value; + break; + + case PANGO_ATTR_FOREGROUND: + if (fg_color) + *fg_color = ((PangoAttrColor *)attr)->color; + if (fg_set) + *fg_set = TRUE; + + break; + + case PANGO_ATTR_BACKGROUND: + if (bg_color) + *bg_color = ((PangoAttrColor *)attr)->color; + if (bg_set) + *bg_set = TRUE; + + break; + + case PANGO_ATTR_SHAPE: + if (shape_set) + *shape_set = TRUE; + if (logical_rect) + *logical_rect = ((PangoAttrShape *)attr)->logical_rect; + if (ink_rect) + *ink_rect = ((PangoAttrShape *)attr)->ink_rect; + break; + + case PANGO_ATTR_RISE: + if (rise) + *rise = ((PangoAttrInt *)attr)->value; + break; + + default: + break; + } + tmp_list = tmp_list->next; + } +} +