/** * gtk_text_attributes_unref: * @values: a #GtkTextAttributes * * Decrements the reference count on @values, freeing the structure * if the reference count reaches 0. **/ void gtk_text_attributes_unref (GtkTextAttributes *values) { g_return_if_fail (values != NULL); g_return_if_fail (values->refcount > 0); values->refcount -= 1; if (values->refcount == 0) { if (values->tabs) pango_tab_array_free (values->tabs); if (values->font) pango_font_description_free (values->font); if (values->pg_bg_color) gdk_color_free (values->pg_bg_color); if (values->pg_bg_rgba) gdk_rgba_free (values->pg_bg_rgba); if (values->appearance.rgba[0]) gdk_rgba_free (values->appearance.rgba[0]); if (values->appearance.rgba[1]) gdk_rgba_free (values->appearance.rgba[1]); g_slice_free (GtkTextAttributes, values); } }
void ui_insert_text(char *s, int x, int y, int h, int w, double *rgba, enum alignment align) { PangoTabArray *tabs; int height; pango_layout_set_width(ui->w[ui->cur].pangolayout, w * PANGO_SCALE); switch (align) { case RIGHT: pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_RIGHT); break; case CENTER: pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_CENTER); break; default: pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_LEFT); } tabs = pango_tab_array_new_with_positions(1, TRUE, PANGO_TAB_LEFT, config.tabs); pango_layout_set_wrap(ui->w[ui->cur].pangolayout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(ui->w[ui->cur].pangolayout, PANGO_ELLIPSIZE_END); pango_layout_set_font_description(ui->w[ui->cur].pangolayout, ui->w[ui->cur].pangofont); pango_layout_set_tabs(ui->w[ui->cur].pangolayout, tabs); pango_layout_set_markup(ui->w[ui->cur].pangolayout, s, -1); cairo_set_source_rgba(ui->w[ui->cur].c, rgba[0], rgba[1], rgba[2], rgba[3]); pango_cairo_update_layout(ui->w[ui->cur].c, ui->w[ui->cur].pangolayout); pango_layout_get_pixel_size(ui->w[ui->cur].pangolayout, NULL, &height); /* use (h - height) / 2 to center-align vertically */ cairo_move_to(ui->w[ui->cur].c, x, y + (h - height) / 2); pango_cairo_show_layout(ui->w[ui->cur].c, ui->w[ui->cur].pangolayout); pango_tab_array_free(tabs); }
void bug_information_window_new(GtkWidget * window) { GtkWidget *dialog; GtkTextBuffer *buffer; GtkWidget *scrolled_window, *text_view; PangoTabArray *tab_array; /* Basic dialog with a close button */ dialog = gtk_dialog_new_with_buttons(_("Bug information"), (window) ? (GtkWindow *) playlist3_get_window() : NULL, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CLOSE, GTK_RESPONSE_YES, NULL); /* Set default window size */ gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 800); /* The buffer that holds the "report" */ buffer = gtk_text_buffer_new(NULL); bug_information_generate_message(buffer); /* View to show the textbuffer */ text_view = gtk_text_view_new(); /* setup textview */ /* set tabarray */ tab_array = pango_tab_array_new_with_positions(1, TRUE, PANGO_TAB_LEFT, 500); gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view), TRUE); gtk_text_view_set_tabs(GTK_TEXT_VIEW(text_view), tab_array); pango_tab_array_free(tab_array); /* not editable */ gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), FALSE); /* set margins */ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_view), 12); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text_view), 12); /* Add the text buffer */ gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view), buffer); /* scrolled window, this allows the text view to scroll */ scrolled_window = gtk_scrolled_window_new(NULL, NULL); /* setup scrolled window */ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_ETCHED_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* add text view to scrolled_window */ gtk_container_add(GTK_CONTAINER(scrolled_window), text_view); /* add scrolled_window to dialog */ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrolled_window, TRUE, TRUE, 0); /* Add dialogs response handler */ g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL); /* show dialog */ gtk_widget_show_all(dialog); if (window == NULL) { gtk_dialog_run(GTK_DIALOG(dialog)); } }
void _gcr_display_view_append_value (GcrDisplayView *self, GcrRenderer *renderer, const gchar *field, const gchar *value, gboolean monospace) { GcrDisplayItem *item; PangoRectangle extents; PangoTabArray *tabs; PangoLayout *layout; GtkTextIter iter; gchar *text; g_return_if_fail (GCR_IS_DISPLAY_VIEW (self)); g_return_if_fail (field); item = lookup_display_item (self, renderer); g_return_if_fail (item); if (item->details && !item->expanded) return; text = g_strdup_printf ("%s:", field); if (value == NULL) value = ""; /* Measure the width of the field */ layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), text); pango_layout_get_extents (layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); g_object_unref (layout); /* Make the tab wide enough to accomodate */ if (extents.width > item->field_width) { item->field_width = extents.width + COLUMN_MARGIN; tabs = pango_tab_array_new (1, TRUE); pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, item->field_width); g_object_set (item->field_tag, "left-margin", FIELD_MARGIN, "indent", 0 - item->field_width, "tabs", tabs, NULL); pango_tab_array_free (tabs); } gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending); gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, text, -1, item->field_tag, item->extra_tag, NULL); gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\t", 1, item->extra_tag, NULL); gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, value, -1, item->field_tag, monospace ? self->pv->monospace_tag : item->extra_tag, monospace ? item->extra_tag : NULL, NULL); gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1, item->extra_tag, NULL); g_free (text); }
void indent_refresh_tab_width(GtkWidget *text_view) { PangoTabArray *tab_array; tab_array = pango_tab_array_new(1, TRUE); pango_tab_array_set_tab(tab_array, 0, PANGO_TAB_LEFT, calculate_real_tab_width(text_view, current_tab_width)); gtk_text_view_set_tabs(GTK_TEXT_VIEW(text_view), tab_array); pango_tab_array_free(tab_array); }
/** * gtk_text_attributes_copy_values: * @src: a #GtkTextAttributes * @dest: another #GtkTextAttributes * * Copies the values from @src to @dest so that @dest has * the same values as @src. Frees existing values in @dest. */ void gtk_text_attributes_copy_values (GtkTextAttributes *src, GtkTextAttributes *dest) { guint orig_refcount; if (src == dest) return; /* Remove refs */ if (dest->tabs) pango_tab_array_free (dest->tabs); if (dest->font) pango_font_description_free (dest->font); if (dest->pg_bg_color) gdk_color_free (dest->pg_bg_color); if (dest->pg_bg_rgba) gdk_rgba_free (dest->pg_bg_rgba); if (dest->appearance.rgba[0]) gdk_rgba_free (dest->appearance.rgba[0]); if (dest->appearance.rgba[1]) gdk_rgba_free (dest->appearance.rgba[1]); /* Copy */ orig_refcount = dest->refcount; *dest = *src; if (src->tabs) dest->tabs = pango_tab_array_copy (src->tabs); dest->language = src->language; if (src->font) dest->font = pango_font_description_copy (src->font); if (src->pg_bg_color) dest->pg_bg_color = gdk_color_copy (src->pg_bg_color); if (src->pg_bg_rgba) dest->pg_bg_rgba = gdk_rgba_copy (src->pg_bg_rgba); if (src->appearance.rgba[0]) dest->appearance.rgba[0] = gdk_rgba_copy (src->appearance.rgba[0]); if (src->appearance.rgba[1]) dest->appearance.rgba[1] = gdk_rgba_copy (src->appearance.rgba[1]); dest->refcount = orig_refcount; }
static VALUE rg_tabs(VALUE self) { VALUE ret = Qnil; PangoTabArray* tabs = pango_layout_get_tabs(_SELF(self)); if (tabs) { ret = PANGOTABARRAY2RVAL(tabs); pango_tab_array_free(tabs); } return ret; }
static VALUE rg_tabs(VALUE self) { VALUE ret = Qnil; PangoTabArray* tabs = pango_layout_get_tabs(_SELF(self)); if (tabs) { ret = BOXED2RVAL(tabs, PANGO_TYPE_TAB_ARRAY); pango_tab_array_free(tabs); } return ret; }
static void balsa_print_object_default_draw(BalsaPrintObject * self, GtkPrintContext * context, cairo_t * cairo_ctx) { BalsaPrintObjectDefault *pod; gdouble c_max_height; gdouble c_offset; PangoLayout *layout; PangoFontDescription *font; PangoTabArray *tabs; /* set up */ pod = BALSA_PRINT_OBJECT_DEFAULT(self); g_assert(pod != NULL); c_max_height = MAX(pod->c_text_height, pod->c_image_height); c_offset = pod->c_image_width + 4 * C_LABEL_SEP; /* print the icon */ if (pod->pixbuf) cairo_print_pixbuf(cairo_ctx, pod->pixbuf, self->c_at_x, self->c_at_y, 1.0); /* print the description */ font = pango_font_description_from_string(balsa_app.print_header_font); layout = gtk_print_context_create_pango_layout(context); pango_layout_set_font_description(layout, font); pango_font_description_free(font); pango_layout_set_indent(layout, -pod->p_label_width); tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT, pod->p_label_width); pango_layout_set_tabs(layout, tabs); pango_tab_array_free(tabs); pango_layout_set_width(layout, C_TO_P(self->c_width - c_offset)); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_layout_set_text(layout, pod->description, -1); cairo_move_to(cairo_ctx, self->c_at_x + c_offset, self->c_at_y + (c_max_height - pod->c_text_height) * 0.5); pango_cairo_show_layout(cairo_ctx, layout); g_object_unref(G_OBJECT(layout)); }
static void append_field_and_value (GcrCertificateDetailsWidget *self, const gchar *field, const gchar *value, gboolean monospace) { PangoRectangle extents; PangoTabArray *tabs; PangoLayout *layout; GtkTextIter iter; gchar *text; text = g_strdup_printf ("%s:", field); if (value == NULL) value = ""; /* Measure the width of the field */ layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), text); pango_layout_get_extents (layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); g_object_unref (layout); /* Make the tab wide enough to accomodate */ if (extents.width > self->pv->field_width) { self->pv->field_width = extents.width + COLUMN_MARGIN; tabs = pango_tab_array_new (1, TRUE); pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, self->pv->field_width); g_object_set (self->pv->field_tag, "left-margin", FIELD_MARGIN, "indent", 0 - self->pv->field_width, "tabs", tabs, NULL); pango_tab_array_free (tabs); } gtk_text_buffer_get_end_iter (self->pv->buffer, &iter); gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, text, -1, "field", NULL); gtk_text_buffer_insert (self->pv->buffer, &iter, "\t", 1); gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, value, -1, "field", monospace ? "monospace" : NULL, NULL); gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1); g_free (text); }
/** Insert the column displaying translated choices in the given GtkTreeView. * * @param fe frontend * @param view column destination */ static void insert_choice_column(struct frontend * fe, GtkTreeView * view) { GtkCellRenderer * renderer; PangoTabArray * tab_array; if (CAN_ALIGN(fe)) { /* XXX: check NULL */ tab_array = pango_tab_array_new(0 /* start with no tabs */, FALSE /* use pango unit */); adjust_tabs(GTK_WIDGET(view), tab_array, gtk_tree_view_get_model(view)); renderer = cdebconf_gtk_align_text_renderer_new(); cdebconf_gtk_align_text_renderer_set_tab_array( ALIGN_TEXT_RENDERER(renderer), tab_array); pango_tab_array_free(tab_array); } else { renderer = gtk_cell_renderer_text_new(); } gtk_tree_view_insert_column_with_attributes( view, -1 /* insert at the end */, NULL /* no title */, renderer, "text", CHOICE_MODEL_TRANSLATED_VALUE, NULL /* end of attribute list */); }
static void cb_begin_print(GtkPrintOperation *op, GtkPrintContext *ctx, gpointer data) { gint layout_height; gchar *text; GtkTextIter start, end; GtkTextBuffer *buffer = gtk_text_view_get_buffer(data); PangoTabArray *tabs; gtk_text_buffer_get_bounds(buffer, &start, &end); text = g_strchomp(gtk_text_buffer_get_text(buffer, &start, &end, FALSE)); page_width = gtk_print_context_get_width(ctx); page_height = gtk_print_context_get_height(ctx); font_desc = gtk_widget_get_style(data)->font_desc; layout = gtk_print_context_create_pango_layout(ctx); pango_layout_set_width(layout, page_width * PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); pango_layout_set_text(layout, text, -1); get_tab_array(&tabs, ctx, data); if (tabs) { pango_layout_set_tabs(layout, tabs); pango_tab_array_free(tabs); } pango_layout_get_size(layout, NULL, &layout_height); line_count = pango_layout_get_line_count(layout); text_height = pango_font_description_get_size(font_desc) / PANGO_SCALE; lines_per_page = page_height / text_height; n_pages = (line_count - 1) / lines_per_page + 1; gtk_print_operation_set_n_pages(op, n_pages); g_free(text); }
GList * balsa_print_object_default(GList * list, GtkPrintContext * context, LibBalsaMessageBody * body, BalsaPrintSetup * psetup) { BalsaPrintObjectDefault *pod; BalsaPrintObject *po; gchar *conttype; PangoFontDescription *header_font; PangoLayout *test_layout; PangoTabArray *tabs; GString *desc_buf; gdouble c_max_height; gchar *part_desc; pod = g_object_new(BALSA_TYPE_PRINT_OBJECT_DEFAULT, NULL); g_assert(pod != NULL); po = BALSA_PRINT_OBJECT(pod); /* create the part */ po->depth = psetup->curr_depth; po->c_width = psetup->c_width - 2 * psetup->curr_depth * C_LABEL_SEP; /* get a pixbuf according to the mime type */ conttype = libbalsa_message_body_get_mime_type(body); pod->pixbuf = libbalsa_icon_finder(NULL, conttype, NULL, NULL, GTK_ICON_SIZE_DND); pod->c_image_width = gdk_pixbuf_get_width(pod->pixbuf); pod->c_image_height = gdk_pixbuf_get_height(pod->pixbuf); /* create a layout for calculating the maximum label width */ header_font = pango_font_description_from_string(balsa_app.print_header_font); test_layout = gtk_print_context_create_pango_layout(context); pango_layout_set_font_description(test_layout, header_font); pango_font_description_free(header_font); desc_buf = g_string_new(""); /* add type and filename (if available) */ pod->p_label_width = p_string_width_from_layout(test_layout, _("Type:")); if ((part_desc = libbalsa_vfs_content_description(conttype))) g_string_append_printf(desc_buf, "%s\t%s (%s)", _("Type:"), part_desc, conttype); else g_string_append_printf(desc_buf, "%s\t%s", _("Type:"), conttype); g_free(part_desc); g_free(conttype); if (body->filename) { gint p_fnwidth = p_string_width_from_layout(test_layout, _("File name:")); if (p_fnwidth > pod->p_label_width) pod->p_label_width = p_fnwidth; g_string_append_printf(desc_buf, "\n%s\t%s", _("File name:"), body->filename); } /* add a small space between label and value */ pod->p_label_width += C_TO_P(C_LABEL_SEP); /* configure the layout so we can calculate the text height */ pango_layout_set_indent(test_layout, -pod->p_label_width); tabs = pango_tab_array_new_with_positions(1, FALSE, PANGO_TAB_LEFT, pod->p_label_width); pango_layout_set_tabs(test_layout, tabs); pango_tab_array_free(tabs); pango_layout_set_width(test_layout, C_TO_P(po->c_width - 4 * C_LABEL_SEP - pod->c_image_width)); pango_layout_set_alignment(test_layout, PANGO_ALIGN_LEFT); pod->c_text_height = P_TO_C(p_string_height_from_layout(test_layout, desc_buf->str)); pod->description = g_string_free(desc_buf, FALSE); /* check if we should move to the next page */ c_max_height = MAX(pod->c_text_height, pod->c_image_height); if (psetup->c_y_pos + c_max_height > psetup->c_height) { psetup->c_y_pos = 0; psetup->page_count++; } /* remember the extent */ po->on_page = psetup->page_count - 1; po->c_at_x = psetup->c_x0 + po->depth * C_LABEL_SEP; po->c_at_y = psetup->c_y0 + psetup->c_y_pos; po->c_width = psetup->c_width - 2 * po->depth * C_LABEL_SEP; po->c_height = c_max_height; /* adjust the y position */ psetup->c_y_pos += c_max_height; return g_list_append(list, po); }
int main(int argc, char **argv) { Application application; g_thread_init(NULL); gtk_init(&argc, &argv); application.midi_file = MidiFile_load(argv[1]); application.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_default_size(application.window, 640, 480); gtk_window_set_title(application.window, "Sequencer"); g_signal_connect(G_OBJECT(application.window), "destroy", G_CALLBACK(exit), NULL); application.vbox = GTK_VBOX(gtk_vbox_new(FALSE, 0)); gtk_container_add(GTK_CONTAINER(application.window), GTK_WIDGET(application.vbox)); application.menu_bar = GTK_MENU_BAR(gtk_menu_bar_new()); gtk_box_pack_start(GTK_BOX(application.vbox), GTK_WIDGET(application.menu_bar), FALSE, FALSE, 0); application.file_menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic("_File")); gtk_menu_shell_append(GTK_MENU_SHELL(application.menu_bar), GTK_WIDGET(application.file_menu_item)); application.file_menu = GTK_MENU(gtk_menu_new()); gtk_menu_item_set_submenu(application.file_menu_item, GTK_WIDGET(application.file_menu)); application.exit_menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic("E_xit")); gtk_menu_shell_append(GTK_MENU_SHELL(application.file_menu), GTK_WIDGET(application.exit_menu_item)); application.scrolled_window = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); gtk_box_pack_start(GTK_BOX(application.vbox), GTK_WIDGET(application.scrolled_window), TRUE, TRUE, 0); gtk_scrolled_window_set_policy(application.scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); application.text_view = GTK_TEXT_VIEW(gtk_text_view_new()); gtk_container_add(GTK_CONTAINER(application.scrolled_window), GTK_WIDGET(application.text_view)); gtk_text_view_set_editable(application.text_view, FALSE); { PangoContext *pango_context; PangoLayout *pango_layout; PangoTabArray *pango_tab_array; int column_width; pango_context = gtk_widget_get_pango_context(GTK_WIDGET(application.text_view)); pango_layout = pango_layout_new(pango_context); pango_layout_set_text(pango_layout, "WWWWWWWW", -1); pango_layout_get_size(pango_layout, &column_width, NULL); pango_tab_array = pango_tab_array_new_with_positions(6, FALSE, PANGO_TAB_LEFT, 0, PANGO_TAB_LEFT, column_width, PANGO_TAB_LEFT, column_width * 2, PANGO_TAB_LEFT, column_width * 3, PANGO_TAB_LEFT, column_width * 4, PANGO_TAB_LEFT, column_width * 5); gtk_text_view_set_tabs(application.text_view, pango_tab_array); pango_tab_array_free(pango_tab_array); } { GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(application.text_view); GtkTextIter text_iter; float previous_displayed_beat = 0.0; MidiFileEvent_t midi_file_event; gtk_text_buffer_get_iter_at_offset(text_buffer, &text_iter, 0); for (midi_file_event = MidiFile_getFirstEvent(application.midi_file); midi_file_event != NULL; midi_file_event = MidiFileEvent_getNextEventInFile(midi_file_event)) { if (MidiFileEvent_isNoteStartEvent(midi_file_event) && (MidiFileTrack_getNumber(MidiFileEvent_getTrack(midi_file_event)) == 1)) { float beat = MidiFile_getBeatFromTick(application.midi_file, MidiFileEvent_getTick(midi_file_event)); while (previous_displayed_beat <= beat) { gchar *text = g_strdup_printf("%.3f\t\t\t\t\t\n", previous_displayed_beat); gtk_text_buffer_insert(text_buffer, &text_iter, text, -1); g_free(text); previous_displayed_beat += 0.25; } { gchar *text = g_strdup_printf("%.3f\t", beat); GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "beat"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, text, -1, text_tag, NULL); g_free(text); } { GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "event_type"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, "NoteStart\t", -1, text_tag, NULL); } { gchar *text = g_strdup_printf("%d\t", MidiFileTrack_getNumber(MidiFileEvent_getTrack(midi_file_event))); GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "track"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, text, -1, text_tag, NULL); g_free(text); } { gchar *text = g_strdup_printf("%d\t", MidiFileNoteStartEvent_getChannel(midi_file_event) + 1); GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "channel"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, text, -1, text_tag, NULL); g_free(text); } { gchar *note_string = _midi_note_number_to_string(MidiFileNoteStartEvent_getNote(midi_file_event)); gchar *text = g_strdup_printf("%s\t", note_string); GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "note"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, text, -1, text_tag, NULL); g_free(text); g_free(note_string); } { gchar *text = g_strdup_printf("%d\n", MidiFileNoteStartEvent_getVelocity(midi_file_event)); GtkTextTag *text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, NULL); g_object_set_data(G_OBJECT(text_tag), "column_type", "velocity"); g_object_set_data(G_OBJECT(text_tag), "midi_file_event", midi_file_event); gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, text, -1, text_tag, NULL); g_free(text); } } } } g_signal_connect(application.text_view, "event-after", G_CALLBACK(_text_view_click_handler), NULL); application.statusbar = GTK_STATUSBAR(gtk_statusbar_new()); gtk_box_pack_start(GTK_BOX(application.vbox), GTK_WIDGET(application.statusbar), FALSE, FALSE, 0); gtk_widget_show_all(GTK_WIDGET(application.window)); gtk_main(); return 0; }
void _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest, GtkTextTag** tags, guint n_tags) { guint n = 0; guint left_margin_accumulative = 0; guint right_margin_accumulative = 0; while (n < n_tags) { GtkTextTag *tag = tags[n]; GtkTextAttributes *vals = tag->priv->values; g_assert (tag->priv->table != NULL); if (n > 0) g_assert (tags[n]->priv->priority > tags[n-1]->priv->priority); if (tag->priv->bg_color_set) { if (dest->appearance.rgba[0]) { gdk_rgba_free (dest->appearance.rgba[0]); dest->appearance.rgba[0] = NULL; } if (vals->appearance.rgba[0]) dest->appearance.rgba[0] = gdk_rgba_copy (vals->appearance.rgba[0]); dest->appearance.draw_bg = TRUE; } if (tag->priv->fg_color_set) { if (dest->appearance.rgba[1]) { gdk_rgba_free (dest->appearance.rgba[1]); dest->appearance.rgba[1] = NULL; } if (vals->appearance.rgba[1]) dest->appearance.rgba[1] = gdk_rgba_copy (vals->appearance.rgba[1]); } if (tag->priv->pg_bg_color_set) { if (dest->pg_bg_rgba) { gdk_rgba_free (dest->pg_bg_rgba); dest->pg_bg_rgba = NULL; } if (dest->pg_bg_color) { G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_color_free (dest->pg_bg_color); dest->pg_bg_color = NULL; G_GNUC_END_IGNORE_DEPRECATIONS } if (vals->pg_bg_rgba) dest->pg_bg_rgba = gdk_rgba_copy (vals->pg_bg_rgba); G_GNUC_BEGIN_IGNORE_DEPRECATIONS if (vals->pg_bg_color) dest->pg_bg_color = gdk_color_copy (vals->pg_bg_color); G_GNUC_END_IGNORE_DEPRECATIONS } if (vals->font) { if (dest->font) pango_font_description_merge (dest->font, vals->font, TRUE); else dest->font = pango_font_description_copy (vals->font); } /* multiply all the scales together to get a composite */ if (tag->priv->scale_set) dest->font_scale *= vals->font_scale; if (tag->priv->justification_set) dest->justification = vals->justification; if (vals->direction != GTK_TEXT_DIR_NONE) dest->direction = vals->direction; if (tag->priv->left_margin_set) { if (tag->priv->accumulative_margin) left_margin_accumulative += vals->left_margin; else dest->left_margin = vals->left_margin; } if (tag->priv->indent_set) dest->indent = vals->indent; if (tag->priv->rise_set) dest->appearance.rise = vals->appearance.rise; if (tag->priv->right_margin_set) { if (tag->priv->accumulative_margin) right_margin_accumulative += vals->right_margin; else dest->right_margin = vals->right_margin; } if (tag->priv->pixels_above_lines_set) dest->pixels_above_lines = vals->pixels_above_lines; if (tag->priv->pixels_below_lines_set) dest->pixels_below_lines = vals->pixels_below_lines; if (tag->priv->pixels_inside_wrap_set) dest->pixels_inside_wrap = vals->pixels_inside_wrap; if (tag->priv->tabs_set) { if (dest->tabs) pango_tab_array_free (dest->tabs); dest->tabs = pango_tab_array_copy (vals->tabs); } if (tag->priv->wrap_mode_set) dest->wrap_mode = vals->wrap_mode; if (tag->priv->underline_set) dest->appearance.underline = vals->appearance.underline; if (GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA_SET (&vals->appearance)) { GdkRGBA rgba; GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA (&vals->appearance, &rgba); GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA (&dest->appearance, &rgba); GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA_SET (&dest->appearance, TRUE); } if (tag->priv->strikethrough_set) dest->appearance.strikethrough = vals->appearance.strikethrough; if (GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA_SET (&vals->appearance)) { GdkRGBA rgba; GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA (&vals->appearance, &rgba); GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA (&dest->appearance, &rgba); GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA_SET (&dest->appearance, TRUE); } if (tag->priv->invisible_set) dest->invisible = vals->invisible; if (tag->priv->editable_set) dest->editable = vals->editable; if (tag->priv->bg_full_height_set) dest->bg_full_height = vals->bg_full_height; if (tag->priv->language_set) dest->language = vals->language; if (tag->priv->fallback_set) dest->no_fallback = vals->no_fallback; if (tag->priv->letter_spacing_set) dest->letter_spacing = vals->letter_spacing; if (tag->priv->font_features_set) dest->font_features = g_strdup (vals->font_features); ++n; }
void _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest, GtkTextTag** tags, guint n_tags) { guint n = 0; guint left_margin_accumulative = 0; guint right_margin_accumulative = 0; while (n < n_tags) { GtkTextTag *tag = tags[n]; GtkTextAttributes *vals = tag->priv->values; g_assert (tag->priv->table != NULL); if (n > 0) g_assert (tags[n]->priv->priority > tags[n-1]->priv->priority); if (tag->priv->bg_color_set) { dest->appearance.bg_color = vals->appearance.bg_color; dest->appearance.draw_bg = TRUE; } if (tag->priv->fg_color_set) dest->appearance.fg_color = vals->appearance.fg_color; if (tag->priv->pg_bg_color_set) { dest->pg_bg_color = gdk_color_copy (vals->pg_bg_color); } if (vals->font) { if (dest->font) pango_font_description_merge (dest->font, vals->font, TRUE); else dest->font = pango_font_description_copy (vals->font); } /* multiply all the scales together to get a composite */ if (tag->priv->scale_set) dest->font_scale *= vals->font_scale; if (tag->priv->justification_set) dest->justification = vals->justification; if (vals->direction != GTK_TEXT_DIR_NONE) dest->direction = vals->direction; if (tag->priv->left_margin_set) { if (tag->priv->accumulative_margin) left_margin_accumulative += vals->left_margin; else dest->left_margin = vals->left_margin; } if (tag->priv->indent_set) dest->indent = vals->indent; if (tag->priv->rise_set) dest->appearance.rise = vals->appearance.rise; if (tag->priv->right_margin_set) { if (tag->priv->accumulative_margin) right_margin_accumulative += vals->right_margin; else dest->right_margin = vals->right_margin; } if (tag->priv->pixels_above_lines_set) dest->pixels_above_lines = vals->pixels_above_lines; if (tag->priv->pixels_below_lines_set) dest->pixels_below_lines = vals->pixels_below_lines; if (tag->priv->pixels_inside_wrap_set) dest->pixels_inside_wrap = vals->pixels_inside_wrap; if (tag->priv->tabs_set) { if (dest->tabs) pango_tab_array_free (dest->tabs); dest->tabs = pango_tab_array_copy (vals->tabs); } if (tag->priv->wrap_mode_set) dest->wrap_mode = vals->wrap_mode; if (tag->priv->underline_set) dest->appearance.underline = vals->appearance.underline; if (tag->priv->strikethrough_set) dest->appearance.strikethrough = vals->appearance.strikethrough; if (tag->priv->invisible_set) dest->invisible = vals->invisible; if (tag->priv->editable_set) dest->editable = vals->editable; if (tag->priv->bg_full_height_set) dest->bg_full_height = vals->bg_full_height; if (tag->priv->language_set) dest->language = vals->language; ++n; } dest->left_margin += left_margin_accumulative; dest->right_margin += right_margin_accumulative; }
PangoLayout* gdip_pango_setup_layout (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc, RectF *box, GDIPCONST GpStringFormat *format, int **charsRemoved) { GpStringFormat *fmt; PangoLayout *layout; PangoContext *context; PangoRectangle logical; /* logical size of text (used for alignment) */ PangoRectangle ink; /* ink size of text (to pixel boundaries) */ PangoAttrList *list = NULL; GString *ftext; PangoTabArray *tabs; PangoLayoutIter *iter; int i; int FrameWidth; /* rc->Width (or rc->Height if vertical) */ int FrameHeight; /* rc->Height (or rc->Width if vertical) */ int FrameX; /* rc->X (or rc->Y if vertical) */ int FrameY; /* rc->Y (or rc->X if vertical) */ int y0; /* y0,y1,clipNN used for checking line positions vs. clip rectangle */ int y1; double clipx1; double clipx2; double clipy1; double clipy2; int trimSpace; /* whether or not to trim the space */ gchar *text = ucs2_to_utf8 (stringUnicode, length); if (!text) return NULL; length = strlen(text); if (charsRemoved) { (*charsRemoved) = GdipAlloc (sizeof (int) * length); if (!*charsRemoved) { GdipFree (text); return NULL; } memset (*charsRemoved, 0, sizeof (int) * length); } /* TODO - Digit substitution */ // g_warning ("layout >%s< (%d) [x %g, y %g, w %g, h %g] [font %s, %g points]", text, length, rc->X, rc->Y, rc->Width, FrameHeight, font->face, font->emSize); /* a NULL format is valid, it means get the generic default values (and free them later) */ if (!format) { GpStatus status = GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt); if (status != Ok) { GdipFree (text); return NULL; } } else { fmt = (GpStringFormat *)format; } layout = pango_cairo_create_layout (graphics->ct); /* context is owned by Pango (i.e. not referenced counted) do not free */ context = pango_layout_get_context (layout); pango_layout_set_font_description (layout, gdip_get_pango_font_description ((GpFont*) font)); if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height)); FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width)); FrameX = SAFE_FLOAT_TO_UINT32 (rc->Y); FrameY = SAFE_FLOAT_TO_UINT32 (rc->X); } else { FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width)); FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height)); FrameX = SAFE_FLOAT_TO_UINT32 (rc->X); FrameY = SAFE_FLOAT_TO_UINT32 (rc->Y); } //g_warning("FW: %d\tFH: %d", FrameWidth, FrameHeight); if ((FrameWidth <= 0) || (fmt->formatFlags & StringFormatFlagsNoWrap)) { pango_layout_set_width (layout, -1); //g_warning ("Setting width: %d", -1); } else { pango_layout_set_width (layout, FrameWidth * PANGO_SCALE); //g_warning ("Setting width: %d", FrameWidth * PANGO_SCALE); } if ((rc->Width != 0) && (rc->Height != 0) && ((fmt->formatFlags & StringFormatFlagsNoClip) == 0)) { // g_warning ("\tclip [%g %g %g %g]", rc->X, rc->Y, rc->Width, rc->Height); /* We do not call cairo_reset_clip because we want to take previous clipping into account */ /* Use rc instead of frame variables because this is pre-transform */ gdip_cairo_rectangle (graphics, rc->X, rc->Y, rc->Width, rc->Height, TRUE); cairo_clip (graphics->ct); } /* with GDI+ the API not the renderer makes the direction decision */ pango_layout_set_auto_dir (layout, FALSE); if (!(fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) != !(fmt->formatFlags & StringFormatFlagsDirectionVertical)) { pango_context_set_base_dir (context, PANGO_DIRECTION_WEAK_RTL); pango_layout_context_changed (layout); /* horizontal alignment */ switch (fmt->alignment) { case StringAlignmentNear: pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); break; case StringAlignmentCenter: pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); break; case StringAlignmentFar: pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); break; } } else { /* pango default base dir is WEAK_LTR, which is what we want */ /* horizontal alignment */ switch (fmt->alignment) { case StringAlignmentNear: pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); break; case StringAlignmentCenter: pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); break; case StringAlignmentFar: pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); break; } } #ifdef PANGO_VERSION_CHECK #if PANGO_VERSION_CHECK(1,16,0) if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { if (fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) { cairo_rotate (graphics->ct, M_PI/2.0); cairo_translate (graphics->ct, 0, -FrameHeight); pango_cairo_update_context (graphics->ct, context); } else { cairo_rotate (graphics->ct, 3.0*M_PI/2.0); cairo_translate (graphics->ct, -FrameWidth, 0); pango_cairo_update_context (graphics->ct, context); } /* only since Pango 1.16 */ pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO); pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE); pango_layout_context_changed (layout); } #endif #endif /* TODO - StringFormatFlagsDisplayFormatControl scan and replace them ??? */ /* Trimming options seem to apply only to the end of the string - gdi+ will still wrap * with preference to word first, then character. Unfortunately, pango doesn't have * any way to differentiate wrapping behavior from trimming behavior that I could find */ pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); switch (fmt->trimming) { case StringTrimmingNone: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingCharacter: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingWord: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); break; case StringTrimmingEllipsisCharacter: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; case StringTrimmingEllipsisWord: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; case StringTrimmingEllipsisPath: pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE); if (!(fmt->formatFlags & StringFormatFlagsNoWrap)) pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE); break; } /* some stuff can only be done by manipulating the attributes (but we can avoid this most of the time) */ if ((fmt->formatFlags & StringFormatFlagsNoFontFallback) || (font->style & (FontStyleUnderline | FontStyleStrikeout))) { list = gdip_get_layout_attributes (layout); /* StringFormatFlagsNoFontFallback */ if (fmt->formatFlags & StringFormatFlagsNoFontFallback) { PangoAttribute *attr = pango_attr_fallback_new (FALSE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } if (font->style & FontStyleUnderline) { PangoAttribute *attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } if (font->style & FontStyleStrikeout) { PangoAttribute *attr = pango_attr_strikethrough_new (TRUE); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert (list, attr); } } if (fmt->numtabStops > 0) { float tabPosition; tabs = pango_tab_array_new (fmt->numtabStops, FALSE); tabPosition = fmt->firstTabOffset; for (i = 0; i < fmt->numtabStops; i++) { tabPosition += fmt->tabStops[i]; pango_tab_array_set_tab (tabs, i, PANGO_TAB_LEFT, (gint)min (tabPosition, PANGO_MAX) * PANGO_SCALE); } pango_layout_set_tabs (layout, tabs); pango_tab_array_free (tabs); } //g_warning ("length before ws removal: %d", length); trimSpace = (fmt->formatFlags & StringFormatFlagsMeasureTrailingSpaces) == 0; switch (fmt->hotkeyPrefix) { case HotkeyPrefixHide: /* we need to remove any accelerator from the string */ ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved); break; case HotkeyPrefixShow: /* optimization: is seems that we never see the hotkey when using an underline font */ if (font->style & FontStyleUnderline) { /* so don't bother drawing it (and simply add the '&' character) */ ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved); } else { /* find accelerator and add attribute to the next character (unless it's the prefix too) */ if (!list) list = gdip_get_layout_attributes (layout); ftext = gdip_process_string (text, length, 1, trimSpace, list, charsRemoved); } break; default: ftext = gdip_process_string (text, length, 0, trimSpace, NULL, charsRemoved); break; } length = ftext->len; //g_warning ("length after ws removal: %d", length); if (list) { pango_layout_set_attributes (layout, list); pango_attr_list_unref (list); } // g_warning("\tftext>%s< (%d)", ftext->str, -1); pango_layout_set_text (layout, ftext->str, ftext->len); GdipFree (text); g_string_free(ftext, TRUE); /* Trim the text after the last line for ease of counting lines/characters */ /* Also prevents drawing whole lines outside the boundaries if NoClip was specified */ /* In case of pre-existing clipping, use smaller of clip rectangle or our specified height */ if (FrameHeight > 0) { cairo_clip_extents (graphics->ct, &clipx1, &clipy1, &clipx2, &clipy2); if (clipy2 > 0 && !(fmt->formatFlags & StringFormatFlagsNoClip)) clipy2 = min (clipy2, FrameHeight + FrameY); else clipy2 = FrameHeight + FrameY; iter = pango_layout_get_iter (layout); do { if (iter == NULL) break; pango_layout_iter_get_line_yrange (iter, &y0, &y1); //g_warning("yrange: %d %d clipy2: %f", y0 / PANGO_SCALE, y1 / PANGO_SCALE, clipy2); /* StringFormatFlagsLineLimit */ if (((fmt->formatFlags & StringFormatFlagsLineLimit) && y1 / PANGO_SCALE > clipy2) || (y0 / PANGO_SCALE > clipy2)) { PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter); pango_layout_set_text (layout, pango_layout_get_text (layout), line->start_index); break; } } while (pango_layout_iter_next_line (iter)); pango_layout_iter_free (iter); } pango_layout_get_pixel_extents (layout, &ink, &logical); // g_warning ("\tlogical\t[x %d, y %d, w %d, h %d][x %d, y %d, w %d, h %d]", logical.x, logical.y, logical.width, logical.height, ink.x, ink.y, ink.width, ink.height); if ((fmt->formatFlags & StringFormatFlagsNoFitBlackBox) == 0) { /* By default don't allow overhang - ink space may be larger than logical space */ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { box->X = min (ink.y, logical.y); box->Y = min (ink.x, logical.x); box->Height = max (ink.width, logical.width); box->Width = max (ink.height, logical.height); } else { box->X = min (ink.x, logical.x); box->Y = min (ink.y, logical.y); box->Height = max (ink.height, logical.height); box->Width = max (ink.width, logical.width); } } else { /* Allow overhang */ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { box->X = logical.y; box->Y = logical.x; box->Height = logical.width; box->Width = logical.height; } else { box->X = logical.x; box->Y = logical.y; box->Height = logical.height; box->Width = logical.width; } } // g_warning ("\tbox\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height); /* vertical alignment*/ if (fmt->formatFlags & StringFormatFlagsDirectionVertical) { switch (fmt->lineAlignment) { case StringAlignmentNear: break; case StringAlignmentCenter: box->X += (rc->Width - box->Width) / 2; break; case StringAlignmentFar: box->X += (rc->Width - box->Width); break; } } else { switch (fmt->lineAlignment) { case StringAlignmentNear: break; case StringAlignmentCenter: box->Y += (rc->Height - box->Height) / 2; break; case StringAlignmentFar: box->Y += (rc->Height - box->Height); break; } } // g_warning ("va-box\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height); pango_cairo_update_layout (graphics->ct, layout); return layout; }
void bg_gtk_textview_update(bg_gtk_textview_t * t, const char * text) { const char * next_tab; const char * pos; const char * end_pos; int line; int tab_pos; int line_width; int i; PangoTabArray * tab_array; GtkTextIter start_iter; GtkTextIter end_iter; GdkRectangle start_rect; GdkRectangle end_rect; pos = text; next_tab = strchr(pos, '\t'); /* No tabs here, just copy the text */ if(!next_tab) { gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(t->textview), GTK_WRAP_WORD); gtk_text_buffer_set_text(t->buffer, text, -1); } else /* This is the complicated version */ { line = 0; tab_pos = 0; while(1) { next_tab = strchr(pos, '\t'); end_pos = strchr(pos, '\n'); if(!end_pos) end_pos = pos + strlen(pos); if(next_tab > end_pos) next_tab = NULL; /* Insert everything before the tab and calculate width */ gtk_text_buffer_get_end_iter(t->buffer, &end_iter); if(!next_tab) { gtk_text_buffer_insert(t->buffer, &end_iter, pos, (int)(end_pos - pos)); } else { gtk_text_buffer_insert(t->buffer, &end_iter, pos, (int)(next_tab - pos)); } gtk_text_buffer_get_bounds(t->buffer, &start_iter, &end_iter); for(i = 0; i < line; i++) { gtk_text_view_forward_display_line(GTK_TEXT_VIEW(t->textview), &start_iter); } gtk_text_view_get_iter_location(GTK_TEXT_VIEW(t->textview), &start_iter, &start_rect); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(t->textview), &end_iter, &end_rect); line_width = end_rect.x + end_rect.width; if(tab_pos < line_width) tab_pos = line_width; /* Insert everything after the tab */ if(next_tab) { gtk_text_buffer_get_end_iter(t->buffer, &end_iter); gtk_text_buffer_insert(t->buffer, &end_iter, next_tab, (int)(end_pos - next_tab)); } pos = end_pos; line++; if(*pos == '\0') break; else { while(*pos == '\n') { gtk_text_buffer_get_end_iter(t->buffer, &end_iter); gtk_text_buffer_insert(t->buffer, &end_iter, pos, 1); pos++; } } } /* Set the tab positions */ tab_array = pango_tab_array_new_with_positions(1, /* gint size, */ 1, /* gboolean positions_in_pixels, */ PANGO_TAB_LEFT, /* PangoTabAlign first_alignment, */ tab_pos+10 /* gint first_position, */ ); gtk_text_view_set_tabs(GTK_TEXT_VIEW(t->textview), tab_array); pango_tab_array_free(tab_array); } gtk_text_buffer_get_bounds(t->buffer, &start_iter, &end_iter); gtk_text_buffer_apply_tag(t->buffer, text_tag, &start_iter, &end_iter); };