static VALUE layout_iter_get_layout_extents(VALUE self) { PangoRectangle ink_rect, logical_rect; pango_layout_iter_get_layout_extents(_SELF(self), &ink_rect, &logical_rect); return rb_assoc_new(BOXED2RVAL(&ink_rect, PANGO_TYPE_RECTANGLE), BOXED2RVAL(&logical_rect, PANGO_TYPE_RECTANGLE)); }
static void render_para (GdkDrawable *drawable, GtkTextRenderState *render_state, GtkTextLineDisplay *line_display, /* Top-left corner of paragraph including all margins */ int x, int y, int selection_start_index, int selection_end_index, GList **widgets) { GSList *shaped_pointer = line_display->shaped_objects; PangoLayout *layout = line_display->layout; int byte_offset = 0; PangoLayoutIter *iter; PangoRectangle layout_logical; int screen_width; GdkGC *fg_gc, *bg_gc; gint state; gboolean first = TRUE; iter = pango_layout_get_iter (layout); pango_layout_iter_get_layout_extents (iter, NULL, &layout_logical); /* Adjust for margins */ layout_logical.x += line_display->x_offset * PANGO_SCALE; layout_logical.y += line_display->top_margin * PANGO_SCALE; screen_width = line_display->total_width; if (GTK_WIDGET_HAS_FOCUS (render_state->widget)) state = GTK_STATE_SELECTED; else state = GTK_STATE_ACTIVE; fg_gc = render_state->widget->style->text_gc [state]; bg_gc = render_state->widget->style->base_gc [state]; do { PangoLayoutLine *line = pango_layout_iter_get_line (iter); int selection_y, selection_height; int first_y, last_y; PangoRectangle line_rect; int baseline; pango_layout_iter_get_line_extents (iter, NULL, &line_rect); baseline = pango_layout_iter_get_baseline (iter); pango_layout_iter_get_line_yrange (iter, &first_y, &last_y); /* Adjust for margins */ line_rect.x += line_display->x_offset * PANGO_SCALE; line_rect.y += line_display->top_margin * PANGO_SCALE; baseline += line_display->top_margin * PANGO_SCALE; /* Selection is the height of the line, plus top/bottom * margin if we're the first/last line */ selection_y = y + PANGO_PIXELS (first_y) + line_display->top_margin; selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y); if (first) { selection_y -= line_display->top_margin; selection_height += line_display->top_margin; } if (pango_layout_iter_at_last_line (iter)) selection_height += line_display->bottom_margin; first = FALSE; if (selection_start_index < byte_offset && selection_end_index > line->length + byte_offset) /* All selected */ { gdk_draw_rectangle (drawable, bg_gc, TRUE, x + line_display->left_margin, selection_y, screen_width, selection_height); render_layout_line (drawable, render_state, line, &shaped_pointer, x + PANGO_PIXELS (line_rect.x), y + PANGO_PIXELS (baseline), TRUE, widgets); } else { GSList *shaped_pointer_tmp = shaped_pointer; render_layout_line (drawable, render_state, line, &shaped_pointer, x + PANGO_PIXELS (line_rect.x), y + PANGO_PIXELS (baseline), FALSE, widgets); if (selection_start_index <= byte_offset + line->length && selection_end_index > byte_offset) /* Some selected */ { GdkRegion *clip_region = get_selected_clip (render_state, layout, line, x + line_display->x_offset, selection_y, selection_height, selection_start_index, selection_end_index); gdk_gc_set_clip_region (fg_gc, clip_region); gdk_gc_set_clip_region (bg_gc, clip_region); gdk_draw_rectangle (drawable, bg_gc, TRUE, x + PANGO_PIXELS (line_rect.x), selection_y, PANGO_PIXELS (line_rect.width), selection_height); render_layout_line (drawable, render_state, line, &shaped_pointer_tmp, x + PANGO_PIXELS (line_rect.x), y + PANGO_PIXELS (baseline), TRUE, widgets); gdk_gc_set_clip_region (fg_gc, NULL); gdk_gc_set_clip_region (bg_gc, NULL); gdk_region_destroy (clip_region); /* Paint in the ends of the line */ if (line_rect.x > line_display->left_margin * PANGO_SCALE && ((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) || (line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length))) { gdk_draw_rectangle (drawable, bg_gc, TRUE, x + line_display->left_margin, selection_y, PANGO_PIXELS (line_rect.x) - line_display->left_margin, selection_height); } if (line_rect.x + line_rect.width < (screen_width + line_display->left_margin) * PANGO_SCALE && ((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) || (line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset))) { int nonlayout_width; nonlayout_width = line_display->left_margin + screen_width - PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width); gdk_draw_rectangle (drawable, bg_gc, TRUE, x + PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width), selection_y, nonlayout_width, selection_height); } } } byte_offset += line->length; } while (pango_layout_iter_next_line (iter)); pango_layout_iter_free (iter); }