static GdkPixbuf * create_gallery (BaconVideoWidget *bvw, const char *input, const char *output) { GdkPixbuf *screenshot, *pixbuf = NULL; cairo_t *cr; cairo_surface_t *surface; PangoLayout *layout; PangoFontDescription *font_desc; gint64 stream_length, screenshot_interval, pos; guint columns = 3, rows, current_column, current_row, x, y; gint screenshot_width = 0, screenshot_height = 0, x_padding = 0, y_padding = 0; gfloat scale = 1.0; gchar *header_text, *duration_text, *filename; /* Calculate how many screenshots we're going to take */ stream_length = bacon_video_widget_get_stream_length (bvw); /* As a default, we have one screenshot per minute of stream, * but adjusted so we don't have any gaps in the resulting gallery. */ if (gallery == 0) { gallery = stream_length / 60000; while (gallery % 3 != 0 && gallery % 4 != 0 && gallery % 5 != 0) { gallery++; } } if (gallery < GALLERY_MIN) gallery = GALLERY_MIN; if (gallery > GALLERY_MAX) gallery = GALLERY_MAX; screenshot_interval = stream_length / gallery; /* Put a lower bound on the screenshot interval so we can't enter an infinite loop below */ if (screenshot_interval == 0) screenshot_interval = 1; PROGRESS_DEBUG ("Producing gallery of %u screenshots, taken at %" G_GINT64_FORMAT " millisecond intervals throughout a %" G_GINT64_FORMAT " millisecond-long stream.", gallery, screenshot_interval, stream_length); /* Calculate how to arrange the screenshots so we don't get ones orphaned on the last row. * At this point, only deal with arrangements of 3, 4 or 5 columns. */ y = G_MAXUINT; for (x = 3; x <= 5; x++) { if (gallery % x == 0 || x - gallery % x < y) { y = x - gallery % x; columns = x; /* Have we found an optimal solution already? */ if (y == x) break; } } rows = ceil ((gfloat) gallery / (gfloat) columns); PROGRESS_DEBUG ("Outputting as %u rows and %u columns.", rows, columns); /* Take the screenshots and composite them into a pixbuf */ current_column = current_row = x = y = 0; for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) { screenshot = capture_frame_at_time (bvw, input, output, pos); if (pixbuf == NULL) { screenshot_width = gdk_pixbuf_get_width (screenshot); screenshot_height = gdk_pixbuf_get_height (screenshot); /* Calculate a scaling factor so that screenshot_width -> output_size */ scale = (float) output_size / (float) screenshot_width; x_padding = x = MAX (output_size * 0.05, 1); y_padding = y = MAX (scale * screenshot_height * 0.05, 1); PROGRESS_DEBUG ("Scaling each screenshot by %f.", scale); /* Create our massive pixbuf */ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, columns * output_size + (columns + 1) * x_padding, (guint) (rows * scale * screenshot_height + (rows + 1) * y_padding)); gdk_pixbuf_fill (pixbuf, 0x000000ff); PROGRESS_DEBUG ("Created output pixbuf (%ux%u).", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); } /* Composite the screenshot into our gallery */ gdk_pixbuf_composite (screenshot, pixbuf, x, y, output_size, scale * screenshot_height, (gdouble) x, (gdouble) y, scale, scale, GDK_INTERP_BILINEAR, 255); g_object_unref (screenshot); PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " milliseconds (address %u) at (%u,%u).", pos, GPOINTER_TO_UINT (screenshot), x, y); /* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */ PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0)); current_column = (current_column + 1) % columns; x += output_size + x_padding; if (current_column == 0) { x = x_padding; y += scale * screenshot_height + y_padding; current_row++; } } PROGRESS_DEBUG ("Converting pixbuf to a Cairo surface."); /* Load the pixbuf into a Cairo surface and overlay the text. The height is the height of * the gallery plus the necessary height for 3 lines of header (at ~18px each), plus some * extra padding. */ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf) + GALLERY_HEADER_HEIGHT + y_padding); cr = cairo_create (surface); cairo_surface_destroy (surface); /* First, copy across the gallery pixbuf */ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, GALLERY_HEADER_HEIGHT + y_padding); cairo_rectangle (cr, 0.0, GALLERY_HEADER_HEIGHT + y_padding, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); cairo_fill (cr); g_object_unref (pixbuf); /* Build the header information */ duration_text = totem_time_to_string (stream_length); filename = NULL; if (strstr (input, "://")) { char *local; local = g_filename_from_uri (input, NULL, NULL); filename = g_path_get_basename (local); g_free (local); } if (filename == NULL) filename = g_path_get_basename (input); /* Translators: The first string is "Filename" (as translated); the second is an actual filename. The third string is "Resolution" (as translated); the fourth and fifth are screenshot height and width, respectively. The sixth string is "Duration" (as translated); the seventh is the movie duration in words. */ header_text = g_strdup_printf (_("<b>%s</b>: %s\n<b>%s</b>: %d\303\227%d\n<b>%s</b>: %s"), _("Filename"), filename, _("Resolution"), screenshot_width, screenshot_height, _("Duration"), duration_text); g_free (duration_text); g_free (filename); PROGRESS_DEBUG ("Writing header text with Pango."); /* Write out some header information */ layout = pango_cairo_create_layout (cr); font_desc = pango_font_description_from_string ("Sans 18px"); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); pango_layout_set_markup (layout, header_text, -1); g_free (header_text); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_move_to (cr, (gdouble) x_padding, (gdouble) y_padding); pango_cairo_show_layout (cr, layout); /* Go through each screenshot and write its timestamp */ current_column = current_row = 0; x = x_padding + output_size; y = y_padding * 2 + GALLERY_HEADER_HEIGHT + scale * screenshot_height; font_desc = pango_font_description_from_string ("Sans 10px"); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); PROGRESS_DEBUG ("Writing screenshot timestamps with Pango."); for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) { gchar *timestamp_text; gint layout_width, layout_height; timestamp_text = totem_time_to_string (pos); pango_layout_set_text (layout, timestamp_text, -1); pango_layout_get_pixel_size (layout, &layout_width, &layout_height); /* Display the timestamp in the bottom-right corner of the current screenshot */ cairo_move_to (cr, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height); /* We have to stroke the text so it's visible against screenshots of the same * foreground color. */ pango_cairo_layout_path (cr, layout); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ cairo_stroke_preserve (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_fill (cr); PROGRESS_DEBUG ("Writing timestamp \"%s\" at (%f,%f).", timestamp_text, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height); /* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */ PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0)); g_free (timestamp_text); current_column = (current_column + 1) % columns; x += output_size + x_padding; if (current_column == 0) { x = x_padding + output_size; y += scale * screenshot_height + y_padding; current_row++; } } g_object_unref (layout); PROGRESS_DEBUG ("Converting Cairo surface back to pixbuf."); /* Create a new pixbuf from the Cairo context */ pixbuf = cairo_surface_to_pixbuf (cairo_get_target (cr)); cairo_destroy (cr); return pixbuf; }
static gboolean do_tests (CallbackData *data) { PangoFontDescription *fd; static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff }; PangoAttrList *attr_list, *attr_list_copy; PangoAttribute *attr; /* TEST 1: change the text */ clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 0"); pango_layout_set_text (data->test_layout, "Counter 0", -1); g_assert (check_result (data, "Change text", TRUE) == FALSE); /* TEST 2: change a single character */ clutter_text_set_text (CLUTTER_TEXT (data->label), "Counter 1"); pango_layout_set_text (data->test_layout, "Counter 1", -1); g_assert (check_result (data, "Change a single character", TRUE) == FALSE); /* TEST 3: move the label */ clutter_actor_set_position (data->label, 10, 0); g_assert (check_result (data, "Move the label", FALSE) == FALSE); /* TEST 4: change the font */ clutter_text_set_font_name (CLUTTER_TEXT (data->label), "Serif 15"); fd = pango_font_description_from_string ("Serif 15"); pango_layout_set_font_description (data->test_layout, fd); pango_font_description_free (fd); g_assert (check_result (data, "Change the font", TRUE) == FALSE); /* TEST 5: change the color */ clutter_text_set_color (CLUTTER_TEXT (data->label), &red); g_assert (check_result (data, "Change the color", FALSE) == FALSE); /* TEST 6: change the attributes */ attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); attr->start_index = 0; attr->end_index = 2; attr_list = pango_attr_list_new (); pango_attr_list_insert (attr_list, attr); attr_list_copy = pango_attr_list_copy (attr_list); clutter_text_set_attributes (CLUTTER_TEXT (data->label), attr_list); pango_layout_set_attributes (data->test_layout, attr_list_copy); pango_attr_list_unref (attr_list_copy); pango_attr_list_unref (attr_list); g_assert (check_result (data, "Change the attributes", TRUE) == FALSE); /* TEST 7: change the text again */ clutter_text_set_attributes (CLUTTER_TEXT (data->label), NULL); clutter_text_set_text (CLUTTER_TEXT (data->label), long_text); pango_layout_set_attributes (data->test_layout, NULL); pango_layout_set_text (data->test_layout, long_text, -1); g_assert (check_result (data, "Change the text again", TRUE) == FALSE); /* TEST 8: enable markup */ clutter_text_set_use_markup (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_markup (data->test_layout, long_text, -1); g_assert (check_result (data, "Enable markup", TRUE) == FALSE); /* This part can't be a test because Clutter won't restrict the width if wrapping and ellipsizing is disabled so the extents will be different, but we still want to do it for the later tests */ clutter_actor_set_width (data->label, 200); pango_layout_set_width (data->test_layout, 200 * PANGO_SCALE); /* Force a redraw so that changing the width won't affect the results */ force_redraw (data); /* TEST 9: enable ellipsize */ clutter_text_set_ellipsize (CLUTTER_TEXT (data->label), PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_END); g_assert (check_result (data, "Enable ellipsize", TRUE) == FALSE); clutter_text_set_ellipsize (CLUTTER_TEXT (data->label), PANGO_ELLIPSIZE_NONE); pango_layout_set_ellipsize (data->test_layout, PANGO_ELLIPSIZE_NONE); force_redraw (data); /* TEST 10: enable line wrap */ clutter_text_set_line_wrap (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_WORD); g_assert (check_result (data, "Enable line wrap", TRUE) == FALSE); /* TEST 11: change wrap mode * FIXME - broken */ clutter_text_set_line_wrap_mode (CLUTTER_TEXT (data->label), PANGO_WRAP_CHAR); pango_layout_set_wrap (data->test_layout, PANGO_WRAP_CHAR); g_assert (check_result (data, "Change wrap mode", TRUE) == FALSE); /* TEST 12: enable justify */ clutter_text_set_justify (CLUTTER_TEXT (data->label), TRUE); pango_layout_set_justify (data->test_layout, TRUE); /* Pango appears to have a bug which means that you can't change the justification after setting the text but this fixes it. See http://bugzilla.gnome.org/show_bug.cgi?id=551865 */ pango_layout_context_changed (data->test_layout); g_assert (check_result (data, "Enable justify", TRUE) == FALSE); /* TEST 13: change alignment */ clutter_text_set_line_alignment (CLUTTER_TEXT (data->label), PANGO_ALIGN_RIGHT); pango_layout_set_alignment (data->test_layout, PANGO_ALIGN_RIGHT); g_assert (check_result (data, "Change alignment", TRUE) == FALSE); clutter_main_quit (); return FALSE; }
static void ppg_ruler_draw_ruler (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkAllocation alloc; PangoLayout *layout; cairo_t *cr; GtkStyle *style; GdkColor text_color; gint text_width; gint text_height; gdouble every = 1.0; gdouble n_seconds; gdouble v; gdouble p; gint x; gint xx; gint n; gint z = 0; g_return_if_fail(PPG_IS_RULER(ruler)); priv = ruler->priv; gtk_widget_get_allocation(GTK_WIDGET(ruler), &alloc); style = gtk_widget_get_style(GTK_WIDGET(ruler)); cr = gdk_cairo_create(priv->ruler); cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, 0, 0, alloc.width, alloc.height); cairo_fill(cr); cairo_restore(cr); text_color = style->text[GTK_STATE_NORMAL]; cairo_set_line_width(cr, 1.0); gdk_cairo_set_source_color(cr, &text_color); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, priv->font_desc); pango_layout_set_markup(layout, "00:00:00", -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); text_width += 5; n_seconds = priv->upper - priv->lower; if ((alloc.width / n_seconds) < text_width) { every = ceil(text_width / (alloc.width / n_seconds)); } for (v = ceil(priv->lower); v < priv->upper; v += every) { gdk_cairo_set_source_color(cr, &text_color); x = get_x_offset(priv, &alloc, v); cairo_move_to(cr, x + 0.5, alloc.height - 1.5); cairo_line_to(cr, x + 0.5, 0.5); /* * TODO: Mini lines. */ for (p = v, n = 0, z = 0; p < v + every; p += (every / 10), n++, z++) { if (n == 0 || n == 10) { continue; } xx = get_x_offset(priv, &alloc, p); cairo_move_to(cr, xx + 0.5, alloc.height - 1.5); if (z % 2 == 0) { cairo_line_to(cr, xx + 0.5, text_height + 8.5); } else { cairo_line_to(cr, xx + 0.5, text_height + 5.5); } } cairo_stroke(cr); cairo_move_to(cr, x + 1.5, 1.5); ppg_ruler_update_layout_text(ruler, layout, v); pango_cairo_show_layout(cr, layout); } g_object_unref(layout); cairo_destroy(cr); }
/* Do the Pango text rendering. If called when pixmap is bg_text_layer, | it is a background draw. But if called from push_decal_pixmaps() it is | considered a push operation because it is being done whenever any panel | decals or krells are modified. In this case, Pango does the pixel pushing | instead of gkrellm as was done in pre 2.2.0. */ static void panel_draw_decal_text_list(GdkPixmap *pixmap, GkrellmDecal *d) { PangoLayout *layout; GdkRectangle rect; GList *list; GkrellmText *tx; GkrellmTextstyle *ts; gchar *s; gint x, y; layout = gtk_widget_create_pango_layout(gkrellm_get_top_window(), NULL); rect.x = d->x; rect.y = d->y; rect.width = d->w; rect.height = d->h; gdk_gc_set_clip_rectangle(_GK.text_GC, &rect); for (list = d->text_list; list; list = list->next) { tx = (GkrellmText *) list->data; if (!*tx->text) continue; ts = &tx->text_style; pango_layout_set_font_description(layout, ts->font); x = tx->x_off; y = tx->y_off; if (d->flags & DF_SCROLL_TEXT_DIVERTED) { if (d->flags & DF_SCROLL_TEXT_CENTER) pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); if (d->flags & DF_SCROLL_TEXT_H_LOOP) { x %= d->scroll_width; if (x > 0) x -= d->scroll_width; s = g_strconcat(tx->text, tx->text, NULL); if (d->flags & DF_TEXT_USE_MARKUP) pango_layout_set_markup(layout, s, strlen(s)); else pango_layout_set_text(layout, s, strlen(s)); g_free(s); } else if (d->flags & DF_SCROLL_TEXT_V_LOOP) { y %= d->scroll_height + d->y_ink; if (y > 0) y -= d->scroll_height + d->y_ink; s = g_strconcat(tx->text, "\n", tx->text, NULL); if (d->flags & DF_TEXT_USE_MARKUP) pango_layout_set_markup(layout, s, strlen(s)); else pango_layout_set_text(layout, s, strlen(s)); g_free(s); } else { if (d->flags & DF_TEXT_USE_MARKUP) pango_layout_set_markup(layout, tx->text,strlen(tx->text)); else pango_layout_set_text(layout, tx->text, strlen(tx->text)); } } else { if (d->flags & DF_TEXT_USE_MARKUP) pango_layout_set_markup(layout, tx->text, strlen(tx->text)); else pango_layout_set_text(layout, tx->text, strlen(tx->text)); } x += d->x; y += d->y; if (ts->effect) { gdk_gc_set_foreground(_GK.text_GC, &ts->shadow_color); gdk_draw_layout_with_colors(pixmap, _GK.text_GC, x + 1, y + 1, layout, &ts->shadow_color, NULL); } gdk_gc_set_foreground(_GK.text_GC, &ts->color); gdk_draw_layout(pixmap, _GK.text_GC, x, y, layout); } gdk_gc_set_clip_rectangle(_GK.text_GC, NULL); g_object_unref(layout); }
static void acwin_calculate_window_size(Tacwin * acw, GList * items, GList * items2, const gchar *closetag, gint *numitems) { GList *tmplist; gboolean runtwo = FALSE; gchar *longest = NULL, *tmp; guint longestlen = 1; *numitems = 0; DBG_AUTOCOMP("acwin_calculate_window_size, items=%p, items2=%p, closetag=%s\n", items, items2, closetag); if (closetag) { longest = g_markup_escape_text(closetag, -1); longestlen = strlen(longest); } tmplist = g_list_first(items); while (!runtwo || tmplist) { guint len; if (!tmplist) { tmplist = g_list_first(items2); runtwo = TRUE; if (!tmplist) break; } g_assert(tmplist != NULL); g_assert(tmplist->data != NULL); /* DBG_AUTOCOMP("acwin_calculate_window_size, tmplist=%p", tmplist); DBG_AUTOCOMP(", tmplist->data=%p",tmplist->data); DBG_AUTOCOMP("=%s\n", (gchar *)tmplist->data);*/ tmp = g_markup_escape_text(tmplist->data, -1); len = strlen(tmp); if (len > longestlen) { longest = tmp; longestlen = len; } else { g_free(tmp); } (*numitems)++; tmplist = g_list_next(tmplist); } if (longest) { gint len, rowh,min_h,nat_h; PangoLayout *panlay = gtk_widget_create_pango_layout(GTK_WIDGET(acw->tree), NULL); pango_layout_set_markup(panlay, longest, -1); pango_layout_get_pixel_size(panlay, &len, &rowh); DBG_AUTOCOMP("longest=%s which has len=%d and rowheight=%d\n", longest, len, rowh); /* rowh+9 has been found by trial and error on a particular gtk theme and resolution, so there is quite a chance that this will not be optimal for other themes or for example on a high resolution display. I've tried to request this size but I cannot find it. I've now changed it to nat_h+5, hopefully nat_h is already a more dynamic value */ /*gint spacing,height; GtkRequisition min_size, nat_size; gtk_cell_renderer_get_preferred_height(acw->cell,GTK_WIDGET(acw->tree),&min_h,&nat_h); spacing= gtk_tree_view_column_get_spacing(acw->column); gtk_tree_view_column_cell_get_size(acw->column,NULL,NULL,NULL,NULL,&height); gtk_widget_get_preferred_size(GTK_WIDGET(acw->tree),&min_size,&nat_size); g_print("row=%d,rowh+9=%d,min_h=%d,nat_h=%d,spacing=%d,height=%d,nat_size.h=%d\n",rowh,rowh+9,min_h,nat_h,spacing,height,min_size.height);*/ #if GTK_CHECK_VERSION(3,0,0) gtk_cell_renderer_get_preferred_height(acw->cell,GTK_WIDGET(acw->tree),&min_h,&nat_h); #else nat_h=rowh+2; #endif acw->h = MIN((*numitems) * (nat_h+5), 350); /*MIN(MAX((*numitems + 1) * rowh + 8, 150), 350);*/ acw->w = acw->listwidth = MIN(len + 20, 350); DBG_AUTOCOMP("acwin_calculate_window_size, numitems=%d, rowh=%d, new height=%d, new width=%d\n", *numitems, rowh, acw->h, acw->listwidth); gtk_widget_set_size_request(GTK_WIDGET(acw->scroll), acw->listwidth, acw->h); /* ac_window */ g_free(longest); g_object_unref(G_OBJECT(panlay)); } }
void calendar_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint npage, gpointer user_data) { PangoLayout *layout; PangoFontDescription *month_name_font, *day_name_font, *day_num_font, *event_font; cairo_t *cr; GDate *date; gdouble page_width, page_height, day_width, day_height; gint text_width, text_height, header_height, event_height, mnf_height, dnf_height, duf_height; gint day, month, i, j; guint32 julian; gboolean monday, actual; gchar buffer[BUFFER_SIZE]; gint padding = config.cal_print_padding; GUI *appGUI = (GUI *) user_data; date = g_date_new_julian (g_date_get_julian (appGUI->cal->date)); g_return_if_fail (date != NULL); cr = gtk_print_context_get_cairo_context (context); layout = gtk_print_context_create_pango_layout (context); month_name_font = pango_font_description_from_string (config.cal_print_month_name_font); day_name_font = pango_font_description_from_string (config.cal_print_day_name_font); day_num_font = pango_font_description_from_string (config.cal_print_day_num_font); event_font = pango_font_description_from_string (config.cal_print_event_font); pango_layout_set_text (layout, "Aj", -1); pango_layout_set_font_description (layout, month_name_font); pango_layout_get_pixel_size (layout, NULL, &mnf_height); mnf_height *= 1.2; pango_layout_set_font_description (layout, day_name_font); pango_layout_get_pixel_size (layout, NULL, &dnf_height); dnf_height *= 1.2; pango_layout_set_font_description (layout, day_num_font); pango_layout_get_pixel_size (layout, NULL, &duf_height); page_width = gtk_print_context_get_width (context); day_width = page_width / 7; page_height = gtk_print_context_get_height (context); header_height = mnf_height + dnf_height; day_height = (page_height - header_height) / 6; event_height = day_height - duf_height - padding * 3; cairo_set_line_width (cr, 1); monday = (config.display_options & GUI_CALENDAR_WEEK_START_MONDAY) ? TRUE : FALSE; /* Month and year */ pango_layout_set_font_description (layout, month_name_font); g_date_strftime (buffer, BUFFER_SIZE, "%B %Y", date); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_size (layout, &text_width, NULL); cairo_move_to (cr, (page_width - text_width) / 2, 0); pango_cairo_show_layout (cr, layout); /* Day names */ pango_layout_set_font_description (layout, day_name_font); for (i = 0; i < 7; i++) { g_snprintf (buffer, BUFFER_SIZE, "%s", utl_get_day_name (i + 7 + monday, FALSE)); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_size (layout, &text_width, NULL); cairo_move_to (cr, day_width * i + (day_width - text_width) / 2, mnf_height); pango_cairo_show_layout (cr, layout); } /* Day */ g_date_set_day (date, 1); day = g_date_get_weekday (date); month = g_date_get_month (date); day = monday ? day - 1 : day % 7; if (day > 0) g_date_subtract_days (date, day); day = g_date_get_day (date); julian = g_date_get_julian (date); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_width (layout, (day_width - padding * 2) * PANGO_SCALE); pango_layout_set_height (layout, event_height * PANGO_SCALE); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_indent (layout, -4 * PANGO_SCALE); for (i = 0; i < 6; i++) { for (j = 0; j < 7; j++) { actual = (month == g_date_get_month (date)) ? TRUE : FALSE; day = g_date_get_day (date); cairo_rectangle (cr, day_width * j, header_height + day_height * i, day_width, day_height); if (actual) { cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); } else { cairo_set_source_rgb (cr, 0.8, 0.8, 0.8); } cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); pango_layout_set_font_description (layout, day_num_font); if (actual) { cairo_move_to (cr, day_width * j + padding, header_height + day_height * i + padding); if ((j == 0 && !monday) || (j == 5 && monday) || j == 6) { g_snprintf (buffer, BUFFER_SIZE, "<span color=\"red\">%d</span>", day); } else { g_snprintf (buffer, BUFFER_SIZE, "%d", day); } pango_layout_set_markup (layout, buffer, -1); pango_cairo_show_layout (cr, layout); cal_print_get_events (buffer, julian, appGUI); pango_layout_set_markup (layout, "", -1); pango_layout_set_text (layout, buffer, -1); pango_layout_set_font_description (layout, event_font); pango_layout_get_pixel_size (layout, NULL, &text_height); cairo_move_to (cr, day_width * j + padding, header_height + day_height * (i + 1) - text_height - padding); pango_cairo_show_layout (cr, layout); } else { cairo_move_to (cr, day_width * j + padding, header_height + day_height * i + padding); g_snprintf (buffer, BUFFER_SIZE, "<span color=\"white\">%d</span>", day); pango_layout_set_markup (layout, buffer, -1); pango_cairo_show_layout (cr, layout); } g_date_add_days (date, 1); julian++; } } g_date_free (date); pango_font_description_free (month_name_font); pango_font_description_free (day_name_font); pango_font_description_free (day_num_font); pango_font_description_free (event_font); g_object_unref (layout); }
/*! \brief draw_infotext() draws the static textual data for the trace on the left hand side of the logviewer */ G_MODULE_EXPORT void draw_infotext(void) { /* Draws the textual (static) info on the left side of the window..*/ gint name_x = 0; gint name_y = 0; gint text_border = 10; gint info_ctr = 0; gint h = 0; gint i = 0; gint width = 0; gint height = 0; gint max = 0; Viewable_Value *v_value = NULL; PangoLayout *layout; GdkPixmap *pixmap = lv_data->pixmap; GtkAllocation allocation; gtk_widget_get_allocation(lv_data->darea,&allocation); h = allocation.height; gdk_draw_rectangle(pixmap, gtk_widget_get_style(lv_data->darea)->black_gc, TRUE, 0,0, lv_data->info_width,h); if (!lv_data->font_desc) { lv_data->font_desc = pango_font_description_from_string("courier"); pango_font_description_set_size(lv_data->font_desc,(10)*PANGO_SCALE); } if (!lv_data->highlight_gc) lv_data->highlight_gc = initialize_gc(lv_data->pixmap,HIGHLIGHT); lv_data->spread = (GINT)((float)h/(float)lv_data->active_traces); name_x = text_border; layout = gtk_widget_create_pango_layout(lv_data->darea,NULL); for (i=0;i<lv_data->active_traces;i++) { v_value = (Viewable_Value *)g_list_nth_data(lv_data->tlist,i); info_ctr = (lv_data->spread * (i+1))- (lv_data->spread/2); pango_layout_set_markup(layout,v_value->vname,-1); pango_layout_set_font_description(layout,lv_data->font_desc); pango_layout_get_pixel_size(layout,&width,&height); name_y = info_ctr - height - 2; if (width > max) max = width; gdk_draw_layout(pixmap,v_value->trace_gc,name_x,name_y,layout); } lv_data->info_width = max + (text_border * 2.5); for (i=0;i<lv_data->active_traces;i++) { gdk_draw_rectangle(pixmap, gtk_widget_get_style(lv_data->darea)->white_gc, FALSE, 0,i*lv_data->spread, lv_data->info_width-1,lv_data->spread); } }
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)); }
/* TODO remove redundant code */ static void i7_cell_renderer_transcript_render(GtkCellRenderer *self, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { I7_CELL_RENDERER_TRANSCRIPT_USE_PRIVATE; int x, y, width, height; unsigned xpad, ypad, transcript_width; GtkStateType state; cairo_t *cr; PangoRectangle command_rect; PangoLayout *layout; GtkStyle *style = gtk_widget_get_style(widget); /* Get the size we calculated earlier and then take the padding into account */ g_object_get(self, "xpad", &xpad, "ypad", &ypad, NULL); gtk_cell_renderer_get_size(self, widget, cell_area, &x, &y, &width, &height); x += cell_area->x + (int)xpad; y += cell_area->y + (int)ypad; width -= (int)xpad * 2; height -= (int)ypad * 2; /* Decide what state to draw the widget components in */ switch(flags) { case GTK_CELL_RENDERER_PRELIT: state = GTK_STATE_PRELIGHT; break; case GTK_CELL_RENDERER_INSENSITIVE: state = GTK_STATE_INSENSITIVE; break; default: state = GTK_STATE_NORMAL; } /* Get a cairo context to draw the rectangles on directly; use GTK themed drawing to draw everything else */ cr = gdk_cairo_create(GDK_DRAWABLE(window)); /* Draw the command */ layout = gtk_widget_create_pango_layout(widget, priv->command); pango_layout_get_pixel_extents(layout, NULL, &command_rect); set_rgb_style(cr, STYLE_COMMAND); cairo_rectangle(cr, (double)x, (double)y, (double)width, (double)(command_rect.height + priv->text_padding * 2)); cairo_fill(cr); gtk_paint_layout(style, window, state, TRUE, cell_area, widget, NULL, x + priv->text_padding, y + priv->text_padding, layout); g_object_unref(layout); /* Draw the transcript text */ transcript_width = priv->default_width / 2 - xpad; if(priv->changed) set_rgb_style(cr, STYLE_CHANGED); else set_rgb_style(cr, STYLE_UNCHANGED); cairo_rectangle(cr, (double)x, (double)(y + command_rect.height + priv->text_padding * 2), (double)(width / 2), (double)(height - command_rect.height - priv->text_padding * 2)); cairo_fill(cr); layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_markup(layout, priv->transcript_text, -1); pango_layout_set_width(layout, (int)(transcript_width - priv->text_padding * 2) * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); gtk_paint_layout(style, window, state, TRUE, cell_area, widget, NULL, x + (int)priv->text_padding, y + command_rect.height + (int)priv->text_padding * 3, layout); g_object_unref(layout); /* Draw the expected text */ switch(priv->match_type) { case CANT_COMPARE: set_rgb_style(cr, STYLE_NO_EXPECTED); break; case NO_MATCH: set_rgb_style(cr, STYLE_NO_MATCH); break; case NEAR_MATCH: set_rgb_style(cr, STYLE_NEAR_MATCH); break; case EXACT_MATCH: default: set_rgb_style(cr, STYLE_EXACT_MATCH); break; } cairo_rectangle(cr, (double)(x + width / 2), (double)(y + command_rect.height + priv->text_padding * 2), (double)(width / 2), (double)(height - command_rect.height - priv->text_padding * 2)); cairo_fill(cr); layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_markup(layout, priv->expected_text, -1); pango_layout_set_width(layout, (int)(transcript_width - priv->text_padding * 2) * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); gtk_paint_layout(style, window, state, TRUE, cell_area, widget, NULL, x + width / 2 + (int)priv->text_padding, y + command_rect.height + (int)priv->text_padding * 3, layout); g_object_unref(layout); /* Draw some lines */ gtk_paint_hline(style, window, state, cell_area, widget, NULL, x, x + width, y + command_rect.height + priv->text_padding * 2); gtk_paint_vline(style, window, state, cell_area, widget, NULL, y + command_rect.height + priv->text_padding * 2, y + height, x + width / 2); /* Draw a border around the highlighted node */ if(priv->current) { cairo_set_line_width(cr, 4.0); set_rgb_style(cr, STYLE_HIGHLIGHT); cairo_rectangle(cr, (double)x + 2.0, (double)y + 2.0, (double)width - 4.0, (double)height - 4.0); cairo_stroke(cr); } /* Draw a border around the active node */ if(priv->played) { cairo_set_line_width(cr, 2.0); set_rgb_style(cr, STYLE_ACTIVE); cairo_rectangle(cr, (double)x + 1.0, (double)y + 1.0, (double)width - 2.0, (double)height - 2.0); cairo_stroke(cr); } cairo_destroy(cr); }
static void write_text_full ( cairo_t* cr, const char *txt, PangoFontDescription *font, const float x, const float y, const float ang, const int align, const float * const col) { int tw, th; cairo_save(cr); PangoLayout * pl = pango_cairo_create_layout(cr); pango_layout_set_font_description(pl, font); if (strncmp(txt, "<markup>", 8)) { pango_layout_set_text(pl, txt, -1); } else { pango_layout_set_markup(pl, txt, -1); } pango_layout_get_pixel_size(pl, &tw, &th); cairo_translate (cr, rintf(x), rintf(y)); if (ang != 0) { cairo_rotate (cr, ang); } switch(abs(align)) { case 1: cairo_translate (cr, -tw, ceil(th/-2.0)); pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT); break; case 2: cairo_translate (cr, ceil(tw/-2.0), ceil(th/-2.0)); pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER); break; case 3: cairo_translate (cr, 0, ceil(th/-2.0)); pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT); break; case 4: cairo_translate (cr, -tw, -th); pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT); break; case 5: cairo_translate (cr, ceil(tw/-2.0), -th); pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER); break; case 6: cairo_translate (cr, 0, -th); pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT); break; case 7: cairo_translate (cr, -tw, 0); pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT); break; case 8: cairo_translate (cr, ceil(tw/-2.0), 0); pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER); break; case 9: cairo_translate (cr, 0, 0); pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT); break; default: break; } if (align < 0) { cairo_set_source_rgba (cr, .0, .0, .0, .5); cairo_rectangle (cr, 0, 0, tw, th); cairo_fill (cr); } #if 1 cairo_set_source_rgba (cr, col[0], col[1], col[2], col[3]); pango_cairo_show_layout(cr, pl); #else cairo_set_source_rgba (cr, col[0], col[1], col[2], col[3]); pango_cairo_layout_path(cr, pl); cairo_fill(cr); #endif g_object_unref(pl); cairo_restore(cr); cairo_new_path (cr); }
static void dma_sparse_view_paint_margin (DmaSparseView *view, GdkEventExpose *event) { GtkTextView *text_view; GdkWindow *win; PangoLayout *layout; gint y1, y2; gint y, height; gchar str [16]; gint margin_width; gint margin_length; gint text_width; DmaSparseIter buf_iter; GtkTextIter text_iter; guint prev_address = G_MAXUINT; text_view = GTK_TEXT_VIEW (view); if (!view->priv->show_line_numbers && !view->priv->show_line_markers) { gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, 0); return; } win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); y1 = event->area.y; y2 = y1 + event->area.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); /* set size. */ g_snprintf (str, sizeof (str), "0x%X", G_MAXUINT); margin_length = strlen(str) - 2; layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), str); pango_layout_get_pixel_size (layout, &text_width, NULL); pango_layout_set_width (layout, text_width); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); /* determine the width of the left margin. */ if (view->priv->show_line_numbers) margin_width = text_width + 4; else margin_width = 0; if (view->priv->show_line_markers) margin_width += GUTTER_PIXMAP; g_return_if_fail (margin_width != 0); gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_LEFT, margin_width); /* Display all addresses */ dma_sparse_iter_copy (&buf_iter, &view->priv->start); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer (text_view), &text_iter); /* Skip line while position doesn't need to be repaint */ gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); if (y < y1) { do { if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y1); } /* Display address */ do { gint pos; guint address; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y, NULL, &pos); address = dma_sparse_iter_get_address (&buf_iter); if (view->priv->show_line_numbers) { g_snprintf (str, sizeof (str),"0x%0*lX", margin_length, (long unsigned int)address); pango_layout_set_markup (layout, str, -1); gtk_paint_layout (gtk_widget_get_style (GTK_WIDGET (view)), win, gtk_widget_get_state (GTK_WIDGET (view)), FALSE, NULL, GTK_WIDGET (view), NULL, text_width + 2, pos, layout); } /* Display marker */ if ((prev_address != address) && (view->priv->show_line_markers)) { gint current_marker = dma_sparse_buffer_get_marks (view->priv->buffer, address); if (current_marker) { gint x; if (view->priv->show_line_numbers) x = text_width + 4; else x = 0; draw_line_markers (view, current_marker, x, pos); prev_address = address; } } if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y2); g_object_unref (G_OBJECT (layout)); }
static void shell_search_renderer_set_layout (ShellSearchRenderer *cell, GtkWidget *widget) { gchar *display_string; ShellSearchRendererPrivate *priv = cell->priv; gchar *needle, *haystack; gchar *full_string; if (!priv->layout) { priv->layout = pango_layout_new (gtk_widget_get_pango_context (widget)); pango_layout_set_ellipsize (priv->layout, PANGO_ELLIPSIZE_END); } full_string = priv->search_target; if (priv->search_string != NULL) needle = g_utf8_casefold (priv->search_string, -1); else needle = NULL; if (full_string != NULL) haystack = g_utf8_casefold (full_string, -1); else haystack = NULL; /* clear any previous attributes */ pango_layout_set_attributes (priv->layout, NULL); if (priv->search_string && priv->search_target && priv->title && (strstr (haystack, needle))) { gchar *start; gchar *lead, *trail, *leaddot; gchar *match; gint count; #define CONTEXT 10 count = strlen (needle); start = full_string + (strstr (haystack, needle) - haystack); lead = MAX (start - CONTEXT, full_string); trail = start + count; if (lead == full_string) leaddot = ""; else leaddot = "…"; match = g_strndup (start, count); lead = g_strndup (lead, start - lead); display_string = g_markup_printf_escaped ("%s\n" "<small>%s%s<b>%s</b>%s</small>", priv->title, leaddot, lead, match, trail); g_free (match); g_free (lead); } else display_string = g_markup_escape_text (priv->title, -1); pango_layout_set_markup (priv->layout, display_string, -1); g_free (display_string); g_free (needle); g_free (haystack); }
static void gutter_renderer_text_draw (GtkSourceGutterRenderer *renderer, cairo_t *cr, GdkRectangle *background_area, GdkRectangle *cell_area, GtkTextIter *start, GtkTextIter *end, GtkSourceGutterRendererState state) { GtkSourceGutterRendererText *text = GTK_SOURCE_GUTTER_RENDERER_TEXT (renderer); gint width; gint height; PangoAttrList *attr_list; gfloat xalign; gfloat yalign; GtkSourceGutterRendererAlignmentMode mode; GtkTextView *view; gint x = 0; gint y = 0; GtkStyleContext *context; /* Chain up to draw background */ if (GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw != NULL) { GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw (renderer, cr, background_area, cell_area, start, end, state); } view = gtk_source_gutter_renderer_get_view (renderer); if (text->priv->is_markup) { pango_layout_set_markup (text->priv->cached_layout, text->priv->text, -1); } else { pango_layout_set_text (text->priv->cached_layout, text->priv->text, -1); } attr_list = pango_layout_get_attributes (text->priv->cached_layout); if (!attr_list) { pango_layout_set_attributes (text->priv->cached_layout, pango_attr_list_copy (text->priv->cached_attr_list)); } else { pango_attr_list_insert (attr_list, pango_attribute_copy (text->priv->fg_attr)); } pango_layout_get_pixel_size (text->priv->cached_layout, &width, &height); gtk_source_gutter_renderer_get_alignment (renderer, &xalign, &yalign); mode = gtk_source_gutter_renderer_get_alignment_mode (renderer); switch (mode) { case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_CELL: x = cell_area->x + (cell_area->width - width) * xalign; y = cell_area->y + (cell_area->height - height) * yalign; break; case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_FIRST: center_on (renderer, cell_area, start, width, height, xalign, yalign, &x, &y); break; case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_LAST: center_on (renderer, cell_area, end, width, height, xalign, yalign, &x, &y); break; } context = gtk_widget_get_style_context (GTK_WIDGET (view)); gtk_render_layout (context, cr, x, y, text->priv->cached_layout); }
static void aosd_osd_create ( void ) { gint max_width, layout_width, layout_height; PangoRectangle ink, log; GdkScreen *screen = gdk_screen_get_default(); gint pos_x = 0, pos_y = 0; gint pad_left = 0 , pad_right = 0 , pad_top = 0 , pad_bottom = 0; gint screen_width, screen_height; aosd_deco_style_data_t style_data; /* calculate screen_width and screen_height */ if ( osd_data->cfg_osd->position.multimon_id > -1 ) { /* adjust coordinates and size according to selected monitor */ GdkRectangle rect; gdk_screen_get_monitor_geometry( screen , osd_data->cfg_osd->position.multimon_id , &rect ); pos_x = rect.x; pos_y = rect.y; screen_width = rect.width; screen_height = rect.height; } else { /* use total space available, even when composed by multiple monitor */ screen_width = gdk_screen_get_width( screen ); screen_height = gdk_screen_get_height( screen ); pos_x = 0; pos_y = 0; } /* pick padding from selected decoration style */ aosd_deco_style_get_padding( osd_data->cfg_osd->decoration.code , &pad_top , &pad_bottom , &pad_left , &pad_right ); if ( osd_data->cfg_osd->position.maxsize_width > 0 ) { gint max_width_default = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x); max_width = osd_data->cfg_osd->position.maxsize_width - pad_left - pad_right; /* ignore user-defined max_width if it is too small or too large */ if (( max_width < 1 ) || ( max_width > max_width_default )) max_width = max_width_default; } else { max_width = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x); } osd_data->pango_context = pango_cairo_font_map_create_context( PANGO_CAIRO_FONT_MAP(pango_cairo_font_map_get_default())); osd_data->pango_layout = pango_layout_new(osd_data->pango_context); pango_layout_set_markup( osd_data->pango_layout, osd_data->markup_message , -1 ); pango_layout_set_ellipsize( osd_data->pango_layout , PANGO_ELLIPSIZE_NONE ); pango_layout_set_justify( osd_data->pango_layout , FALSE ); pango_layout_set_width( osd_data->pango_layout , PANGO_SCALE * max_width ); pango_layout_get_pixel_extents( osd_data->pango_layout , &ink , &log ); layout_width = ink.width; layout_height = log.height; /* osd position */ switch ( osd_data->cfg_osd->position.placement ) { case AOSD_POSITION_PLACEMENT_TOP: pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2; pos_y += 0; break; case AOSD_POSITION_PLACEMENT_TOPRIGHT: pos_x += screen_width - (layout_width + pad_left + pad_right); pos_y += 0; break; case AOSD_POSITION_PLACEMENT_MIDDLELEFT: pos_x += 0; pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2; break; case AOSD_POSITION_PLACEMENT_MIDDLE: pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2; pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2; break; case AOSD_POSITION_PLACEMENT_MIDDLERIGHT: pos_x += screen_width - (layout_width + pad_left + pad_right); pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2; break; case AOSD_POSITION_PLACEMENT_BOTTOMLEFT: pos_x += 0; pos_y += screen_height - (layout_height + pad_top + pad_bottom); break; case AOSD_POSITION_PLACEMENT_BOTTOM: pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2; pos_y += screen_height - (layout_height + pad_top + pad_bottom); break; case AOSD_POSITION_PLACEMENT_BOTTOMRIGHT: pos_x += screen_width - (layout_width + pad_left + pad_right); pos_y += screen_height - (layout_height + pad_top + pad_bottom); break; case AOSD_POSITION_PLACEMENT_TOPLEFT: default: pos_x += 0; pos_y += 0; break; } /* add offset to position */ pos_x += osd_data->cfg_osd->position.offset_x; pos_y += osd_data->cfg_osd->position.offset_y; ghosd_set_position( osd , pos_x , pos_y , layout_width + pad_left + pad_right , layout_height + pad_top + pad_bottom ); ghosd_set_event_button_cb( osd , aosd_button_func , NULL ); style_data.layout = osd_data->pango_layout; style_data.text = &(osd_data->cfg_osd->text); style_data.decoration = &(osd_data->cfg_osd->decoration); osd_data->fade_data.surface = NULL; osd_data->fade_data.user_data = &style_data; osd_data->fade_data.width = layout_width + pad_left + pad_right; osd_data->fade_data.height = layout_height + pad_top + pad_bottom; osd_data->fade_data.alpha = 0; osd_data->fade_data.deco_code = osd_data->cfg_osd->decoration.code; osd_data->dalpha_in = 1.0 / ( osd_data->cfg_osd->animation.timing_fadein / (gfloat)AOSD_TIMING ); osd_data->dalpha_out = 1.0 / ( osd_data->cfg_osd->animation.timing_fadeout / (gfloat)AOSD_TIMING ); osd_data->ddisplay_stay = 1.0 / ( osd_data->cfg_osd->animation.timing_display / (gfloat)AOSD_TIMING ); ghosd_set_render( osd , (GhosdRenderFunc)aosd_fade_func , &(osd_data->fade_data) , NULL ); /* show the osd (with alpha 0, invisible) */ ghosd_show( osd ); return; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P A N G O I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPANGOImage() reads an image in the Pango Markup Language Format. % % The format of the ReadPANGOImage method is: % % Image *ReadPANGOImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadPANGOImage(const ImageInfo *image_info, ExceptionInfo *exception) { cairo_font_options_t *font_options; cairo_surface_t *surface; char *caption, *property; cairo_t *cairo_image; const char *option; DrawInfo *draw_info; Image *image; MagickBooleanType status; PangoAlignment align; PangoContext *context; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelPacket fill_color; RectangleInfo page; register unsigned char *p; size_t stride; ssize_t y; unsigned char *pixels; /* 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"); /* Format caption. */ option=GetImageOption(image_info,"filename"); if (option == (const char *) NULL) property=InterpretImageProperties(image_info,image,image_info->filename); else if (LocaleNCompare(option,"pango:",6) == 0) property=InterpretImageProperties(image_info,image,option+6); else property=InterpretImageProperties(image_info,image,option); (void) SetImageProperty(image,"caption",property); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption")); /* Get context. */ fontmap=pango_cairo_font_map_new(); pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), image->x_resolution); font_options=cairo_font_options_create(); option=GetImageOption(image_info,"pango:hinting"); if (option != (const char *) NULL) { if (LocaleCompare(option,"none") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE); if (LocaleCompare(option,"full") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL); } context=pango_font_map_create_context(fontmap); pango_cairo_context_set_font_options(context,font_options); cairo_font_options_destroy(font_options); option=GetImageOption(image_info,"pango: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 NorthWestGravity: case WestGravity: case SouthWestGravity: { gravity=PANGO_GRAVITY_WEST; break; } case NorthEastGravity: case EastGravity: case SouthEastGravity: { 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,"pango: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,"pango:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageOption(image_info,"pango: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,"pango:justify"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_justify(layout,1); option=GetImageOption(image_info,"pango:single-paragraph"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageOption(image_info,"pango: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,"pango:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(int) ((StringToLong(option)* image->x_resolution*PANGO_SCALE+36)/72.0+0.5)); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: align=PANGO_ALIGN_LEFT; break; default: { if (draw_info->gravity == CenterGravity) { align=PANGO_ALIGN_CENTER; break; } 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); if (draw_info->font != (char *) NULL) { PangoFontDescription *description; /* Set font. */ description=pango_font_description_from_string(draw_info->font); pango_font_description_set_size(description,(int) (PANGO_SCALE* draw_info->pointsize+0.5)); pango_layout_set_font_description(layout,description); pango_font_description_free(description); } option=GetImageOption(image_info,"pango:markup"); if ((option != (const char *) NULL) && (IsMagickTrue(option) == MagickFalse)) pango_layout_set_text(layout,caption,-1); else { GError *error; error=(GError *) NULL; if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0) (void) ThrowMagickException(exception,GetMagickModule(),CoderError, error->message,"`%s'",image_info->filename); pango_layout_set_markup(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+2*page.x; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns* image->x_resolution+36.0)/72.0+0.5)); } if (image->rows == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->rows=extent.y+extent.height+2*page.y; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows* image->y_resolution+36.0)/72.0+0.5)); } /* Render markup. */ stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, image->columns); pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32, image->columns,image->rows,stride); cairo_image=cairo_create(surface); cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_image); cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER); cairo_translate(cairo_image,page.x,page.y); pango_cairo_show_layout(cairo_image,layout); cairo_destroy(cairo_image); cairo_surface_destroy(surface); g_object_unref(layout); g_object_unref(fontmap); /* Convert surface to image. */ (void) SetImageBackgroundColor(image); p=pixels; for (y=0; y < (ssize_t) image->rows; y++) { register PixelPacket *q; register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { double gamma; fill_color.blue=ScaleCharToQuantum(*p++); fill_color.green=ScaleCharToQuantum(*p++); fill_color.red=ScaleCharToQuantum(*p++); fill_color.opacity=QuantumRange-ScaleCharToQuantum(*p++); /* Disassociate alpha. */ gamma=1.0-QuantumScale*fill_color.opacity; gamma=MagickEpsilonReciprocal(gamma); fill_color.blue*=gamma; fill_color.green*=gamma; fill_color.red*=gamma; MagickCompositeOver(&fill_color,fill_color.opacity,q,(MagickRealType) q->opacity,q); q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } /* Relinquish resources. */ pixels=(unsigned char *) RelinquishMagickMemory(pixels); draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); return(GetFirstImageInList(image)); }
static void gwy_vruler_real_draw_ticks(GwyRuler *ruler, gint pixelsize, gint min_label_spacing, gint min_tick_spacing) { gdouble lower, upper, max; gint text_size, labels, i, scale_depth; gdouble range, measure, base, step, first; GwyScaleScale scale; GwySIValueFormat *format; PangoLayout *layout; PangoRectangle rect; gchar *unit_str; gint unitstr_len, j; gint width, tick_length, xthickness, ythickness; gboolean units_drawn; GtkWidget *widget; GdkGC *gc; gint digit_width, digit_xoffset; const gchar *utf8p, *utf8next; gint ascent, descent, ypos; struct { GwyScaleScale scale; double base; } tick_info[4]; widget = GTK_WIDGET(ruler); xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; format = ruler->vformat; upper = ruler->upper; lower = ruler->lower; if (upper <= lower || pixelsize < 2 || pixelsize > 10000) return; max = ruler->max_size; if (max == 0) max = MAX(fabs(lower), fabs(upper)); range = upper - lower; measure = range/format->magnitude / pixelsize; max /= format->magnitude; switch (ruler->units_placement && ruler->units) { case GWY_UNITS_PLACEMENT_AT_ZERO: unit_str = g_strdup_printf("%d %s", (lower > 0) ? (gint)(lower/format->magnitude) : 0, format->units); break; default: unit_str = g_strdup_printf("%d", (gint)max); break; } layout = gtk_widget_create_pango_layout(widget, "012456789"); pango_layout_get_extents(layout, NULL, &rect); digit_width = PANGO_PIXELS(rect.width)/10 + 1; digit_xoffset = rect.x; pango_layout_set_markup(layout, unit_str, -1); pango_layout_get_extents(layout, &rect, NULL); ascent = PANGO_ASCENT(rect); descent = PANGO_DESCENT(rect); text_size = g_utf8_strlen(pango_layout_get_text(layout), -1); text_size = PANGO_PIXELS(ascent + descent)*text_size; /* reallocate unit_str with some margin */ unitstr_len = strlen(unit_str) + 16; unit_str = g_renew(gchar, unit_str, unitstr_len); /* fit as many labels as you can */ labels = floor(pixelsize/(text_size + ythickness + min_label_spacing)); labels = MAX(labels, 1); if (labels > 6) labels = 6 + (labels - 5)/2; step = range/format->magnitude / labels; base = compute_base(step, 10); step /= base; if (step >= 5.0 || base < 1.0) { scale = GWY_SCALE_1; base *= 10; } else if (step >= 2.5) scale = GWY_SCALE_5; else if (step >= 2.0) scale = GWY_SCALE_2_5; else scale = GWY_SCALE_2; step = steps[scale]; /* draw labels */ width = widget->allocation.width - 2*xthickness; units_drawn = FALSE; first = floor(lower/format->magnitude / (base*step))*base*step; for (i = 0; ; i++) { gint pos; gdouble val; val = i*step*base + first; pos = floor((val - lower/format->magnitude)/measure); if (pos >= pixelsize) break; if (pos < 0) continue; if (!units_drawn && (upper < 0 || val >= 0) && ruler->units_placement == GWY_UNITS_PLACEMENT_AT_ZERO && ruler->units) { g_snprintf(unit_str, unitstr_len, "%d %s", ROUND(val), format->units); units_drawn = TRUE; } else g_snprintf(unit_str, unitstr_len, "%d", ROUND(val)); pango_layout_set_markup(layout, unit_str, -1); utf8p = unit_str; utf8next = g_utf8_next_char(utf8p); j = 0; ypos = pos + ythickness + 1; while (*utf8p) { pango_layout_set_text(layout, utf8p, utf8next - utf8p); pango_layout_get_extents(layout, &rect, NULL); gtk_paint_layout(widget->style, ruler->backing_store, GTK_WIDGET_STATE(widget), FALSE, NULL, widget, "vruler", xthickness + 1 + PANGO_PIXELS(digit_xoffset), ypos, layout); utf8p = utf8next; utf8next = g_utf8_next_char(utf8p); ypos += PANGO_PIXELS(PANGO_ASCENT(rect) + PANGO_DESCENT(rect)) + 2; j++; } } /* draw tick marks, from smallest to largest */ scale_depth = 0; while (scale && scale_depth < (gint)G_N_ELEMENTS(tick_info)) { tick_info[scale_depth].scale = scale; tick_info[scale_depth].base = base; scale = next_scale(scale, &base, measure, min_tick_spacing); scale_depth++; } scale_depth--; gc = widget->style->fg_gc[GTK_STATE_NORMAL]; while (scale_depth > -1) { tick_length = width/(scale_depth + 1) - 2; scale = tick_info[scale_depth].scale; base = tick_info[scale_depth].base; step = steps[scale]; first = floor(lower/format->magnitude / (base*step))*base*step; for (i = 0; ; i++) { gint pos; gdouble val; val = (i + 0.000001)*step*base + first; pos = floor((val - lower/format->magnitude)/measure); if (pos >= pixelsize) break; if (pos < 0) continue; gdk_draw_line(ruler->backing_store, gc, width + xthickness - tick_length, pos, width + xthickness, pos); } scale_depth--; } g_free(unit_str); g_object_unref(layout); }
static void pkg_graph_2d_paint (PkgGraph2d *graph) { PkgGraph2dPrivate *priv = graph->priv; cairo_t *cr; gfloat w, h; gdouble x0, x1, x2; gdouble y0, y1, y2; gdouble dashes[] = {1., 2.}; gdouble *epochs = NULL; gdouble tmp; gsize n_epochs = 0; gint i; clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(priv->texture)); clutter_actor_get_size(CLUTTER_ACTOR(graph), &w, &h); /* * Create cairo context and set defaults. */ cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(priv->texture)); cairo_set_line_width(cr, 1.); cairo_set_dash(cr, dashes, 2, 0.); /* * Get coordinates for drawing primary extends. */ pkg_graph_2d_get_primary_extents(graph, &x0, &x1, &x2, &y0, &y1, &y2); /* * Draw the background color. */ cairo_set_source_rgb(cr, 1., 1., 1.); cairo_rectangle(cr, x1, y2, x2 - x1, y1); cairo_fill(cr); /* * Draw the bounding box. */ cairo_set_source_rgb(cr, 0., 0., 0.); cairo_move_to(cr, x0, y2); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x2, y0); cairo_move_to(cr, x0, y1); cairo_line_to(cr, x2, y1); cairo_move_to(cr, x1, y0 - .5); cairo_line_to(cr, x1, y2); cairo_stroke(cr); /* * Draw the x-scale epochs. */ if (pkg_scale_get_epochs(priv->x_scale, &epochs, &n_epochs)) { if (n_epochs > 0) { for (i = 0; i < n_epochs; i++) { if (pkg_scale_translate(priv->x_scale, epochs[i], &tmp)) { PangoFontDescription *font_desc; PangoLayout *layout; gchar *format, *markup; gint pw, ph; /* * Only draw the line if it isn't right near the end of * the visiable region of the graph. */ if (tmp + 5. < floor(w)) { cairo_move_to(cr, tmp, y0 - .5); cairo_line_to(cr, tmp, y2); } /* * Draw the y-scale grid-line value. */ format = pkg_scale_format_string(priv->x_scale, epochs[i]); if (format != NULL) { font_desc = pango_font_description_from_string("Bold Sans 8"); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, font_desc); markup = g_strdup_printf("<span size=\"smaller\">%s</span>", format); pango_layout_set_markup(layout, markup, -1); pango_layout_get_pixel_size(layout, &pw, &ph); if (i == 0) { cairo_move_to(cr, tmp + 2., y1 + 2.); } else { cairo_move_to(cr, tmp - pw - 2., y1 + 2.); } pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_desc); g_free(format); g_free(markup); } } } cairo_stroke(cr); } } /* * Draw the y-scale epochs. */ if (pkg_scale_get_epochs(priv->y_scale, &epochs, &n_epochs)) { if (n_epochs > 0) { for (i = 0; i < n_epochs; i++) { if (pkg_scale_translate(priv->y_scale, epochs[i], &tmp)) { PangoFontDescription *font_desc; PangoLayout *layout; gchar *format, *markup; gint pw, ph; cairo_move_to(cr, x0, floor(y1 - tmp) + .5); cairo_line_to(cr, x2, floor(y1 - tmp) + .5); /* * Draw the y-scale grid-line value. */ format = pkg_scale_format_string(priv->y_scale, epochs[i]); if (format != NULL) { font_desc = pango_font_description_from_string("Bold Sans 8"); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, font_desc); markup = g_strdup_printf("<span size=\"smaller\">%s</span>", format); pango_layout_set_markup(layout, markup, -1); pango_layout_get_pixel_size(layout, &pw, &ph); if (i == 0) { cairo_move_to(cr, x1 - pw - 2., y1 - tmp - ph - 2.); } else { cairo_move_to(cr, x1 - pw - 2., y1 - tmp + 2.); } pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_desc); g_free(markup); g_free(format); } } } cairo_stroke(cr); } } priv->x_label = "X Label Here"; priv->y_label = "Y Label Here"; /* * Draw the X scale label. */ if (priv->x_label) { PangoFontDescription *font_desc; PangoLayout *layout; gchar *markup; gint pw, ph; font_desc = pango_font_description_from_string("Bold Sans 10"); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, font_desc); markup = g_strdup_printf("<span size=\"smaller\">%s</span>", priv->x_label); pango_layout_set_markup(layout, markup, -1); pango_layout_get_pixel_size(layout, &pw, &ph); cairo_move_to(cr, ((w - pw) / 2.), h - ph); pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_desc); g_free(markup); } /* * Draw the Y scale label. */ if (priv->x_label) { PangoFontDescription *font_desc; PangoLayout *layout; gchar *markup; gint pw, ph; font_desc = pango_font_description_from_string("Bold Sans 10"); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, font_desc); markup = g_strdup_printf("<span size=\"smaller\">%s</span>", priv->y_label); pango_layout_set_markup(layout, markup, -1); pango_layout_get_pixel_size(layout, &pw, &ph); cairo_move_to(cr, 0., h - ((h - pw) / 2.)); cairo_rotate(cr, M_PI / -2.); pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_desc); g_free(markup); } /* * Free cairo context and resources. */ cairo_destroy(cr); /* * Render the children data points. */ pkg_graph_2d_paint_children(graph); }
static void draw(GtkWidget *widget, cairo_t *cr, gpointer data) { CalibArea *calib_area = (CalibArea*)data; int i; double x; double y; PangoLayout *layout; PangoRectangle logical_rect; GtkStyleContext *context; char *markup; resize_display(calib_area); context = gtk_widget_get_style_context (widget); /* Black background and reset the operator */ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); /* If calibration is successful, just draw the tick */ if (calib_area->icon_success) { draw_success_icon (calib_area, cr); return; } /* Print the help lines */ layout = pango_layout_new (gtk_widget_get_pango_context (widget)); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); markup = g_strdup_printf ("<span foreground=\"white\"><big><b>%s</b></big>\n<big>%s</big></span>", _(HELP_TEXT_TITLE), _(HELP_TEXT_MAIN)); pango_layout_set_markup (layout, markup, -1); g_free (markup); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); x = (calib_area->display_width - logical_rect.width) / 2 + logical_rect.x; y = (calib_area->display_height - logical_rect.height) / 2 - logical_rect.height - 40 + logical_rect.y; gtk_render_layout (context, cr, x + logical_rect.x, y + logical_rect.y, layout); g_object_unref (layout); /* Draw the points */ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); i = calib_area->calibrator.num_clicks; cairo_set_line_width(cr, 1); cairo_move_to(cr, calib_area->X[i] - CROSS_LINES, calib_area->Y[i] - 0.5); cairo_rel_line_to(cr, CROSS_LINES*2, 0); cairo_move_to(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - CROSS_LINES); cairo_rel_line_to(cr, 0, CROSS_LINES*2); cairo_stroke(cr); cairo_set_line_width(cr, 2); cairo_arc(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - 0.5, CROSS_CIRCLE, 0.0, 2.0 * M_PI); cairo_stroke(cr); cairo_set_line_width(cr, 5); cairo_arc(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - 0.5, CROSS_CIRCLE2, 0.0, 2.0 * M_PI); cairo_stroke(cr); /* Draw the clock background */ cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, CLOCK_RADIUS/2, 0.0, 2.0 * M_PI); cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_fill_preserve(cr); cairo_stroke(cr); cairo_set_line_width(cr, CLOCK_LINE_WIDTH); cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, (CLOCK_RADIUS - CLOCK_LINE_WIDTH - CLOCK_LINE_PADDING)/2, 3/2.0*M_PI, (3/2.0*M_PI) + ((double)calib_area->time_elapsed/(double)MAX_TIME) * 2*M_PI); cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_stroke(cr); /* Draw the message (if any) */ if (calib_area->message != NULL) { cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); /* Frame the message */ layout = pango_layout_new (gtk_widget_get_pango_context (widget)); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); markup = g_strdup_printf ("<span foreground=\"white\"><big>%s</big></span>", _(calib_area->message)); pango_layout_set_markup (layout, markup, -1); g_free (markup); pango_layout_get_pixel_extents (layout, NULL, &logical_rect); x = (calib_area->display_width - logical_rect.width) / 2 + logical_rect.x; y = (calib_area->display_height - logical_rect.height + CLOCK_RADIUS) / 2 + 60 + logical_rect.y; cairo_set_line_width(cr, 2); cairo_rectangle(cr, x - 10 - 0.5 , y - 10 - 0.5, logical_rect.width + 20 + 1, logical_rect.height + 20 + 1); cairo_stroke (cr); /* Print the message */ gtk_render_layout (context, cr, x + logical_rect.x, y + logical_rect.y, layout); g_object_unref (layout); } }
static void gwy_color_axis_draw_label(GtkWidget *widget) { GwyColorAxis *axis; PangoLayout *layout; GwySIValueFormat *format = NULL; GString *strmin, *strmax; GdkGC *mygc; PangoRectangle rect; gwy_debug(""); mygc = gdk_gc_new(widget->window); axis = GWY_COLOR_AXIS(widget); /*compute minimum and maximum numbers*/ strmax = g_string_new(" "); if (axis->max == 0) { if (axis->min == 0) g_string_printf(strmax, "0.0"); else { format = gwy_si_unit_get_format(axis->siunit, axis->max, NULL); g_string_printf(strmax, "0.0 "); g_string_append(strmax, format->units); } } else { format = gwy_si_unit_get_format(axis->siunit, axis->max, NULL); g_string_printf(strmax, "%3.1f ", axis->max/format->magnitude); g_string_append(strmax, format->units); } strmin = g_string_new(" "); if (axis->min == 0) { if (axis->max == 0) g_string_printf(strmin, "0.0"); else { format = gwy_si_unit_get_format(axis->siunit, axis->max, format); g_string_printf(strmin, "0.0 "); g_string_append(strmin, format->units); } } else { /*yes, realy axis->max*/ format = gwy_si_unit_get_format(axis->siunit, axis->max, format); g_string_printf(strmin, "%3.1f ", axis->min/format->magnitude); g_string_append(strmin, format->units); } if (axis->orientation == GTK_ORIENTATION_VERTICAL) { /*draw frame around axis*/ gdk_draw_rectangle(widget->window, mygc, 0, 0, 0, widget->allocation.width - axis->par.textarea, widget->allocation.height - 1); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, 0, widget->allocation.width - axis->par.textarea + axis->par.tick_length, 0); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, widget->allocation.height/2, widget->allocation.width - axis->par.textarea + axis->par.tick_length, widget->allocation.height/2); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, widget->allocation.height - 1, widget->allocation.width - axis->par.textarea + axis->par.tick_length, widget->allocation.height - 1); /*draw text*/ layout = gtk_widget_create_pango_layout(widget, ""); pango_layout_set_font_description(layout, axis->par.font); pango_layout_set_markup(layout, strmax->str, strmax->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - axis->par.textarea + 2, 2, layout); pango_layout_set_markup(layout, strmin->str, strmin->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - axis->par.textarea + 2, widget->allocation.height - rect.height - 2, layout); } else { /*draw frame around axis*/ gdk_draw_rectangle(widget->window, mygc, FALSE, 0, axis->par.textarea, widget->allocation.width - 1, widget->allocation.height - 1); gdk_draw_line(widget->window, mygc, 0, axis->par.textarea - axis->par.tick_length, 0, axis->par.textarea); gdk_draw_line(widget->window, mygc, widget->allocation.width/2, axis->par.textarea - axis->par.tick_length, widget->allocation.width/2, axis->par.textarea); gdk_draw_line(widget->window, mygc, widget->allocation.width - 1, axis->par.textarea - axis->par.tick_length, widget->allocation.width - 1, axis->par.textarea); /*draw text*/ layout = gtk_widget_create_pango_layout(widget, ""); pango_layout_set_font_description(layout, axis->par.font); pango_layout_set_markup(layout, strmin->str, strmin->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, 2, axis->par.textarea - rect.height - 2, layout); pango_layout_set_markup(layout, strmax->str, strmax->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - rect.width - 2, axis->par.textarea - rect.height - 2, layout); } g_object_unref(mygc); g_object_unref(layout); if (format) gwy_si_unit_value_format_free(format); g_string_free(strmin, TRUE); g_string_free(strmax, TRUE); }
static GdkPixbuf *image_osd_info_render(ImageWindow *imd) { GdkPixbuf *pixbuf; gint width, height; PangoLayout *layout; const gchar *name; gchar *name_escaped; gchar *text; gchar *size; gint n, t; CollectionData *cd; CollectInfo *info; gchar *ct; name = image_get_name(imd); if (name) { name_escaped = g_markup_escape_text(name, -1); } else { name_escaped = NULL; } cd = image_get_collection(imd, &info); if (cd) { gchar *buf; t = g_list_length(cd->list); n = g_list_index(cd->list, info) + 1; buf = g_markup_escape_text((cd->name) ? cd->name : _("Untitled"), -1); ct = g_strdup_printf("<i>%s</i>\n", buf); g_free(buf); } else { LayoutWindow *lw; lw = layout_find_by_image(imd); if (lw) { if (lw->slideshow) { n = g_list_length(lw->slideshow->list_done); t = n + g_list_length(lw->slideshow->list); if (n == 0) n = t; } else { t = layout_list_count(lw, NULL); n = layout_list_get_index(lw, image_get_path(lw->image)) + 1; } } else if (view_window_find_image(imd, &n, &t)) { n++; } else { t = 1; n = 1; } if (n < 1) n = 1; if (t < 1) t = 1; ct = g_strdup(""); } size = text_from_size_abrev(imd->size); if (!name_escaped) { text = g_strdup_printf(_("Untitled")); } else if (imd->unknown) { text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%s - %s", ct, n, t, name_escaped, text_from_time(imd->mtime), size); } else { gint w, h; if (imd->delay_flip && imd->il && imd->il->pixbuf && image_get_pixbuf(imd) != imd->il->pixbuf) { w = gdk_pixbuf_get_width(imd->il->pixbuf); h = gdk_pixbuf_get_height(imd->il->pixbuf); } else { pixbuf_renderer_get_image_size(PIXBUF_RENDERER(imd->pr), &w, &h); } text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%d x %d - %s - %s", ct, n, t, name_escaped, w, h, text_from_time(imd->mtime), size); } g_free(size); g_free(ct); g_free(name_escaped); layout = gtk_widget_create_pango_layout(imd->pr, NULL); pango_layout_set_markup(layout, text, -1); g_free(text); pango_layout_get_pixel_size(layout, &width, &height); width += 10; height += 10; pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); pixbuf_set_rect_fill(pixbuf, 3, 3, width-6, height-6, 240, 240, 240, 210); pixbuf_set_rect(pixbuf, 0, 0, width, height, 240, 240, 240, 80, 1, 1, 1, 1); pixbuf_set_rect(pixbuf, 1, 1, width-2, height-2, 240, 240, 240, 130, 1, 1, 1, 1); pixbuf_set_rect(pixbuf, 2, 2, width-4, height-4, 240, 240, 240, 180, 1, 1, 1, 1); pixbuf_pixel_set(pixbuf, 0, 0, 0, 0, 0, 0); pixbuf_pixel_set(pixbuf, width - 1, 0, 0, 0, 0, 0); pixbuf_pixel_set(pixbuf, 0, height - 1, 0, 0, 0, 0); pixbuf_pixel_set(pixbuf, width - 1, height - 1, 0, 0, 0, 0); pixbuf_draw_layout(pixbuf, layout, imd->pr, 5, 5, 0, 0, 0, 255); g_object_unref(G_OBJECT(layout)); return pixbuf; }
static void gutter_renderer_text_draw (GtkSourceGutterRenderer *renderer, cairo_t *cr, GdkRectangle *background_area, GdkRectangle *cell_area, GtkTextIter *start, GtkTextIter *end, GtkSourceGutterRendererState state) { GtkSourceGutterRendererText *text = GTK_SOURCE_GUTTER_RENDERER_TEXT (renderer); GtkTextView *view; gint width; gint height; gfloat xalign; gfloat yalign; GtkSourceGutterRendererAlignmentMode mode; gint x = 0; gint y = 0; GtkStyleContext *context; /* Chain up to draw background */ if (GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw != NULL) { GTK_SOURCE_GUTTER_RENDERER_CLASS (gtk_source_gutter_renderer_text_parent_class)->draw (renderer, cr, background_area, cell_area, start, end, state); } view = gtk_source_gutter_renderer_get_view (renderer); if (text->priv->is_markup) { pango_layout_set_markup (text->priv->cached_layout, text->priv->text, -1); } else { pango_layout_set_text (text->priv->cached_layout, text->priv->text, -1); } pango_layout_get_pixel_size (text->priv->cached_layout, &width, &height); gtk_source_gutter_renderer_get_alignment (renderer, &xalign, &yalign); /* Avoid calculations if we don't wrap text */ if (gtk_text_view_get_wrap_mode (view) == GTK_WRAP_NONE) { mode = GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_CELL; } else { mode = gtk_source_gutter_renderer_get_alignment_mode (renderer); } switch (mode) { case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_CELL: x = cell_area->x + (cell_area->width - width) * xalign; y = cell_area->y + (cell_area->height - height) * yalign; break; case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_FIRST: center_on (view, cell_area, start, width, height, xalign, yalign, &x, &y); break; case GTK_SOURCE_GUTTER_RENDERER_ALIGNMENT_MODE_LAST: center_on (view, cell_area, end, width, height, xalign, yalign, &x, &y); break; default: g_assert_not_reached (); } context = gtk_widget_get_style_context (GTK_WIDGET (view)); gtk_render_layout (context, cr, x, y, text->priv->cached_layout); }
static void draw_text_bubble (cairo_t *cr, GtkWidget *widget, gdouble pointx, gdouble pointy) { static const double corner_radius = 9.0; static const double margin_top = 12.0; static const double margin_bottom = 12.0; static const double margin_left = 24.0; static const double margin_right = 24.0; CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv; GtkAllocation alloc; PangoLayout *layout; PangoRectangle text_rect; double x; double y; double width; double height; if (!priv->bubble_text) return; gtk_widget_get_allocation (widget, &alloc); layout = gtk_widget_create_pango_layout (widget, NULL); /* Layout the text */ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_spacing (layout, 3); pango_layout_set_markup (layout, priv->bubble_text, -1); pango_layout_get_pixel_extents (layout, NULL, &text_rect); /* Calculate the bubble size based on the text layout size */ width = text_rect.width + margin_left + margin_right; height = text_rect.height + margin_top + margin_bottom; if (pointx < alloc.width / 2) x = pointx + 25; else x = pointx - width - 25; y = pointy - height / 2; /* Make sure it fits in the visible area */ x = CLAMP (x, 0, alloc.width - width); y = CLAMP (y, 0, alloc.height - height); cairo_save (cr); cairo_translate (cr, x, y); /* Draw the bubble */ cairo_new_sub_path (cr); cairo_arc (cr, width - corner_radius, corner_radius, corner_radius, radians (-90), radians (0)); cairo_arc (cr, width - corner_radius, height - corner_radius, corner_radius, radians (0), radians (90)); cairo_arc (cr, corner_radius, height - corner_radius, corner_radius, radians (90), radians (180)); cairo_arc (cr, corner_radius, corner_radius, corner_radius, radians (180), radians (270)); cairo_close_path (cr); cairo_set_source_rgba (cr, 0.2, 0.2, 0.2, 0.7); cairo_fill (cr); /* And finally draw the text */ cairo_set_source_rgb (cr, 1, 1, 1); cairo_move_to (cr, margin_left, margin_top); pango_cairo_show_layout (cr, layout); g_object_unref (layout); cairo_restore (cr); }
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 void texbox_update ( textbox *tb ) { if ( tb->update ) { if ( tb->main_surface ) { cairo_destroy ( tb->main_draw ); cairo_surface_destroy ( tb->main_surface ); tb->main_draw = NULL; tb->main_surface = NULL; } tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); tb->main_draw = cairo_create ( tb->main_surface ); PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); pango_font_description_free ( pfd ); cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_SOURCE ); pango_cairo_update_layout ( tb->main_draw, tb->layout ); char *text = tb->text ? tb->text : ""; int text_len = strlen ( text ); int font_height = textbox_get_font_height ( tb ); int cursor_x = 0; int cursor_width = MAX ( 2, font_height / 10 ); if ( tb->changed ) { if ( tb->flags & TB_MARKUP ) { pango_layout_set_markup ( tb->layout, text, text_len ); } else{ pango_layout_set_text ( tb->layout, text, text_len ); } } if ( tb->flags & TB_EDITABLE ) { PangoRectangle pos; int cursor_offset = 0; cursor_offset = MIN ( tb->cursor, text_len ); pango_layout_get_cursor_pos ( tb->layout, cursor_offset, &pos, NULL ); // Add a small 4px offset between cursor and last glyph. cursor_x = pos.x / PANGO_SCALE; } // Skip the side MARGIN on the X axis. int x = SIDE_MARGIN; int y = 0; if ( tb->flags & TB_RIGHT ) { int line_width = 0; // Get actual width. pango_layout_get_pixel_size ( tb->layout, &line_width, NULL ); x = ( tb->w - line_width - SIDE_MARGIN ); } else if ( tb->flags & TB_CENTER ) { int tw = textbox_get_font_width ( tb ); x = ( ( tb->w - tw - 2 * SIDE_MARGIN ) ) / 2; } short fh = textbox_get_font_height ( tb ); if ( fh > tb->h ) { y = 0; } else { y = ( ( tb->h - fh ) ) / 2; } // Set ARGB Color col = tb->color_bg; cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); cairo_paint ( tb->main_draw ); // Set ARGB col = tb->color_fg; cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); cairo_move_to ( tb->main_draw, x, y ); pango_cairo_show_layout ( tb->main_draw, tb->layout ); //cairo_fill(tb->draw); // draw the cursor if ( tb->flags & TB_EDITABLE ) { cairo_rectangle ( tb->main_draw, x + cursor_x, y, cursor_width, font_height ); cairo_fill ( tb->main_draw ); } tb->update = FALSE; } }
void rendertext(cairo_t *cr) { PangoContext* context = NULL; PangoLayout *layout = NULL; PangoFontDescription *desc = NULL; PangoFontMap* font_map = NULL; PangoRectangle lastInkRect; PangoRectangle lastLogicalRect; memset(&lastInkRect, 0, sizeof(PangoRectangle)); memset(&lastLogicalRect, 0, sizeof(PangoRectangle)); // font_map = pango_ft2_font_map_new(); // if (NULL == font_map) { // printf("+ error: cannot create the pango font map.\n"); // exit(EXIT_FAILURE); // } // context = pango_font_map_create_context(font_map); // if (NULL == context) { // printf("+ error: cannot create pango font context.\n"); // exit(EXIT_FAILURE); // } //cairo_translate(cr, 10, 20); layout = pango_cairo_create_layout(cr); if (NULL == layout) { printf("+ error: cannot create the pango layout.\n"); exit(EXIT_FAILURE); } desc = pango_font_description_from_string("Comic Sans Africa 40"); pango_layout_set_font_description(layout, desc); //pango_font_map_load_font(font_map, context, desc); pango_font_description_free(desc); pango_layout_set_markup(layout, "Hello World!", -1); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); //pango_ft2_render_layout(bmp, layout, 30, 100); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); pango_layout_get_pixel_extents(layout, &lastInkRect, &lastLogicalRect); cairo_translate(cr, 0, lastInkRect.height); pango_layout_set_markup(layout, "\t\u2022 <span foreground=\"green\"><b>Second</b></span> Hello!", -1); desc = pango_font_description_from_string("Comic Sans Africa 24"); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); pango_layout_get_pixel_extents(layout, &lastInkRect, &lastLogicalRect); cairo_translate(cr, 0, lastInkRect.height); pango_layout_set_markup(layout, "\t\u2022 <span foreground=\"green\"><b>Third</b></span> Hello!", -1); desc = pango_font_description_from_string("Skia 24"); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); g_object_unref(layout); //g_object_unref(font_map); //g_object_unref(context); }
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { DocInfo *dinfo = user_data; cairo_t *cr; gdouble width, height; g_return_if_fail(dinfo != NULL); g_return_if_fail((guint)page_nr < dinfo->pages->len); if (dinfo->pages->len > 0) { gdouble fraction = (page_nr + 1) / (gdouble) dinfo->pages->len; gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr + 1, dinfo->pages->len); 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); } cr = gtk_print_context_get_cairo_context(context); width = gtk_print_context_get_width(context); height = gtk_print_context_get_height(context); if (printing_prefs.print_page_header) add_page_header(dinfo, cr, width, page_nr); dinfo->fr.chrg.cpMin = g_array_index(dinfo->pages, gint, page_nr); if ((guint)page_nr + 1 < dinfo->pages->len) dinfo->fr.chrg.cpMax = g_array_index(dinfo->pages, gint, page_nr + 1) - 1; else /* it's the last page, print 'til the end */ dinfo->fr.chrg.cpMax = sci_get_length(dinfo->sci); scintilla_send_message(dinfo->sci, SCI_FORMATRANGE, TRUE, (sptr_t) &dinfo->fr); /* reset color */ cairo_set_source_rgb(cr, 0, 0, 0); if (printing_prefs.print_line_numbers) { /* print a thin line between the line number margin and the data */ gint y1 = 0, y2 = height; if (printing_prefs.print_page_header) y1 += (dinfo->line_height * 3) - 2; /* "- 2": to connect the line number line to * the page header frame */ if (printing_prefs.print_page_numbers) y2 -= (dinfo->line_height * 2) - 2; cairo_set_line_width(cr, 0.3); cairo_move_to(cr, dinfo->margin_width, y1); cairo_line_to(cr, dinfo->margin_width, y2); 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); } }