コード例 #1
0
ファイル: diacairo-renderer.c プロジェクト: brunetton/dia
/* 
 * render functions 
 */ 
static void
begin_render(DiaRenderer *self, const Rectangle *update)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
  real onedu = 0.0;
  real lmargin = 0.0, tmargin = 0.0;
  gboolean paginated = renderer->surface && /* only with our own pagination, not GtkPrint */
    cairo_surface_get_type (renderer->surface) == CAIRO_SURFACE_TYPE_PDF && !renderer->skip_show_page;

  if (renderer->surface && !renderer->cr)
    renderer->cr = cairo_create (renderer->surface);
  else
    g_assert (renderer->cr);

  /* remember current state, so we can start from new with every page */
  cairo_save (renderer->cr);

  if (paginated && renderer->dia) {
    DiagramData *data = renderer->dia;
    /* Dia's paper.width already contains the scale, cairo needs it without 
     * Similar for margins, Dia's without, but cairo wants them?
     */
    real width = (data->paper.lmargin + data->paper.width * data->paper.scaling + data->paper.rmargin)
          * (72.0 / 2.54) + 0.5;
    real height = (data->paper.tmargin + data->paper.height * data->paper.scaling + data->paper.bmargin)
           * (72.0 / 2.54) + 0.5;
    /* "Changes the size of a PDF surface for the current (and
     * subsequent) pages." Pagination setup? */
    cairo_pdf_surface_set_size (renderer->surface, width, height);
    lmargin = data->paper.lmargin / data->paper.scaling;
    tmargin = data->paper.tmargin / data->paper.scaling;
  }

  cairo_scale (renderer->cr, renderer->scale, renderer->scale);
  /* to ensure no clipping at top/left we need some extra gymnastics,
   * otherwise a box with a line witdh one one pixel might loose the
   * top/left border as in bug #147386 */
  ensure_minimum_one_device_unit (renderer, &onedu);

  if (update && paginated) {
    cairo_rectangle (renderer->cr, lmargin, tmargin,
                     update->right - update->left, update->bottom - update->top);
    cairo_clip (renderer->cr);
    cairo_translate (renderer->cr, -update->left + lmargin, -update->top + tmargin);
  } else
    cairo_translate (renderer->cr, -renderer->dia->extents.left + onedu, -renderer->dia->extents.top + onedu);
  /* no more blurred UML diagrams */
  cairo_set_antialias (renderer->cr, CAIRO_ANTIALIAS_NONE);

  /* clear background */
  if (renderer->with_alpha)
    {
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             0.0);
    }
  else
    {
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
  cairo_paint (renderer->cr);
  if (renderer->with_alpha)
    {
      /* restore to default drawing */
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
#ifdef HAVE_PANGOCAIRO_H
  if (!renderer->layout)
    renderer->layout = pango_cairo_create_layout (renderer->cr);
#endif

  cairo_set_fill_rule (renderer->cr, CAIRO_FILL_RULE_EVEN_ODD);

#if 0 /* try to work around bug #341481 - no luck */
  {
    cairo_font_options_t *fo = cairo_font_options_create ();
    cairo_get_font_options (renderer->cr, fo);
    /* try to switch off kerning */
    cairo_font_options_set_hint_style (fo, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics (fo, CAIRO_HINT_METRICS_OFF);

    cairo_set_font_options (renderer->cr, fo);
    cairo_font_options_destroy (fo);
#ifdef HAVE_PANGOCAIRO_H
    pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout));
    pango_layout_context_changed (renderer->layout);
#endif
  }
#endif
  
  DIAG_STATE(renderer->cr)
}
コード例 #2
0
ファイル: lrc_desktop.c プロジェクト: lovesnow/linnya
gboolean	ly_3lrc_desktop_on_expose_cb	(GtkWidget * widget, cairo_t *cr, gpointer data)
{
	gchar desktop_font[1024]="Sans Regular 25";
	ly_reg_get("3lrc_desktop_font", "%1024[^\n]", desktop_font);

	gchar path[1024];
	g_snprintf(path,sizeof(path),"%sicon/null.png",LY_GLB_PROG_UIXDIR);
	if(!desktop_bg)
		desktop_bg=cairo_image_surface_create_from_png(path);

	cairo_set_source_surface(cr, desktop_bg, 0, 0);
	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
	cairo_paint(cr);
	
	int width;
	int height;
	width = gtk_widget_get_allocated_width (widget);
	height = gtk_widget_get_allocated_height (widget);
	
	int x=0;
	int y=height;
	
	//鼠标进入
	if(flag_notify)
	{
		//填充圆角矩形拖动区域
		cairo_set_source_rgba(cr,0,0,0,0.3);
		cairo_move_to (cr, 0 + 5, 0);
		cairo_line_to (cr, 0 + width - 5, 0);
		cairo_move_to (cr, 0 + width, 0 + 5);
		cairo_line_to (cr, 0 + width, 0 + height - 5);
		cairo_move_to (cr, 0 + width - 5, 0 + height);
		cairo_line_to (cr, 0 + 5, 0 + height);
		cairo_move_to (cr, 0, 0 + height - 5);
		cairo_line_to (cr, 0, 0 + 5);
		cairo_arc (cr, 0 + 5, 0 + 5, 5, M_PI, 3 * M_PI / 2.0);
		cairo_arc (cr, 0 + width - 5, 0 + 5, 5, 3 * M_PI / 2, 2 * M_PI);
		cairo_arc (cr, 0 + width - 5, 0 + height - 5, 5, 0, M_PI / 2);
		cairo_arc (cr, 0 + 5, 0 + height - 5, 5, M_PI / 2, M_PI);
		cairo_fill(cr);
	}
	
	if(ly_lrc_get_length()>0)
	{
		//计算占空比
		gint64 t1=0;
		gint64 t2=0;
		
		LyMdhMetadata *md=NULL;
		md=ly_pqm_get_current_md();
		if(!md)
			return FALSE;
		if(ly_lrc_get_index()+1<ly_lrc_get_length())
			t1=(ly_lrc_get_array()[ly_lrc_get_index()+1])->time-(ly_lrc_get_array()[ly_lrc_get_index()])->time;
		else
			t1=ly_mdh_time_str2int(md->duration)-ly_mdh_time_str2int(md->start)-(ly_lrc_get_array()[ly_lrc_get_index()])->time;
		
		t2=ly_aud_get_position_abs()-ly_mdh_time_str2int(md->start)-(ly_lrc_get_array()[ly_lrc_get_index()])->time;
		if(t1!=0)
		{
			x=(int)((t2/(gdouble)t1)*pos_layout[X]);
		}
		
		//画歌词
		cairo_set_source_rgb(cr,0,0,0);
		
		//确定起始点
		if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2))
		{
			cairo_move_to(cr, 0-(x-width/2), 5);
			x=width/2;
		}
		else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2))
			cairo_move_to(cr, 0-(pos_layout[X]-width), 5);
		else
			cairo_move_to(cr, 0, 5);
		
		PangoLayout *layout;
		PangoFontDescription *desc;
		layout = pango_cairo_create_layout (cr);
		
		pango_layout_set_text(layout, ly_lrc_get_array()[ly_lrc_get_index()]->text, -1);
		desc = pango_font_description_from_string (desktop_font);
		pango_layout_set_font_description (layout, desc);
		pango_font_description_free (desc);
		
		
		pango_layout_get_size(layout,&pos_layout[X],&pos_layout[Y]);
		pos_layout[X]=pos_layout[X]/1000;
		
		pango_cairo_update_layout (cr, layout);
		pango_cairo_layout_path (cr, layout);
		cairo_clip(cr);
		g_object_unref (layout);
		
		//画背景条
		cairo_pattern_t *pat;
		pat = cairo_pattern_create_linear (0, 0,10.0, 150);
		cairo_pattern_add_color_stop_rgb (pat, 0.1, 65535/65535.0, 10449/65535.0, 0/65535.0);
		cairo_pattern_add_color_stop_rgb (pat, 0.5, 65535/65535.0, 61062/65535.0, 0/65535.0);
		cairo_pattern_add_color_stop_rgb (pat, 0.9, 65535/65535.0, 10449/65535.0, 0/65535.0);
		//画矩形
		if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2))
			cairo_rectangle (cr, 0, 0, width/2, y);
		else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2))
			cairo_rectangle (cr, 0, 0, width-(pos_layout[X]-x), y);
		else
			cairo_rectangle (cr, 0, 0, x, y);
		cairo_set_source (cr, pat);
		cairo_fill(cr);
		cairo_pattern_destroy (pat);
		pat = cairo_pattern_create_linear (0, 0,10.0, 150);
		cairo_pattern_add_color_stop_rgb (pat, 0.1, 19532/65535.0, 65535/65535.0, 65535/65535.0);
		cairo_pattern_add_color_stop_rgb (pat, 0.5, 5539/65535.0, 0/65535.0, 65535/65535.0);
		cairo_pattern_add_color_stop_rgb (pat, 0.9, 19532/65535.0, 65535/65535.0, 65535/65535.0);
		//画矩形
		if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2))
			cairo_rectangle (cr, width/2, 0, width-(width/2), y);
		else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2))
			cairo_rectangle (cr, width-(pos_layout[X]-x), 0, pos_layout[X]-x, y);
		else
			cairo_rectangle (cr, x, 0, width-x, y);
		cairo_set_source (cr, pat);
		cairo_fill(cr);
		cairo_pattern_destroy (pat);
	}
	
	int lrc_desktop=1;
	int lrc_desktop_fix=0;
	if(!ly_reg_get("3lrc_desktop_state", "%d:%d", &lrc_desktop, &lrc_desktop_fix))
	{
		ly_reg_set("3lrc_desktop_state", "%d:%d", lrc_desktop, lrc_desktop_fix);
	}
	if(lrc_desktop_fix>0)
		gtk_widget_set_sensitive(widget,FALSE);
	else
		gtk_widget_set_sensitive(widget,TRUE);
	cairo_region_t *region;
	if(!(lrc_desktop_fix))
	{
		cairo_rectangle_int_t rect;
		rect.x=rect.y=0;
		rect.width=width;
		rect.height=height;
		region=cairo_region_create_rectangle(&rect);
	}
	else
	{
		region=cairo_region_create();
	}
	gdk_window_input_shape_combine_region (gtk_widget_get_window(widget), region, 0, 0);
	cairo_region_destroy (region);
	
	return FALSE;
}
コード例 #3
0
ファイル: hb-export.c プロジェクト: maxiwell/homebank
void hb_export_pdf_listview(GtkTreeView *treeview, gchar *filepath, gchar *accname)
{
cairo_surface_t *surf;
cairo_t *cr;
PdfPrintContext ppc;
PangoFontDescription *desc;
PangoLayout *layout;
GtkTreeModel *model;
GtkTreeIter	iter;
gboolean valid;
gint i, col;

	
	DB( g_print("[gtk-chart] export to pdf\n") );

	model = gtk_tree_view_get_model(treeview);
	
	papersize(&ppc);

	//gchar *filename = "/home/max/Desktop/hb-txn-export.pdf";
	double width;	//=210 * 2.83;
	double height;	//=297 * 2.83;
	
	width  = ppc.w;
	height = ppc.h;

	surf = cairo_pdf_surface_create (filepath, width, height);
	
	if( cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS )
	//todo: manage error later on
		return;

	
	cr = cairo_create (surf);
	//cairo_pdf_surface_set_size(surf, width * 2.83, height * 2.83);

	//g_print("width=%d\n", cairo_image_surface_get_width( surf));
	double x1, x2, y1, y2;
	cairo_clip_extents (cr, &x1, &y1, &x2, &y2);

	DB( g_print("surface w=%f, h=%f\n", x2 - x1, y2 - y1) );
	double pwidth = x2 - x1;
	
	
	/* Create a PangoLayout, set the font and text */
	layout = pango_cairo_create_layout (cr);

	/* get and copy the font from the treeview widget */
	gtk_style_context_get(gtk_widget_get_style_context(GTK_WIDGET(treeview)), GTK_STATE_FLAG_NORMAL, "font", &desc, NULL);
	ppc.desc = pango_font_description_copy(desc);

	DB( g_print("family: %s\n", pango_font_description_get_family(desc)) );
	DB( g_print("size: %d (%d)\n", pango_font_description_get_size (desc), pango_font_description_get_size (desc )/PANGO_SCALE) );


	
	/* header is 1 line for date page number at top, then a title in bold, then 2 empty lines */
	gint header_height = PDF_FONT_NORMAL * 2 + PDF_FONT_TITLE;
	gint nb_lines = gtk_tree_model_iter_n_children(model, NULL);

	/* should include here the headertitle line */
	
	gint lpp = floor ((height-header_height-ppc.mt-ppc.mb) / (PDF_FONT_NORMAL + PDF_LINE_MARGIN));
	gint page, num_pages = (nb_lines - 1) / lpp + 1;

	DB( g_print("\n - should pdf %d lines, lpp=%d, num_pages=%d\n", nb_lines, lpp, num_pages) );


	gint tot_lines = 0;
	gint cur_page_line = 1;

	gchar dbuffer[255];
	gchar amtbuf[G_ASCII_DTOSTR_BUF_SIZE];
	gchar balbuf[G_ASCII_DTOSTR_BUF_SIZE];

	GDate *date = g_date_new ();

	//cairo_set_font_size(cr, PDF_FONT_NORMAL);
	pango_font_description_set_absolute_size(ppc.desc, PDF_FONT_NORMAL * PANGO_SCALE);
	pango_layout_set_font_description (layout, ppc.desc);
	
	/* reset struct */
	hb_pdf_set_col_title(&ppc);
	
	for(col=0;col<PDF_NUMCOL;col++)
	{
	int tw, th;

		ppc.column_width[col] = 0;
		pango_layout_set_text (layout, ppc.column_txt[col], -1);
		pango_layout_get_size (layout, &tw, &th);
		ppc.column_width[col] = MAX(ppc.column_width[col], tw / PANGO_SCALE);
	}


	DB( g_print(" - compute width\n") );

	/* first pass to get max width */
	valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
	while (valid)
	{
	Transaction *txn;
	int tw, th;
			
		gtk_tree_model_get (model, &iter, LST_DSPOPE_DATAS, &txn, -1);

		i = 0;
		g_date_set_julian (date, txn->date);
		g_date_strftime (dbuffer, 255-1, "%x", date);
		pango_layout_set_text (layout, dbuffer, -1);
		pango_layout_get_size (layout, &tw, &th);
		ppc.column_width[i] = MAX(ppc.column_width[i], tw / PANGO_SCALE);
		
		i = 1;
		if(txn->info != NULL && strlen(txn->info) > 0)
		{
			pango_layout_set_text (layout, txn->info, -1);
			pango_layout_get_size (layout, &tw, &th);
			ppc.column_width[i] = MAX(ppc.column_width[i], tw / PANGO_SCALE);
		}
		
		i = 4;
		hb_strfnum(amtbuf, G_ASCII_DTOSTR_BUF_SIZE-1, txn->amount, txn->kcur, GLOBALS->minor);
		pango_layout_set_text (layout, amtbuf, -1);
		pango_layout_get_size (layout, &tw, &th);
		ppc.column_width[i] = MAX(ppc.column_width[i], tw / PANGO_SCALE);

		i = 5;
		pango_layout_set_text (layout, "R", -1);
		pango_layout_get_size (layout, &tw, &th);
		ppc.column_width[i] = MAX(ppc.column_width[i], tw / PANGO_SCALE);

		i = 6;
		hb_strfnum(balbuf, G_ASCII_DTOSTR_BUF_SIZE-1, txn->balance, txn->kcur, GLOBALS->minor);
		pango_layout_set_text (layout, balbuf, -1);
		pango_layout_get_size (layout, &tw, &th);
		ppc.column_width[i] = MAX(ppc.column_width[i], tw / PANGO_SCALE);

		valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
	}

	/* distribute remaining size */
	gdouble tmp = pwidth - ppc.ml - ppc.mr - (PDF_COL_MARGIN*PDF_NUMCOL);


	DB( g_print(" page width=%f, remain width=%f\n", pwidth, tmp) );
	
	tmp -= ppc.column_width[0];
	tmp -= ppc.column_width[4];
	tmp -= ppc.column_width[5];
	tmp -= ppc.column_width[6];
	
	/* info=1/4 payee=1/4 memo=2/4 */
	ppc.column_width[1] = tmp / 4;;
	ppc.column_width[2] = tmp / 4;
	ppc.column_width[3] = 2*tmp / 4;

	DB( g_print(" page width=%f, remain width=%f\n", width, tmp) );
	
	#if MYDEBUG == 1
	for(i=0;i<PDF_NUMCOL;i++)
		g_print(" col%d=%g ", i, ppc.column_width[i]);

	g_print("\n");
	#endif

	DB( g_print("\n - start printing\n") );
	
	gint y;
	page = 1;
	valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
	while (valid)
	{
	Transaction *txn;
	int tw, th;
			
		gtk_tree_model_get (model, &iter, LST_DSPOPE_DATAS, &txn, -1);

		//DB( g_print(" - %d, %d, %s\n", x, y, txn->memo) );
		if(cur_page_line == 1)
		{
			//helpdraw
			#if HELPDRAW == 1
			//page with margin
			hb_pdf_draw_help_rect(cr, 0xFF0000FF, ppc.ml+0.5, ppc.mt+0.5, width-(ppc.ml+ppc.mr), height - (ppc.mt+ppc.mb));
			hb_pdf_draw_help_rect(cr, 0xFF00FFFF, ppc.ml+0.5, ppc.mt+0.5, width-(ppc.ml+ppc.mr), header_height);
			#endif

			cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);

			// draw account title
			pango_font_description_set_absolute_size(ppc.desc, PDF_FONT_TITLE * PANGO_SCALE);
			pango_layout_set_font_description (layout, ppc.desc);

			pango_layout_set_text (layout, accname, -1);
			pango_layout_get_pixel_size (layout, &tw, &th);
			cairo_move_to(cr, pwidth/2 - (tw/2), ppc.mt);
			pango_cairo_show_layout (cr, layout);

			// draw column titles
			pango_font_description_set_absolute_size(ppc.desc, PDF_FONT_NORMAL * PANGO_SCALE);
			pango_layout_set_font_description (layout, ppc.desc);

			g_sprintf(dbuffer, "Page %d/%d", page, num_pages);
			pango_layout_set_text (layout, dbuffer, -1);
			pango_layout_get_pixel_size (layout, &tw, &th);
			cairo_move_to(cr, pwidth - ppc.mr - tw, ppc.mt);
			pango_cairo_show_layout (cr, layout);

			//x = ppc.ml;
			y = ppc.mt + header_height - (PDF_FONT_NORMAL + PDF_LINE_MARGIN);
			hb_pdf_set_col_title(&ppc);

			hb_pdf_draw_line(&ppc, cr, y, TRUE, FALSE);
		}

		/* print a single line */
		//x = ppc.ml;
		y = ppc.mt + header_height + (cur_page_line * (PDF_FONT_NORMAL + PDF_LINE_MARGIN));



		/* reset struct */
		for(i=0;i<PDF_NUMCOL;i++)
		{
			ppc.column_txt[i] = NULL;
		}
		
		i = 0;
		g_date_set_julian (date, txn->date);
		g_date_strftime (dbuffer, 255-1, "%x", date);
		ppc.column_txt[i] = dbuffer;
		
		i = 1;
		ppc.column_txt[i] = txn->info;

		i = 2;
		Payee *p = da_pay_get(txn->kpay);
		if(p)
			ppc.column_txt[i] = p->name;

		i = 3;
		/*Category *c = da_cat_get(txn->kcat);
		if(c)
			ppc.column_txt[i] = da_cat_get_fullname(c);*/
		ppc.column_txt[i] = txn->memo;
			
		i = 4;
		hb_strfnum(amtbuf, G_ASCII_DTOSTR_BUF_SIZE-1, txn->amount, txn->kcur, GLOBALS->minor);
		ppc.column_txt[i] = amtbuf;

		i = 5;
		ppc.column_txt[i] = "";
		if(txn->status == TXN_STATUS_CLEARED)
			ppc.column_txt[i] = "c";
		else
		if(txn->status == TXN_STATUS_RECONCILED)
			ppc.column_txt[i] = "R";
		
		i = 6;
		hb_strfnum(balbuf, G_ASCII_DTOSTR_BUF_SIZE-1, txn->balance, txn->kcur, GLOBALS->minor);
		ppc.column_txt[i] = balbuf;

		hb_pdf_draw_line(&ppc, cr, y, FALSE, (cur_page_line % 2));
		
		/* free any fullcat name */
		/*if(ppc.column_txt[3] != NULL)
			g_free(ppc.column_txt[3]);*/
		
		/* export page */		
		if(cur_page_line >= lpp)
		{
			DB( g_print("\n - next page %d\n", page) );
			
			cairo_show_page(cr);
			cur_page_line = 0;
			page++;
		}

		cur_page_line++;
		tot_lines++;
		valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
	}

	g_date_free(date);

	g_object_unref (layout);
	pango_font_description_free (ppc.desc);

	cairo_destroy (cr);
	cairo_surface_destroy (surf);

}
コード例 #4
0
ファイル: gen_image.c プロジェクト: x42/fil4.lv2
static void write_text_full (
		cairo_t* cr,
		const char *txt,
		PangoFontDescription *font,
		const float x, const float y,
		const float ang, const int align,
		const float * const col) {
	int tw, th;
	cairo_save(cr);

	PangoLayout * pl = pango_cairo_create_layout(cr);
	pango_layout_set_font_description(pl, font);
	if (strncmp(txt, "<markup>", 8)) {
		pango_layout_set_text(pl, txt, -1);
	} else {
		pango_layout_set_markup(pl, txt, -1);
	}
	pango_layout_get_pixel_size(pl, &tw, &th);
	cairo_translate (cr, rintf(x), rintf(y));
	if (ang != 0) { cairo_rotate (cr, ang); }
	switch(abs(align)) {
		case 1:
			cairo_translate (cr, -tw, ceil(th/-2.0));
			pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT);
			break;
		case 2:
			cairo_translate (cr, ceil(tw/-2.0), ceil(th/-2.0));
			pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER);
			break;
		case 3:
			cairo_translate (cr, 0, ceil(th/-2.0));
			pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT);
			break;
		case 4:
			cairo_translate (cr, -tw, -th);
			pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT);
			break;
		case 5:
			cairo_translate (cr, ceil(tw/-2.0), -th);
			pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER);
			break;
		case 6:
			cairo_translate (cr, 0, -th);
			pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT);
			break;
		case 7:
			cairo_translate (cr, -tw, 0);
			pango_layout_set_alignment (pl, PANGO_ALIGN_RIGHT);
			break;
		case 8:
			cairo_translate (cr, ceil(tw/-2.0), 0);
			pango_layout_set_alignment (pl, PANGO_ALIGN_CENTER);
			break;
		case 9:
			cairo_translate (cr, 0, 0);
			pango_layout_set_alignment (pl, PANGO_ALIGN_LEFT);
			break;
		default:
			break;
	}
	if (align < 0) {
		cairo_set_source_rgba (cr, .0, .0, .0, .5);
		cairo_rectangle (cr, 0, 0, tw, th);
		cairo_fill (cr);
	}
