static PyObject * Scintilla_get_tab_width(Scintilla *self) { gint width; SCI_RET_IF_FAIL(self); width = sci_get_tab_width(self->sci); return Py_BuildValue("i", width); }
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { DocInfo *dinfo = user_data; GeanyEditor *editor; cairo_t *cr; gdouble width, height; gdouble x = 0.0, y = 0.0; /*gint layout_h;*/ gint count; GString *str; if (dinfo == NULL || page_nr >= dinfo->n_pages) return; editor = dinfo->doc->editor; if (dinfo->n_pages > 0) { gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages; gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text); g_free(text); } #ifdef GEANY_PRINT_DEBUG geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d", page_nr, dinfo->n_pages, dinfo->lines_per_page); #endif str = g_string_sized_new(256); cr = gtk_print_context_get_cairo_context(context); width = gtk_print_context_get_width(context); height = gtk_print_context_get_height(context); cairo_set_source_rgb(cr, 0, 0, 0); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.2); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_move_to(cr, 0, 0); pango_layout_set_width(dinfo->layout, width * PANGO_SCALE); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(dinfo->layout, FALSE); pango_layout_set_justify(dinfo->layout, FALSE); if (printing_prefs.print_page_header) add_page_header(dinfo, cr, width, page_nr); count = 0; /* the actual line counter for the current page, might be different from * dinfo->cur_line due to possible line breaks */ while (count < dinfo->lines_per_page) { gchar c = 'a'; gint style = -1; PangoAttrList *layout_attr; PangoAttribute *attr; gint colours[3] = { 0 }; gboolean add_linenumber = TRUE; gboolean at_eol; while (count < dinfo->lines_per_page && c != '\0') { at_eol = FALSE; g_string_erase(str, 0, str->len); /* clear the string */ /* line numbers */ if (printing_prefs.print_line_numbers && add_linenumber) { /* if we had a wrapped line on the last page which needs to be continued, don't * add a line number */ if (dinfo->long_line) { add_linenumber = FALSE; } else { gchar *line_number = NULL; gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1); gchar *fill = g_strnfill( dinfo->max_line_number_margin - cur_line_number_margin - 1, ' '); line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1); g_string_append(str, line_number); dinfo->cur_line++; /* increase document line */ add_linenumber = FALSE; style = STYLE_LINENUMBER; c = 'a'; /* dummy value */ g_free(fill); g_free(line_number); } } /* data */ else { style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos); c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c == '\0' || style == -1) { /* if c gets 0, we are probably out of document boundaries, * so stop to break out of outer loop */ count = dinfo->lines_per_page; break; } dinfo->cur_pos++; /* convert tabs to spaces which seems to be better than using Pango tabs */ if (c == '\t') { gint tab_width = sci_get_tab_width(editor->sci); gchar *s = g_strnfill(tab_width, ' '); g_string_append(str, s); g_free(s); } /* don't add line breaks, they are handled manually below */ else if (c == '\r' || c == '\n') { gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); at_eol = TRUE; if (c == '\r' && c_next == '\n') dinfo->cur_pos++; /* skip LF part of CR/LF */ } else { g_string_append_c(str, c); /* finally add the character */ /* handle UTF-8: since we add char by char (better: byte by byte), we need to * keep UTF-8 characters together(e.g. two bytes for one character) * the input is always UTF-8 and c is signed, so all non-Ascii * characters are less than 0 and consist of all bytes less than 0. * style doesn't change since it is only one character with multiple bytes. */ while (c < 0) { c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c < 0) { /* only add the byte when it is part of the UTF-8 character * otherwise we could add e.g. a '\n' and it won't be visible in the * printed document */ g_string_append_c(str, c); dinfo->cur_pos++; } } } } if (! at_eol) { /* set text */ pango_layout_set_text(dinfo->layout, str->str, -1); /* attributes */ layout_attr = pango_attr_list_new(); /* foreground colour */ get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]); attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* background colour */ get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]); attr = pango_attr_background_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* bold text */ if (dinfo->styles[style][BOLD]) { attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD); ADD_ATTR(layout_attr, attr); } /* italic text */ if (dinfo->styles[style][ITALIC]) { attr = pango_attr_style_new(PANGO_STYLE_ITALIC); ADD_ATTR(layout_attr, attr); } pango_layout_set_attributes(dinfo->layout, layout_attr); pango_layout_context_changed(dinfo->layout); pango_attr_list_unref(layout_attr); } cairo_get_current_point(cr, &x, &y); /* normal line break at eol character in document */ if (at_eol) { /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/ cairo_move_to(cr, 0, y + dinfo->line_height); count++; /* we added a new document line so request a new line number */ add_linenumber = TRUE; } else { gint x_offset = 0; /* maybe we need to force a line break because of too long line */ if (x >= (width - dinfo->font_width)) { /* don't start the line at horizontal origin because we need to skip the * line number margin */ if (printing_prefs.print_line_numbers) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; } /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/ /* this is faster but not exactly the same as above */ cairo_move_to(cr, x_offset, y + dinfo->line_height); cairo_get_current_point(cr, &x, &y); count++; } if (count < dinfo->lines_per_page) { /* str->len is counted in bytes not characters, so use g_utf8_strlen() */ x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width); if (dinfo->long_line && count == 0) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; dinfo->long_line = FALSE; } pango_cairo_show_layout(cr, dinfo->layout); cairo_move_to(cr, x + x_offset, y); } else /* we are on a wrapped line but we are out of lines on this page, so continue * the current line on the next page and remember to continue in current line */ dinfo->long_line = TRUE; } } } if (printing_prefs.print_line_numbers) { /* print a thin line between the line number margin and the data */ gint y_start = 0; if (printing_prefs.print_page_header) y_start = (dinfo->line_height * 3) - 2; /* "- 2": to connect the line number line to * the page header frame */ cairo_set_line_width(cr, 0.3); cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start); cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y + dinfo->line_height); /* y is last added line, we reuse it */ cairo_stroke(cr); } if (printing_prefs.print_page_numbers) { gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1); pango_layout_set_markup(dinfo->layout, line, -1); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER); cairo_move_to(cr, 0, height - dinfo->line_height); pango_cairo_show_layout(cr, dinfo->layout); g_free(line); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.3); cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height)); cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height)); cairo_stroke(cr); #endif } g_string_free(str, TRUE); }