示例#1
0
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;
}
示例#2
0
文件: pdf.c 项目: Debian/gpdftext
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);
}
示例#3
0
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;
	}
}
示例#6
0
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;
}
示例#7
0
文件: gui_util.c 项目: bert/fped
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);
}
示例#8
0
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);
}
示例#9
0
文件: vikviewport.c 项目: gdt/viking
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;
  }
}
示例#10
0
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,
                   &current_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);
    }
}
示例#12
0
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;
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
/* 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;
}
示例#16
0
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);
}
示例#18
0
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;
}
示例#19
0
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;
}
示例#20
0
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;
}
示例#21
0
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);
}
示例#22
0
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;
}
示例#23
0
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);
}
示例#24
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   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));
}
示例#25
0
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;
}
示例#26
0
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;
}
示例#27
0
/* 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;
}
示例#28
0
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;
}
示例#30
-1
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;
}