#if 1
	cairo_set_source_rgba (cr, col[0], col[1], col[2], col[3]);
	pango_cairo_show_layout(cr, pl);
#else
	cairo_set_source_rgba (cr, col[0], col[1], col[2], col[3]);
	pango_cairo_layout_path(cr, pl);
	cairo_fill(cr);
#endif
	g_object_unref(pl);
	cairo_restore(cr);
	cairo_new_path (cr);
}
コード例 #5
0
ファイル: display.c プロジェクト: jamesshew/guacamole-server
/**
 * Sends the given character to the terminal at the given row and column,
 * rendering the character immediately. This bypasses the guac_terminal_display
 * mechanism and is intended for flushing of updates only.
 */
int __guac_terminal_set(guac_terminal_display* display, int row, int col, int codepoint) {

    int width;

    int bytes;
    char utf8[4];

    /* Use foreground color */
    const guac_terminal_color* color = &display->glyph_foreground;

    /* Use background color */
    const guac_terminal_color* background = &display->glyph_background;

    cairo_surface_t* surface;
    cairo_t* cairo;
    int surface_width, surface_height;
   
    PangoLayout* layout;
    int layout_width, layout_height;
    int ideal_layout_width, ideal_layout_height;

    /* Calculate width in columns */
    width = wcwidth(codepoint);
    if (width < 0)
        width = 1;

    /* Do nothing if glyph is empty */
    if (width == 0)
        return 0;

    /* Convert to UTF-8 */
    bytes = guac_terminal_encode_utf8(codepoint, utf8);

    surface_width = width * display->char_width;
    surface_height = display->char_height;

    ideal_layout_width = surface_width * PANGO_SCALE;
    ideal_layout_height = surface_height * PANGO_SCALE;

    /* Prepare surface */
    surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                         surface_width, surface_height);
    cairo = cairo_create(surface);

    /* Fill background */
    cairo_set_source_rgb(cairo,
            background->red   / 255.0,
            background->green / 255.0,
            background->blue  / 255.0);

    cairo_rectangle(cairo, 0, 0, surface_width, surface_height); 
    cairo_fill(cairo);

    /* Get layout */
    layout = pango_cairo_create_layout(cairo);
    pango_layout_set_font_description(layout, display->font_desc);
    pango_layout_set_text(layout, utf8, bytes);
    pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);

    pango_layout_get_size(layout, &layout_width, &layout_height);

    /* If layout bigger than available space, scale it back */
    if (layout_width > ideal_layout_width || layout_height > ideal_layout_height) {

        double scale = fmin(ideal_layout_width  / (double) layout_width,
                            ideal_layout_height / (double) layout_height);

        cairo_scale(cairo, scale, scale);

        /* Update layout to reflect scaled surface */
        pango_layout_set_width(layout, ideal_layout_width / scale);
        pango_layout_set_height(layout, ideal_layout_height / scale);
        pango_cairo_update_layout(cairo, layout);

    }

    /* Draw */
    cairo_set_source_rgb(cairo,
            color->red   / 255.0,
            color->green / 255.0,
            color->blue  / 255.0);

    cairo_move_to(cairo, 0.0, 0.0);
    pango_cairo_show_layout(cairo, layout);

    /* Draw */
    guac_common_surface_draw(display->display_surface,
        display->char_width * col,
        display->char_height * row,
        surface);

    /* Free all */
    g_object_unref(layout);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);

    return 0;

}
コード例 #6
0
ファイル: FontGtk.cpp プロジェクト: jackiekaon/owb-mirror
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
    cairo_t* cr = context->platformContext();
    cairo_save(cr);
    cairo_translate(cr, point.x(), point.y());

    PangoLayout* layout = pango_cairo_create_layout(cr);
    setPangoAttributes(this, run, layout);

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    // Our layouts are single line
    PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);

    GdkRegion* partialRegion = NULL;
    if (to - from != run.length()) {
        // Clip the region of the run to be rendered
        char* start = g_utf8_offset_to_pointer(utf8, from);
        char* end = g_utf8_offset_to_pointer(start, to - from);
        int ranges[] = {start - utf8, end - utf8};
        partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
        gdk_region_shrink(partialRegion, 0, -pixelSize());
    }

    Color fillColor = context->fillColor();
    float red, green, blue, alpha;

    // Text shadow, inspired by FontMac
    IntSize shadowSize;
    int shadowBlur = 0;
    Color shadowColor;
    bool hasShadow = context->textDrawingMode() == cTextFill &&
        context->getShadow(shadowSize, shadowBlur, shadowColor);

    // TODO: Blur support
    if (hasShadow) {
        // Disable graphics context shadows (not yet implemented) and paint them manually
        context->clearShadow();
        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
        cairo_save(cr);

        shadowFillColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);

        cairo_translate(cr, shadowSize.width(), shadowSize.height());

        if (partialRegion) {
            gdk_cairo_region(cr, partialRegion);
            cairo_clip(cr);
        }

        pango_cairo_show_layout_line(cr, layoutLine);

        cairo_restore(cr);
    }

    fillColor.getRGBA(red, green, blue, alpha);
    cairo_set_source_rgba(cr, red, green, blue, alpha);

    if (partialRegion) {
        gdk_cairo_region(cr, partialRegion);
        cairo_clip(cr);
    }

    pango_cairo_show_layout_line(cr, layoutLine);

    if (context->textDrawingMode() & cTextStroke) {
        Color strokeColor = context->strokeColor();
        strokeColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);
        pango_cairo_layout_line_path(cr, layoutLine);
        cairo_set_line_width(cr, context->strokeThickness());
        cairo_stroke(cr);
    }

    // Re-enable the platform shadow we disabled earlier
    if (hasShadow)
        context->setShadow(shadowSize, shadowBlur, shadowColor);

    // Pango sometimes leaves behind paths we don't want
    cairo_new_path(cr);

    if (partialRegion)
        gdk_region_destroy(partialRegion);

    g_free(utf8);
    g_object_unref(layout);

    cairo_restore(cr);
}
コード例 #7
0
ファイル: control.c プロジェクト: fhrtms/darktable
void *dt_control_expose(void *voidptr)
{
  int width, height, pointerx, pointery;
  if(!darktable.gui->surface) return NULL;
  width = dt_cairo_image_surface_get_width(darktable.gui->surface);
  height = dt_cairo_image_surface_get_height(darktable.gui->surface);
  GtkWidget *widget = dt_ui_center(darktable.gui->ui);
#if GTK_CHECK_VERSION(3, 20, 0)
  gdk_window_get_device_position(gtk_widget_get_window(widget),
      gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(widget))),
      &pointerx, &pointery, NULL);
