gboolean text_to_path (const Text *text, GArray *points) { cairo_t *cr; cairo_surface_t *surface; PangoLayout *layout; PangoRectangle ink_rect; char *str; gboolean ret = FALSE; if (!PANGO_IS_CAIRO_FONT_MAP (pango_context_get_font_map (dia_font_get_context()))) return FALSE; layout = pango_layout_new(dia_font_get_context()); pango_layout_set_font_description (layout, dia_font_get_description (text->font)); pango_layout_set_indent (layout, 0); pango_layout_set_justify (layout, FALSE); pango_layout_set_alignment (layout, text->alignment == ALIGN_LEFT ? PANGO_ALIGN_LEFT : text->alignment == ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_CENTER); str = text_get_string_copy (text); pango_layout_set_text (layout, str, -1); g_free (str); pango_layout_get_extents (layout, &ink_rect, NULL); /* any surface should do - this one is always available */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink_rect.width / PANGO_SCALE, ink_rect.height / PANGO_SCALE); cr = cairo_create (surface); cairo_surface_destroy (surface); pango_cairo_layout_path (cr, layout); /* convert the path */ if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) { cairo_path_t *path; int i; path = cairo_copy_path (cr); for (i=0; i < path->num_data; i += path->data[i].header.length) { cairo_path_data_t *data = &path->data[i]; BezPoint bp; switch (data->header.type) { case CAIRO_PATH_MOVE_TO : bp.type = BEZ_MOVE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; break; case CAIRO_PATH_LINE_TO : bp.type = BEZ_LINE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; break; case CAIRO_PATH_CURVE_TO : bp.type = BEZ_CURVE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; bp.p2.x = data[2].point.x; bp.p2.y = data[2].point.y; bp.p3.x = data[3].point.x; bp.p3.y = data[3].point.y; break; case CAIRO_PATH_CLOSE_PATH : /* can't do anything */ default : continue; } g_array_append_val (points, bp); } ret = (path->status == CAIRO_STATUS_SUCCESS); cairo_path_destroy (path); } /* finally scale it ? */ /* clean up */ g_object_unref (layout); cairo_destroy (cr); return ret; }
static void create_pages (Pqueue * queue) { gchar * msg; gdouble line_height; guint i, id; glong index; PangoLayoutLine * line; PangoRectangle ink_rect, logical_rect; g_return_if_fail (queue); g_return_if_fail (queue->pos < strlen(queue->text)); while (queue->pos < strlen (queue->text)) { while (gtk_events_pending ()) gtk_main_iteration (); for (i = 0; i < queue->lines_per_page; i++) { line = pango_layout_iter_get_line (queue->iter); pango_layout_iter_next_line (queue->iter); pango_layout_iter_get_line_extents (queue->iter, &ink_rect, &logical_rect); index = pango_layout_iter_get_index (queue->iter); if (index == 0) { i = queue->lines_per_page; queue->pos = strlen (queue->text); g_message ("%s", _("Error: Pango iter index is zero.")); continue; } line_height = logical_rect.height / PANGO_SCALE; if ((queue->page_height + line_height) > (queue->height - (EDGE_MARGIN/2))) { queue->pos += index; queue->page_height = EDGE_MARGIN; gtk_progress_bar_pulse (queue->progressbar); pango_cairo_update_layout (queue->cr, queue->layout); queue->layout = make_new_page (queue->context, queue->desc, queue->height, queue->width); i = queue->lines_per_page; queue->page_count++; pango_layout_set_text (queue->layout, (queue->text+queue->pos), -1); queue->iter = pango_layout_get_iter (queue->layout); pango_cairo_show_layout_line (queue->cr, line); pango_cairo_update_layout (queue->cr, queue->layout); cairo_show_page (queue->cr); } else pango_cairo_show_layout_line (queue->cr, line); queue->page_height += line_height; cairo_move_to (queue->cr, SIDE_MARGIN / 2, queue->page_height); } } pango_layout_iter_free (queue->iter); gtk_progress_bar_set_fraction (queue->progressbar, 0.0); cairo_surface_destroy(queue->surface); pango_font_description_free (queue->desc); g_object_unref (queue->context); g_object_unref (queue->layout); cairo_destroy (queue->cr); id = gtk_statusbar_get_context_id (queue->statusbar, PACKAGE); msg = g_strdup_printf (ngettext("Saved PDF file. (%ld page)", "Saved PDF file (%ld pages).", queue->page_count), queue->page_count); gtk_statusbar_push (queue->statusbar, id, msg); g_free (msg); }
gboolean text_get_extents (const gchar *fontname, const gchar *text, gint *width, gint *height, gint *ascent, gint *descent) { PangoFontDescription *font_desc; PangoContext *context; PangoLayout *layout; PangoFontMap *fontmap; PangoRectangle rect; g_return_val_if_fail (fontname != NULL, FALSE); g_return_val_if_fail (text != NULL, FALSE); fontmap = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT); if (! fontmap) g_error ("You are using a Pango that has been built against a cairo " "that lacks the Freetype font backend"); pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), 72.0); /* FIXME: resolution */ context = pango_font_map_create_context (fontmap); g_object_unref (fontmap); layout = pango_layout_new (context); g_object_unref (context); font_desc = pango_font_description_from_string (fontname); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); pango_layout_set_text (layout, text, -1); pango_layout_get_pixel_extents (layout, NULL, &rect); if (width) *width = rect.width; if (height) *height = rect.height; if (ascent || descent) { PangoLayoutIter *iter; PangoLayoutLine *line; iter = pango_layout_get_iter (layout); line = pango_layout_iter_get_line_readonly (iter); pango_layout_iter_free (iter); pango_layout_line_get_pixel_extents (line, NULL, &rect); if (ascent) *ascent = PANGO_ASCENT (rect); if (descent) *descent = - PANGO_DESCENT (rect); } g_object_unref (layout); return TRUE; }
static gboolean draw_callback(GtkWidget *widget,cairo_t *cr,gpointer data) { guint width=gtk_widget_get_allocated_width(widget); guint height=gtk_widget_get_allocated_height(widget); double sw,sh,spacing; //PangoLayout* pn=gtk_widget_create_pango_layout(widget,"HELLO? IS THIS WORKING?(\u2126)"); PangoContext* pc=gtk_widget_get_pango_context(widget); PangoLayout* pn=pango_layout_new(pc); sw=((double)width-2*gutter)/grid.width; sh=((double)height-2*gutter)/grid.height; spacing=MIN(sw,sh); cairo_set_source_rgb(cr,0,0,255); // cairo_arc(cr,mouseX,mouseY,5,0,2*G_PI); cairo_translate(cr,(double)width/2,(double)height/2); cairo_translate(cr,-(double)grid.width/2.0*spacing,-(double)grid.height/2.0*spacing); int i,j; cairo_set_source_rgb(cr,0,0,0); for(i=0;i<grid.map.ccount;i++) { Component* c=grid.map.components+i; int A=c->A; int B=c->B; draw_component(cr,pc,spacing,spacing*(A%(grid.width+1)),spacing*(A/(grid.width+1)),spacing*(B%(grid.width+1)),spacing*(B/(grid.width+1)),c); } cairo_set_source_rgb(cr,0,0,0); char buffer[20]; for(i=0;i<=grid.width;i++) { for(j=0;j<=grid.height;j++) { if(draw_flags&VOLTAGES){ sprintf(buffer,"%.2fV",grid.map.vertices[i+j*(grid.width+1)].voltage); pango_layout_set_text(pn,buffer,-1); int w,h; pango_layout_get_pixel_size(pn,&w,&h); cairo_arc(cr,i*spacing,j*spacing,25,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); cairo_move_to(cr,i*spacing-w/2,j*spacing-h/2); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_new_path(cr); /* sprintf(buffer,"%gV",grid.map.vertices[i+j*(grid.width+1)].voltage); pango_layout_set_text(pn,buffer,-1); int w,h; pango_layout_get_pixel_size(pn,&w,&h); cairo_arc(cr,i*spacing,j*spacing,w/2,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); cairo_move_to(cr,i*spacing-w/2,j*spacing-h/2); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_new_path(cr);*/ }else{ cairo_arc(cr,i*spacing,j*spacing,2,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); } } } //pango_cairo_show_layout(cr,pn); return FALSE; }
void draw_component(cairo_t *cr,PangoContext* pc,double unit,double x1,double y1,double x2,double y2,Component* com) { PangoLayout* pn=pango_layout_new(pc); char buffer[20]; double ang=atan2(y2-y1,x2-x1); if((ang>90&&ang<270)){ ang-=180; } int w=0; int h=0; if(draw_flags&CURRENTS){ sprintf(buffer,"%.3gA",com->current); cairo_move_to(cr,(x1+x2)/2,(y1+y2)/2); pango_layout_set_text(pn,buffer,-1); cairo_save(cr); cairo_translate(cr,(x1+x2)/2,(y1+y2)/2); pango_layout_get_pixel_size(pn,&w,&h); cairo_rotate(cr,ang); cairo_move_to(cr,-w/2,10); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_restore(cr); } if(com->type==WIRE) { cairo_move_to(cr,x1,y1); cairo_line_to(cr,x2,y2); cairo_stroke(cr); return; } if(com->type==RESISTOR) { //char buffer[20]; //sprintf(buffer,"%g\u2126 %gA",*(double*)com->data,com->current); cairo_move_to(cr,x1,y1); cairo_save(cr); cairo_translate(cr,(x1+x2)/2,(y1+y2)/2); /*cairo_move_to(cr,unit*.2,unit*.2); PangoLayout* pn=pango_layout_new(pc); pango_layout_set_text(pn,buffer,-1); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn);*/ cairo_scale(cr,unit,unit); cairo_rotate(cr,atan2(y2-y1,x2-x1)); cairo_line_to(cr,-.25,0); cairo_line_to(cr,-.1875,.125); cairo_line_to(cr,-.0625,-.125); cairo_line_to(cr,.0625,.125); cairo_line_to(cr,.1875,-.125); cairo_line_to(cr,.25,0); cairo_restore(cr); cairo_line_to(cr,x2,y2); cairo_stroke(cr); cairo_save(cr); cairo_translate(cr,(x1+x2)/2,(y1+y2)/2); cairo_rotate(cr,ang); sprintf(buffer,"%g\u2126",*(double*)com->data); pango_layout_set_text(pn,buffer,-1); pango_layout_get_pixel_size(pn,&w,&h); cairo_move_to(cr,-w/2,-h-10); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_restore(cr); cairo_new_path(cr); return; } if(com->type==BATTERY) { if(*(double*)com->data==0){ cairo_save(cr); const double dash[]={10}; cairo_set_dash(cr,dash,1,0); cairo_move_to(cr,x1,y1); cairo_line_to(cr,x2,y2); cairo_stroke(cr); cairo_restore(cr); }else{ if(*(double*)com->data<0){ double tmp=x1; x1=x2; x2=tmp; tmp=y1; y1=y2; y2=tmp; } cairo_move_to(cr,x1,y1); cairo_save(cr); cairo_translate(cr,(x1+x2)/2,(y1+y2)/2); cairo_scale(cr,unit,unit); cairo_rotate(cr,atan2(y2-y1,x2-x1)); cairo_line_to(cr,-.05,0); cairo_move_to(cr,-.05,.25); cairo_line_to(cr,-.05,-.25); cairo_move_to(cr,.05,.15); cairo_line_to(cr,.05,-.15); cairo_move_to(cr,-.15,-.25); cairo_line_to(cr,-.25,-.25); cairo_move_to(cr,-.2,-.2); cairo_line_to(cr,-.2,-.3); cairo_move_to(cr,.05,0); cairo_restore(cr); cairo_line_to(cr,x2,y2); cairo_stroke(cr); } return; } }
bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const { if (!IsOk() || !(GetUnderlined() || GetStrikethrough())) return false; PangoAttrList* attrs = pango_attr_list_new(); PangoAttribute* a; #ifndef __WXGTK3__ if (wx_pango_version_check(1,16,0)) { // a PangoLayout which has leading/trailing spaces with underlined font // is not correctly drawn by this pango version: Pango won't underline the spaces. // This can be a problem; e.g. wxHTML rendering of underlined text relies on // this behaviour. To workaround this problem, we use a special hack here // suggested by pango maintainer Behdad Esfahbod: we prepend and append two // empty space characters and give them a dummy colour attribute. // This will force Pango to underline the leading/trailing spaces, too. const char* text = pango_layout_get_text(layout); const size_t n = strlen(text); if ((n > 0 && text[0] == ' ') || (n > 1 && text[n - 1] == ' ')) { wxCharBuffer buf(n + 6); // copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format memcpy(buf.data(), "\342\200\214", 3); // copy the user string memcpy(buf.data() + 3, text, n); // copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format memcpy(buf.data() + 3 + n, "\342\200\214", 3); pango_layout_set_text(layout, buf, n + 6); // Add dummy attributes (use colour as it's invisible anyhow for 0 // width spaces) to ensure that the spaces in the beginning/end of the // string are underlined too. a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614); a->start_index = 0; a->end_index = 3; pango_attr_list_insert(attrs, a); a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614); a->start_index = n + 3; a->end_index = n + 6; pango_attr_list_insert(attrs, a); } } #endif // !__WXGTK3__ if (GetUnderlined()) { a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pango_attr_list_insert(attrs, a); } if (GetStrikethrough()) { a = pango_attr_strikethrough_new(true); pango_attr_list_insert(attrs, a); } pango_layout_set_attributes(layout, attrs); pango_attr_list_unref(attrs); return true; }
void render_text(GdkDrawable *da, GdkGC *gc, int x, int y, double angle, const char *s, const char *font, double xalign, double yalign, int xmax, int ymax) { GdkScreen *screen; PangoRenderer *renderer; PangoContext *context; PangoLayout *layout; PangoFontDescription *desc; int width, height; PangoMatrix m = PANGO_MATRIX_INIT; double f_min, f; /* set up the renderer */ screen = gdk_drawable_get_screen(da); renderer = gdk_pango_renderer_get_default(screen); gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), da); gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), gc); /* start preparing the layout */ context = gdk_pango_context_get_for_screen(screen); layout = pango_layout_new(context); pango_layout_set_text(layout, s, -1); /* apply the font */ desc = pango_font_description_from_string(font); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); /* align and position the text */ pango_layout_get_size(layout, &width, &height); f_min = 1.0; if (xmax) { f = xmax/((double) width/PANGO_SCALE); if (f < f_min) f_min = f; } if (ymax) { f = ymax/((double) height/PANGO_SCALE); if (f < f_min) f_min = f; } if (f_min < MIN_FONT_SCALE) f_min = MIN_FONT_SCALE; pango_matrix_translate(&m, x, y); pango_matrix_rotate(&m, angle); pango_matrix_translate(&m, -xalign*f_min*width/PANGO_SCALE, (yalign-1)*f_min*height/PANGO_SCALE); pango_matrix_scale(&m, f_min, f_min); pango_context_set_matrix(context, &m); pango_layout_context_changed(layout); pango_renderer_draw_layout(renderer, layout, 0, 0); /* clean up renderer */ gdk_pango_renderer_set_drawable(GDK_PANGO_RENDERER(renderer), NULL); gdk_pango_renderer_set_gc(GDK_PANGO_RENDERER(renderer), NULL); /* free objects */ g_object_unref(layout); g_object_unref(context); }
static void gtk_shruler_draw_ticks (GtkSHRuler *ruler) { GtkWidget *widget = GTK_WIDGET (ruler); GtkStyle *style = gtk_widget_get_style (widget); GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler); GtkStateType state = gtk_widget_get_state (widget); GtkAllocation allocation; cairo_t *cr; gint i; gint width, height; gint xthickness; gint ythickness; gint length; gdouble lower, upper; /* Upper and lower limits, in ruler units */ gdouble increment; /* Number of pixels per unit */ gint scale; /* Number of units per major unit */ gdouble start, end, cur; gchar unit_str[32]; gint digit_height; gint digit_offset; gint text_size; gint pos; gdouble max_size; GtkCMUnit unit; PangoLayout *layout; PangoRectangle logical_rect, ink_rect; if (! gtk_widget_is_drawable (widget)) return; gtk_widget_get_allocation (widget, &allocation); xthickness = style->xthickness; ythickness = style->ythickness; layout = gtk_shruler_get_layout (widget, "0123456789"); pango_layout_get_extents (layout, &ink_rect, &logical_rect); digit_height = PANGO_PIXELS (ink_rect.height) + 2; digit_offset = ink_rect.y; if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; height = allocation.height - ythickness * 2; } else { width = allocation.height; height = allocation.width - ythickness * 2; } cr = cairo_create (priv->backing_store); gdk_cairo_set_source_color (cr, &style->bg[state]); cairo_paint (cr); gdk_cairo_set_source_color (cr, &style->fg[state]); gtk_shruler_get_range (ruler, &lower, &upper, &max_size); if ((upper - lower) == 0) goto out; increment = (gdouble) width / (upper - lower); /* determine the scale * use the maximum extents of the ruler to determine the largest * possible number to be displayed. Calculate the height in pixels * of this displayed text. Use this height to find a scale which * leaves sufficient room for drawing the ruler. * * We calculate the text size as for the vruler instead of * actually measuring the text width, so that the result for the * scale looks consistent with an accompanying vruler. */ scale = ceil (max_size); g_snprintf (unit_str, sizeof (unit_str), "%d", scale); text_size = strlen (unit_str) * digit_height + 1; for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++) if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size) break; if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale)) scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1; unit = gtk_shruler_get_unit (ruler); /* drawing starts here */ length = 0; for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--) { gdouble subd_incr; /* hack to get proper subdivisions at full pixels */ if (unit == CM_UNIT_PIXEL && scale == 1 && i == 1) subd_incr = 1.0; else subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] / (gdouble) ruler_metric.subdivide[i]); if (subd_incr * fabs (increment) <= MINIMUM_INCR) continue; /* don't subdivide pixels */ if (unit == CM_UNIT_PIXEL && subd_incr < 1.0) continue; if (lower < upper) { start = floor (lower / subd_incr) * subd_incr; end = ceil (upper / subd_incr) * subd_incr; } else { start = floor (upper / subd_incr) * subd_incr; end = ceil (lower / subd_incr) * subd_incr; } for (cur = start; cur <= end; cur += subd_incr) { if (((int)cur) % 10 == 0) length = height * 2 / 3; else if (((int)cur) % 5 == 0) length = height / 3; else length = height / 4; pos = ROUND ((cur - lower) * increment); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_rectangle (cr, pos, height + ythickness - length, 1, length); } else { cairo_rectangle (cr, height + xthickness - length, pos, length, 1); } /* draw label */ if (i == 0 && ((int)cur) % 10 == 0) { g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { pango_layout_set_text (layout, unit_str, -1); pango_layout_get_extents (layout, &logical_rect, NULL); cairo_move_to (cr, pos + 2, ythickness + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } else { gint j; for (j = 0; j < (int) strlen (unit_str); j++) { pango_layout_set_text (layout, unit_str + j, 1); pango_layout_get_extents (layout, NULL, &logical_rect); cairo_move_to (cr, xthickness + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } } } } } cairo_fill (cr); out: cairo_destroy (cr); }
void vik_viewport_draw_scale ( VikViewport *vvp ) { g_return_if_fail ( vvp != NULL ); if ( vvp->draw_scale ) { VikCoord left, right; gdouble unit, base, diff, old_unit, old_diff, ratio; gint odd, len, SCSIZE = 5, HEIGHT=10; PangoLayout *pl; gchar s[128]; vik_viewport_screen_to_coord ( vvp, 0, vvp->height, &left ); vik_viewport_screen_to_coord ( vvp, vvp->width/SCSIZE, vvp->height, &right ); vik_units_distance_t dist_units = a_vik_get_units_distance (); switch (dist_units) { case VIK_UNITS_DISTANCE_KILOMETRES: base = vik_coord_diff ( &left, &right ); // in meters break; case VIK_UNITS_DISTANCE_MILES: // in 0.1 miles (copes better when zoomed in as 1 mile can be too big) base = VIK_METERS_TO_MILES(vik_coord_diff ( &left, &right )) * 10.0; break; default: base = 1; // Keep the compiler happy g_critical("Houston, we've had a problem. distance=%d", dist_units); } ratio = (vvp->width/SCSIZE)/base; unit = 1; diff = fabs(base-unit); old_unit = unit; old_diff = diff; odd = 1; while (diff <= old_diff) { old_unit = unit; old_diff = diff; unit = unit * (odd%2 ? 5 : 2); diff = fabs(base-unit); odd++; } unit = old_unit; len = unit * ratio; /* white background */ vik_viewport_draw_line(vvp, vvp->scale_bg_gc, PAD, vvp->height-PAD, PAD + len, vvp->height-PAD); vik_viewport_draw_line(vvp, vvp->scale_bg_gc, PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT); vik_viewport_draw_line(vvp, vvp->scale_bg_gc, PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT); /* black scale */ vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD, vvp->height-PAD, PAD + len, vvp->height-PAD); vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT); vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT); if (odd%2) { int i; for (i=1; i<5; i++) { vik_viewport_draw_line(vvp, vvp->scale_bg_gc, PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); } } else { int i; for (i=1; i<10; i++) { vik_viewport_draw_line(vvp, vvp->scale_bg_gc, PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); } } pl = gtk_widget_create_pango_layout (GTK_WIDGET(&vvp->drawing_area), NULL); pango_layout_set_font_description (pl, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->font_desc); switch (dist_units) { case VIK_UNITS_DISTANCE_KILOMETRES: if (unit >= 1000) { sprintf(s, "%d km", (int)unit/1000); } else { sprintf(s, "%d m", (int)unit); } break; case VIK_UNITS_DISTANCE_MILES: // Handle units in 0.1 miles if (unit < 10.0) { sprintf(s, "%0.1f miles", unit/10.0); } else if ((int)unit == 10.0) { sprintf(s, "1 mile"); } else { sprintf(s, "%d miles", (int)(unit/10.0)); } break; default: g_critical("Houston, we've had a problem. distance=%d", dist_units); } pango_layout_set_text(pl, s, -1); vik_viewport_draw_layout(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc, PAD + len + PAD, vvp->height - PAD - 10, pl); g_object_unref(pl); pl = NULL; } }
static void _paint_lyrics (OlScrollWindow *scroll, cairo_t *cr) { ol_assert (OL_IS_SCROLL_WINDOW (scroll)); GtkWidget *widget = GTK_WIDGET (scroll); ol_assert (GTK_WIDGET_REALIZED (widget)); OlScrollWindowPrivate *priv = OL_SCROLL_WINDOW_GET_PRIVATE (scroll); int line_height = ol_scroll_window_get_font_height (scroll) + priv->line_margin; int count = ol_scroll_window_compute_line_count (scroll); gint width, height; gdk_drawable_get_size (gtk_widget_get_window (GTK_WIDGET (scroll)), &width, &height); /* set the font */ PangoLayout *layout = _get_pango (scroll, cr); /* paint the lyrics*/ cairo_save (cr); cairo_new_path (cr); cairo_rectangle (cr, priv->padding_x, 0, width - priv->padding_x * 2, height - priv->padding_y * 2); cairo_close_path (cr); cairo_clip (cr); int i; gint current_lyric_id; gint lrc_y; _calc_paint_pos (scroll, ¤t_lyric_id, &lrc_y); int begin = current_lyric_id - count / 2; int end = current_lyric_id + count / 2 + 1; int ypos = height / 2 - lrc_y - (count / 2 + 1) * line_height; cairo_set_source_rgb(cr, priv->inactive_color.r, priv->inactive_color.g, priv->inactive_color.b); if (scroll->whole_lyrics != NULL) { for (i = begin; i < end; i++) { ypos += line_height; if (i < 0) continue; if (i >= scroll->whole_lyrics->len) break; pango_layout_set_text (layout, g_ptr_array_index (scroll->whole_lyrics, i), -1); cairo_save (cr); double ratio = _get_active_color_ratio (scroll, i); double alpha = 1.0; if (ypos < line_height / 2.0 + priv->padding_y) alpha = 1.0 - (line_height / 2.0 + priv->padding_y - ypos) * 1.0 / line_height * 2; else if (ypos > height - line_height * 1.5 - priv->padding_y) alpha = (height - line_height - priv->padding_y - ypos) * 1.0 / line_height * 2; if (alpha < 0.0) alpha = 0.0; cairo_set_source_rgba (cr, priv->active_color.r * ratio + priv->inactive_color.r * (1 - ratio), priv->active_color.g * ratio + priv->inactive_color.g * (1 - ratio), priv->active_color.b * ratio + priv->inactive_color.b * (1 - ratio), alpha); cairo_move_to (cr, priv->padding_x, ypos); pango_cairo_update_layout (cr, layout); pango_cairo_show_layout (cr, layout); cairo_restore (cr); } } g_object_unref (layout); cairo_reset_clip (cr); cairo_restore (cr); }
static void gdl_dock_item_grip_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GdlDockItemGrip *grip; GtkContainer *container; GtkRequisition button_requisition = { 0, }; GtkAllocation child_allocation; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (allocation != NULL); grip = GDL_DOCK_ITEM_GRIP (widget); container = GTK_CONTAINER (widget); GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x = allocation->x + container->border_width + ALIGN_BORDER; else child_allocation.x = allocation->x + allocation->width - container->border_width; child_allocation.y = allocation->y + container->border_width; gtk_widget_size_request (grip->_priv->close_button, &button_requisition); if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) child_allocation.x -= button_requisition.width; child_allocation.width = button_requisition.width; child_allocation.height = button_requisition.height; gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x += button_requisition.width; gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) child_allocation.x -= button_requisition.width; child_allocation.width = button_requisition.width; child_allocation.height = button_requisition.height; gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x += button_requisition.width; if (grip->title_window) { GdkRectangle area; /* set layout text */ ensure_title_and_icon_pixbuf (grip); pango_layout_set_text (grip->_priv->title_layout, grip->_priv->title, -1); gdl_dock_item_grip_get_title_area (grip, &area); gdk_window_move_resize (grip->title_window, area.x, area.y, area.width, area.height); if (grip->_priv->icon_pixbuf) area.width -= gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; /* ellipsize title if it doesn't fit the title area */ ellipsize_layout (grip->_priv->title_layout, area.width); } }
static gint gimp_tag_popup_layout_tags (GimpTagPopup *popup, gint width) { PangoFontMetrics *font_metrics; gint x; gint y; gint height = 0; gint i; gint line_height; gint space_width; x = GIMP_TAG_POPUP_MARGIN; y = GIMP_TAG_POPUP_MARGIN; font_metrics = pango_context_get_metrics (popup->context, pango_context_get_font_description (popup->context), NULL); line_height = PANGO_PIXELS ((pango_font_metrics_get_ascent (font_metrics) + pango_font_metrics_get_descent (font_metrics))); space_width = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (font_metrics)); pango_font_metrics_unref (font_metrics); for (i = 0; i < popup->tag_count; i++) { PopupTagData *tag_data = &popup->tag_data[i]; gint w, h; pango_layout_set_text (popup->layout, gimp_tag_get_name (tag_data->tag), -1); pango_layout_get_pixel_size (popup->layout, &w, &h); tag_data->bounds.width = w + 2 * GIMP_TAG_POPUP_PADDING; tag_data->bounds.height = h + 2 * GIMP_TAG_POPUP_PADDING; if (x + space_width + tag_data->bounds.width + GIMP_TAG_POPUP_MARGIN - 1 > width) { x = GIMP_TAG_POPUP_MARGIN; y += line_height + 2 * GIMP_TAG_POPUP_PADDING + GIMP_TAG_POPUP_LINE_SPACING; } tag_data->bounds.x = x; tag_data->bounds.y = y; x += tag_data->bounds.width + space_width; } if (gtk_widget_get_direction (GTK_WIDGET (popup)) == GTK_TEXT_DIR_RTL) { for (i = 0; i < popup->tag_count; i++) { PopupTagData *tag_data = &popup->tag_data[i]; tag_data->bounds.x = (width - tag_data->bounds.x - tag_data->bounds.width); } } height = y + line_height + GIMP_TAG_POPUP_MARGIN; return height; }
static boolean pango_textlayout(textspan_t * span, char **fontpath) { static char buf[1024]; /* returned in fontpath, only good until next call */ static PangoFontMap *fontmap; static PangoContext *context; static PangoFontDescription *desc; static char *fontname; static double fontsize; static gv_font_map* gv_fmap; char *fnt, *psfnt = NULL; PangoLayout *layout; PangoRectangle logical_rect; cairo_font_options_t* options; PangoFont *font; #ifdef ENABLE_PANGO_MARKUP PangoAttrList *attrs; GError *error = NULL; int flags; #endif char *text; double textlayout_scale; PostscriptAlias *pA; if (!context) { fontmap = pango_cairo_font_map_new(); gv_fmap = get_font_mapping(fontmap); #ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT context = pango_font_map_create_context (fontmap); #else context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap)); #endif options=cairo_font_options_create(); cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY); cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON); cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR); pango_cairo_context_set_font_options(context, options); pango_cairo_context_set_resolution(context, FONT_DPI); cairo_font_options_destroy(options); g_object_unref(fontmap); } if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) { fontname = span->font->name; fontsize = span->font->size; pango_font_description_free (desc); pA = span->font->postscript_alias; if (pA) { psfnt = fnt = gv_fmap[pA->xfig_code].gv_font; if(!psfnt) psfnt = fnt = pango_psfontResolve (pA); } else fnt = fontname; desc = pango_font_description_from_string(fnt); /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */ pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE)); if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) { /* -v support */ const char *fontclass; fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font)); buf[0] = '\0'; if (psfnt) { strcat(buf, "(ps:pango "); strcat(buf, psfnt); strcat(buf, ") "); } strcat(buf, "("); strcat(buf, fontclass); strcat(buf, ") "); #ifdef HAVE_PANGO_FC_FONT_LOCK_FACE if (strcmp(fontclass, "PangoCairoFcFont") == 0) { FT_Face face; PangoFcFont *fcfont; FT_Stream stream; FT_StreamDesc streamdesc; fcfont = PANGO_FC_FONT(font); face = pango_fc_font_lock_face(fcfont); if (face) { strcat(buf, "\""); strcat(buf, face->family_name); strcat(buf, ", "); strcat(buf, face->style_name); strcat(buf, "\" "); stream = face->stream; if (stream) { streamdesc = stream->pathname; if (streamdesc.pointer) strcat(buf, (char*)streamdesc.pointer); else strcat(buf, "*no pathname available*"); } else strcat(buf, "*no stream available*"); } pango_fc_font_unlock_face(fcfont); } else #endif { PangoFontDescription *tdesc; char *tfont; tdesc = pango_font_describe(font); tfont = pango_font_description_to_string(tdesc); strcat(buf, "\""); strcat(buf, tfont); strcat(buf, "\" "); g_free(tfont); } *fontpath = buf; } } #ifdef ENABLE_PANGO_MARKUP if ((span->font) && (flags = span->font->flags)) { unsigned char buf[BUFSIZ]; agxbuf xb; agxbinit(&xb, BUFSIZ, buf); agxbput(&xb,"<span"); if (flags & HTML_BF) agxbput(&xb," weight=\"bold\""); if (flags & HTML_IF) agxbput(&xb," style=\"italic\""); if (flags & HTML_UL) agxbput(&xb," underline=\"single\""); if (flags & HTML_S) agxbput(&xb," strikethrough=\"true\""); agxbput (&xb,">"); if (flags & HTML_SUP) agxbput(&xb,"<sup>"); if (flags & HTML_SUB) agxbput(&xb,"<sub>"); agxbput (&xb,xml_string0(span->str, TRUE)); if (flags & HTML_SUB) agxbput(&xb,"</sub>"); if (flags & HTML_SUP) agxbput(&xb,"</sup>"); agxbput (&xb,"</span>"); if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) { fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message); text = span->str; attrs = NULL; } agxbfree (&xb); } else { text = span->str; attrs = NULL; } #else text = span->str; #endif layout = pango_layout_new (context); span->layout = (void *)layout; /* layout free with textspan - see labels.c */ span->free_layout = pango_free_layout; /* function for freeing pango layout */ pango_layout_set_text (layout, text, -1); pango_layout_set_font_description (layout, desc); #ifdef ENABLE_PANGO_MARKUP if (attrs) pango_layout_set_attributes (layout, attrs); #endif pango_layout_get_extents (layout, NULL, &logical_rect); /* if pango doesn't like the font then it sets width=0 but height = garbage */ if (logical_rect.width == 0) logical_rect.height = 0; textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE); span->size.x = (int)(logical_rect.width * textlayout_scale + 1); /* round up so that width/height are never too small */ span->size.y = (int)(logical_rect.height * textlayout_scale + 1); /* FIXME -- Horrible kluge !!! */ /* For now we are using pango for single line blocks only. * The logical_rect.height seems to be too high from the font metrics on some platforms. * Use an assumed height based on the point size. */ span->size.y = (int)(span->font->size * 1.1 + .5); /* The y offset from baseline to 0,0 of the bitmap representation */ #if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1) span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale; #else { /* do it the hard way on rhel5/centos5 */ PangoLayoutIter *iter = pango_layout_get_iter (layout); span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale; } #endif /* The distance below midline for y centering of text strings */ span->yoffset_centerline = 0.2 * span->font->size; if (logical_rect.width == 0) return FALSE; return TRUE; }
unsigned Gosu::pango::textWidth(const std::wstring& text, const std::wstring& fontFace, unsigned fontHeight, unsigned fontFlags) { g_type_init(); int dpi_x = 100, dpi_y = 100; context = pango_ft2_get_context(dpi_x, dpi_y); pango_context_set_language(context, pango_language_from_string ("en_US")); PangoDirection init_dir = PANGO_DIRECTION_LTR; pango_context_set_base_dir(context, init_dir); // static PangoFontDescription *font_description; font_description = pango_font_description_new(); pango_font_description_set_family(font_description, g_strdup(narrow(fontFace).c_str())); pango_font_description_set_style(font_description, (fontFlags & ffItalic) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); pango_font_description_set_variant(font_description, PANGO_VARIANT_NORMAL); pango_font_description_set_weight(font_description, (fontFlags & ffBold) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL); pango_font_description_set_stretch(font_description, PANGO_STRETCH_NORMAL); int init_scale = int(fontHeight/2.0 + 0.5); pango_font_description_set_size(font_description, init_scale * PANGO_SCALE); pango_context_set_font_description(context, font_description); layout = pango_layout_new(context); if(fontFlags & ffUnderline) { // PangoAttribute *attr; attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); attr->start_index = 0; attr->end_index = text.length(); // PangoAttrList* attrList; attrList = pango_attr_list_new(); pango_attr_list_insert(attrList, attr); pango_layout_set_attributes(layout, attrList); pango_attr_list_unref(attrList); } // IMPR: Catch errors? (Last NULL-Pointer) gchar* utf8Str = g_ucs4_to_utf8((gunichar*)text.c_str(), text.length(), NULL, NULL, NULL); pango_layout_set_text(layout, utf8Str, -1); g_free(utf8Str); PangoDirection base_dir = pango_context_get_base_dir(context); pango_layout_set_alignment(layout, base_dir == PANGO_DIRECTION_LTR ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT); pango_layout_set_width(layout, -1); PangoRectangle logical_rect; pango_layout_get_pixel_extents(layout, NULL, &logical_rect); height = logical_rect.height; width = logical_rect.width; return width; }
/* Redraw the vertical ruler */ static gboolean histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { histoDrawing_t *drawing = (histoDrawing_t*)user_data; HistoControlFlowData *histo_cfv = drawing->histo_control_flow_data; gchar text[255]; PangoContext *context; PangoLayout *layout; PangoFontDescription *FontDesc; PangoRectangle ink_rect; gint global_height=0; GdkColor foreground = { 0, 0, 0, 0 }; GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; GdkColor red ={ 0, 0xFFFF, 0x1E00, 0x1000 }; //GdkColor magneta ={ 0, 0x8900, 0x0000, 0x8400 }; g_debug("vertical ruler expose event"); gdk_draw_rectangle (drawing->vertical_ruler->window, drawing->vertical_ruler->style->white_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, padding_width-1/*event->area.width-1*/,event->area.y, padding_width-1/*event->area.width-1*/,event->area.y + event->area.height); snprintf(text, 255, "%.1f", (float)histo_cfv->max_height); layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); context = pango_layout_get_context(layout); FontDesc = pango_context_get_font_description(context); pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); pango_layout_context_changed(layout); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, 1, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_round, drawing->vertical_ruler-> allocation.width-1, 1, drawing->vertical_ruler-> allocation.width-7, 1); snprintf(text, 255, "%d", 0); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if(global_height <= drawing->vertical_ruler->allocation.height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, drawing->vertical_ruler->allocation.height - ink_rect.height-2, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, drawing->vertical_ruler-> allocation.width-1, drawing->vertical_ruler->allocation.height-1, drawing->vertical_ruler-> allocation.width-7, drawing->vertical_ruler->allocation.height-1); } snprintf(text, 255, "%.1f",(float) histo_cfv->max_height/2.0); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if(global_height <= drawing->vertical_ruler->allocation.height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/2, layout, &foreground, &background); gdk_draw_line (drawing->vertical_ruler->window, drawing->ruler_gc_butt, drawing->vertical_ruler-> allocation.width-1, drawing->vertical_ruler-> allocation.height/2, drawing->vertical_ruler-> allocation.width-7, drawing->vertical_ruler->allocation.height/2); } //show number of events at current time: LttTime current_time = lttvwindow_get_current_time(histo_cfv->tab); TimeWindow time_window = lttvwindow_get_time_window(histo_cfv->tab); LttTime time_begin = time_window.start_time; LttTime time_width = time_window.time_width; LttTime time_end = ltt_time_add(time_begin, time_width); if((ltt_time_compare(current_time, time_begin) >= 0)&& (ltt_time_compare(current_time, time_end) <= 0)) { guint *events_at_currenttime; guint max_height=histo_cfv ->max_height; guint x; histo_convert_time_to_pixels( time_window, current_time, drawing->width, &x); // if(x_test<histo_cfv->number_of_process->len) { events_at_currenttime = &g_array_index(histo_cfv->number_of_process,guint,x); if((*events_at_currenttime) > max_height) { snprintf(text, 255, "OverFlow!"); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/5, layout, &red, &background); }else // if((*events_at_currenttime) <= max_height) { snprintf(text, 255, "%.1f", (float) *events_at_currenttime); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_height += ink_rect.height; if ((*events_at_currenttime) == 0) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)-2, layout, &red, &background); } else if ((*events_at_currenttime) == max_height) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, 1, layout, &red, &background); } /*else if ((*events_at_currenttime) == max_height/2) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/2, layout, &red, &background); }*/ else if ((*events_at_currenttime) > max_height/2) { gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, (drawing->vertical_ruler->allocation.height - ink_rect.height)/4, layout, &red, &background); } else{ gdk_draw_layout_with_colors(drawing->vertical_ruler->window, drawing->ruler_gc_butt, 1, ((drawing->vertical_ruler->allocation.height - ink_rect.height)*3)/4, layout, &red, &background); } } } } g_object_unref(layout); return FALSE; }
static void gimp_ruler_draw_ticks (GimpRuler *ruler) { GtkWidget *widget = GTK_WIDGET (ruler); GtkStyleContext *context = gtk_widget_get_style_context (widget); GimpRulerPrivate *priv = GIMP_RULER_GET_PRIVATE (ruler); GtkAllocation allocation; GtkBorder border; GdkRGBA color; cairo_t *cr; gint i; gint width, height; gint length, ideal_length; gdouble lower, upper; /* Upper and lower limits, in ruler units */ gdouble increment; /* Number of pixels per unit */ gint scale; /* Number of units per major unit */ gdouble start, end, cur; gchar unit_str[32]; gint digit_height; gint digit_offset; gint text_size; gint pos; gdouble max_size; GimpUnit unit; PangoLayout *layout; PangoRectangle logical_rect, ink_rect; if (! gtk_widget_is_drawable (widget)) return; gtk_widget_get_allocation (widget, &allocation); gtk_style_context_get_border (context, 0, &border); layout = gimp_ruler_get_layout (widget, "0123456789"); pango_layout_get_extents (layout, &ink_rect, &logical_rect); digit_height = PANGO_PIXELS (ink_rect.height) + 2; digit_offset = ink_rect.y; if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; height = allocation.height - (border.top + border.bottom); } else { width = allocation.height; height = allocation.width - (border.top + border.bottom); } cr = cairo_create (priv->backing_store); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &color); gdk_cairo_set_source_rgba (cr, &color); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_rectangle (cr, border.left, height + border.top, allocation.width - (border.left + border.right), 1); } else { cairo_rectangle (cr, height + border.left, border.top, 1, allocation.height - (border.top + border.bottom)); } gimp_ruler_get_range (ruler, &lower, &upper, &max_size); if ((upper - lower) == 0) goto out; increment = (gdouble) width / (upper - lower); /* determine the scale * use the maximum extents of the ruler to determine the largest * possible number to be displayed. Calculate the height in pixels * of this displayed text. Use this height to find a scale which * leaves sufficient room for drawing the ruler. * * We calculate the text size as for the vruler instead of * actually measuring the text width, so that the result for the * scale looks consistent with an accompanying vruler. */ scale = ceil (max_size); g_snprintf (unit_str, sizeof (unit_str), "%d", scale); text_size = strlen (unit_str) * digit_height + 1; for (scale = 0; scale < (gint)G_N_ELEMENTS (ruler_metric.ruler_scale); scale++) if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size) break; if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale)) scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1; unit = gimp_ruler_get_unit (ruler); /* drawing starts here */ length = 0; for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--) { gdouble subd_incr; /* hack to get proper subdivisions at full pixels */ if (unit == GIMP_UNIT_PIXEL && scale == 1 && i == 1) subd_incr = 1.0; else subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] / (gdouble) ruler_metric.subdivide[i]); if (subd_incr * fabs (increment) <= MINIMUM_INCR) continue; /* don't subdivide pixels */ if (unit == GIMP_UNIT_PIXEL && subd_incr < 1.0) continue; /* Calculate the length of the tickmarks. Make sure that * this length increases for each set of ticks */ ideal_length = height / (i + 1) - 1; if (ideal_length > ++length) length = ideal_length; if (lower < upper) { start = floor (lower / subd_incr) * subd_incr; end = ceil (upper / subd_incr) * subd_incr; } else { start = floor (upper / subd_incr) * subd_incr; end = ceil (lower / subd_incr) * subd_incr; } for (cur = start; cur <= end; cur += subd_incr) { pos = ROUND ((cur - lower) * increment); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_rectangle (cr, pos, height + border.top - length, 1, length); } else { cairo_rectangle (cr, height + border.left - length, pos, length, 1); } /* draw label */ if (i == 0) { g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { pango_layout_set_text (layout, unit_str, -1); pango_layout_get_extents (layout, &logical_rect, NULL); cairo_move_to (cr, pos + 2, border.top + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } else { gint j; for (j = 0; j < (int) strlen (unit_str); j++) { pango_layout_set_text (layout, unit_str + j, 1); pango_layout_get_extents (layout, NULL, &logical_rect); cairo_move_to (cr, border.left + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } } } } } cairo_fill (cr); priv->backing_store_valid = TRUE; out: cairo_destroy (cr); }
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 gboolean gcal_week_view_draw_hours (GcalWeekView *self, cairo_t *cr, GtkWidget *widget) { GtkStyleContext *context; GtkStateFlags state; GtkBorder padding; GdkRGBA color; gboolean ltr; gint i, width, height; gint font_width; PangoLayout *layout; PangoFontDescription *font_desc; context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; gtk_style_context_save (context); gtk_style_context_add_class (context, "hours"); gtk_style_context_get_color (context, state, &color); gtk_style_context_get_padding (context, state, &padding); gtk_style_context_get (context, state, "font", &font_desc, NULL); layout = pango_cairo_create_layout (cr); pango_layout_set_font_description (layout, font_desc); gdk_cairo_set_source_rgba (cr, &color); /* Gets the size of the widget */ width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); /* Draws the hours in the sidebar */ for (i = 0; i < 24; i++) { gchar *hours; if (self->use_24h_format) { hours = g_strdup_printf ("%02d:00", i); } else { hours = g_strdup_printf ("%d %s", i % 12 == 0 ? 12 : i % 12, i > 12 ? _("PM") : _("AM")); } pango_layout_set_text (layout, hours, -1); pango_layout_get_pixel_size (layout, &font_width, NULL); gtk_render_layout (context, cr, ltr ? padding.left : width - font_width - padding.right, (height / 24) * i + padding.top, layout); g_free (hours); } gtk_style_context_restore (context); gtk_style_context_save (context); gtk_style_context_add_class (context, "lines"); gtk_style_context_get_color (context, state, &color); gdk_cairo_set_source_rgba (cr, &color); cairo_set_line_width (cr, 0.65); if (!ltr) { cairo_move_to (cr, 0.5, 0); cairo_rel_line_to (cr, 0, height); } /* Draws the horizontal complete lines */ for (i = 1; i < 24; i++) { cairo_move_to (cr, 0, (height / 24) * i + 0.4); cairo_rel_line_to (cr, width, 0); } cairo_stroke (cr); cairo_set_dash (cr, dashed, 2, 0); /* Draws the horizontal dashed lines */ for (i = 0; i < 24; i++) { cairo_move_to (cr, 0, (height / 24) * i + (height / 48) + 0.4); cairo_rel_line_to (cr, width, 0); } cairo_stroke (cr); gtk_style_context_restore (context); pango_font_description_free (font_desc); g_object_unref (layout); return FALSE; }
static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE); GtkDarktableToggleButton *button = DTGTK_TOGGLEBUTTON(widget); GtkStateFlags state = gtk_widget_get_state_flags(widget); GdkRGBA bg_color, fg_color; GtkStyleContext *context = gtk_widget_get_style_context(widget); if(button->icon_flags & CPF_CUSTOM_BG) bg_color = button->bg; else gtk_style_context_get_background_color(context, state, &bg_color); if(button->icon_flags & CPF_CUSTOM_FG) fg_color = button->fg; else gtk_style_context_get_color(context, state, &fg_color); /* fetch flags */ int flags = DTGTK_TOGGLEBUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* update active state paint flag */ gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if(active) flags |= CPF_ACTIVE; else flags &= ~(CPF_ACTIVE); /* prelight */ if(state & GTK_STATE_FLAG_PRELIGHT) flags |= CPF_PRELIGHT; else flags &= ~CPF_PRELIGHT; /* begin cairo drawing */ GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent nor flat styled */ if((flags & CPF_STYLE_FLAT)) { if(flags & CPF_PRELIGHT || flags & CPF_ACTIVE) { cairo_rectangle(cr, 0, 0, width, height); gdk_cairo_set_source_rgba(cr, &bg_color); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { /* draw default boxed button */ gtk_render_background(context, cr, 0, 0, width, height); if(!(flags & CPF_DO_NOT_USE_BORDER)) gtk_render_frame(context, cr, 0, 0, width, height); } /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } gdk_cairo_set_source_rgba(cr, &fg_color); /* draw icon */ if(DTGTK_TOGGLEBUTTON(widget)->icon) { // if (flags & CPF_IGNORE_FG_STATE) // state = GTK_STATE_NORMAL; int icon_width = text ? height - (border * 2) : width - (border * 2); int icon_height = height - (border * 2); if(icon_width > 0 && icon_height > 0) { if(text) DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags); else DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags); } } /* draw label */ if(text) { int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0)); // if (DTGTK_TOGGLEBUTTON (widget)->icon) lx += width; // GdkRectangle t={x,y,x+width,y+height}; // gtk_paint_layout(style,gtk_widget_get_window(widget), // state,TRUE,&t,widget,"togglebutton",lx,ly,layout); cairo_translate(cr, lx, ly); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return FALSE; }
static gboolean lowlight_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data; dt_iop_lowlight_params_t p = *(dt_iop_lowlight_params_t *)self->params; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); const int inset = DT_IOP_LOWLIGHT_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); cairo_set_source_rgb(cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2 * inset; height -= 2 * inset; cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); cairo_set_source_rgb(cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw grid cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4)); cairo_set_source_rgb(cr, .1, .1, .1); dt_draw_grid(cr, 8, 0, 0, width, height); if(c->mouse_y > 0 || c->dragging) { // draw min/max curves: dt_iop_lowlight_get_params(&p, c->mouse_x, 1., c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_min_xs, c->draw_min_ys); p = *(dt_iop_lowlight_params_t *)self->params; dt_iop_lowlight_get_params(&p, c->mouse_x, .0, c->mouse_radius); dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_max_xs, c->draw_max_ys); } cairo_save(cr); // draw x positions cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_move_to(cr, width * p.transition_x[k], height + inset - DT_PIXEL_APPLY_DPI(1)); cairo_rel_line_to(cr, -arrw * .5f, 0); cairo_rel_line_to(cr, arrw * .5f, -arrw); cairo_rel_line_to(cr, arrw * .5f, arrw); cairo_close_path(cr); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } // draw selected cursor cairo_translate(cr, 0, height); // cairo_set_operator(cr, CAIRO_OPERATOR_ADD); // cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.)); cairo_set_source_rgba(cr, .7, .7, .7, 1.0); p = *(dt_iop_lowlight_params_t *)self->params; dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0, p.transition_y[0]); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]); dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0, p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]); dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_xs, c->draw_ys); cairo_move_to(cr, 0 * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[k]); cairo_stroke(cr); // draw dots on knots cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++) { cairo_arc(cr, width * p.transition_x[k], -height * p.transition_y[k], DT_PIXEL_APPLY_DPI(3.0), 0.0, 2.0 * M_PI); if(c->x_move == k) cairo_fill(cr); else cairo_stroke(cr); } if(c->mouse_y > 0 || c->dragging) { // draw min/max, if selected cairo_set_source_rgba(cr, .7, .7, .7, .6); cairo_move_to(cr, 0, -height * c->draw_min_ys[0]); for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_min_ys[k]); for(int k = DT_IOP_LOWLIGHT_RES - 1; k >= 0; k--) cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_max_ys[k]); cairo_close_path(cr); cairo_fill(cr); // draw mouse focus circle cairo_set_source_rgba(cr, .9, .9, .9, .5); const float pos = DT_IOP_LOWLIGHT_RES * c->mouse_x; int k = (int)pos; const float f = k - pos; if(k >= DT_IOP_LOWLIGHT_RES - 1) k = DT_IOP_LOWLIGHT_RES - 2; float ht = -height * (f * c->draw_ys[k] + (1 - f) * c->draw_ys[k + 1]); cairo_arc(cr, c->mouse_x * width, ht, c->mouse_radius * width, 0, 2. * M_PI); cairo_stroke(cr); } cairo_restore(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // draw labels: PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_absolute_size(desc,(.06 * height) * PANGO_SCALE); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, desc); cairo_set_source_rgb(cr, .1, .1, .1); pango_layout_set_text(layout, _("dark"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .02 * width - ink.y, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("bright"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .98 * width - ink.height, .5 * (height + ink.width)); cairo_save(cr); cairo_rotate(cr, -M_PI * .5f); pango_cairo_show_layout(cr, layout); cairo_restore(cr); pango_layout_set_text(layout, _("day vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .08 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_layout_set_text(layout, _("night vision"), -1); pango_layout_get_pixel_extents(layout, &ink, NULL); cairo_move_to(cr, .5 * (width - ink.width), .97 * height - ink.height); pango_cairo_show_layout(cr, layout); pango_font_description_free(desc); g_object_unref(layout); cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
static void draw_cell (Hitori *hitori, GtkStyleContext *style_context, cairo_t *cr, gfloat cell_size, gdouble x_pos, gdouble y_pos, HitoriVector iter) { gchar *text; PangoLayout *layout; gint text_width, text_height; GtkStateFlags state; gboolean painted = FALSE; PangoFontDescription *font_desc; GtkBorder border; GdkRGBA colour = {0.0, 0.0, 0.0, 0.0}; state = gtk_style_context_get_state (style_context); if (hitori->board[iter.x][iter.y].status & CELL_PAINTED) { painted = TRUE; state = GTK_STATE_FLAG_INSENSITIVE; gtk_style_context_set_state (style_context, state); } /* Set up the border */ gtk_style_context_get_border (style_context, state, &border); border.left = BORDER_LEFT; /* Hack! */ /* Draw the fill */ if (hitori->debug == TRUE) { g_debug ("State: %u", state); } if (painted) { lookup_color (style_context, "painted-bg-color", &colour); } else { lookup_color (style_context, "unpainted-bg-color", &colour); } gdk_cairo_set_source_rgba (cr, &colour); cairo_rectangle (cr, x_pos, y_pos, cell_size, cell_size); cairo_fill (cr); /* If the cell is tagged, draw the tag dots */ if (hitori->board[iter.x][iter.y].status & CELL_TAG1) { if (painted) { lookup_color (style_context, "tag1-painted-color", &colour); } else { lookup_color (style_context, "tag1-unpainted-color", &colour); } gdk_cairo_set_source_rgba (cr, &colour); cairo_move_to (cr, x_pos, y_pos + TAG_OFFSET); cairo_line_to (cr, x_pos, y_pos); cairo_line_to (cr, x_pos + TAG_OFFSET, y_pos); cairo_arc (cr, x_pos + TAG_OFFSET, y_pos + TAG_OFFSET, TAG_RADIUS * cell_size, 0.0, 0.5 * M_PI); cairo_fill (cr); } if (hitori->board[iter.x][iter.y].status & CELL_TAG2) { if (painted) { lookup_color (style_context, "tag2-painted-color", &colour); } else { lookup_color (style_context, "tag2-unpainted-color", &colour); } gdk_cairo_set_source_rgba (cr, &colour); cairo_move_to (cr, x_pos + cell_size - TAG_OFFSET, y_pos); cairo_line_to (cr, x_pos + cell_size, y_pos); cairo_line_to (cr, x_pos + cell_size, y_pos + TAG_OFFSET); cairo_arc (cr, x_pos + cell_size - TAG_OFFSET, y_pos + TAG_OFFSET, TAG_RADIUS * cell_size, 0.5 * M_PI, 1.0 * M_PI); cairo_fill (cr); } /* Draw the border */ if (painted) { lookup_color (style_context, "painted-border-color", &colour); } else { lookup_color (style_context, "unpainted-border-color", &colour); } gdk_cairo_set_source_rgba (cr, &colour); cairo_set_line_width (cr, border.left); cairo_rectangle (cr, x_pos, y_pos, cell_size, cell_size); cairo_stroke (cr); /* Draw the text */ text = g_strdup_printf ("%u", hitori->board[iter.x][iter.y].num); layout = pango_cairo_create_layout (cr); pango_layout_set_text (layout, text, -1); font_desc = (painted == TRUE) ? hitori->painted_font_desc : hitori->normal_font_desc; if (hitori->board[iter.x][iter.y].status & CELL_ERROR) { lookup_color (style_context, "mistaken-number-color", &colour); gdk_cairo_set_source_rgba (cr, &colour); pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); } else if (painted) { lookup_color (style_context, "painted-number-color", &colour); gdk_cairo_set_source_rgba (cr, &colour); pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL); } else { g_assert (!painted); lookup_color (style_context, "unpainted-number-color", &colour); gdk_cairo_set_source_rgba (cr, &colour); pango_font_description_set_weight (font_desc, PANGO_WEIGHT_NORMAL); } pango_layout_set_font_description (layout, font_desc); pango_layout_get_pixel_size (layout, &text_width, &text_height); cairo_move_to (cr, x_pos + (cell_size - text_width) / 2, y_pos + (cell_size - text_height) / 2); pango_cairo_show_layout (cr, layout); g_free (text); g_object_unref (layout); }
static gboolean draw (GtkWidget *widget, cairo_t *cr, gpointer data) { GtkAllocation allocation; GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); PangoContext *widget_context; PangoFontDescription *font_desc; PangoLayout *layout; PangoRectangle logical_rect; GLfloat text_w, text_h; GLfloat tangent_h; gtk_widget_get_allocation (widget, &allocation); /* Font */ widget_context = gtk_widget_get_pango_context (widget); font_desc = pango_context_get_font_description (widget_context); pango_font_description_set_size (font_desc, 24 * PANGO_SCALE); pango_context_set_font_description (ft2_context, font_desc); /* Text layout */ layout = pango_layout_new (ft2_context); pango_layout_set_width (layout, PANGO_SCALE * allocation.width); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_text (layout, text, -1); /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCallList (1); /* Text color */ glColor3f (1.0, 0.9, 0.0); /* Text position */ pango_layout_get_extents (layout, NULL, &logical_rect); text_w = PANGO_PIXELS (logical_rect.width); text_h = PANGO_PIXELS (logical_rect.height); /* * tangent = Z_NEAR * tan (FOVY_2 * G_PI / 180.0) * w = allocation.width * h = allocation.height * * x = -1.0 * (text_w/w) * tangent * (w/h) = -text_w * tangent / h * y = -1.0 * (text_h/h) * tangent = -text_h * tangent / h * z = Z_NEAR */ tangent_h = Z_NEAR * tan (FOVY_2 * G_PI / 180.0); tangent_h /= allocation.height; glRasterPos3f (-text_w * tangent_h, -text_h * tangent_h, Z_NEAR); /* Render text */ gl_pango_ft2_render_layout (layout); if (gdk_gl_drawable_is_double_buffered (gldrawable)) gdk_gl_drawable_swap_buffers (gldrawable); else glFlush (); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ g_object_unref (G_OBJECT (layout)); return TRUE; }
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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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 gboolean gimp_tag_popup_list_expose (GtkWidget *widget, GdkEventExpose *event, GimpTagPopup *popup) { GdkWindow *window = gtk_widget_get_window (widget); GtkStyle *style = gtk_widget_get_style (widget); cairo_t *cr; PangoAttribute *attribute; PangoAttrList *attributes; gint i; cr = gdk_cairo_create (event->window); gdk_cairo_region (cr, event->region); cairo_clip (cr); cairo_set_line_width (cr, 1.0); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); for (i = 0; i < popup->tag_count; i++) { PopupTagData *tag_data = &popup->tag_data[i]; pango_layout_set_text (popup->layout, gimp_tag_get_name (tag_data->tag), -1); switch (tag_data->state) { case GTK_STATE_SELECTED: attributes = pango_attr_list_copy (popup->combo_entry->selected_item_attr); break; case GTK_STATE_INSENSITIVE: attributes = pango_attr_list_copy (popup->combo_entry->insensitive_item_attr); break; default: attributes = pango_attr_list_copy (popup->combo_entry->normal_item_attr); break; } if (tag_data == popup->prelight && tag_data->state != GTK_STATE_INSENSITIVE) { attribute = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); pango_attr_list_insert (attributes, attribute); } pango_layout_set_attributes (popup->layout, attributes); pango_attr_list_unref (attributes); if (tag_data->state == GTK_STATE_SELECTED) { gdk_cairo_set_source_color (cr, &popup->combo_entry->selected_item_color); cairo_rectangle (cr, tag_data->bounds.x - 1, tag_data->bounds.y - popup->scroll_y, tag_data->bounds.width + 2, tag_data->bounds.height); cairo_fill (cr); cairo_translate (cr, 0.5, 0.5); cairo_move_to (cr, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y - 1); cairo_line_to (cr, tag_data->bounds.x + tag_data->bounds.width - 1, tag_data->bounds.y - popup->scroll_y - 1); cairo_move_to (cr, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y + tag_data->bounds.height); cairo_line_to (cr, tag_data->bounds.x + tag_data->bounds.width - 1, tag_data->bounds.y - popup->scroll_y + tag_data->bounds.height); cairo_stroke (cr); cairo_translate (cr, -0.5, -0.5); } cairo_move_to (cr, (tag_data->bounds.x + GIMP_TAG_POPUP_PADDING), (tag_data->bounds.y - popup->scroll_y + GIMP_TAG_POPUP_PADDING)); pango_cairo_show_layout (cr, popup->layout); if (tag_data == popup->prelight && tag_data->state != GTK_STATE_INSENSITIVE && ! popup->single_select_disabled) { gtk_paint_focus (style, window, tag_data->state, &event->area, widget, NULL, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y, tag_data->bounds.width, tag_data->bounds.height); } } cairo_destroy (cr); return FALSE; }
static void gtk_plot_gdk_draw_string (GtkPlotPC *pc, gint tx, gint ty, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font_name, gint font_height, GtkJustification just, const gchar *text) { GdkGC *gc; GList *family = NULL; gint x0, y0; gint old_width, old_height; gboolean bold, italic; gint fontsize; gint ascent, descent; gint numf; gint width, height; gint x, y; gint i; PangoFontDescription *font = NULL, *latin_font = NULL; GtkPSFont *psfont, *base_psfont, *latin_psfont; gchar subs[2], insert_char; const gchar *aux = text; const gchar *lastchar = text; const gchar *wtext = text; const gchar *xaux = text; gchar new_text[strlen(text)+1]; gchar num[4]; PangoRectangle rect; PangoFontMetrics *metrics = NULL; PangoLayout *layout = NULL; gint real_x, real_y, real_width, real_height; GdkColor real_fg = *fg; GdkColor real_bg = *bg; PangoMatrix matrix = PANGO_MATRIX_INIT; PangoContext *context = GTK_PLOT_GDK(pc)->context; GdkDrawable *drawable = GTK_PLOT_GDK(pc)->drawable; gint sign_x = 1, sign_y = 0; if(!GTK_PLOT_GDK(pc)->drawable) return; if(!GTK_PLOT_GDK(pc)->gc) return; if(!text || strlen(text) == 0) return; gc = GTK_PLOT_GDK(pc)->gc; layout = GTK_PLOT_GDK(pc)->layout; if(!gc) return; gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent); if(height == 0 || width == 0) return; old_width = width; old_height = height; if(angle == 90 || angle == 270) { old_width = height; old_height = width; } switch(angle){ case 90: sign_x = 0; sign_y = -1; break; case 180: sign_x = -1; sign_y = 0; break; case 270: sign_x = 0; sign_y = 1; break; case 0: default: sign_x = 1; sign_y = 0; break; } switch(just){ case GTK_JUSTIFY_LEFT: switch(angle){ case 0: ty -= ascent; break; case 90: ty -= height; tx -= ascent; break; case 180: tx -= width; ty -= descent; break; case 270: tx -= descent; break; } break; case GTK_JUSTIFY_RIGHT: switch(angle){ case 0: tx -= width; ty -= ascent; break; case 90: tx -= ascent; ty += height; break; case 180: tx += width; ty -= descent; break; case 270: tx -= descent; break; } break; case GTK_JUSTIFY_CENTER: default: switch(angle){ case 0: tx -= width / 2.; ty -= ascent; break; case 90: tx -= ascent; ty += height / 2.; break; case 180: tx += width / 2.; ty -= descent; break; case 270: tx -= descent; ty -= height / 2.; break; } } real_x = tx; real_y = ty; real_width = width; real_height = height; pango_matrix_rotate (&matrix, angle); pango_context_set_matrix (context, &matrix); pango_layout_context_changed (layout); if(!transparent){ gdk_gc_set_foreground(gc, &real_bg); gdk_draw_rectangle(drawable, gc, TRUE, tx, ty, old_width, old_height); } /* TEST */ /* gdk_draw_rectangle(text_pixmap, gc, FALSE, 0, 0, old_width-1, old_height-1); */ gtk_psfont_get_families(&family, &numf); base_psfont = psfont = gtk_psfont_get_by_name(font_name); font = gtk_psfont_get_font_description(psfont, font_height); italic = psfont->italic; bold = psfont->bold; fontsize = font_height; x0 = x = 0; y0 = y = 0; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } else { latin_psfont = NULL; latin_font = NULL; } gdk_gc_set_foreground(gc, &real_fg); aux = text; while(aux && *aux != '\0' && *aux != '\n'){ if(*aux == '\\'){ aux = g_utf8_next_char(aux); switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); aux = g_utf8_next_char(aux); break; case '8': case 'g': psfont = gtk_psfont_get_by_family("Symbol", italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); aux = g_utf8_next_char(aux); break; case 'B': bold = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(latin_font){ latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux = g_utf8_next_char(aux); break; } num[3] = '\0'; insert_char = (gchar)atoi(num); subs[0] = insert_char; subs[1] = '\0'; pango_layout_set_font_description(layout, font); pango_layout_set_text(layout, subs, 1); pango_layout_get_extents(layout, NULL, &rect); x += sign_x*PANGO_PIXELS(rect.width); y += sign_y*PANGO_PIXELS(rect.width); aux += 4; lastchar = aux - 1; break; case 'i': italic = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); if(latin_font) pango_font_description_free(latin_font); latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'S': case '^': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(metrics) pango_font_metrics_unref(metrics); metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout))); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } if(angle == 180) y = y0 + fontsize; else if(angle == 270) x = x0 + sign_y*fontsize; aux = g_utf8_next_char(aux); break; case 's': case '_': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(metrics) pango_font_metrics_unref(metrics); metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout))); if(angle == 0) y = y0 + fontsize; else if(angle == 90) x = x0 - sign_y*fontsize; if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case '+': fontsize += 3; y -= sign_x*3; x += sign_y*3; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case '-': fontsize -= 3; y += sign_x*3; x -= sign_y*3; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if (psfont->i18n_latinfamily) { latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize); } aux = g_utf8_next_char(aux); break; case 'N': psfont = base_psfont; fontsize = font_height; pango_font_description_free(font); font = gtk_psfont_get_font_description(psfont, fontsize); if(angle == 0 || angle == 180) y = y0; else x = x0; italic = psfont->italic; bold = psfont->bold; aux = g_utf8_next_char(aux); break; case 'b': if (lastchar) { const gchar *aux2 = lastchar; gint i = g_utf8_prev_char(lastchar) != --aux2 ? 2 : 1; pango_layout_set_text(layout, lastchar, i); pango_layout_get_extents(layout, NULL, &rect); x -= sign_x*PANGO_PIXELS(rect.width); y -= sign_y*PANGO_PIXELS(rect.width); if (lastchar == wtext) lastchar = NULL; else lastchar = g_utf8_prev_char(lastchar); } else { pango_layout_set_text(layout, "X", 1); pango_layout_get_extents(layout, NULL, &rect); x -= sign_x*PANGO_PIXELS(rect.width); y -= sign_y*PANGO_PIXELS(rect.width); } aux = g_utf8_next_char(aux); break; default: if(aux && *aux != '\0' && *aux !='\n'){ gint new_width = 0; new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y, psfont, fontsize, aux); x += sign_x * new_width; y += sign_y * new_width; lastchar = aux; aux = g_utf8_next_char(aux); } break; } } else { gint new_len = 0; gint new_width = 0; lastchar = aux; while(aux && *aux != '\0' && *aux !='\n' && *aux != '\\'){ xaux = aux; new_len += g_utf8_next_char(aux) != ++xaux ? 2 : 1; aux = g_utf8_next_char(aux); } xaux = lastchar; for(i = 0; i < new_len; i++) new_text[i] = *xaux++; new_text[new_len] = '\0'; new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y, psfont, fontsize, new_text); x += sign_x * new_width; y += sign_y * new_width; lastchar = aux; } } pango_font_description_free(font); if(latin_font) pango_font_description_free(latin_font); if(metrics) pango_font_metrics_unref(metrics); /* border */ gdk_gc_set_foreground(gc, &real_fg); gtk_plot_pc_set_dash(pc, 0, NULL, 0); gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); gtk_plot_pc_draw_rectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: gtk_plot_pc_draw_rectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } return; }
/* Redraw the ruler */ static gboolean histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { histoDrawing_t *drawing = (histoDrawing_t*)user_data; TimeWindow time_window = lttvwindow_get_time_window(drawing->histo_control_flow_data->tab); gchar text[255]; PangoContext *context; PangoLayout *layout; PangoFontDescription *FontDesc; PangoRectangle ink_rect; gint global_width=0; GdkColor foreground = { 0, 0, 0, 0 }; GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; LttTime window_end = time_window.end_time; LttTime half_width = ltt_time_div(time_window.time_width,2.0); LttTime window_middle = ltt_time_add(half_width, time_window.start_time); g_debug("ruler expose event"); gdk_draw_rectangle (drawing->ruler->window, drawing->ruler->style->white_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, event->area.x, 1, event->area.x + event->area.width, 1); snprintf(text, 255, "%lus\n%luns", time_window.start_time.tv_sec, time_window.start_time.tv_nsec); layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); context = pango_layout_get_context(layout); FontDesc = pango_context_get_font_description(context); pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); pango_layout_context_changed(layout); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, 0, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_round, 1, 1, 1, 7); snprintf(text, 255, "%lus\n%luns", window_end.tv_sec, window_end.tv_nsec); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; if(global_width <= drawing->ruler->allocation.width) { gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width - ink_rect.width, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width-1, 1, drawing->ruler->allocation.width-1, 7); } snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec, window_middle.tv_nsec); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_extents(layout, &ink_rect, NULL); global_width += ink_rect.width; if(global_width <= drawing->ruler->allocation.width) { gdk_draw_layout_with_colors(drawing->ruler->window, drawing->ruler_gc_butt, (drawing->ruler->allocation.width - ink_rect.width)/2, 6, layout, &foreground, &background); gdk_draw_line (drawing->ruler->window, drawing->ruler_gc_butt, drawing->ruler->allocation.width/2, 1, drawing->ruler->allocation.width/2, 7); } g_object_unref(layout); return FALSE; }
static void sctp_graph_draw(struct sctp_udata *u_data) { int length, lwidth; guint32 distance=5, i, e, sec, w, start, a, j, b; gint label_width, label_height; char label_string[15]; gfloat dis; gboolean write_label = FALSE; PangoLayout *layout; if (u_data->io->x1_tmp_sec == 0 && u_data->io->x1_tmp_usec == 0) u_data->io->offset = 0; else u_data->io->offset = 5; if (u_data->io->x2_tmp_sec - u_data->io->x1_tmp_sec > 1500) { u_data->io->min_x=u_data->io->x1_tmp_sec; u_data->io->max_x=u_data->io->x2_tmp_sec; u_data->io->uoff = TRUE; } else { u_data->io->min_x=((guint32) (u_data->io->x1_tmp_sec*1000000.0))+u_data->io->x1_tmp_usec; u_data->io->max_x=((guint32) (u_data->io->x2_tmp_sec*1000000.0))+u_data->io->x2_tmp_usec; u_data->io->uoff = FALSE; } u_data->io->tmp_width = u_data->io->max_x - u_data->io->min_x; if (u_data->dir == 1) { if (u_data->io->tmp == FALSE) { if (u_data->assoc->sort_tsn1 != NULL) u_data->io->max_y = u_data->io->tmp_max_tsn1 - u_data->io->tmp_min_tsn1; else u_data->io->max_y = 0; u_data->io->min_y = 0; } else { u_data->io->max_y = u_data->io->tmp_max_tsn1; u_data->io->min_y = u_data->io->tmp_min_tsn1; } } else if (u_data->dir == 2) { if (u_data->io->tmp == FALSE) { if (u_data->assoc->tsn2 != NULL) u_data->io->max_y = u_data->io->tmp_max_tsn2 - u_data->io->tmp_min_tsn2; else u_data->io->max_y = 0; u_data->io->min_y = 0; } else { u_data->io->max_y = u_data->io->tmp_max_tsn2; u_data->io->min_y = u_data->io->tmp_min_tsn2; } } gdk_draw_rectangle(u_data->io->pixmap, u_data->io->draw_area->style->white_gc, TRUE, 0, 0, u_data->io->draw_area->allocation.width, u_data->io->draw_area->allocation.height); distance = 5; /* x_axis */ gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER+u_data->io->offset,u_data->io->pixmap_height - BOTTOM_BORDER, u_data->io->pixmap_width - RIGHT_BORDER + u_data->io->offset, u_data->io->pixmap_height - BOTTOM_BORDER); gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, u_data->io->pixmap_width - RIGHT_BORDER + u_data->io->offset, u_data->io->pixmap_height - BOTTOM_BORDER, u_data->io->pixmap_width - RIGHT_BORDER + u_data->io->offset - 5, u_data->io->pixmap_height - BOTTOM_BORDER - 5); gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, u_data->io->pixmap_width - RIGHT_BORDER + u_data->io->offset, u_data->io->pixmap_height - BOTTOM_BORDER, u_data->io->pixmap_width - RIGHT_BORDER + u_data->io->offset - 5, u_data->io->pixmap_height - BOTTOM_BORDER + 5); u_data->io->axis_width = u_data->io->pixmap_width - LEFT_BORDER - RIGHT_BORDER - u_data->io->offset; if(u_data->io->tmp_width>0){ u_data->io->x_interval = (float)((u_data->io->axis_width*1.0)/u_data->io->tmp_width); /*distance in pixels between 2 data points*/ } else { u_data->io->x_interval = (float)(u_data->io->axis_width); } e=0; if (u_data->io->x_interval < 1) { dis = 1 / u_data->io->x_interval; while (dis >1) { dis /= 10; e++; } distance = 1; for (i=0; i<=e+1; i++) distance *= 10; } else distance = 5; g_snprintf(label_string, sizeof(label_string), "%d", 0); memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), 15); layout = gtk_widget_create_pango_layout(u_data->io->draw_area, label_string); pango_layout_get_pixel_size(layout, &label_width, &label_height); if (u_data->io->x1_tmp_usec == 0) sec = u_data->io->x1_tmp_sec; else sec = u_data->io->x1_tmp_sec+1; if (u_data->io->offset != 0) { g_snprintf(label_string, sizeof(label_string), "%u", u_data->io->x1_tmp_sec); memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string)); pango_layout_set_text(layout, label_string, -1); pango_layout_get_pixel_size(layout, &lwidth, NULL); gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER - 25, u_data->io->pixmap_height - BOTTOM_BORDER + 20, layout); } w = (guint32)(500 / (guint32)(distance * u_data->io->x_interval)); if (w == 0) w = 1; if (w == 4 || w==3 || w==2) { w = 5; a = distance / 10; b = (guint32)((u_data->io->min_x/100000))%10; /* start for labels*/ } else { a = distance / 5; b = 0; } if (!u_data->io->uoff) { if (a>=1000000) { start=u_data->io->min_x/1000000*1000000; if (a==1000000) b = 0; } else { start=u_data->io->min_x/100000; if (start%2!=0) start--; start*=100000; b = (guint32)((start/100000))%10; } } else { start = u_data->io->min_x; if (start%2!=0) start--; b = 0; } for (i=start, j=b; i<=u_data->io->max_x; i+=a, j++) { if (!u_data->io->uoff) if (i >= u_data->io->min_x && i % 1000000 != 0) { length = 5; g_snprintf(label_string, sizeof(label_string), "%d", i%1000000); if (j % w == 0) { length = 10; memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string)); pango_layout_set_text(layout, label_string, -1); pango_layout_get_pixel_size(layout, &lwidth, NULL); gdk_draw_layout(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval - lwidth / 2), u_data->io->pixmap_height - BOTTOM_BORDER + 10, layout); } gdk_draw_line(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval), u_data->io->pixmap_height - BOTTOM_BORDER, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval), u_data->io->pixmap_height - BOTTOM_BORDER + length); } if (!u_data->io->uoff) { if (i%1000000==0 && j%w==0) { sec=i/1000000; write_label = TRUE; } } else { if (j%w == 0) { sec = i; write_label = TRUE; } } if (write_label) { gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval), u_data->io->pixmap_height - BOTTOM_BORDER, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval), u_data->io->pixmap_height - BOTTOM_BORDER + 10); g_snprintf(label_string, sizeof(label_string), "%d", sec); memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string)); pango_layout_set_text(layout, label_string, -1); pango_layout_get_pixel_size(layout, &lwidth, NULL); gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, (guint32)(LEFT_BORDER + u_data->io->offset + (i - u_data->io->min_x) * u_data->io->x_interval-10), u_data->io->pixmap_height - BOTTOM_BORDER + 20, layout); write_label = FALSE; } } g_strlcpy(label_string, "sec", sizeof(label_string)); memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string)); pango_layout_set_text(layout, label_string, -1); pango_layout_get_pixel_size(layout, &lwidth, NULL); gdk_draw_layout(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, u_data->io->pixmap_width - RIGHT_BORDER - 10, u_data->io->pixmap_height - BOTTOM_BORDER + 30, layout); distance = 5; /* y-axis */ gdk_draw_line(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, LEFT_BORDER,TOP_BORDER - u_data->io->offset, LEFT_BORDER, u_data->io->pixmap_height - BOTTOM_BORDER - u_data->io->offset); gdk_draw_line(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, LEFT_BORDER, TOP_BORDER - u_data->io->offset, LEFT_BORDER - 5, TOP_BORDER - u_data->io->offset + 5); gdk_draw_line(u_data->io->pixmap, u_data->io->draw_area->style->black_gc, LEFT_BORDER, TOP_BORDER - u_data->io->offset, LEFT_BORDER + 5, TOP_BORDER - u_data->io->offset + 5); u_data->io->y_interval = (float)(((u_data->io->pixmap_height - TOP_BORDER - BOTTOM_BORDER) * 1.0)/(u_data->io->max_y - u_data->io->min_y)); e = 0; if (u_data->io->y_interval < 1) { dis = 1 / u_data->io->y_interval; while (dis > 1) { dis /= 10; e++; } distance = 1; for (i=0; i<=e; i++) distance = distance * 10; } else if (u_data->io->y_interval<2) distance = 10; if (u_data->io->max_y > 0) { for (i=u_data->io->min_y/distance*distance; i<=u_data->io->max_y; i+=distance/5) { if (i >= u_data->io->min_y) { length = 5; g_snprintf(label_string, sizeof(label_string), "%d", i); if (i%distance == 0 || (distance <= 5 && u_data->io->y_interval > 10)) { length = 10; memcpy(label_string,(gchar *)g_locale_to_utf8(label_string, -1 , NULL, NULL, NULL), sizeof(label_string)); pango_layout_set_text(layout, label_string, -1); pango_layout_get_pixel_size(layout, &lwidth, NULL); gdk_draw_layout(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER - length - lwidth - 5, (guint32)(u_data->io->pixmap_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval - 3), layout); } gdk_draw_line(u_data->io->pixmap,u_data->io->draw_area->style->black_gc, LEFT_BORDER - length, (guint32)(u_data->io->pixmap_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval), LEFT_BORDER, (guint32)(u_data->io->pixmap_height - BOTTOM_BORDER - u_data->io->offset - (i - u_data->io->min_y) * u_data->io->y_interval)); } } } else simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No Data Chunks sent"); }
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 _lib_navigation_draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_navigation_t *d = (dt_lib_navigation_t *)self->data; const int inset = DT_NAVIGATION_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; dt_develop_t *dev = darktable.develop; /* double buffering of image data: only take new data if valid */ if(dev->preview_pipe->backbuf && dev->preview_status == DT_DEV_PIXELPIPE_VALID) { /* re-allocate in case of changed image dimensions */ if(d->buffer == NULL || dev->preview_pipe->backbuf_width != d->wd || dev->preview_pipe->backbuf_height != d->ht) { g_free(d->buffer); d->wd = dev->preview_pipe->backbuf_width; d->ht = dev->preview_pipe->backbuf_height; d->buffer = g_malloc0((size_t)d->wd * d->ht * 4 * sizeof(unsigned char)); } /* update buffer if new data is available */ if(d->buffer && dev->preview_pipe->input_timestamp > d->timestamp) { dt_pthread_mutex_t *mutex = &dev->preview_pipe->backbuf_mutex; dt_pthread_mutex_lock(mutex); memcpy(d->buffer, dev->preview_pipe->backbuf, (size_t)d->wd * d->ht * 4 * sizeof(unsigned char)); d->timestamp = dev->preview_pipe->input_timestamp; dt_pthread_mutex_unlock(mutex); } } /* get the current style */ cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyleContext *context = gtk_widget_get_style_context(widget); gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); width -= 2 * inset; height -= 2 * inset; cairo_translate(cr, inset, inset); /* draw navigation image if available */ if(d->buffer) { cairo_save(cr); const int wd = d->wd; const int ht = d->ht; const float scale = fminf(width / (float)wd, height / (float)ht); const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data(d->buffer, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width / 2.0, height / 2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f * wd, -.5f * ht); // draw shadow around float alpha = 1.0f; for(int k = 0; k < 4; k++) { cairo_rectangle(cr, -k / scale, -k / scale, wd + 2 * k / scale, ht + 2 * k / scale); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } cairo_rectangle(cr, 0, 0, wd - 2, ht - 1); cairo_set_source_surface(cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); cairo_fill(cr); cairo_surface_destroy(surface); // draw box where we are dt_dev_zoom_t zoom = dt_control_get_dev_zoom(); int closeup = dt_control_get_dev_closeup(); float zoom_x = dt_control_get_dev_zoom_x(); float zoom_y = dt_control_get_dev_zoom_y(); const float min_scale = dt_dev_get_zoom_scale(dev, DT_ZOOM_FIT, closeup ? 2.0 : 1.0, 0); const float cur_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2.0 : 1.0, 0); // avoid numerical instability for small resolutions: double h, w; if(cur_scale > min_scale) { float boxw = 1, boxh = 1; dt_dev_check_zoom_bounds(darktable.develop, &zoom_x, &zoom_y, zoom, closeup, &boxw, &boxh); cairo_translate(cr, wd * (.5f + zoom_x), ht * (.5f + zoom_y)); cairo_set_source_rgb(cr, 0., 0., 0.); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.f / scale)); boxw *= wd; boxh *= ht; cairo_rectangle(cr, -boxw / 2 - 1, -boxh / 2 - 1, boxw + 2, boxh + 2); cairo_stroke(cr); cairo_set_source_rgb(cr, 1., 1., 1.); cairo_rectangle(cr, -boxw / 2, -boxh / 2, boxw, boxh); cairo_stroke(cr); } cairo_restore(cr); if(fabsf(cur_scale - min_scale) > 0.001f) { /* Zoom % */ PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); const float fontsize = DT_PIXEL_APPLY_DPI(11); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_layout_set_font_description(layout, desc); cairo_translate(cr, 0, height); cairo_set_source_rgba(cr, 1., 1., 1., 0.5); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); char zoomline[5]; snprintf(zoomline, sizeof(zoomline), "%.0f%%", cur_scale * 100); pango_layout_set_text(layout, zoomline, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); h = d->zoom_h = ink.height; w = d->zoom_w = ink.width; cairo_move_to(cr, width - w - h * 1.1 - ink.x, - fontsize); cairo_save(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0)); GdkRGBA *color; gtk_style_context_get(context, gtk_widget_get_state_flags(widget), "background-color", &color, NULL); gdk_cairo_set_source_rgba(cr, color); pango_cairo_layout_path(cr, layout); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_fill(cr); cairo_restore(cr); gdk_rgba_free(color); pango_font_description_free(desc); g_object_unref(layout); } else { // draw the zoom-to-fit icon cairo_translate(cr, 0, height); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); static int height = -1; if(height == -1) { PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_font_description_set_absolute_size(desc, DT_PIXEL_APPLY_DPI(11) * PANGO_SCALE); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, "100%", -1); // dummy text, just to get the height pango_layout_get_pixel_extents(layout, &ink, NULL); height = ink.height; pango_font_description_free(desc); g_object_unref(layout); } h = d->zoom_h = height; w = h * 1.5; float sp = h * 0.6; d->zoom_w = w + sp; cairo_move_to(cr, width - w - h - sp, -1.0 * h); cairo_rectangle(cr, width - w - h - sp, -1.0 * h, w, h); cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_fill(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0)); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_move_to(cr, width - w * 0.8 - h - sp, -1.0 * h); cairo_line_to(cr, width - w - h - sp, -1.0 * h); cairo_line_to(cr, width - w - h - sp, -0.7 * h); cairo_stroke(cr); cairo_move_to(cr, width - w - h - sp, -0.3 * h); cairo_line_to(cr, width - w - h - sp, 0); cairo_line_to(cr, width - w * 0.8 - h - sp, 0); cairo_stroke(cr); cairo_move_to(cr, width - w * 0.2 - h - sp, 0); cairo_line_to(cr, width - h - sp, 0); cairo_line_to(cr, width - h - sp, -0.3 * h); cairo_stroke(cr); cairo_move_to(cr, width - h - sp, -0.7 * h); cairo_line_to(cr, width - h - sp, -1.0 * h); cairo_line_to(cr, width - w * 0.2 - h - sp, -1.0 * h); cairo_stroke(cr); } cairo_move_to(cr, width - 0.95 * h, -0.9 * h); cairo_line_to(cr, width - 0.05 * h, -0.9 * h); cairo_line_to(cr, width - 0.5 * h, -0.1 * h); cairo_fill(cr); } /* blit memsurface into widget */ cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }