// within the parent handled auto width/height modes void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) { if ( tb->flags & TB_AUTOWIDTH ) { pango_layout_set_width ( tb->layout, -1 ); w = textbox_get_width ( tb ); } else { // set ellipsize if ( ( tb->flags & TB_EDITABLE ) == TB_EDITABLE ) { pango_layout_set_ellipsize ( tb->layout, PANGO_ELLIPSIZE_MIDDLE ); } else if ( ( tb->flags & TB_WRAP ) != TB_WRAP ) { pango_layout_set_ellipsize ( tb->layout, PANGO_ELLIPSIZE_END ); } } if ( tb->flags & TB_AUTOHEIGHT ) { // Width determines height! int tw = MAX ( 1, w ); pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tw - 2 * SIDE_MARGIN ) ); h = textbox_get_height ( tb ); } if ( x != tb->x || y != tb->y || w != tb->w || h != tb->h ) { tb->x = x; tb->y = y; tb->h = MAX ( 1, h ); tb->w = MAX ( 1, w ); } // We always want to update this pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->w - 2 * SIDE_MARGIN ) ); tb->update = TRUE; }
static void font_measure_full(const RrFont *f, const gchar *str, gint *x, gint *y, gint shadow_x, gint shadow_y, gboolean flow, gint maxwidth) { PangoRectangle rect; pango_layout_set_text(f->layout, str, -1); if (flow) { pango_layout_set_single_paragraph_mode(f->layout, FALSE); pango_layout_set_width(f->layout, maxwidth * PANGO_SCALE); pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_NONE); } else { /* single line mode */ pango_layout_set_single_paragraph_mode(f->layout, TRUE); pango_layout_set_width(f->layout, -1); pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_MIDDLE); } /* pango_layout_get_pixel_extents lies! this is the right way to get the size of the text's area */ pango_layout_get_extents(f->layout, NULL, &rect); #if PANGO_VERSION_MAJOR > 1 || \ (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16) /* pass the logical rect as the ink rect, this is on purpose so we get the full area for the text */ pango_extents_to_pixels(&rect, NULL); #else rect.width = (rect.width + PANGO_SCALE - 1) / PANGO_SCALE; rect.height = (rect.height + PANGO_SCALE - 1) / PANGO_SCALE; #endif *x = rect.width + ABS(shadow_x) + 4 /* we put a 2 px edge on each side */; *y = rect.height + ABS(shadow_y); }
static PyObject * _pango_layout_set_text(PyObject *self, PyObject *args) { PangoLayout *layout; char *text; int len, width=-1, align=0, ellipsize = 0; if (!PyArg_ParseTuple(args, "ls#|iii", &layout, &text, &len, &width, &align, &ellipsize)) return NULL; if(width > 0) { pango_layout_set_ellipsize(layout, ellipsize); pango_layout_set_width(layout, width * PANGO_SCALE); pango_layout_set_alignment(layout, align); } else { pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); pango_layout_set_width(layout, -1); pango_layout_set_alignment(layout, 0); } pango_layout_set_text(layout, text, len); Py_RETURN_NONE; }
static void add_page_header(DocInfo *dinfo, cairo_t *cr, gint width, gint page_nr) { gint ph_height = dinfo->line_height * 3; gchar *data; gchar *datetime; gchar *tmp_file_name = (dinfo->doc->file_name != NULL) ? dinfo->doc->file_name : GEANY_STRING_UNTITLED; gchar *file_name = (printing_prefs.page_header_basename) ? g_path_get_basename(tmp_file_name) : g_strdup(tmp_file_name); PangoLayout *layout = dinfo->layout; /* draw the frame */ cairo_set_line_width(cr, 0.3); cairo_set_source_rgb(cr, 0, 0, 0); cairo_rectangle(cr, 2, 2, width - 4, ph_height - 4); cairo_stroke(cr); /* width - 8: 2px between doc border and frame border, 2px between frame border and text * and this on left and right side, so (2 + 2) * 2 */ pango_layout_set_width(layout, (width - 8) * PANGO_SCALE); if ((g_utf8_strlen(file_name, -1) * dinfo->font_width) >= ((width - 4) - (dinfo->font_width * 2))) /* if the filename is wider than the available space on the line, skip parts of it */ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE); data = g_strdup_printf("<b>%s</b>", file_name); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 0.5); pango_cairo_show_layout(cr, layout); g_free(data); g_free(file_name); data = g_strdup_printf(_("<b>Page %d of %d</b>"), page_nr + 1, dinfo->n_pages); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); datetime = utils_get_date_time(printing_prefs.page_header_datefmt, &(dinfo->print_time)); if (G_LIKELY(NZV(datetime))) { data = g_strdup_printf("<b>%s</b>", datetime); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); cairo_move_to(cr, 2, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); } g_free(datetime); /* reset layout and re-position cairo context */ pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(layout, FALSE); pango_layout_set_justify(layout, FALSE); pango_layout_set_width(layout, width * PANGO_SCALE); cairo_move_to(cr, 0, dinfo->line_height * 3); }
void draw_clock(void *obj, cairo_t *c) { Clock *clock = obj; PangoLayout *layout = pango_cairo_create_layout(c); pango_layout_set_font_description(layout, time1_font_desc); pango_layout_set_width(layout, clock->area.width * PANGO_SCALE); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); pango_layout_set_text(layout, buf_time, strlen(buf_time)); cairo_set_source_rgba(c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha); pango_cairo_update_layout(c, layout); draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow); if (time2_format) { pango_layout_set_font_description(layout, time2_font_desc); pango_layout_set_indent(layout, 0); pango_layout_set_text(layout, buf_date, strlen(buf_date)); pango_layout_set_width(layout, clock->area.width * PANGO_SCALE); pango_cairo_update_layout(c, layout); draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow); } g_object_unref(layout); }
void draw_init_font (drawctx_t *ctx, int type, int reset) { if (reset || !ctx->pango_ready) { if (ctx->pangoctx) { g_object_unref (ctx->pangoctx); ctx->pangoctx = NULL; } if (ctx->pangolayout) { g_object_unref (ctx->pangolayout); ctx->pangolayout = NULL; } if (ctx->font_style) { g_object_unref (ctx->font_style); ctx->font_style = NULL; } ctx->font_style = gtk_style_new (); if (ctx->font_style->font_desc) { pango_font_description_free (ctx->font_style->font_desc); ctx->font_style->font_desc = get_new_font_description_from_type (type); } ctx->pangoctx = gdk_pango_context_get (); ctx->pangolayout = pango_layout_new (ctx->pangoctx); pango_layout_set_ellipsize (ctx->pangolayout, PANGO_ELLIPSIZE_END); PangoFontDescription *desc = ctx->font_style->font_desc; ctx->font_weight = pango_font_description_get_weight (desc); pango_layout_set_font_description (ctx->pangolayout, desc); ctx->pango_ready = 1; } else if (ctx->pango_ready) { PangoFontDescription *desc = ctx->font_style->font_desc; pango_layout_set_font_description (ctx->pangolayout, desc); } }
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); }
void draw_init_font (drawctx_t *ctx, GtkStyle *new_font_style) { if (!ctx->pango_ready || (new_font_style && ctx->font_style != new_font_style)) { if (ctx->pangoctx) { g_object_unref (ctx->pangoctx); ctx->pangoctx = NULL; } if (ctx->pangolayout) { g_object_unref (ctx->pangolayout); ctx->pangolayout = NULL; } ctx->font_style = new_font_style ? new_font_style : gtk_widget_get_default_style (); ctx->pangoctx = gdk_pango_context_get (); ctx->pangolayout = pango_layout_new (ctx->pangoctx); pango_layout_set_ellipsize (ctx->pangolayout, PANGO_ELLIPSIZE_END); PangoFontDescription *desc = ctx->font_style->font_desc; ctx->font_weight = pango_font_description_get_weight (desc); pango_layout_set_font_description (ctx->pangolayout, desc); ctx->pango_ready = 1; } else if (new_font_style) { PangoFontDescription *desc = ctx->font_style->font_desc; pango_layout_set_font_description (ctx->pangolayout, desc); } }
static VALUE rg_set_ellipsize(VALUE self, VALUE ellipsize) { pango_layout_set_ellipsize(_SELF(self), RVAL2GENUM(ellipsize, PANGO_TYPE_ELLIPSIZE_MODE)); return self; }
/** * draw the title if asked * * \param context the GtkPrintContext * \param line_position the position to insert the title * \param page_width the page width * * \return the new line_position to continue to fill the page * */ static gint print_tree_view_list_draw_title ( GtkPrintContext *context, gint line_position ) { if ( title_string && strlen ( title_string ) ) { PangoLayout *layout; devel_debug_int (line_position); cairo_move_to ( cr, 0, line_position ); /* create the new layout */ layout = gtk_print_context_create_pango_layout ( context ); pango_layout_set_text ( layout, title_string, -1 ); pango_layout_set_font_description ( layout, gsb_data_print_config_get_font_title () ); pango_layout_set_width ( layout, page_width * PANGO_SCALE ); pango_layout_set_alignment ( layout, PANGO_ALIGN_CENTER ); pango_layout_set_ellipsize ( layout, PANGO_ELLIPSIZE_END ); pango_cairo_show_layout ( cr, layout ); g_object_unref ( layout ); /* add title line and blank line */ line_position = line_position + size_title; } return line_position; }
void tooltip_update() { if (!g_tooltip.tooltip_text) { tooltip_hide(0); return; } tooltip_update_geometry(); if (just_shown) { if (!panel_horizontal) y -= height / 2; // center vertically just_shown = FALSE; } tooltip_adjust_geometry(); XMoveResizeWindow(server.display, g_tooltip.window, x, y, width, height); // Stuff for drawing the tooltip cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height); cairo_t *c = cairo_create(cs); Color bc = g_tooltip.bg->fill_color; Border b = g_tooltip.bg->border; if (server.real_transparency) { clear_pixmap(g_tooltip.window, 0, 0, width, height); draw_rect(c, b.width, b.width, width - 2 * b.width, height - 2 * b.width, b.radius - b.width / 1.571); cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha); } else { cairo_rectangle(c, 0., 0, width, height); cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]); } cairo_fill(c); cairo_set_line_width(c, b.width); if (server.real_transparency) draw_rect(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width, b.radius); else cairo_rectangle(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width); cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha); cairo_stroke(c); Color fc = g_tooltip.font_color; cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha); PangoLayout *layout = pango_cairo_create_layout(c); pango_layout_set_font_description(layout, g_tooltip.font_desc); pango_layout_set_wrap(layout, PANGO_WRAP_WORD); pango_layout_set_text(layout, g_tooltip.tooltip_text, -1); PangoRectangle r1, r2; pango_layout_get_pixel_extents(layout, &r1, &r2); pango_layout_set_width(layout, width * PANGO_SCALE); pango_layout_set_height(layout, height * PANGO_SCALE); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); // I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and // vert.) cairo_move_to(c, -r1.x / 2 + g_tooltip.bg->border.width + g_tooltip.paddingx, -r1.y / 2 + 1 + g_tooltip.bg->border.width + g_tooltip.paddingy); pango_cairo_show_layout(c, layout); g_object_unref(layout); cairo_destroy(c); cairo_surface_destroy(cs); }
static PangoLayout * create_layout_with_attrs (GtkWidget *widget, GdTwoLinesRenderer *self, PangoEllipsizeMode ellipsize) { PangoLayout *layout; gint wrap_width; PangoWrapMode wrap_mode; PangoAlignment alignment; g_object_get (self, "wrap-width", &wrap_width, "wrap-mode", &wrap_mode, "alignment", &alignment, NULL); layout = pango_layout_new (gtk_widget_get_pango_context (widget)); pango_layout_set_ellipsize (layout, ellipsize); pango_layout_set_wrap (layout, wrap_mode); pango_layout_set_alignment (layout, alignment); if (wrap_width != -1) pango_layout_set_width (layout, wrap_width * PANGO_SCALE); return layout; }
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 draw_execp(void *obj, cairo_t *c) { Execp *execp = obj; PangoLayout *layout = pango_cairo_create_layout(c); if (execp->backend->has_icon && execp->backend->icon) { imlib_context_set_image(execp->backend->icon); // Render icon render_image(execp->area.pix, execp->frontend->iconx, execp->frontend->icony); } // draw layout pango_layout_set_font_description(layout, execp->backend->font_desc); pango_layout_set_width(layout, execp->frontend->textw * PANGO_SCALE); pango_layout_set_alignment(layout, execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); if (!execp->backend->has_markup) pango_layout_set_text(layout, execp->backend->text, strlen(execp->backend->text)); else pango_layout_set_markup(layout, execp->backend->text, strlen(execp->backend->text)); pango_cairo_update_layout(c, layout); draw_text(layout, c, execp->frontend->textx, execp->frontend->texty, &execp->backend->font_color, panel_config.font_shadow); g_object_unref(layout); }
/** * draw a cell of a model * * \param context the GtkPrintContext * \param line_position the position to insert the column * \param column_position the position to insert the data * * \return the new column_position * */ static gint print_tree_view_list_draw_cell ( GtkPrintContext *context, gint line_position, gint column_position, gint column, const gchar *text ) { PangoLayout *layout; /* draw first the column */ column_position = print_tree_view_list_draw_column ( column_position, line_position ); cairo_move_to (cr, column_position, line_position); /* create the new layout */ layout = gtk_print_context_create_pango_layout (context); pango_layout_set_text ( layout, text, -1 ); pango_layout_set_font_description ( layout, gsb_data_print_config_get_font_transactions () ); pango_layout_set_width ( layout,columns_width[column] ); pango_layout_set_alignment ( layout, alignment[column] ); pango_layout_set_ellipsize ( layout, PANGO_ELLIPSIZE_END ); pango_cairo_show_layout ( cr, layout ); g_object_unref ( layout ); return column_position; }
static void test_file (const gchar *filename, GString *string) { gchar *contents; gchar *markup; gsize length; GError *error = NULL; PangoLayout *layout; gchar *p; gint width = 0; gint ellipsize_at = 0; PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_NONE; PangoWrapMode wrap = PANGO_WRAP_WORD; PangoFontDescription *desc; if (!g_file_get_contents (filename, &contents, &length, &error)) { fprintf (stderr, "%s\n", error->message); g_error_free (error); return; } p = strchr (contents, '\n'); g_assert (p); markup = p + 1; *p = '\0'; parse_params (contents, &width, &ellipsize_at, &ellipsize, &wrap); layout = pango_layout_new (context); desc = pango_font_description_from_string ("Cantarell 11"); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_markup (layout, markup, length); g_free (contents); if (width != 0) pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_ellipsize (layout, ellipsize); pango_layout_set_wrap (layout, wrap); g_string_append (string, pango_layout_get_text (layout)); g_string_append (string, "\n---\n\n"); g_string_append_printf (string, "wrapped: %d\n", pango_layout_is_wrapped (layout)); g_string_append_printf (string, "ellipsized: %d\n", pango_layout_is_ellipsized (layout)); g_string_append_printf (string, "lines: %d\n", pango_layout_get_line_count (layout)); if (width != 0) g_string_append_printf (string, "width: %d\n", pango_layout_get_width (layout)); g_string_append (string, "\n---\n\n"); dump_attrs (pango_layout_get_attributes (layout), string); g_string_append (string, "\n---\n\n"); dump_lines (layout, string); g_string_append (string, "\n---\n\n"); dump_runs (layout, string); g_object_unref (layout); }
static void set_text(DC *dc, const char *text, int force_width, int breaklines) { if (force_width != -1) force_width *= PANGO_SCALE; pango_layout_set_width(dc->plo, force_width); pango_layout_set_ellipsize(dc->plo, breaklines ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END); pango_layout_set_text(dc->plo, text, strlen(text)); }
void planner_print_job_show_clipped (PlannerPrintJob *job, gdouble x, gdouble y, const gchar *str, gdouble x1, gdouble y1, gdouble x2, gdouble y2) { PlannerPrintJobPriv *priv; gint height; priv = job->priv; x1 = MAX (x1, 0); x2 = MIN (x2, job->width); y1 = MAX (y1, 0); y2 = MIN (y2, job->height); /* Don't try to print anything if the text starts outside the clip rect. */ if (x < x1 || x > x2) { return; } cairo_save (job->cr); cairo_set_line_width (job->cr, 1); cairo_new_path (job->cr); planner_print_job_moveto (job, x1, y1); planner_print_job_lineto (job, x1, y2); planner_print_job_lineto (job, x2, y2); planner_print_job_lineto (job, x2, y1); cairo_close_path (job->cr); cairo_clip (job->cr); PangoLayout *layout = gtk_print_context_create_pango_layout (job->pc); pango_layout_set_text (layout, str, strlen(str)); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_width (layout, (x2 - x1) * PANGO_SCALE); pango_layout_set_font_description (layout, priv->current_font); pango_layout_context_changed (layout); pango_layout_get_pixel_size (layout, NULL, &height); planner_print_job_moveto (job, x, y - priv->font_height); pango_cairo_show_layout (job->cr, layout); g_object_unref (layout); cairo_restore (job->cr); }
ttext& ttext::set_ellipse_mode(const PangoEllipsizeMode ellipse_mode) { if(ellipse_mode != ellipse_mode_) { assert(context_); pango_layout_set_ellipsize(layout_, ellipse_mode); ellipse_mode_ = ellipse_mode; calculation_dirty_ = true; surface_dirty_ = true; } return *this; }
// within the parent handled auto width/height modes void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) { unsigned int offset = ( tb->flags & TB_INDICATOR ) ? DOT_OFFSET : 0; if ( tb->flags & TB_AUTOWIDTH ) { pango_layout_set_width ( tb->layout, -1 ); unsigned int offset = ( tb->flags & TB_INDICATOR ) ? DOT_OFFSET : 0; w = textbox_get_font_width ( tb ) + widget_padding_get_padding_width ( WIDGET ( tb ) ) + offset; } else { // set ellipsize if ( ( tb->flags & TB_EDITABLE ) == TB_EDITABLE ) { pango_layout_set_ellipsize ( tb->layout, PANGO_ELLIPSIZE_MIDDLE ); } else if ( ( tb->flags & TB_WRAP ) != TB_WRAP ) { pango_layout_set_ellipsize ( tb->layout, PANGO_ELLIPSIZE_END ); } } if ( tb->flags & TB_AUTOHEIGHT ) { // Width determines height! int tw = MAX ( 1, w ); pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tw - widget_padding_get_padding_width ( WIDGET ( tb ) ) - offset ) ); int hd = textbox_get_height ( tb ); h = MAX ( hd, h ); } if ( x != tb->widget.x || y != tb->widget.y || w != tb->widget.w || h != tb->widget.h ) { tb->widget.x = x; tb->widget.y = y; tb->widget.h = MAX ( 1, h ); tb->widget.w = MAX ( 1, w ); } // We always want to update this pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->widget.w - widget_padding_get_padding_width ( WIDGET ( tb ) ) - offset ) ); tb->update = TRUE; widget_queue_redraw ( WIDGET ( tb ) ); }
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 draw_header (GtkPrintContext * cnt, gint pn, gint pc) { cairo_t *cr; PangoFontDescription *desc; PangoLayout *layout; gint pw, tw, th; gchar *page; cr = gtk_print_context_get_cairo_context (cnt); pw = gtk_print_context_get_width (cnt); layout = gtk_print_context_create_pango_layout (cnt); desc = pango_font_description_from_string (HEADER_FONT); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_text (layout, options.common_data.uri, -1); pango_layout_get_pixel_size (layout, &tw, &th); if (tw > pw) { pango_layout_set_width (layout, pw); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START); pango_layout_get_pixel_size (layout, &tw, &th); } cairo_move_to (cr, (pw - tw) / 2, (HEADER_HEIGHT - th) / 2); pango_cairo_show_layout (cr, layout); page = g_strdup_printf ("%d/%d", pn, pc); pango_layout_set_text (layout, page, -1); g_free (page); pango_layout_set_width (layout, -1); pango_layout_get_pixel_size (layout, &tw, &th); cairo_move_to (cr, pw - tw - 4, (HEADER_HEIGHT - th) / 2); pango_cairo_show_layout (cr, layout); g_object_unref (layout); cairo_move_to (cr, 0.0, HEADER_HEIGHT); cairo_line_to (cr, pw, HEADER_HEIGHT); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 1); cairo_stroke (cr); }
/** * draw a line of a transaction * * \param * * \return the new line_position * */ static gint print_transactions_list_draw_row ( GtkPrintContext *context, CustomRecord *record, gint line_position ) { gint column; gfloat alignment[] = { PANGO_ALIGN_CENTER, PANGO_ALIGN_CENTER, PANGO_ALIGN_LEFT, PANGO_ALIGN_CENTER, PANGO_ALIGN_RIGHT, PANGO_ALIGN_RIGHT, PANGO_ALIGN_RIGHT }; for (column=0 ; column<CUSTOM_MODEL_VISIBLE_COLUMNS ; column++) { PangoLayout *layout; gchar *text; gint column_position; column_position = columns_position[column]; /* draw first the column */ column_position = print_transactions_list_draw_column (column_position, line_position); /* get the text */ text = record -> visible_col[column]; if (!text) continue; cairo_move_to (cr, column_position, line_position); /* create the new layout */ layout = gtk_print_context_create_pango_layout (context); pango_layout_set_text (layout, text, -1); pango_layout_set_font_description (layout, gsb_data_print_config_get_font_transactions ()); pango_layout_set_width (layout,columns_width[column]); pango_layout_set_alignment (layout, alignment[column]); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_cairo_show_layout (cr, layout); g_object_unref (layout); } /* go to the next row */ line_position = line_position + size_row; return line_position; }
static void draw_text (GtkWidget * widget, cairo_t * cr, int x, int y, int width, float r, float g, float b, float a, const char * font, const char * text) { cairo_move_to(cr, x, y); cairo_set_operator(cr, CAIRO_OPERATOR_ATOP); cairo_set_source_rgba(cr, r, g, b, a); PangoFontDescription * desc = pango_font_description_from_string (font); PangoLayout * pl = gtk_widget_create_pango_layout (widget, NULL); pango_layout_set_text (pl, text, -1); pango_layout_set_font_description(pl, desc); pango_font_description_free(desc); pango_layout_set_width (pl, width * PANGO_SCALE); pango_layout_set_ellipsize (pl, PANGO_ELLIPSIZE_END); pango_cairo_show_layout(cr, pl); g_object_unref(pl); }
void draw_task (void *obj, cairo_t *c) { Task *tsk = obj; tsk->state_pix[tsk->current_state] = tsk->area.pixmap; PangoLayout *layout; int width=0, height; Panel *panel = (Panel*)tsk->area.panel; //printf("draw_task %d %d\n", tsk->area.posx, tsk->area.posy); if (panel->g_task.text) { /* Layout */ layout = pango_cairo_create_layout (c); pango_layout_set_font_description (layout, panel->g_task.font_desc); pango_layout_set_text(layout, tsk->title, -1); /* Drawing width and Cut text */ // pango use U+22EF or U+2026 pango_layout_set_width(layout, ((Taskbar*)tsk->area.parent)->text_width * PANGO_SCALE); pango_layout_set_height(layout, panel->g_task.text_height * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); /* Center text */ if (panel->g_task.centered) pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); else pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); pango_layout_get_pixel_size (layout, &width, &height); color_rgba_t text_color = panel->g_task.font_colors[tsk->current_state]; double text_posy = (panel->g_task.area.bounds.height - height) / 2.0; draw_text (layout, c, panel->g_task.text_posx, text_posy, &text_color, panel->font_shadow); g_object_unref (layout); } if (panel->g_task.icon) { draw_task_icon (tsk, width); } }
static PangoLayout * create_layout_with_attrs (GtkWidget *widget, const GdkRectangle *cell_area, GdTwoLinesRenderer *self, PangoEllipsizeMode ellipsize) { PangoLayout *layout; gint wrap_width, xpad; PangoWrapMode wrap_mode; PangoAlignment alignment; g_object_get (self, "wrap-width", &wrap_width, "wrap-mode", &wrap_mode, "alignment", &alignment, "xpad", &xpad, NULL); layout = pango_layout_new (gtk_widget_get_pango_context (widget)); pango_layout_set_ellipsize (layout, ellipsize); pango_layout_set_alignment (layout, alignment); if (wrap_width != -1) { pango_layout_set_width (layout, wrap_width * PANGO_SCALE); pango_layout_set_wrap (layout, wrap_mode); } else { if (cell_area != NULL) pango_layout_set_width (layout, (cell_area->width - 2 * xpad) * PANGO_SCALE); else pango_layout_set_width (layout, -1); pango_layout_set_wrap (layout, PANGO_WRAP_CHAR); } return layout; }
/** * draw the title of the columns * * \param line_position the position to insert the titles * * \return the new line_position to continue to fill the page * */ static gint print_transactions_list_draw_columns_title ( GtkPrintContext *context, gint line_position) { gint column; if (!gsb_data_print_config_get_draw_columns_name ()) return line_position; for (column=0 ; column<CUSTOM_MODEL_VISIBLE_COLUMNS ; column++) { PangoLayout *layout; gchar *text; gint column_position; column_position = columns_position[column]; /* get the text */ text = _(titres_colonnes_liste_operations[column]); if (!text) continue; cairo_move_to (cr, column_position, line_position); /* create the new layout */ layout = gtk_print_context_create_pango_layout (context); pango_layout_set_text (layout, text, -1); pango_layout_set_font_description (layout, gsb_data_print_config_get_font_transactions ()); pango_layout_set_width (layout,columns_width[column]); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_cairo_show_layout (cr, layout); g_object_unref (layout); } line_position = line_position + size_row + gsb_data_print_config_get_draw_lines (); return line_position; }
/** * @brief Instance initializer function for the \e GtkExperimentTranscript widget * * @param klass Newly constructed \e GtkExperimentTranscript instance */ static void gtk_experiment_transcript_init(GtkExperimentTranscript *klass) { GtkWidget *item, *submenu, *image; klass->priv = GTK_EXPERIMENT_TRANSCRIPT_GET_PRIVATE(klass); klass->speaker = NULL; klass->interactive_format.default_font = NULL; klass->interactive_format.default_text_color = NULL; klass->interactive_format.default_bg_color = NULL; klass->priv->flag_mask = 0; klass->priv->time_adjustment = gtk_adjustment_new(0., 0., 0., 0., 0., 0.); g_object_ref_sink(klass->priv->time_adjustment); klass->priv->time_adj_on_value_changed_id = g_signal_connect(G_OBJECT(klass->priv->time_adjustment), "value-changed", G_CALLBACK(time_adj_on_value_changed), klass); klass->priv->layer_text = NULL; klass->priv->layer_text_layout = gtk_widget_create_pango_layout(GTK_WIDGET(klass), NULL); pango_layout_set_wrap(klass->priv->layer_text_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(klass->priv->layer_text_layout, PANGO_ELLIPSIZE_END); klass->priv->backdrop.start = 0; klass->priv->backdrop.end = 0; klass->priv->contribs = NULL; klass->priv->formats = NULL; klass->priv->interactive_format.regexp = NULL; klass->priv->interactive_format.attribs = NULL; /** @todo It should be possible to reset font and colors (to widget defaults) */ klass->priv->menu = gtk_menu_new(); gtk_menu_attach_to_widget(GTK_MENU(klass->priv->menu), GTK_WIDGET(klass), NULL); item = gtk_image_menu_item_new_with_mnemonic("Choose _Font..."); image = gtk_image_new_from_stock(GTK_STOCK_SELECT_FONT, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); g_signal_connect(item, "activate", G_CALLBACK(choose_font_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), item); gtk_widget_show(item); item = gtk_image_menu_item_new_with_mnemonic("Choose _Text Color..."); image = gtk_image_new_from_stock(GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); g_signal_connect(item, "activate", G_CALLBACK(choose_text_color_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), item); gtk_widget_show(item); item = gtk_image_menu_item_new_with_mnemonic("Choose _Background Color..."); image = gtk_image_new_from_stock(GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); g_signal_connect(item, "activate", G_CALLBACK(choose_bg_color_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), item); gtk_widget_show(item); submenu = gtk_menu_new(); item = gtk_menu_item_new_with_label("Text Alignment"); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), item); gtk_widget_show(item); /* * position in alignment_group list corresponds with PangoAlignment * (PANGO_ALIGN_RIGHT, PANGO_ALIGN_CENTER, PANGO_ALIGN_LEFT) */ item = gtk_radio_menu_item_new_with_mnemonic(NULL, "_Left"); klass->priv->alignment_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); g_signal_connect(item, "activate", G_CALLBACK(text_alignment_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); item = gtk_radio_menu_item_new_with_mnemonic(klass->priv->alignment_group, "_Center"); klass->priv->alignment_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); g_signal_connect(item, "activate", G_CALLBACK(text_alignment_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); item = gtk_radio_menu_item_new_with_mnemonic(klass->priv->alignment_group, "_Right"); klass->priv->alignment_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); g_signal_connect(item, "activate", G_CALLBACK(text_alignment_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); gtk_widget_show_all(submenu); gtk_experiment_transcript_set_alignment(klass, PANGO_ALIGN_LEFT); item = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), item); gtk_widget_show(item); klass->priv->menu_reverse_item = gtk_check_menu_item_new_with_mnemonic("_Reverse"); g_signal_connect(klass->priv->menu_reverse_item, "activate", G_CALLBACK(reverse_activated), klass); gtk_menu_shell_append(GTK_MENU_SHELL(klass->priv->menu), klass->priv->menu_reverse_item); gtk_widget_show(klass->priv->menu_reverse_item); gtk_widget_set_can_focus(GTK_WIDGET(klass), TRUE); }
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); }
static Image *ReadCAPTIONImage(const ImageInfo *image_info, ExceptionInfo *exception) { char *caption, *property; const char *option; DrawInfo *draw_info; FT_Bitmap *canvas; Image *image; PangoAlignment align; PangoContext *context; PangoFontDescription *description; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelPacket fill_color; RectangleInfo page; register PixelPacket *q; register unsigned char *p; ssize_t y; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); (void) ResetImagePage(image,"0x0+0+0"); /* Get context. */ fontmap=(PangoFontMap *) pango_ft2_font_map_new(); pango_ft2_font_map_set_resolution((PangoFT2FontMap *) fontmap, image->x_resolution,image->y_resolution); option=GetImageOption(image_info,"caption:hinting"); pango_ft2_font_map_set_default_substitute((PangoFT2FontMap *) fontmap, PangoSubstitute,(char *) option,NULL); context=pango_font_map_create_context(fontmap); option=GetImageOption(image_info,"caption:language"); if (option != (const char *) NULL) pango_context_set_language(context,pango_language_from_string(option)); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); pango_context_set_base_dir(context,draw_info->direction == RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); switch (draw_info->gravity) { case NorthGravity: gravity=PANGO_GRAVITY_NORTH; break; case WestGravity: gravity=PANGO_GRAVITY_WEST; break; case EastGravity: gravity=PANGO_GRAVITY_EAST; break; case SouthGravity: gravity=PANGO_GRAVITY_SOUTH; break; default: gravity=PANGO_GRAVITY_AUTO; break; } pango_context_set_base_gravity(context,gravity); option=GetImageOption(image_info,"caption:gravity-hint"); if (option != (const char *) NULL) { if (LocaleCompare(option,"line") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE); if (LocaleCompare(option,"natural") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL); if (LocaleCompare(option,"strong") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG); } /* Configure layout. */ layout=pango_layout_new(context); option=GetImageOption(image_info,"caption:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageOption(image_info,"caption:ellipsize"); if (option != (const char *) NULL) { if (LocaleCompare(option,"end") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END); if (LocaleCompare(option,"middle") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE); if (LocaleCompare(option,"none") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE); if (LocaleCompare(option,"start") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START); } option=GetImageOption(image_info,"caption:justify"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_justify(layout,1); option=GetImageOption(image_info,"caption:single-paragraph"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageOption(image_info,"caption:wrap"); if (option != (const char *) NULL) { if (LocaleCompare(option,"char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_CHAR); if (LocaleCompare(option,"word") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD); if (LocaleCompare(option,"word-char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR); } option=GetImageOption(image_info,"caption:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(StringToLong(option)*image->x_resolution* PANGO_SCALE+36)/72); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: default: align=PANGO_ALIGN_LEFT; break; } if ((align != PANGO_ALIGN_CENTER) && (draw_info->direction == RightToLeftDirection)) align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align); pango_layout_set_alignment(layout,align); description=pango_font_description_from_string(draw_info->font == (char *) NULL ? "helvetica" : draw_info->font); pango_font_description_set_size(description,PANGO_SCALE*draw_info->pointsize); pango_layout_set_font_description(layout,description); pango_font_description_free(description); property=InterpretImageProperties(image_info,image,image_info->filename); (void) SetImageProperty(image,"caption",property); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption")); /* Render caption. */ option=GetImageOption(image_info,"caption:markup"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_markup(layout,caption,-1); else pango_layout_set_text(layout,caption,-1); pango_layout_context_changed(layout); page.x=0; page.y=0; if (image_info->page != (char *) NULL) (void) ParseAbsoluteGeometry(image_info->page,&page); if (image->columns == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->columns=extent.x+extent.width; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(PANGO_SCALE*image->columns* image->x_resolution+36.0)/72.0); } if (image->rows == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->rows=extent.y+extent.height; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(PANGO_SCALE*image->rows* image->y_resolution+36.0)/72.0); } /* Create canvas. */ canvas=(FT_Bitmap *) AcquireMagickMemory(sizeof(*canvas)); if (canvas == (FT_Bitmap *) NULL) { draw_info=DestroyDrawInfo(draw_info); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } canvas->width=image->columns; canvas->pitch=(canvas->width+3) & ~3; canvas->rows=image->rows; canvas->buffer=(unsigned char *) AcquireQuantumMemory(canvas->pitch, canvas->rows*sizeof(*canvas->buffer)); if (canvas->buffer == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } canvas->num_grays=256; canvas->pixel_mode=ft_pixel_mode_grays; ResetMagickMemory(canvas->buffer,0x00,canvas->pitch*canvas->rows); pango_ft2_render_layout(canvas,layout,0,0); /* Convert caption to image. */ image->columns+=2*page.x; image->rows+=2*page.y; if (SetImageBackgroundColor(image) == MagickFalse) { draw_info=DestroyDrawInfo(draw_info); canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); caption=DestroyString(caption); image=DestroyImageList(image); return((Image *) NULL); } p=canvas->buffer; for (y=page.y; y < (ssize_t) (image->rows-page.y); y++) { register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; q+=page.x; for (x=page.x; x < (ssize_t) (image->columns-page.x); x++) { MagickRealType fill_opacity; (void) GetFillColor(draw_info,x,y,&fill_color); fill_opacity=QuantumRange-(*p)/canvas->num_grays*(QuantumRange- fill_color.opacity); if (draw_info->text_antialias == MagickFalse) fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0; MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q); p++; q++; } for ( ; x < (ssize_t) ((canvas->width+3) & ~3); x++) p++; } /* Relinquish resources. */ draw_info=DestroyDrawInfo(draw_info); canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer); canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas); caption=DestroyString(caption); return(GetFirstImageInList(image)); }