#else
  GdkDevice *device
      = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(widget)));
  gdk_window_get_device_position(gtk_widget_get_window(widget), device, &pointerx, &pointery, NULL);
#endif

  // create a gtk-independent surface to draw on
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  // TODO: control_expose: only redraw the part not overlapped by temporary control panel show!
  //
  float tb = 8; // fmaxf(10, width/100.0);
  darktable.control->tabborder = tb;
  darktable.control->width = width;
  darktable.control->height = height;

  GdkRGBA color;
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  gboolean color_found = gtk_style_context_lookup_color (context, "bg_color", &color);
  if(!color_found)
  {
    color.red = 1.0;
    color.green = 0.0;
    color.blue = 0.0;
    color.alpha = 1.0;
  }
  gdk_cairo_set_source_rgba(cr, &color);

  cairo_set_line_width(cr, tb);
  cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb);
  cairo_stroke(cr);
  cairo_set_line_width(cr, 1.5);
  color_found = gtk_style_context_lookup_color (context, "really_dark_bg_color", &color);
  if(!color_found)
  {
    color.red = 1.0;
    color.green = 0.0;
    color.blue = 0.0;
    color.alpha = 1.0;
  }
  gdk_cairo_set_source_rgba(cr, &color);
  cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb);
  cairo_stroke(cr);

  cairo_save(cr);
  cairo_translate(cr, tb, tb);
  cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb);
  cairo_clip(cr);
  cairo_new_path(cr);
  // draw view
  dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb,
                         pointery - tb);
  cairo_restore(cr);

  // draw log message, if any
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  if(darktable.control->log_ack != darktable.control->log_pos)
  {
    PangoRectangle ink;
    PangoLayout *layout;
    PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
    const float fontsize = DT_PIXEL_APPLY_DPI(14);
    pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
    pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, darktable.control->log_message[darktable.control->log_ack], -1);
    pango_layout_get_pixel_extents(layout, &ink, NULL);
    const float pad = DT_PIXEL_APPLY_DPI(20.0f), xc = width / 2.0;
    const float yc = height * 0.85 + DT_PIXEL_APPLY_DPI(10), wd = pad + ink.width * .5f;
    float rad = DT_PIXEL_APPLY_DPI(14);
    cairo_set_line_width(cr, 1.);
    cairo_move_to(cr, xc - wd, yc + rad);
    for(int k = 0; k < 5; k++)
    {
      cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI);
      cairo_line_to(cr, xc + wd, yc - rad);
      cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0);
      cairo_line_to(cr, xc - wd, yc + rad);
      if(k == 0)
      {
        color_found = gtk_style_context_lookup_color (context, "selected_bg_color", &color);
        if(!color_found)
        {
          color.red = 1.0;
          color.green = 0.0;
          color.blue = 0.0;
          color.alpha = 1.0;
        }
        gdk_cairo_set_source_rgba(cr, &color);
        cairo_fill_preserve(cr);
      }
      cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k));
      cairo_stroke(cr);
      rad += .5f;
    }
    color_found = gtk_style_context_lookup_color (context, "fg_color", &color);
    if(!color_found)
    {
      color.red = 1.0;
      color.green = 0.0;
      color.blue = 0.0;
      color.alpha = 1.0;
    }
    gdk_cairo_set_source_rgba(cr, &color);
    cairo_move_to(cr, xc - wd + .5f * pad, (yc + 1. / 3. * fontsize) - fontsize);
    pango_cairo_show_layout(cr, layout);
    pango_font_description_free(desc);
    g_object_unref(layout);
  }
  // draw busy indicator
  if(darktable.control->log_busy > 0)
  {
    PangoRectangle ink;
    PangoLayout *layout;
    PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
    const float fontsize = DT_PIXEL_APPLY_DPI(14);
    pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
    pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
    layout = pango_cairo_create_layout(cr);
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, _("working.."), -1);
    pango_layout_get_pixel_extents(layout, &ink, NULL);
    const float xc = width / 2.0, yc = height * 0.85 - DT_PIXEL_APPLY_DPI(30), wd = ink.width * .5f;
    cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize - fontsize);
    pango_cairo_layout_path(cr, layout);
    cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
    cairo_fill_preserve(cr);
    cairo_set_line_width(cr, 0.7);
    cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
    cairo_stroke(cr);
    pango_font_description_free(desc);
    g_object_unref(layout);
  }
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);

  cairo_destroy(cr);

  cairo_t *cr_pixmap = cairo_create(darktable.gui->surface);
  cairo_set_source_surface(cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);

  cairo_surface_destroy(cst);
  return NULL;
}
コード例 #8
0
static GdkPixbuf *
create_gallery (ThumbApp *app)
{
	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;
	GFile *file;

	/* Calculate how many screenshots we're going to take */
	stream_length = app->duration;

	/* 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;

	g_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);

	g_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) {
		if (pos == stream_length)
			screenshot = capture_frame_at_time (app, pos - 1);
		else
			screenshot = capture_frame_at_time (app, 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);

			g_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);

			g_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);

		g_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++;
		}
	}

	g_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, FALSE, FALSE);
	file = g_file_new_for_commandline_arg (app->input);
	filename = g_file_get_basename (file);
	g_object_unref (file);

	/* 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_markup_printf_escaped (_("<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);

	g_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);

	g_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, FALSE, FALSE);

		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);

		g_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);

	g_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;
}
コード例 #9
0
ファイル: togglebutton.c プロジェクト: Acidburn0zzz/darktable
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
  {
    GdkRGBA *bc;
    gtk_style_context_get(context, state, "background-color", &bc, NULL);
    bg_color = *bc;
    gdk_rgba_free(bc);
  }
  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;
}
コード例 #10
0
ファイル: rbpangocairocontext.c プロジェクト: Vasfed/pango
/* Convenience */
static VALUE
rg_create_pango_layout(VALUE self)
{
    return GOBJ2RVAL_UNREF(pango_cairo_create_layout(RVAL2CRCONTEXT(self)));
}
コード例 #11
0
gboolean cd_do_render_listing_notification (gpointer pUserData, CDListing *pListing, cairo_t *pCairoContext)
{
	//g_print ("%s ()\n", __func__);
	int iWidth = pListing->container.iWidth, iHeight = pListing->container.iHeight;
	int iLeftMargin = myDialogs.dialogTextDescription.iSize + 2, iRightMargin = (myDialogs.dialogTextDescription.iSize + 2) / 2;
	int iTopMargin = (myDialogs.dialogTextDescription.iSize + 2) + GAP, iBottomMargin = (myDialogs.dialogTextDescription.iSize + 2) * 4 + GAP;
	CDEntry *pEntry;
	
	// on dessine un cadre et un fond
	double fRadius = MIN (6, myDialogs.dialogTextDescription.iSize/2+1);
	double fLineWidth = 1.;
	cairo_set_line_width (pCairoContext, fLineWidth);
	
	cairo_save (pCairoContext);
	cairo_translate (pCairoContext, 0, fLineWidth);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iTopMargin - GAP);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);

	cairo_translate (pCairoContext, 0, iTopMargin + fLineWidth);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iHeight - iTopMargin - iBottomMargin - GAP);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);
	
	cairo_translate (pCairoContext, 0, iHeight - iTopMargin - 2*fLineWidth - iBottomMargin + GAP);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iBottomMargin - GAP - fLineWidth);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);
	cairo_restore (pCairoContext);
	
	PangoLayout *pLayout = pango_cairo_create_layout (pCairoContext);
	PangoFontDescription *pDesc = pango_font_description_new ();
	
	pango_font_description_set_absolute_size (pDesc, myDialogs.dialogTextDescription.iSize * PANGO_SCALE);
	pango_font_description_set_family_static (pDesc, myDialogs.dialogTextDescription.cFont);
	pango_font_description_set_weight (pDesc, myDialogs.dialogTextDescription.iWeight);
	pango_font_description_set_style (pDesc, myLabels.iconTextDescription.iStyle);
	pango_layout_set_font_description (pLayout, pDesc);
	pango_font_description_free (pDesc);
	
	// on dessine les entrees.
	if (pListing->pEntries != NULL)
	{
		// on dessine chaque entree.
		int iNbSteps = _listing_compute_nb_steps (pListing);  // nb d'etapes pour l'apparition du texte.
		int iOffsetX = NB_STEPS_FOR_1_ENTRY - (iNbSteps - pListing->iAppearanceAnimationCount) - 1;
		if (pListing->iNbEntries >= myConfig.iNbLinesInListing)
			iOffsetX += myConfig.iNbLinesInListing/4*NB_STEPS_LATE;  // permet de donner une transparence aux 25% dernieres lignes.
		double dx, dy, dm = myConfig.iNbLinesInListing * (myDialogs.dialogTextDescription.iSize + 2) / 2;
		dm = 0;
		dy = iTopMargin - pListing->fCurrentOffset + 1 + dm;
		double ymax = MIN (iTopMargin + pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2), iHeight - iBottomMargin);
		GList *e;
		for (e = pListing->pEntries; e != NULL; e = e->next)
		{
			if (iOffsetX >= NB_STEPS_FOR_1_ENTRY)  // en dehors a droite a partir de celui-ci.
				break ;
			pEntry = e->data;
			if (pEntry->bHidden)
				continue ;
			
			dx = myDialogs.dialogTextDescription.iSize + 2;  // marge a gauche.
			//if (iOffsetX > 0 && pListing->iAppearanceAnimationCount > 0)
			//	dx += (double) iOffsetX * (iWidth - (myDialogs.dialogTextDescription.iSize + 2)) / NB_STEPS_FOR_1_ENTRY;
			dy += (myDialogs.dialogTextDescription.iSize + 2);
			while (dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1)
				dy += pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2);
			while (dy > ymax)
				dy -= pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2);
			if (dy > ymax || dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1)
				continue;
			cairo_save (pCairoContext);
			cairo_translate (pCairoContext, dx, dy);
			
			// on fait un clip si necessaire.
			if (dy + myDialogs.dialogTextDescription.iSize + 2 > iHeight - iBottomMargin || dy < iTopMargin)  // cette entree n'est que partiellement visible.
			{
				if (dy < iTopMargin)  // elle depasse en haut.
					cairo_rectangle (pCairoContext, -iLeftMargin, iTopMargin - dy, iWidth, myDialogs.dialogTextDescription.iSize + 2 -(iTopMargin - dy));
				else  // elle depasse en bas.
					cairo_rectangle (pCairoContext, -iLeftMargin, 0, iWidth, iHeight - iBottomMargin - dy);
				cairo_clip (pCairoContext);
			}
			
			// on dessine l'icone.
			if (pEntry->pIconSurface != NULL)
			{
				cairo_set_source_surface (pCairoContext, pEntry->pIconSurface, - iLeftMargin + 1, 0.);
				cairo_paint (pCairoContext);
			}
			
			// on souligne l'entree courante.
			if (e == pListing->pCurrentEntry)
			{
				double f = 1. - (double) pListing->iCurrentEntryAnimationCount / NB_STEPS_FOR_CURRENT_ENTRY;
				if (f != 0)
				{
					cairo_save (pCairoContext);
					double rx = .5*(iWidth - iLeftMargin - iRightMargin);
					double ry = .5*(myDialogs.dialogTextDescription.iSize + 2);
					cairo_pattern_t *pPattern = cairo_pattern_create_radial (ry,
						ry,
						0.,
						ry,
						ry,
						f * ry);
					cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_NONE);
					
					cairo_pattern_add_color_stop_rgba (pPattern,
						0.,
						0., 0., 1., .3);
					cairo_pattern_add_color_stop_rgba (pPattern,
						1.,
						0., 0., 0., 0.);
					cairo_scale (pCairoContext, rx/ry, 1.);
					cairo_set_source (pCairoContext, pPattern);
					cairo_paint (pCairoContext);
					cairo_pattern_destroy (pPattern);
					cairo_restore (pCairoContext);
					
					// on dessine l'indicateur de sous-listing.
					if (pEntry->list != NULL)
					{
						cairo_set_source_rgba (pCairoContext, 0., 0., 0., f);
						cairo_move_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_rel_line_to (pCairoContext, iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_rel_line_to (pCairoContext, -iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_close_path (pCairoContext);
						cairo_stroke (pCairoContext);
					}
				}
			}
			
			// on dessine le texte.
			cairo_set_source_rgba (pCairoContext, 0., 0., 0., 1. - (double) iOffsetX / NB_STEPS_FOR_1_ENTRY);
			pango_layout_set_text (pLayout, pEntry->cName, -1);
			pango_cairo_show_layout (pCairoContext, pLayout);
			
			// on separe la 1ere entree de la derniere.
			if (e->prev == NULL)
			{
				cairo_set_source_rgba (pCairoContext, 0., 0., 0., .5);
				cairo_move_to (pCairoContext, 0., 1.);
				cairo_rel_line_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, 0.);
				double dashes = 2.;
				cairo_set_dash (pCairoContext, &dashes, 1, 0.);
				cairo_stroke (pCairoContext);
				cairo_set_dash (pCairoContext, &dashes, 0, 0.);
			}
			
			cairo_restore (pCairoContext);
			iOffsetX += NB_STEPS_LATE;
		}
		
		// on dessine le chemin de l'entree courante.
		if (pListing->pCurrentEntry)
		{
			pEntry = pListing->pCurrentEntry->data;
			cairo_save (pCairoContext);
			cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
			cairo_translate (pCairoContext, fRadius - pListing->iTitleOffset, 0.);
			pango_layout_set_text (pLayout, pEntry->cPath ? pEntry->cPath : pEntry->cName, -1);
			PangoRectangle ink, log;
			pango_layout_get_pixel_extents (pLayout, &ink, &log);
			pListing->iTitleWidth = ink.width;
			pango_cairo_show_layout (pCairoContext, pLayout);
			cairo_restore (pCairoContext);
		}
	}
	
	// on dessine l'etat de la recherche.
	cairo_translate (pCairoContext, 0, iHeight - iBottomMargin);
	cairo_set_source_surface (pCairoContext, myData.pScoobySurface, 0., 0.);
	cairo_paint (pCairoContext);
	
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	cairo_translate (pCairoContext, 2 * (myDialogs.dialogTextDescription.iSize + 2), GAP);
	if (myData.cStatus != NULL)
	{
		pango_layout_set_text (pLayout, myData.cStatus, -1);
	}
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	// on dessine le filtre.
	cairo_translate (pCairoContext, 0., myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_MATCH_CASE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F1) Match case"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_MUSIC) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F2) Music"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_IMAGE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F3) Image"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_VIDEO) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F4) Video"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_TEXT) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F5) Text"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_HTML) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F6) Html"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_SOURCE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F7) Sources"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	g_object_unref (pLayout);
}
コード例 #12
0
ファイル: SVGCanvasTextCairo.cpp プロジェクト: KastB/OpenCPN
void wxSVGCanvasTextCairo::InitText(const wxString& text, const wxCSSStyleDeclaration& style, wxSVGMatrix* matrix) {
	BeginChar(matrix);
	
	// create path from text
	cairo_t* cr = ((wxSVGCanvasPathCairo*) m_char->path)->GetCr();
	
#if defined(__WXMSW__) || defined(__WXMAC__)
	int size = (int) style.GetFontSize();
	int fstyle = style.GetFontStyle() == wxCSS_VALUE_ITALIC ? wxFONTSTYLE_ITALIC
			: (style.GetFontStyle() == wxCSS_VALUE_OBLIQUE ? wxFONTSTYLE_SLANT : wxFONTSTYLE_NORMAL);
	wxFontWeight weight = style.GetFontWeight() == wxCSS_VALUE_BOLD ? wxFONTWEIGHT_BOLD
			: style.GetFontWeight() == wxCSS_VALUE_BOLDER ? wxFONTWEIGHT_MAX
			: style.GetFontWeight() == wxCSS_VALUE_LIGHTER ? wxFONTWEIGHT_LIGHT : wxFONTWEIGHT_NORMAL;
	wxFont fnt(size, wxFONTFAMILY_DEFAULT, fstyle, weight, false, style.GetFontFamily());
#ifdef __WXMSW__
	HFONT hfont = (HFONT) fnt.GetResourceHandle();
	cairo_set_font_face(cr, cairo_win32_font_face_create_for_hfont(hfont));
#else
	CGFontRef cgFont = fnt.OSXGetCGFont();
	cairo_set_font_face(cr, cairo_quartz_font_face_create_for_cgfont(cgFont));
#endif	
	cairo_set_font_size(cr, style.GetFontSize());
	
	cairo_font_extents_t fextents;
	cairo_font_extents(cr, &fextents);
	
	double maxWidth = 0;
	if (style.GetTextAnchor() == wxCSS_VALUE_MIDDLE || style.GetTextAnchor() == wxCSS_VALUE_END) {
		wxStringTokenizer tokenzr(text, wxT("\n"));
		while (tokenzr.HasMoreTokens()) {
			wxString token = tokenzr.GetNextToken();
			cairo_text_extents_t extents;
			cairo_text_extents(cr, (const char*) token.utf8_str(), &extents);
			if (maxWidth < extents.width)
				maxWidth = extents.width;
		}
	}
	
	wxStringTokenizer tokenzr(text, wxT("\n"));
	double x_advance = 0;
	double width = 0;
	double height = 0;
	double y = 0;
	while (tokenzr.HasMoreTokens()) {
		wxString token = tokenzr.GetNextToken();
		
		// get text extents
		cairo_text_extents_t extents;
		cairo_text_extents(cr, (const char*) token.utf8_str(), &extents);
		double x = style.GetTextAnchor() == wxCSS_VALUE_END ? maxWidth - extents.width
				: style.GetTextAnchor() == wxCSS_VALUE_MIDDLE ? (maxWidth - extents.width) / 2 : 0;
		
		m_char->path->MoveTo(m_tx + x, m_ty + y);
		cairo_text_path(cr, (const char*) token.utf8_str());
		
		if (x_advance < extents.x_advance)
			x_advance = extents.x_advance;
		if (width < extents.width)
			width = extents.width;
		height += fextents.height;
		if (tokenzr.HasMoreTokens())
			y += fextents.height;
	}
	
	// set bbox
	m_char->bbox = wxSVGRect(m_tx, m_ty, width, height);
	
	// increase current position (m_tx)
	if (style.GetTextAnchor() == wxCSS_VALUE_MIDDLE || style.GetTextAnchor() == wxCSS_VALUE_END) {
		wxSVGRect bbox = m_char->path->GetResultBBox(style);
		m_tx += x_advance > bbox.GetWidth() ? x_advance : bbox.GetWidth();
	} else
		m_tx += x_advance;
#else
	PangoLayout* layout = pango_cairo_create_layout(cr);
	PangoFontDescription* font = pango_font_description_new();
	pango_font_description_set_family(font, style.GetFontFamily().ToAscii());
	pango_font_description_set_weight(font, style.GetFontWeight() == wxCSS_VALUE_BOLD ? PANGO_WEIGHT_BOLD
			: PANGO_WEIGHT_NORMAL);
	pango_font_description_set_style(font, style.GetFontStyle() == wxCSS_VALUE_ITALIC ? PANGO_STYLE_ITALIC
			: (style.GetFontStyle() == wxCSS_VALUE_OBLIQUE ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL));
	pango_font_description_set_absolute_size(font, style.GetFontSize() * PANGO_SCALE);

	PangoContext* ctx = pango_layout_get_context(layout);
	PangoFont* f = pango_context_load_font(ctx, font);
	if (f == NULL)
		pango_font_description_set_style(font, PANGO_STYLE_NORMAL);
	pango_layout_set_font_description(layout, font);
	
	if (style.GetTextAnchor() != wxCSS_VALUE_START)
		pango_layout_set_alignment(layout, style.GetTextAnchor() == wxCSS_VALUE_MIDDLE ? PANGO_ALIGN_CENTER : PANGO_ALIGN_RIGHT);
	pango_layout_set_text(layout, (const char*) text.utf8_str(), -1);
	
	int baseline = pango_layout_get_baseline(layout);
	m_char->path->MoveTo(m_tx, m_ty - ((double)baseline / PANGO_SCALE));
	pango_cairo_layout_path(cr, layout);
	
	// set bbox and increase current position (m_tx)
	int lwidth, lheight;
	pango_layout_get_size(layout, &lwidth, &lheight);
	double width = ((double)lwidth / PANGO_SCALE);
	double height = ((double)lheight / PANGO_SCALE);
	m_char->bbox = wxSVGRect(m_tx, m_ty, width, height);
	if (style.GetTextAnchor() == wxCSS_VALUE_MIDDLE || style.GetTextAnchor() == wxCSS_VALUE_END) {
		wxSVGRect bbox = m_char->path->GetResultBBox(style);
		m_tx += width > bbox.GetWidth() ? width : bbox.GetWidth();
	} else
		m_tx += width;
		
	g_object_unref(layout);
	pango_font_description_free(font);
#endif
}
コード例 #13
0
ファイル: attractor_view.c プロジェクト: oliviaguest/smm
static void gtk_attractor_view_paint(GtkWidget *widget)
{
    GtkAttractor_View *attractor_view = GTK_ATTRACTOR_VIEW(widget);






    int width, height;
    PangoLayout *layout;
    CairoxTextParameters text_p;
    char buffer[64];
    cairo_t *cr;
    int p, c;

    width = widget->allocation.width;
    height = widget->allocation.height;

    cr = gdk_cairo_create(widget->window);

    /* Transparent background */
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
    cairo_paint(cr);
    //int current_attractor_i = ((iterations_so_far) && (iterations_so_far < C_MAX)) ? (iterations_so_far) : (0);
    layout = pango_cairo_create_layout(cr);
// 	if (!training) {
//         g_snprintf(buffer, 64, "Step: %d", step_number);
//         cairox_text_parameters_set(&text_p, 20, height-20, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0);
//         cairox_paint_pango_text(cr, &text_p, layout, buffer);

    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_set_line_width(cr, 1);

// 	  cairo_rectangle(cr, 20, 20, 120, 80);
    cairo_rectangle(cr, X_MARGIN, Y_MARGIN, width - (2.0 * X_MARGIN), height - (2.0 * Y_MARGIN));
    cairo_stroke_preserve(cr);
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_fill(cr);

    double n_rows = (double) (P + 6);
    double row_height = (height - (Y_MARGIN*2)) / n_rows;

    double n_columns = ATTRACTOR_LESION_LEVEL + 1.0;
    double column_width = (width - (X_MARGIN*2)) / n_columns;

    int smaller_font_size = 14, bigger_font_size = 16;
    if (n_rows > 36) {
        smaller_font_size = 12;
        bigger_font_size = 15;
    }

    pangox_layout_set_font_size(layout, bigger_font_size);
    g_snprintf(buffer, 64, "Pattern Name");
    cairox_text_parameters_set(&text_p, X_MARGIN*2, row_height*2, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0);
    cairox_paint_pango_text(cr, &text_p, layout, buffer);

    for (c = 0; c < ATTRACTOR_LESION_LEVEL; c++) {
        g_snprintf(buffer, 64, "%1.1f%% Lesioned", c * 100.0 / (double) ATTRACTOR_LESION_LEVEL);
        cairox_text_parameters_set(&text_p, column_width*(c+1), row_height*2, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0);
        cairox_paint_pango_text(cr, &text_p, layout, buffer);
    }


    pangox_layout_set_font_size(layout, smaller_font_size);

    for (p = 0; p < P; p++) {
        g_snprintf(buffer, 64, "%s", get_name_string(p));
        cairox_text_parameters_set(&text_p, X_MARGIN*2, (p+4)* row_height, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0);
        cairox_paint_pango_text(cr, &text_p, layout, buffer);
    }

    if (attractor_view->response[0][0][0] != -1) {

        for (c = 0; c < ATTRACTOR_LESION_LEVEL; c++) {

            for (p = 0; p < P; p++) {
                g_snprintf(buffer, 64, "%s", get_name_string(attractor_view->response[c][attractor_view->type][p]));
                cairox_text_parameters_set(&text_p, column_width*(c+1), (p+4)* row_height, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0);
                cairox_paint_pango_text(cr, &text_p, layout, buffer);
            }
        }
    }





    g_object_unref(layout);

    cairo_destroy(cr);

}
コード例 #14
0
ファイル: navigation.c プロジェクト: WhiteSymmetry/darktable
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;
}
コード例 #15
0
static gboolean _tristatebutton_expose(GtkWidget *widget, GdkEventExpose *event)
{
  g_return_val_if_fail(widget != NULL, FALSE);
  g_return_val_if_fail(DTGTK_IS_TRISTATEBUTTON(widget), FALSE);
  g_return_val_if_fail(event != NULL, FALSE);
  GtkStyle *style = gtk_widget_get_style(widget);
  int state = gtk_widget_get_state(widget);

  /* fix text style */
  for(int i = 0; i < 5; i++) style->text[i] = style->fg[i];

  /* fetch flags */
  int flags = DTGTK_TRISTATEBUTTON(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 = DTGTK_TRISTATEBUTTON(widget)->state > 0;
  if(active)
    flags |= CPF_ACTIVE;
  else
    flags &= ~(CPF_ACTIVE);


  /* begin cairo drawing */
  cairo_t *cr;
  cr = gdk_cairo_create(gtk_widget_get_window(widget));

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int x = allocation.x;
  int y = allocation.y;
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent nor flat styled */
  if((flags & CPF_STYLE_FLAT))
  {
    if(state != GTK_STATE_NORMAL)
    {
      cairo_rectangle(cr, x, y, width, height);
      cairo_set_source_rgba(cr, style->bg[state].red / 65535.0, style->bg[state].green / 65535.0,
                            style->bg[state].blue / 65535.0, 0.5);
      cairo_fill(cr);
    }
  }
  else if(!(flags & CPF_BG_TRANSPARENT))
  {
    cairo_rectangle(cr, x, y, width, height);
    float rs = 1.0, gs = 1.0, bs = 1.0;

    if(DTGTK_TRISTATEBUTTON(widget)->state == 1)
      rs = gs = bs = 3.0;
    else if(DTGTK_TRISTATEBUTTON(widget)->state == 2)
      rs = 3.0;

    cairo_set_source_rgba(cr, (style->bg[state].red / 65535.0) * rs, (style->bg[state].green / 65535.0) * gs,
                          (style->bg[state].blue / 65535.0) * bs, 0.5);
    cairo_fill(cr);
  }

  /* 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);
  }

  cairo_set_source_rgb(cr, style->fg[state].red / 65535.0, style->fg[state].green / 65535.0,
                       style->fg[state].blue / 65535.0);

  /* draw button image if any */
  GtkWidget *image = gtk_button_get_image(GTK_BUTTON(widget));
  if(image)
  {
    GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image));

    if(pixbuf)
    {
      /* Draw the pixbuf */
      gint pbw = gdk_pixbuf_get_width(pixbuf);
      gint pbh = gdk_pixbuf_get_height(pixbuf);
      gdk_cairo_set_source_pixbuf(cr, pixbuf, allocation.x + ((allocation.width / 2) - (pbw / 2)),
                                  allocation.y + ((allocation.height / 2) - (pbh / 2)));
      cairo_paint(cr);
    }
  }


  /* draw icon */
  if(DTGTK_TRISTATEBUTTON(widget)->icon)
  {
    //     if (flags & CPF_IGNORE_FG_STATE)
    //       state = GTK_STATE_NORMAL;


    if(text)
      DTGTK_TRISTATEBUTTON(widget)
          ->icon(cr, x + border, y + border, height - (border * 2), height - (border * 2), flags);
    else
      DTGTK_TRISTATEBUTTON(widget)
          ->icon(cr, x + border, y + border, width - (border * 2), height - (border * 2), flags);
  }


  /* draw label */
  if(text)
  {
    int lx = x + DT_PIXEL_APPLY_DPI(2), ly = y + ((height / 2.0) - (ph / 2.0));
    cairo_translate(cr, lx, ly);
    pango_cairo_show_layout(cr, layout);
    g_object_unref(layout);
  }

  cairo_destroy(cr);

  return FALSE;
}
コード例 #16
0
ファイル: togglebutton.c プロジェクト: EvilBit/darktable
static gboolean _togglebutton_expose(GtkWidget *widget, GdkEventExpose *event)
{
  g_return_val_if_fail (widget != NULL, FALSE);
  g_return_val_if_fail (DTGTK_IS_TOGGLEBUTTON(widget), FALSE);
  g_return_val_if_fail (event != NULL, FALSE);
  GtkStyle *style=gtk_widget_get_style(widget);
  int state = gtk_widget_get_state(widget);

  /* fix text style */
  for(int i=0; i<5; i++)
    style->text[i]=style->fg[i];

  /* fetch flags */
  int flags = DTGTK_TOGGLEBUTTON (widget)->icon_flags;

  /* set inner border */
  int border = (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_PRELIGHT)
    flags |= CPF_PRELIGHT;
  else
    flags &=~CPF_PRELIGHT;

  /* begin cairo drawing */
  cairo_t *cr;
  cr = gdk_cairo_create (gtk_widget_get_window(widget));

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int x = allocation.x;
  int y = allocation.y;
  int width = allocation.width;
  int height = allocation.height;

  /* draw standard button background if not transparent nor flat styled */
  if( (flags & CPF_STYLE_FLAT ))
  {
    if( state != GTK_STATE_NORMAL )
    {
      cairo_rectangle (cr,x,y,width,height);
      cairo_set_source_rgba (cr,
                             style->bg[state].red/65535.0,
                             style->bg[state].green/65535.0,
                             style->bg[state].blue/65535.0,
                             0.5);
      cairo_fill (cr);
    }
  }
  else if( !(flags & CPF_BG_TRANSPARENT) )
  {
    /* draw default boxed button */
    gtk_paint_box (gtk_widget_get_style(widget), gtk_widget_get_window(widget),
                   gtk_widget_get_state(widget),
                   GTK_SHADOW_OUT, NULL, widget, "button",
                   x, y, 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,style->font_desc);
    pango_layout_set_text (layout,text,-1);
    pango_layout_get_pixel_size (layout,&pw,&ph);
  }

  cairo_set_source_rgb (cr,
                        style->fg[state].red/65535.0,
                        style->fg[state].green/65535.0,
                        style->fg[state].blue/65535.0);

  /* draw icon */
  if (DTGTK_TOGGLEBUTTON (widget)->icon)
  {
//     if (flags & CPF_IGNORE_FG_STATE)
//       state = GTK_STATE_NORMAL;


    if (text)
      DTGTK_TOGGLEBUTTON (widget)->icon (cr,x+border,y+border,height-(border*2),height-(border*2),flags);
    else
      DTGTK_TOGGLEBUTTON (widget)->icon (cr,x+border,y+border,width-(border*2),height-(border*2),flags);
  }


  /* draw label */
  if (text)
  {
    int lx=x+2, ly=y+((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);
  }

  cairo_destroy (cr);

  return FALSE;
}
コード例 #17
0
ファイル: env.c プロジェクト: Andy753421/grits
/* Info */
static void info_expose(GritsCallback *compass, GritsOpenGL *opengl, gpointer _env)
{
	GtkAllocation alloc;
	gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);

	/* Create cairo  surface */
	guint            tex     = 0;
	const gchar     *label0  = "Location: %7.3lf°, %8.3lf°, %4.0fm";
	const gchar     *label1  = "Cursor:   %7.3lf°, %8.3lf°, %4.0fm";
	gdouble          width   = 300;
	gdouble          height  = 200;
	cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
	cairo_t         *cairo   = cairo_create(surface);

	/* Text */
	gdouble lat, lon, elev;
	grits_viewer_get_location(GRITS_VIEWER(opengl), &lat, &lon, &elev);
	gchar *text0 = g_strdup_printf(label0, lat, lon, elev);
	gchar *text1 = g_strdup_printf(label1, lat, lon, elev);

	/* Draw outline */
	cairo_set_line_width(cairo, 3);
	cairo_set_source_rgba(cairo, 0, 0, 0, 0.75);
	cairo_move_to(cairo, 2, 20); cairo_text_path(cairo, text0);
	cairo_move_to(cairo, 2, 40); cairo_text_path(cairo, text1);
	cairo_stroke(cairo);

	/* Draw filler */
	cairo_set_source_rgba(cairo, 1, 1, 1, 1);
	cairo_move_to(cairo, 2, 20); cairo_show_text(cairo, text0);
	cairo_move_to(cairo, 2, 40); cairo_show_text(cairo, text1);

	/* Setup pango */
	PangoLayout          *layout = pango_cairo_create_layout(cairo);
	PangoFontDescription *font   = pango_font_description_from_string("Mono 9");
	pango_layout_set_font_description(layout, font);
	pango_font_description_free(font);
	pango_layout_set_text(layout, text0, -1);
	pango_cairo_update_layout(cairo, layout);
	cairo_set_line_join(cairo, CAIRO_LINE_JOIN_ROUND);
	cairo_move_to(cairo, 2, 40);
	pango_cairo_layout_path(cairo, layout);
	for (float w = 0.2; w <= 0.8; w+=0.2) {
		cairo_set_line_width(cairo, (1-w)*8);
		cairo_set_source_rgba(cairo, 0, 0, 0, w);
		cairo_stroke_preserve(cairo);
	}
	cairo_set_source_rgba(cairo, 1, 1, 1, 1);
	pango_cairo_show_layout(cairo, layout);

	/* Load GL texture */
	glEnable(GL_TEXTURE_2D);
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height,
	        0, GL_BGRA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface));
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	/* Draw surface */
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex);
	glDisable(GL_CULL_FACE);
	glTranslatef(alloc.width - width, alloc.height - height, 0);
	glBegin(GL_QUADS);
	glTexCoord2f(1, 0); glVertex3f(width, 0     , 0); // 0 - 3    0
	glTexCoord2f(1, 1); glVertex3f(width, height, 0); // 1 - |    |
	glTexCoord2f(0, 1); glVertex3f(0    , height, 0); // 2 - |    |
	glTexCoord2f(0, 0); glVertex3f(0    , 0     , 0); // 3 - 2----1
	glEnd();
}
コード例 #18
0
cairo_surface_t*
render_text_to_surface (gchar*                      text,
			gint                        width,
			gint                        height,
			const cairo_font_options_t* font_opts,
			gdouble                     dpi)
{
	cairo_surface_t*      surface;
	cairo_t*              cr;
	PangoFontDescription* desc;
	PangoLayout*          layout;

	// sanity check
	if (!text      ||
	    width <= 0 ||
	    height <= 0)
		return NULL;

	// create surface
	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					      width,
					      height);
	if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
		return NULL;

	// create context
	cr = cairo_create (surface);
	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
	{
		cairo_surface_destroy (surface);
		return NULL;
	}

	// clear context
	cairo_scale (cr, 1.0f, 1.0f);
	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint (cr);

	//
	layout = pango_cairo_create_layout (cr);
	desc = pango_font_description_new ();

	pango_font_description_set_size (desc, 12 * PANGO_SCALE);
	pango_font_description_set_family_static (desc, "Candara");
	pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);

	pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);
	pango_layout_set_width (layout, width * PANGO_SCALE);
	pango_layout_set_height (layout, height * PANGO_SCALE);
	pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);

	// print and layout string (pango-wise)
	pango_layout_set_text (layout, text, -1);

	// make sure system-wide font-options like hinting, antialiasing etc.
	// are taken into account
	pango_cairo_context_set_font_options (pango_layout_get_context (layout),
					      font_opts);
	pango_cairo_context_set_resolution  (pango_layout_get_context (layout),
					     dpi);
	pango_layout_context_changed (layout);

	// draw pango-text to our cairo-context
	cairo_move_to (cr, 0.0f, 0.0f);
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);

	// this call leaks 3803 bytes, I've no idea how to fix that
	pango_cairo_show_layout (cr, layout);

	// clean up
	g_object_unref (layout);
	cairo_destroy (cr);

	return surface;	
}
コード例 #19
0
ファイル: ppg-ruler.c プロジェクト: chergert/perfkit
/**
 * ppg_ruler_draw_ruler:
 * @ruler: (in): A #PpgRuler.
 *
 * Draws the background of the ruler containing the time values and ticks
 * to an offscreen pixmap that can be blitted to the widget during
 * "expose-event".
 *
 * Returns: None.
 * Side effects: None.
 */
static void
ppg_ruler_draw_ruler (PpgRuler *ruler)
{
	PpgRulerPrivate *priv;
	GtkAllocation alloc;
	PangoLayout *layout;
	cairo_t *cr;
	GtkStyle *style;
	GdkColor text_color;
	gint text_width;
	gint text_height;
	gdouble every = 1.0;
	gdouble n_seconds;
	gdouble v;
	gdouble p;
	gint pw;
	gint ph;
	gint x;
	gint xx;
	gint n;
	gint z = 0;

	g_return_if_fail(PPG_IS_RULER(ruler));

	priv = ruler->priv;

	gtk_widget_get_allocation(GTK_WIDGET(ruler), &alloc);
	style = gtk_widget_get_style(GTK_WIDGET(ruler));
	cr = cairo_create(priv->ruler);

	cairo_save(cr);
	cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
	cairo_rectangle(cr, 0, 0, alloc.width, alloc.height);
	cairo_fill(cr);
	cairo_restore(cr);

	text_color = style->text[GTK_STATE_NORMAL];
	cairo_set_line_width(cr, 1.0);
	gdk_cairo_set_source_color(cr, &text_color);

	layout = pango_cairo_create_layout(cr);
	pango_layout_set_font_description(layout, priv->font_desc);
	pango_layout_set_markup(layout, "00:00:00.000", -1);
	pango_layout_get_pixel_size(layout, &text_width, &text_height);
	text_width += 5;

	n_seconds = priv->upper - priv->lower;
	if ((alloc.width / n_seconds) < text_width) {
		every = ceil(text_width / (alloc.width / n_seconds));
	}

	for (v = floor(priv->lower); v < priv->upper; v += every) {
		gdk_cairo_set_source_color(cr, &text_color);
		x = get_x_offset(priv, &alloc, v);
		cairo_move_to(cr, x + 0.5, alloc.height - 1.5);
		cairo_line_to(cr, x + 0.5, 0.5);

		/*
		 * Mini lines.
		 */
		for (p = v, n = 0, z = 0;
		     p < v + every;
		     p += (every / 10), n++, z++)
		{
			if (n == 0 || n == 10) {
				continue;
			}

			xx = get_x_offset(priv, &alloc, p);
			cairo_move_to(cr, xx + 0.5, alloc.height - 1.5);
			if (z % 2 == 0) {
				cairo_line_to(cr, xx + 0.5, text_height + 8.5);
			} else {
				cairo_line_to(cr, xx + 0.5, text_height + 5.5);
			}
		}

		cairo_stroke(cr);

		cairo_move_to(cr, x + 1.5, 1.5);
		ppg_ruler_update_layout_text(ruler, layout,
		                             CLAMP(v, priv->lower, priv->upper));

		/*
		 * If there is enough room to draw this layout before we get to the
		 * next layout, then draw it.
		 */
		pango_layout_get_pixel_size(layout, &pw, &ph);
		if ((x + pw) < get_x_offset(priv, &alloc, floor(v) + every)) {
			pango_cairo_show_layout(cr, layout);
		}
	}

	g_object_unref(layout);
	cairo_destroy(cr);
}
コード例 #20
0
ファイル: contingcs.c プロジェクト: gcms/gustavo
static void
conting_cs_draw(ContingDrawing *self, cairo_t *cr)
{
    ContingSymbol *symb;
    ContingComponent *comp;
	GdkColor *color;

    ArtPoint pw0, pw1;
    GdkRectangle rect;
	gdouble affine[6];

    g_return_if_fail(self != NULL && CONTING_IS_CS(self));

    symb = CONTING_SYMBOL(self);
    comp = CONTING_COMPONENT(self);

	g_object_get(self, "color", &color, NULL);

    pw0 = comp->p0;
    pw1 = comp->p1;

    rect.x = (pw0.x < pw1.x ? pw0.x : pw1.x);
    rect.y = (pw0.y < pw1.y ? pw0.y : pw1.y);
    rect.width = fabs(pw1.x - pw0.x);
    rect.height = fabs(pw1.y - pw0.y);

	cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);

	cairo_arc(cr,
			rect.x + ((gdouble) rect.width / 2.0),
			rect.y + ((gdouble) rect.height / 2.0),
			(gdouble) rect.width / 2.0, 0, 2 * M_PI);
	cairo_set_source_rgb(cr,
			(gdouble) color->red / (gdouble) G_MAXUINT16,
			(gdouble) color->green / (gdouble) G_MAXUINT16,
			(gdouble) color->blue / (gdouble) G_MAXUINT16);
	cairo_stroke(cr);

	cr = conting_drawing_get_cairo_absolute(self);
	conting_drawing_get_i2w_affine_absolute(self, affine);
	cairo_transform(cr, (cairo_matrix_t *) affine);
	cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
	
	cairo_set_source_rgb(cr,
			(gdouble) color->red / (gdouble) G_MAXUINT16,
			(gdouble) color->green / (gdouble) G_MAXUINT16,
			(gdouble) color->blue / (gdouble) G_MAXUINT16);
    {
        PangoLayout *layout;
        PangoFontDescription *font;

        layout = pango_cairo_create_layout(cr);

        font = pango_font_description_new();
        pango_font_description_set_size(font, 4 * PANGO_SCALE);
    /*  g_print("size = %d\n", pango_font_description_get_size(font)); */
        pango_font_description_set_family_static(font, "Arial");
        pango_font_description_set_style(font, PANGO_STYLE_NORMAL);

        pango_layout_set_font_description(layout, font);
        pango_layout_set_text(layout, "CS", 2);
		
		cairo_move_to(cr, pw0.x + 1, pw0.y + 2);
		pango_cairo_update_layout(cr, layout);
		pango_cairo_show_layout(cr, layout);

		g_object_unref(layout);
	}


	cairo_stroke(cr);

	cairo_destroy(cr);

	CONTING_DRAWING_CLASS(parent_class)->draw(self, cr);
}
コード例 #21
0
ファイル: ogra2cairo.c プロジェクト: htrb/ngraph-gtk
static void
draw_str(struct gra2cairo_local *local, int draw, char *str, struct fontmap *font, int size, int space, int *fw, int *ah, int *dh)
{
  PangoAttribute *attr;
  PangoAttrList *alist;
  PangoLayoutIter *piter;
  int w, h, baseline;

  if (size == 0 || str == NULL) {
    if (fw)
      *fw = 0;

    if (ah)
      *ah = 0;

    if (dh)
      *dh = 0;
    return;
  }

  if (local->layout == NULL) {
    local->layout = pango_cairo_create_layout(local->cairo);
  }

  alist = pango_attr_list_new();
  attr = pango_attr_size_new_absolute(mxd2ph(local, size) * PANGO_SCALE);
  pango_attr_list_insert(alist, attr);

  attr = pango_attr_letter_spacing_new(mxd2ph(local, space) * PANGO_SCALE);
  pango_attr_list_insert(alist, attr);

  pango_layout_set_font_description(local->layout, font->font);
  pango_layout_set_attributes(local->layout, alist);
  pango_attr_list_unref(alist);

  pango_layout_set_text(local->layout, str, -1);

  pango_layout_get_pixel_size(local->layout, &w, &h);
  piter = pango_layout_get_iter(local->layout);
  baseline = pango_layout_iter_get_baseline(piter) / PANGO_SCALE;

  if (fw)
    *fw = w;

  if (ah)
    *ah = baseline;

  if (dh)
    *dh = h - baseline;

  if (draw && str) {
    double x, y;
    double cx, cy;

    x = - local->fontsin * baseline;
    y = - local->fontcos * baseline;

    cairo_get_current_point(local->cairo, &cx, &cy);
    relative_move(local->cairo, x, y);

    cairo_save(local->cairo);
    cairo_rotate(local->cairo, -local->fontdir * G_PI / 180.);
    pango_cairo_update_layout(local->cairo, local->layout);
    if (local->text2path) {
      pango_cairo_layout_path(local->cairo, local->layout);
      cairo_fill(local->cairo);
      cairo_restore(local->cairo);
      cairo_move_to(local->cairo, cx + w * local->fontcos, cy - w * local->fontsin);
    } else {
      pango_cairo_show_layout(local->cairo, local->layout);
      cairo_restore(local->cairo);
      relative_move(local->cairo, w * local->fontcos - x, - w * local->fontsin - y);
    }
  }

  pango_layout_iter_free(piter);
}
コード例 #22
0
void render_glyph(
	cairo_t* cr,
	PangoFontDescription* font_desc,
	PangoFont* font,
	const guint code_point,
	const size_t cell_x,
	const size_t cell_y,
	const size_t cell_size,
	const double tex_size,
	const int ascent,
	const int descent,
	std::ostream& bgm_out
)
{
	PangoLayout *layout = pango_cairo_create_layout(cr);

	char str[6] = {'\0'};
	size_t len = 0;
	oglplus::aux::ConvertCodePointToUTF8(code_point, str, len);

	pango_layout_set_font_description(layout, font_desc);
	pango_layout_set_text(layout, str, len);

	const int baseline = pango_layout_get_baseline(layout);
	const double inv_ps = 1.0 / double(PANGO_SCALE);
	const double font_size = ascent+descent;

	PangoRectangle ink_rect, log_rect;
	pango_layout_get_extents(
		layout,
		&ink_rect,
		&log_rect
	);

	// code point number
	bgm_out << code_point << std::endl;
	// hex representation of the number
	bgm_out	<< std::hex
		<< "0x"
		<< code_point
		<< std::dec
		<< std::endl;
	// the utf-8 sequence
	bgm_out << "'" << str << "'" << std::endl;
	//
	// vertex[0] logical rectangle metrics
	//
	// Left bearing (x)
	bgm_out << PANGO_LBEARING(log_rect)/font_size << std::endl;
	// Right bearing (x+width)
	bgm_out << PANGO_RBEARING(log_rect)/font_size << std::endl;
	// Ascent
	bgm_out << (baseline-log_rect.y)/font_size << std::endl;
	// Descent
	bgm_out << (log_rect.height+log_rect.y-baseline)/font_size << std::endl;
	//
	// vertex[1] ink rectangle metrics
	//
	// Left bearing (x)
	bgm_out << PANGO_LBEARING(ink_rect)/font_size << std::endl;
	// Right bearing (x+width)
	bgm_out << PANGO_RBEARING(ink_rect)/font_size << std::endl;
	// Ascent
	bgm_out << (baseline-ink_rect.y)/font_size << std::endl;
	// Descent
	bgm_out << (ink_rect.y+ink_rect.height-baseline)/font_size << std::endl;
	//
	// vertex[2] texture coordinates
	//
	// Origin X
	bgm_out << (cell_x*cell_size+ink_rect.x*inv_ps)/tex_size << std::endl;
	// Origin Y
	bgm_out << 1.0-(cell_y*cell_size+baseline*inv_ps)/tex_size << std::endl;
	// Width
	bgm_out << ((ink_rect.width)*inv_ps)/tex_size << std::endl;
	// Height
	bgm_out << ((ink_rect.height)*inv_ps)/tex_size << std::endl;


	// separating newline
	bgm_out << std::endl;

	cairo_new_path(cr);
	cairo_move_to(cr, cell_x*cell_size, cell_y*cell_size);
	cairo_set_line_width(cr, 0.5);

	pango_cairo_update_layout(cr, layout);
	pango_cairo_layout_path(cr, layout);
	cairo_fill(cr);

	g_object_unref(layout);
}
コード例 #23
0
ファイル: hb-export.c プロジェクト: maxiwell/homebank
static void hb_pdf_draw_line(PdfPrintContext *ppc, cairo_t *cr, gdouble y, gboolean bold, gboolean rulehint)
{
PangoLayout *layout;
gint i;
gdouble x;

	/* Create a PangoLayout, set the font and text */
	layout = pango_cairo_create_layout (cr);

	//desc = pango_font_description_from_string (FONT);
	if(bold)
		pango_font_description_set_weight(ppc->desc, PANGO_WEIGHT_BOLD);
	else
		pango_font_description_set_weight(ppc->desc, PANGO_WEIGHT_NORMAL);

	pango_layout_set_font_description (layout, ppc->desc);

	
	x = ppc->ml;

	/* rule hint */
	#if RULEHINT == 1
	if( rulehint )
	{
		cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
		cairo_rectangle (cr, x, y, ppc->w - ppc->ml - ppc->mr, PDF_FONT_NORMAL);
		cairo_fill(cr);
	}
	#endif


	cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
	cairo_move_to(cr, x, y);

	for(i=0;i<PDF_NUMCOL;i++)
	{
		if(ppc->column_txt[i] != NULL)
		{
		int width, height;

			pango_layout_set_text (layout, ppc->column_txt[i], -1);
			pango_layout_get_size (layout, &width, &height);
			if( i==1 || i==2 || i==3 )
			{
				pango_layout_set_width(layout, ppc->column_width[i]*PANGO_SCALE);
				pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
			}

			//cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
			
			if( i==0 || i==4 || i==6 ) // pad right: date/amount/balance
			{
				//if(*ppc->column_txt[i] != '-')
				   //cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.66); //grey
				cairo_move_to(cr, x + ppc->column_width[i] - (width/PANGO_SCALE) , y);
			}
			else
				cairo_move_to(cr, x, y);
			
			pango_cairo_show_layout (cr, layout);

			/* test line */
			/*cairo_set_line_width(cr, 1.0);
			cairo_move_to(cr, x, y + .5);
			cairo_line_to(cr, x + ppc->column_width[i], y+.5);
			cairo_stroke(cr);
			*/
			
		}
		x += ppc->column_width[i] + PDF_COL_MARGIN;
	}

	g_object_unref (layout);	

}