Пример #1
0
/* {EV_FONT_IMP}.string_size */
EIF_REFERENCE F1035_13204 (EIF_REFERENCE Current, EIF_REFERENCE arg1)
{
	GTCX
	EIF_REFERENCE loc1 = (EIF_REFERENCE) 0;
	EIF_POINTER loc2 = (EIF_POINTER) 0;
	EIF_POINTER loc3 = (EIF_POINTER) 0;
	EIF_POINTER loc4 = (EIF_POINTER) 0;
	EIF_POINTER loc5 = (EIF_POINTER) 0;
	EIF_INTEGER_32 loc6 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc7 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc8 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc9 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc10 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc11 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc12 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc13 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc14 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc15 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc16 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc17 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc18 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc19 = (EIF_INTEGER_32) 0;
	EIF_INTEGER_32 loc20 = (EIF_INTEGER_32) 0;
	EIF_REFERENCE loc21 = (EIF_REFERENCE) 0;
	EIF_POINTER tp1;
	EIF_POINTER tp2;
	EIF_INTEGER_32 ti4_1;
	EIF_REFERENCE Result = ((EIF_REFERENCE) 0);
	
	RTLD;
	
	RTLI(5);
	RTLR(0,loc21);
	RTLR(1,Current);
	RTLR(2,loc1);
	RTLR(3,arg1);
	RTLR(4,Result);
	
	RTGC;
	loc21 = RTOSCF(13229,F1035_13229,(Current));
	loc1 = F1049_13651(RTCV(loc21), arg1);
	loc2 = RTOSCF(8093,F791_8093,(RTCV(loc21)));
	tp1 = *(EIF_POINTER *)(RTCV(loc1)+ _PTROFF_0_1_0_1_0_0_);
	ti4_1 = *(EIF_INTEGER_32 *)(RTCV(loc1)+ _LNGOFF_0_1_0_0_);
	pango_layout_set_text((PangoLayout*) loc2, (char*) tp1, (int) ti4_1);
	tp1 = *(EIF_POINTER *)(Current+ _PTROFF_3_2_0_8_0_0_);
	pango_layout_set_font_description((PangoLayout*) loc2, (PangoFontDescription*) tp1);
	loc4 = (EIF_POINTER) calloc (sizeof(PangoRectangle), 1);
	loc5 = RTOSCF(13207,F1035_13207,(Current));
	pango_layout_get_pixel_extents((PangoLayout*) loc2, (PangoRectangle*) loc4, (PangoRectangle*) loc5);
	loc3 = F791_8094(RTCV(loc21));
	loc20 = (EIF_INTEGER_32) pango_layout_iter_get_baseline((PangoLayoutIter*) loc3);
	ti4_1 = (EIF_INTEGER_32) PANGO_SCALE;
	loc20 = (EIF_INTEGER_32) (EIF_INTEGER_32) (loc20 / ti4_1);
	pango_layout_iter_free((PangoLayoutIter*) loc3);
	loc6 = (EIF_INTEGER_32) (((PangoRectangle *)loc5)->x);
	loc7 = (EIF_INTEGER_32) (((PangoRectangle *)loc5)->y);
	loc8 = (EIF_INTEGER_32) (((PangoRectangle *)loc5)->width);
	loc9 = (EIF_INTEGER_32) (((PangoRectangle *)loc5)->height);
	loc10 = (EIF_INTEGER_32) (((PangoRectangle *)loc4)->x);
	loc11 = (EIF_INTEGER_32) (((PangoRectangle *)loc4)->y);
	loc12 = (EIF_INTEGER_32) (((PangoRectangle *)loc4)->width);
	loc13 = (EIF_INTEGER_32) (((PangoRectangle *)loc4)->height);
	loc14 = (EIF_INTEGER_32) loc8;
	loc15 = (EIF_INTEGER_32) loc9;
	if ((EIF_BOOLEAN) (loc12 > ((EIF_INTEGER_32) 0L))) {
		loc16 = (EIF_INTEGER_32) loc10;
		loc17 = (EIF_INTEGER_32) (EIF_INTEGER_32) ((EIF_INTEGER_32) (loc16 + loc12) - loc8);
	}
	if ((EIF_BOOLEAN) (loc13 > ((EIF_INTEGER_32) 0L))) {
		loc18 = (EIF_INTEGER_32) loc11;
		loc19 = (EIF_INTEGER_32) (EIF_INTEGER_32) ((EIF_INTEGER_32) (loc18 + loc13) - loc9);
	}
	Result = RTOSCF(13205,F1035_13205,(Current));
	ti4_1 = eif_max_int32 (loc14,((EIF_INTEGER_32) 1L));
	F842_8563(RTCV(Result), ti4_1, ((EIF_INTEGER_32) 1L));
	ti4_1 = eif_max_int32 (loc15,((EIF_INTEGER_32) 1L));
	F842_8563(RTCV(Result), ti4_1, ((EIF_INTEGER_32) 2L));
	F842_8563(RTCV(Result), loc16, ((EIF_INTEGER_32) 3L));
	F842_8563(RTCV(Result), loc17, ((EIF_INTEGER_32) 4L));
	F842_8563(RTCV(Result), loc20, ((EIF_INTEGER_32) 5L));
	F842_8563(RTCV(Result), loc18, ((EIF_INTEGER_32) 6L));
	F842_8563(RTCV(Result), loc19, ((EIF_INTEGER_32) 7L));
	free(loc4);
	{
	/* INLINED CODE (default_pointer) */
	tp1 = (EIF_POINTER)  0;
	/* END INLINED CODE */
	}
	tp2 = tp1;
	pango_layout_set_font_description((PangoLayout*) loc2, (PangoFontDescription*) tp2);
	RTLE;
	return Result;
}
Пример #2
0
/* Smith.c: Routines for plotting Smith charts */
void gtk_graph_smith_plot_axes(GtkGraph *graph)
{
gint i ;
gint x, y, w, h;
gfloat ri[] = {0.2, 0.5, 1.0, 2.0, 5.0}, rxl[]={0.20, 0.5, 1, 2, 5}, coeff1, r, store, arc_angle;
gfloat yend, xend; // The x and y co-ordinates of the end of the reactance lines
gchar label[10];
gint text_width, text_height;
gint xpos = 0, ypos = 0;		// X and Y co-ordinate locations of radial labels

PangoFontDescription *fontdesc = NULL;
PangoLayout *layout = NULL;

g_return_if_fail (graph != NULL);
g_return_if_fail (GTK_IS_GRAPH (graph));
g_return_if_fail (GTK_WIDGET_REALIZED (graph));
g_return_if_fail (graph->graph_type == SMITH);

fontdesc = pango_font_description_from_string("Sans 10");
layout = gtk_widget_create_pango_layout(GTK_WIDGET(graph), NULL);
pango_layout_set_font_description(layout, fontdesc);

/* Plot the concentric grid */

centre_x = user_origin_x + user_width / 2;
centre_y = user_origin_y + user_width / 2;
gdk_draw_arc(buffer, Gridcontext, FALSE, centre_x - graph->dependant->scale_factor, centre_y - graph->dependant->scale_factor, 2.0 * graph->dependant->scale_factor, 2.0 * graph->dependant->scale_factor, 0, 23040);

for (i = 0 ; i < 5 ; i++)
	{
/* Draw the circles of Constant Resistance */
	coeff1 = ri[i] / (1.0+ri[i]);
	r = 1.0 / (ri[i] + 1.0);
	x = centre_x + (gint)((coeff1 - r) * graph->dependant->scale_factor);
	y = centre_y - (gint) (r * graph->dependant->scale_factor);
	w = 2.0 * r * graph->dependant->scale_factor;
	h = 2.0 * r * graph->dependant->scale_factor;
	gdk_draw_arc(buffer, Gridcontext, FALSE, x, y, w, h, 0, 23039);
		
	g_snprintf(label, 10, "%.0f", ri[i] * graph->smith_Z0);
    pango_layout_set_text(layout, label, -1);
    pango_layout_get_pixel_size(layout, &text_width, &text_height);
	xpos = x - text_width / 2;
	ypos = centre_y ;
	gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout);

/* Draw the circles of Constant Reactance */

	r = 1.0 / rxl[i];
	x = centre_x + (gint) ((1 - r) * graph->dependant->scale_factor);
	w = 2.0 * r * graph->dependant->scale_factor;
	h = 2.0 * r * graph->dependant->scale_factor;

/* Now Label the Constant Reactance curves */
	g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0);
    pango_layout_set_text(layout, label, -1);
    pango_layout_get_pixel_size(layout, &text_width, &text_height);
	store = 2.0 * r/(r*r + 1);
	yend = store * (gfloat)(graph->dependant->scale_factor);
	xend = sqrt(1 - store*store) * (gfloat)(graph->dependant->scale_factor);
	
	switch(i)
		{
		case 0:
		case 1:
			g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			pango_layout_get_pixel_size(layout, &text_width, &text_height);
			ypos = centre_y - (gint)yend;
			xpos = centre_x - (gint)xend;
			gdk_draw_layout(buffer, BandWcontext, xpos - text_width, ypos - text_height, layout);
			g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			ypos = centre_y + (gint)yend;
			gdk_draw_layout(buffer, BandWcontext, xpos - text_width, ypos, layout);
			arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)((centre_y + r * graph->dependant->scale_factor)-ypos)) *180.0 / 3.141592654;
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, (gint)(arc_angle * 64.0)); // Capacitive Circles
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 17280 - (gint) (arc_angle*64.0), (gint) (arc_angle*64.0));	// Inductive Circles
			break;
		case 2:
			g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			pango_layout_get_pixel_size(layout, &text_width, &text_height);
			ypos = centre_y - (gint)yend;
			xpos = centre_x - (gint)xend;
			gdk_draw_layout(buffer, BandWcontext, xpos - text_width/2, ypos - text_height, layout);
			g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			ypos = centre_y + yend;
			gdk_draw_layout(buffer, BandWcontext, xpos - text_width/2, ypos, layout);
			arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)(ypos - (centre_y + r * graph->dependant->scale_factor))) *180.0 / 3.141592654;
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, (gint) (arc_angle*64.0)); // Capacitive Circles
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 17280 - (gint) (arc_angle*64.0), (gint) (arc_angle*64.0));	// Inductive Circles
			break;
		case 3:
		case 4:
			g_snprintf(label, 10, "+j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			pango_layout_get_pixel_size(layout, &text_width, &text_height);
			ypos = centre_y - (gint)yend;
			xpos = centre_x + (gint)xend;
			gdk_draw_layout(buffer, BandWcontext, xpos, ypos - text_height, layout);
			g_snprintf(label, 10, "-j%0.f", rxl[i]*graph->smith_Z0);
			pango_layout_set_text(layout, label, -1);
			ypos = centre_y + (gint)yend;
			gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout);
			arc_angle = atan((gfloat)(centre_x + graph->dependant->scale_factor - xpos)/(gfloat)(ypos - (centre_y + r * graph->dependant->scale_factor))) *180.0 / 3.141592654;
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y, w, h, 5760, 11520 - (gint) (arc_angle*64.0)); // Capacitive Circles
			gdk_draw_arc(buffer, Gridcontext, FALSE, x, centre_y - (gint) ((2 *r) * graph->dependant->scale_factor), w, h, 5760 + (gint) (arc_angle*64.0), 11520 - (gint) (arc_angle*64.0));	// Inductive Circles
			break;
		}
	}
	
/* Draw the Real Axis */	
gdk_draw_line(buffer, Gridcontext, centre_x - user_width/2, centre_y, centre_x + user_width/2, centre_y);	
g_snprintf(label, 10, "+inf");
pango_layout_set_text(layout, label, -1);
pango_layout_get_pixel_size(layout, &text_width, &text_height);
xpos = centre_x + user_width/2.0 - text_width/2 ;
ypos = centre_y ;
gdk_draw_layout(buffer, BandWcontext, xpos, ypos, layout);
	
pango_font_description_free(fontdesc);
g_object_unref(layout);	
}
Пример #3
0
void _HYPlatformGraphicPane::_SetFont (_HYFont f)
{
	HYFont2PangoFontDesc(f,theFont);
	pango_layout_set_font_description (textLayout, theFont ); // ref ?
	_ResetCharGlyphs ();
}
Пример #4
0
static gboolean lowlight_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_lowlight_gui_data_t *c = (dt_iop_lowlight_gui_data_t *)self->gui_data;
  dt_iop_lowlight_params_t p = *(dt_iop_lowlight_params_t *)self->params;

  dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0,
                          p.transition_y[0]);
  for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
    dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]);
  dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0,
                          p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]);

  const int inset = DT_IOP_LOWLIGHT_INSET;
  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);
  int width = allocation.width, height = allocation.height;
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  cairo_set_source_rgb(cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  width -= 2 * inset;
  height -= 2 * inset;

  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0));
  cairo_set_source_rgb(cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);

  cairo_set_source_rgb(cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);

  // draw grid
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4));
  cairo_set_source_rgb(cr, .1, .1, .1);
  dt_draw_grid(cr, 8, 0, 0, width, height);


  if(c->mouse_y > 0 || c->dragging)
  {
    // draw min/max curves:
    dt_iop_lowlight_get_params(&p, c->mouse_x, 1., c->mouse_radius);
    dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0,
                            p.transition_y[0]);
    for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
      dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]);
    dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0,
                            p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]);
    dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_min_xs,
                              c->draw_min_ys);

    p = *(dt_iop_lowlight_params_t *)self->params;
    dt_iop_lowlight_get_params(&p, c->mouse_x, .0, c->mouse_radius);
    dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0,
                            p.transition_y[0]);
    for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
      dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]);
    dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0,
                            p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]);
    dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_max_xs,
                              c->draw_max_ys);
  }

  cairo_save(cr);

  // draw x positions
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));
  const float arrw = DT_PIXEL_APPLY_DPI(7.0f);
  for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
  {
    cairo_move_to(cr, width * p.transition_x[k], height + inset - DT_PIXEL_APPLY_DPI(1));
    cairo_rel_line_to(cr, -arrw * .5f, 0);
    cairo_rel_line_to(cr, arrw * .5f, -arrw);
    cairo_rel_line_to(cr, arrw * .5f, arrw);
    cairo_close_path(cr);
    if(c->x_move == k)
      cairo_fill(cr);
    else
      cairo_stroke(cr);
  }

  // draw selected cursor
  cairo_translate(cr, 0, height);

  // cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
  // cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.));
  cairo_set_source_rgba(cr, .7, .7, .7, 1.0);

  p = *(dt_iop_lowlight_params_t *)self->params;
  dt_draw_curve_set_point(c->transition_curve, 0, p.transition_x[DT_IOP_LOWLIGHT_BANDS - 2] - 1.0,
                          p.transition_y[0]);
  for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
    dt_draw_curve_set_point(c->transition_curve, k + 1, p.transition_x[k], p.transition_y[k]);
  dt_draw_curve_set_point(c->transition_curve, DT_IOP_LOWLIGHT_BANDS + 1, p.transition_x[1] + 1.0,
                          p.transition_y[DT_IOP_LOWLIGHT_BANDS - 1]);
  dt_draw_curve_calc_values(c->transition_curve, 0.0, 1.0, DT_IOP_LOWLIGHT_RES, c->draw_xs, c->draw_ys);
  cairo_move_to(cr, 0 * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[0]);
  for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++)
    cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_ys[k]);
  cairo_stroke(cr);

  // draw dots on knots
  cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
  cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.));
  for(int k = 0; k < DT_IOP_LOWLIGHT_BANDS; k++)
  {
    cairo_arc(cr, width * p.transition_x[k], -height * p.transition_y[k], DT_PIXEL_APPLY_DPI(3.0), 0.0,
              2.0 * M_PI);
    if(c->x_move == k)
      cairo_fill(cr);
    else
      cairo_stroke(cr);
  }

  if(c->mouse_y > 0 || c->dragging)
  {
    // draw min/max, if selected
    cairo_set_source_rgba(cr, .7, .7, .7, .6);
    cairo_move_to(cr, 0, -height * c->draw_min_ys[0]);
    for(int k = 1; k < DT_IOP_LOWLIGHT_RES; k++)
      cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_min_ys[k]);
    for(int k = DT_IOP_LOWLIGHT_RES - 1; k >= 0; k--)
      cairo_line_to(cr, k * width / (float)(DT_IOP_LOWLIGHT_RES - 1), -height * c->draw_max_ys[k]);
    cairo_close_path(cr);
    cairo_fill(cr);
    // draw mouse focus circle
    cairo_set_source_rgba(cr, .9, .9, .9, .5);
    const float pos = DT_IOP_LOWLIGHT_RES * c->mouse_x;
    int k = (int)pos;
    const float f = k - pos;
    if(k >= DT_IOP_LOWLIGHT_RES - 1) k = DT_IOP_LOWLIGHT_RES - 2;
    float ht = -height * (f * c->draw_ys[k] + (1 - f) * c->draw_ys[k + 1]);
    cairo_arc(cr, c->mouse_x * width, ht, c->mouse_radius * width, 0, 2. * M_PI);
    cairo_stroke(cr);
  }

  cairo_restore(cr);

  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);

  // draw labels:
  PangoLayout *layout;
  PangoRectangle ink;
  PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc);
  pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
  pango_font_description_set_absolute_size(desc,(.06 * height) * PANGO_SCALE);
  layout = pango_cairo_create_layout(cr);
  pango_layout_set_font_description(layout, desc);
  cairo_set_source_rgb(cr, .1, .1, .1);

  pango_layout_set_text(layout, _("dark"), -1);
  pango_layout_get_pixel_extents(layout, &ink, NULL);
  cairo_move_to(cr, .02 * width - ink.y, .5 * (height + ink.width));
  cairo_save(cr);
  cairo_rotate(cr, -M_PI * .5f);
  pango_cairo_show_layout(cr, layout);
  cairo_restore(cr);

  pango_layout_set_text(layout, _("bright"), -1);
  pango_layout_get_pixel_extents(layout, &ink, NULL);
  cairo_move_to(cr, .98 * width - ink.height, .5 * (height + ink.width));
  cairo_save(cr);
  cairo_rotate(cr, -M_PI * .5f);
  pango_cairo_show_layout(cr, layout);
  cairo_restore(cr);


  pango_layout_set_text(layout, _("day vision"), -1);
  pango_layout_get_pixel_extents(layout, &ink, NULL);
  cairo_move_to(cr, .5 * (width - ink.width), .08 * height - ink.height);
  pango_cairo_show_layout(cr, layout);

  pango_layout_set_text(layout, _("night vision"), -1);
  pango_layout_get_pixel_extents(layout, &ink, NULL);
  cairo_move_to(cr, .5 * (width - ink.width), .97 * height - ink.height);
  pango_cairo_show_layout(cr, layout);

  pango_font_description_free(desc);
  g_object_unref(layout);
  cairo_destroy(cr);
  cairo_set_source_surface(crf, cst, 0, 0);
  cairo_paint(crf);
  cairo_surface_destroy(cst);
  return TRUE;
}
Пример #5
0
static void
draw_info_header (GtkPrintContext *context,
                  cairo_t         *cr,
                  PrintData       *data)
{
  PangoLayout          *layout;
  PangoFontDescription *desc;
  gdouble               text_height;
  gdouble               text_width;
  gdouble               fname_text_width;
  gint                  layout_height;
  gint                  layout_width;
  gchar                 date_buffer[100];
  GDate                *date;
  const gchar          *name_str;
  GimpParasite         *parasite;
  const gchar          *end_ptr;
  gchar                *filename;
  gdouble               cr_width;

  cairo_save (cr);

  cr_width  = gtk_print_context_get_width (context);
  cairo_rectangle (cr, 0, 0, cr_width, HEADER_HEIGHT);
  cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
  cairo_fill_preserve (cr);

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

  layout = gtk_print_context_create_pango_layout (context);

  desc = pango_font_description_from_string ("sans 14");
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free (desc);

  pango_layout_set_width (layout, -1);
  pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);

  /* image name */
  pango_layout_set_text (layout, gimp_image_get_name (data->image_id), -1);

  pango_layout_get_size (layout, &layout_width, &layout_height);
  text_height = (gdouble) layout_height / PANGO_SCALE;

  cairo_move_to (cr, 0.02 * cr_width,  (HEADER_HEIGHT - text_height) / 5);
  pango_cairo_show_layout (cr, layout);

  /* user name */
  name_str = g_get_real_name ();
  if (name_str && g_utf8_validate (name_str, -1, &end_ptr))
    {
      pango_layout_set_text (layout, name_str, -1);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      text_width = (gdouble) layout_width / PANGO_SCALE;

      cairo_move_to (cr, 0.5 * cr_width - 0.5 * text_width,
                     (HEADER_HEIGHT - text_height) / 5);
      pango_cairo_show_layout (cr, layout);
    }

  /* date */
  date = g_date_new ();
  g_date_set_time_t (date, time (NULL));
  g_date_strftime (date_buffer, 100, "%x", date);
  g_date_free (date);
  pango_layout_set_text (layout, date_buffer, -1);

  pango_layout_get_size (layout, &layout_width, &layout_height);
  text_height = (gdouble) layout_height / PANGO_SCALE;
  text_width = (gdouble) layout_width / PANGO_SCALE;

  cairo_move_to (cr,
                 0.98 * cr_width - text_width,
                 (HEADER_HEIGHT - text_height) / 5);
  pango_cairo_show_layout (cr, layout);

  /* file name if any */
  filename = gimp_image_get_filename (data->image_id);

  if (filename)
    {
      pango_layout_set_text (layout,
                             gimp_filename_to_utf8 (filename), -1);
      g_free (filename);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      fname_text_width = (gdouble) layout_width / PANGO_SCALE;

      cairo_move_to (cr,
                     0.02 * cr_width,  4 * (HEADER_HEIGHT - text_height) / 5);
      pango_cairo_show_layout (cr, layout);
    }
  else
    {
      fname_text_width = 0;
    }

  /* image comment if it is short */
  parasite = gimp_image_parasite_find (data->image_id, "gimp-comment");

  if (parasite)
    {
      pango_layout_set_text (layout, gimp_parasite_data (parasite), -1);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      text_width = (gdouble) layout_width / PANGO_SCALE;

      if (fname_text_width + text_width < 0.8 * cr_width &&
          text_height < 0.5 * HEADER_HEIGHT)
        {
          cairo_move_to (cr, 0.98 * cr_width - text_width,
                         4 * (HEADER_HEIGHT - text_height) / 5);
          pango_cairo_show_layout (cr, layout);
        }

      gimp_parasite_free (parasite);
    }

  g_object_unref (layout);

  cairo_restore (cr);
}
Пример #6
0
// set font size
static void set_font_size(PangoLayout *layout, PangoFontDescription *font, int font_size) {
  pango_font_description_set_size(font, font_size*PANGO_SCALE);
  pango_layout_set_font_description(layout, font);
}
Пример #7
0
void cd_rssreader_show_dialog (GldiModuleInstance *myApplet)
{
    if (myData.pDialog != NULL)  // on detruit le dialogue actuel.
    {
        gldi_object_unref (GLDI_OBJECT(myData.pDialog));
        myData.pDialog = NULL;
        return;
    }
    gldi_dialogs_remove_on_icon (myIcon);  // on enleve tout autre dialogue (message d'erreur).

    if (myData.pItemList != NULL && myData.pItemList->next != NULL && (myData.pItemList->next->next != NULL || ! myData.bError))  // on construit le dialogue contenant toutes les infos.
    {
        // On construit le widget GTK qui contient les lignes avec les liens.
        GtkWidget *pVBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);  // le widget qu'on va inserer dans le dialogue.
        GtkWidget *pScrolledWindow = gtk_scrolled_window_new (NULL, NULL);
        g_object_set (pScrolledWindow, "height-request", 250, NULL);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION (3, 8, 0)
        gtk_container_add (GTK_CONTAINER (pScrolledWindow), pVBox);
#else
        gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow), pVBox);
#endif

        PangoLayout *pLayout = pango_cairo_create_layout (myDrawContext);
        PangoFontDescription *fd = pango_font_description_from_string ("");
        pango_layout_set_font_description (pLayout, fd);

        int w = MIN (600, g_desktopGeometry.Xscreen.width / g_desktopGeometry.iNbScreens / 2);  // we don't know on which screen is place the container...
        gchar *cLine;
        GtkWidget *pLinkButton, *pAlign;
        CDRssItem *pItem;
        GList *it;
        for (it = myData.pItemList->next; it != NULL; it = it->next)
        {
            pItem = it->data;
            if (pItem->cTitle == NULL)
                continue;

            cLine = g_strdup (pItem->cTitle);
            cd_rssreader_cut_line (cLine, pLayout, w);

            if (pItem->cLink != NULL)
                pLinkButton = gtk_link_button_new_with_label (pItem->cLink, cLine);
            else
                pLinkButton = gtk_label_new (cLine);
            g_free (cLine);

            pAlign = gtk_alignment_new (0., 0.5, 0., 0.);
            gtk_container_add (GTK_CONTAINER (pAlign), pLinkButton);
            gtk_box_pack_start (GTK_BOX (pVBox), pAlign, FALSE, FALSE, 0);

            if (pItem->cDescription != NULL)
            {
                cLine = g_strdup (pItem->cDescription);
                cd_rssreader_cut_line (cLine, pLayout, w);
                pLinkButton = gtk_label_new (cLine);
                gtk_label_set_selectable (GTK_LABEL (pLinkButton), TRUE);
                g_free (cLine);

                pAlign = gtk_alignment_new (0., 0.5, 0., 0.);
                gtk_alignment_set_padding (GTK_ALIGNMENT (pAlign), 0, 0, 20, 0);
                gtk_container_add (GTK_CONTAINER (pAlign), pLinkButton);
                gtk_box_pack_start (GTK_BOX (pVBox), pAlign, FALSE, FALSE, 0);
            }

            if (pItem->cAuthor != NULL)
            {
                gchar *by = g_strdup_printf ("  [by %s]", pItem->cAuthor);
                pLinkButton = gtk_label_new (by);
                g_free (by);

                pAlign = gtk_alignment_new (0., 0.5, 0., 0.);
                gtk_alignment_set_padding (GTK_ALIGNMENT (pAlign), 0, 0, 40, 0);
                gtk_container_add (GTK_CONTAINER (pAlign), pLinkButton);
                gtk_box_pack_start (GTK_BOX (pVBox), pAlign, FALSE, FALSE, 0);
            }

            if (pItem->cDate != NULL)
            {
                pLinkButton = gtk_label_new (pItem->cDate);

                pAlign = gtk_alignment_new (1., 0.5, 0., 0.);
                gtk_alignment_set_padding (GTK_ALIGNMENT (pAlign), 0, 0, 40, 0);
                gtk_container_add (GTK_CONTAINER (pAlign), pLinkButton);
                gtk_box_pack_start (GTK_BOX (pVBox), pAlign, FALSE, FALSE, 0);
            }
        }
        pango_font_description_free (fd);

        pItem = myData.pItemList->data;  // le nom du flux en titre du dialogue.

        // on affiche le dialogue.
        myData.pDialog = gldi_dialog_show (pItem->cTitle,
                                           myIcon, myContainer,
                                           0,
                                           myDock ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE,
                                           pScrolledWindow,
                                           NULL,
                                           myApplet,
                                           (GFreeFunc)_on_dialog_destroyed);
        /**g_signal_connect (G_OBJECT (myData.pDialog->container.pWidget),
        	"button-press-event",
        	G_CALLBACK (on_button_press_dialog),
        	myApplet);*/
    }
    else  // on affiche un message clair a l'utilisateur.
    {
        if (myConfig.cUrl == NULL)
            gldi_dialog_show_temporary_with_icon (D_("No URL is defined\nYou can define one by copying the URL in the clipboard,\n and selecting \"Paste the URL\" in the menu."),
                                                  myIcon,
                                                  myContainer,
                                                  1000*myConfig.iNotificationDuration,
                                                  myDock ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
        else
            gldi_dialog_show_temporary_with_icon (D_("No data\nDid you set a valid RSS feed?\nIs your connection alive?"),
                                                  myIcon,
                                                  myContainer,
                                                  1000*myConfig.iNotificationDuration,
                                                  myDock ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
    }
}
Пример #8
0
/**
 * ppg_rt_graph_size_allocate:
 * @graph: (in): A #PpgRtGraph.
 *
 * Handle the "size-allocate" signal for the #PpgRtGraph. Adjust the
 * sizing of various surfaces to match the new size.
 *
 * Returns: None.
 * Side effects: None.
 */
static void
ppg_rt_graph_size_allocate (GtkWidget     *widget,
                            GtkAllocation *alloc)
{
	PpgRtGraphPrivate *priv;
	PangoLayout *layout;
	PpgRtGraph *graph = (PpgRtGraph *)widget;
	GdkWindow *window;
	cairo_t *cr;
	gdouble each;

	g_return_if_fail(PPG_IS_RT_GRAPH(graph));

	priv = graph->priv;

	/*
	 * Chain up to allow Gtk to perform the resize.
	 */
	GTK_WIDGET_CLASS(ppg_rt_graph_parent_class)->size_allocate(widget, alloc);

	/*
	 * Get our window to create our suraces and such.
	 */
	window = gtk_widget_get_window(widget);
	if (!window) {
		return;
	}

	/*
	 * Cleanup after previous cairo surfaces.
	 */
	ppg_clear_pointer(&priv->foreground, cairo_surface_destroy);
	ppg_clear_pointer(&priv->background, cairo_surface_destroy);

	/*
	 * Determine the font height so we can draw our labels.
	 */
	cr = gdk_cairo_create(window);
	layout = pango_cairo_create_layout(cr);
	pango_layout_set_font_description(layout, priv->font_desc);
	pango_layout_set_text(layout, "XXXXXXXXX", -1);
	pango_layout_get_pixel_size(layout, &priv->label_width,
	                            &priv->label_height);
	g_object_unref(layout);
	cairo_destroy(cr);

	/*
	 * Setup ring buffer defaults.
	 */
	priv->offset_time = 0.0;

	/*
	 * Determine the visible data area.
	 */
	priv->content_area.x = 1 + priv->label_width;
	priv->content_area.y = 1;
	priv->content_area.width = alloc->width - priv->label_width - 2;
	priv->content_area.height = alloc->height
	                          - (LABEL_YPAD * 2)
	                          - priv->label_height
	                          - 2;

	/*
	 * Determine the data area including buffer area.
	 */
	each = priv->content_area.width / priv->n_seconds;
	priv->data_area.x = 0;
	priv->data_area.y = 0;
	priv->data_area.width = priv->content_area.width +
	                        ceil(priv->n_buffered * each);
	priv->data_area.height = priv->content_area.height;

	/*
	 * Create new cairo surface for drawing the background.
	 */
	priv->background =
		gdk_window_create_similar_surface(window,
		                                  CAIRO_CONTENT_COLOR_ALPHA,
		                                  alloc->width, alloc->height);

	/*
	 * Create new cairo surface for drawing the foreground. This matches the
	 * size of the content area plus enough space for the buffered region.
	 */
	priv->foreground =
		gdk_window_create_similar_surface(window,
		                                  CAIRO_CONTENT_COLOR_ALPHA,
		                                  priv->data_area.width,
		                                  priv->data_area.height);

	/*
	 * Render the entire graph immediately.
	 */
	ppg_rt_graph_render_background(graph);
	ppg_rt_graph_render_foreground(graph, 0.0, 0.0);
}
Пример #9
0
static Image *ReadCAPTIONImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    *caption,
    *property;

  const char
    *option;

  DrawInfo
    *draw_info;

  FT_Bitmap
    *canvas;

  Image
    *image;

  PangoAlignment
    align;

  PangoContext
    *context;

  PangoFontDescription
    *description;

  PangoFontMap
    *fontmap;

  PangoGravity
    gravity;

  PangoLayout
    *layout;

  PangoRectangle
    extent;

  PixelPacket
    fill_color;

  RectangleInfo
    page;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  ssize_t
    y;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  (void) ResetImagePage(image,"0x0+0+0");
  /*
    Get context.
  */
  fontmap=(PangoFontMap *) pango_ft2_font_map_new();
  pango_ft2_font_map_set_resolution((PangoFT2FontMap *) fontmap,
    image->x_resolution,image->y_resolution);
  option=GetImageOption(image_info,"caption:hinting");
  pango_ft2_font_map_set_default_substitute((PangoFT2FontMap *) fontmap,
    PangoSubstitute,(char *) option,NULL);
  context=pango_font_map_create_context(fontmap);
  option=GetImageOption(image_info,"caption:language");
  if (option != (const char *) NULL)
    pango_context_set_language(context,pango_language_from_string(option));
  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
  pango_context_set_base_dir(context,draw_info->direction ==
    RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
  switch (draw_info->gravity)
  {
    case NorthGravity: gravity=PANGO_GRAVITY_NORTH; break;
    case WestGravity: gravity=PANGO_GRAVITY_WEST; break;
    case EastGravity: gravity=PANGO_GRAVITY_EAST; break;
    case SouthGravity: gravity=PANGO_GRAVITY_SOUTH; break;
    default: gravity=PANGO_GRAVITY_AUTO; break;
  }
  pango_context_set_base_gravity(context,gravity);
  option=GetImageOption(image_info,"caption:gravity-hint");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"line") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE);
      if (LocaleCompare(option,"natural") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL);
      if (LocaleCompare(option,"strong") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG);
    }
  /*
    Configure layout.
  */
  layout=pango_layout_new(context);
  option=GetImageOption(image_info,"caption:auto-dir");
  if (option != (const char *) NULL)
    pango_layout_set_auto_dir(layout,1);
  option=GetImageOption(image_info,"caption:ellipsize");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"end") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END);
      if (LocaleCompare(option,"middle") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE);
      if (LocaleCompare(option,"none") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE);
      if (LocaleCompare(option,"start") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
    }
  option=GetImageOption(image_info,"caption:justify");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_justify(layout,1);
  option=GetImageOption(image_info,"caption:single-paragraph");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_single_paragraph_mode(layout,1);
  option=GetImageOption(image_info,"caption:wrap");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_CHAR);
      if (LocaleCompare(option,"word") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD);
      if (LocaleCompare(option,"word-char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);
    }
  option=GetImageOption(image_info,"caption:indent");
  if (option != (const char *) NULL)
    pango_layout_set_indent(layout,(StringToLong(option)*image->x_resolution*
      PANGO_SCALE+36)/72);
  switch (draw_info->align)
  {
    case CenterAlign: align=PANGO_ALIGN_CENTER; break;
    case RightAlign: align=PANGO_ALIGN_RIGHT; break;
    case LeftAlign:
    default: align=PANGO_ALIGN_LEFT; break;
  }
  if ((align != PANGO_ALIGN_CENTER) &&
      (draw_info->direction == RightToLeftDirection))
    align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align);
  pango_layout_set_alignment(layout,align);
  description=pango_font_description_from_string(draw_info->font ==
    (char *) NULL ? "helvetica" : draw_info->font);
  pango_font_description_set_size(description,PANGO_SCALE*draw_info->pointsize);
  pango_layout_set_font_description(layout,description);
  pango_font_description_free(description);
  property=InterpretImageProperties(image_info,image,image_info->filename);
  (void) SetImageProperty(image,"caption",property);
  property=DestroyString(property);
  caption=ConstantString(GetImageProperty(image,"caption"));
  /*
    Render caption.
  */
  option=GetImageOption(image_info,"caption:markup");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_markup(layout,caption,-1);
  else
    pango_layout_set_text(layout,caption,-1);
  pango_layout_context_changed(layout);
  page.x=0;
  page.y=0;
  if (image_info->page != (char *) NULL)
    (void) ParseAbsoluteGeometry(image_info->page,&page);
  if (image->columns == 0)
    {
      pango_layout_get_pixel_extents(layout,NULL,&extent);
      image->columns=extent.x+extent.width;
    }
  else
    {
      image->columns-=2*page.x;
      pango_layout_set_width(layout,(PANGO_SCALE*image->columns*
        image->x_resolution+36.0)/72.0);
    }
  if (image->rows == 0)
    {
      pango_layout_get_pixel_extents(layout,NULL,&extent);
      image->rows=extent.y+extent.height;
    }
  else
    {
      image->rows-=2*page.y;
      pango_layout_set_height(layout,(PANGO_SCALE*image->rows*
        image->y_resolution+36.0)/72.0);
    }
  /*
    Create canvas.
  */
  canvas=(FT_Bitmap *) AcquireMagickMemory(sizeof(*canvas));
  if (canvas == (FT_Bitmap *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  canvas->width=image->columns;
  canvas->pitch=(canvas->width+3) & ~3;
  canvas->rows=image->rows;
  canvas->buffer=(unsigned char *) AcquireQuantumMemory(canvas->pitch,
    canvas->rows*sizeof(*canvas->buffer));
  if (canvas->buffer == (unsigned char *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  canvas->num_grays=256;
  canvas->pixel_mode=ft_pixel_mode_grays;
  ResetMagickMemory(canvas->buffer,0x00,canvas->pitch*canvas->rows);
  pango_ft2_render_layout(canvas,layout,0,0);
  /*
    Convert caption to image.
  */
  image->columns+=2*page.x;
  image->rows+=2*page.y;
  if (SetImageBackgroundColor(image) == MagickFalse)
    {
      draw_info=DestroyDrawInfo(draw_info);
      canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
      canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
      caption=DestroyString(caption);
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  p=canvas->buffer;
  for (y=page.y; y < (ssize_t) (image->rows-page.y); y++)
  {
    register ssize_t
      x;

    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      break;
    q+=page.x;
    for (x=page.x; x < (ssize_t) (image->columns-page.x); x++)
    {
      MagickRealType
        fill_opacity;

      (void) GetFillColor(draw_info,x,y,&fill_color);
      fill_opacity=QuantumRange-(*p)/canvas->num_grays*(QuantumRange-
        fill_color.opacity);
      if (draw_info->text_antialias == MagickFalse)
        fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
      MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q);
      p++;
      q++;
    }
    for ( ; x < (ssize_t) ((canvas->width+3) & ~3); x++)
      p++;
  }
  /*
    Relinquish resources.
  */
  draw_info=DestroyDrawInfo(draw_info);
  canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
  canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
  caption=DestroyString(caption);
  return(GetFirstImageInList(image));
}
Пример #10
0
int
main (int argc, char **argv)
{
  CoglContext *ctx;
  CoglOnscreen *onscreen;
  CoglFramebuffer *fb;
  GError *error = NULL;
  Data data;
  PangoRectangle hello_label_size;
  float fovy, aspect, z_near, z_2d, z_far;
  CoglDepthState depth_state;
  CoglBool has_swap_notify;

  ctx = cogl_context_new (NULL, &error);
  if (!ctx) {
      fprintf (stderr, "Failed to create context: %s\n", error->message);
      return 1;
  }

  onscreen = cogl_onscreen_new (ctx, 640, 480);
  fb = COGL_FRAMEBUFFER (onscreen);
  data.fb = fb;
  data.framebuffer_width = cogl_framebuffer_get_width (fb);
  data.framebuffer_height = cogl_framebuffer_get_height (fb);

  data.timer = g_timer_new ();

  cogl_onscreen_show (onscreen);

  cogl_framebuffer_set_viewport (fb,
                                 0, 0,
                                 data.framebuffer_width,
                                 data.framebuffer_height);

  fovy = 60; /* y-axis field of view */
  aspect = (float)data.framebuffer_width/(float)data.framebuffer_height;
  z_near = 0.1; /* distance to near clipping plane */
  z_2d = 1000; /* position to 2d plane */
  z_far = 2000; /* distance to far clipping plane */

  cogl_framebuffer_perspective (fb, fovy, aspect, z_near, z_far);

  /* Since the pango renderer emits geometry in pixel/device coordinates
   * and the anti aliasing is implemented with the assumption that the
   * geometry *really* does end up pixel aligned, we setup a modelview
   * matrix so that for geometry in the plane z = 0 we exactly map x
   * coordinates in the range [0,stage_width] and y coordinates in the
   * range [0,stage_height] to the framebuffer extents with (0,0) being
   * the top left.
   *
   * This is roughly what Clutter does for a ClutterStage, but this
   * demonstrates how it is done manually using Cogl.
   */
  cogl_matrix_init_identity (&data.view);
  cogl_matrix_view_2d_in_perspective (&data.view, fovy, aspect, z_near, z_2d,
                                      data.framebuffer_width,
                                      data.framebuffer_height);
  cogl_framebuffer_set_modelview_matrix (fb, &data.view);

  /* Initialize some convenient constants */
  cogl_matrix_init_identity (&identity);
  cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);

  /* rectangle indices allow the GPU to interpret a list of quads (the
   * faces of our cube) as a list of triangles.
   *
   * Since this is a very common thing to do
   * cogl_get_rectangle_indices() is a convenience function for
   * accessing internal index buffers that can be shared.
   */
  data.indices = cogl_get_rectangle_indices (ctx, 6 /* n_rectangles */);
  data.prim = cogl_primitive_new_p3t2 (ctx, COGL_VERTICES_MODE_TRIANGLES,
                                       G_N_ELEMENTS (vertices),
                                       vertices);
  /* Each face will have 6 indices so we have 6 * 6 indices in total... */
  cogl_primitive_set_indices (data.prim,
                              data.indices,
                              6 * 6);

  /* Load a jpeg crate texture from a file */
  printf ("crate.jpg (CC by-nc-nd http://bit.ly/9kP45T) ShadowRunner27 http://bit.ly/m1YXLh\n");
  data.texture = cogl_texture_new_from_file (COGL_EXAMPLES_DATA "crate.jpg",
                                             COGL_TEXTURE_NO_SLICING,
                                             COGL_PIXEL_FORMAT_ANY,
                                             &error);
  if (!data.texture)
    g_error ("Failed to load texture: %s", error->message);

  /* a CoglPipeline conceptually describes all the state for vertex
   * processing, fragment processing and blending geometry. When
   * drawing the geometry for the crate this pipeline says to sample a
   * single texture during fragment processing... */
  data.crate_pipeline = cogl_pipeline_new (ctx);
  cogl_pipeline_set_layer_texture (data.crate_pipeline, 0, data.texture);

  /* Since the box is made of multiple triangles that will overlap
   * when drawn and we don't control the order they are drawn in, we
   * enable depth testing to make sure that triangles that shouldn't
   * be visible get culled by the GPU. */
  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, TRUE);

  cogl_pipeline_set_depth_state (data.crate_pipeline, &depth_state, NULL);

  /* Setup a Pango font map and context */

  data.pango_font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new (ctx));

  cogl_pango_font_map_set_use_mipmapping (data.pango_font_map, TRUE);

  data.pango_context =
    pango_font_map_create_context (PANGO_FONT_MAP (data.pango_font_map));

  data.pango_font_desc = pango_font_description_new ();
  pango_font_description_set_family (data.pango_font_desc, "Sans");
  pango_font_description_set_size (data.pango_font_desc, 30 * PANGO_SCALE);

  /* Setup the "Hello Cogl" text */

  data.hello_label = pango_layout_new (data.pango_context);
  pango_layout_set_font_description (data.hello_label, data.pango_font_desc);
  pango_layout_set_text (data.hello_label, "Hello Cogl", -1);

  pango_layout_get_extents (data.hello_label, NULL, &hello_label_size);
  data.hello_label_width = PANGO_PIXELS (hello_label_size.width);
  data.hello_label_height = PANGO_PIXELS (hello_label_size.height);

  data.swap_ready = TRUE;

  has_swap_notify =
    cogl_has_feature (ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT);

  if (has_swap_notify)
    cogl_onscreen_add_swap_buffers_callback (COGL_ONSCREEN (fb),
                                             swap_notify_cb,
                                             &data);

  while (1)
    {
      CoglPollFD *poll_fds;
      int n_poll_fds;
      int64_t timeout;

      if (data.swap_ready)
        {
          paint (&data);
          cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
        }

      cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);

      if (!has_swap_notify)
        {
          /* If the winsys doesn't support swap event notification
             then we'll just redraw constantly */
          data.swap_ready = TRUE;
          timeout = 0;
        }

      g_poll ((GPollFD *) poll_fds, n_poll_fds,
              timeout == -1 ? -1 : timeout / 1000);

      cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
    }

  return 0;
}
Пример #11
0
/**
 * ppg_rt_graph_render_background:
 * @graph: (in): A #PpgRtGraph.
 *
 * Render the background of the graph.
 *
 * Returns: None.
 * Side effects: None.
 */
static void
ppg_rt_graph_render_background (PpgRtGraph *graph)
{
	static const gdouble dashes[] = { 1.0, 2.0 };
	PpgRtGraphPrivate *priv;
	GtkStateType state;
	PangoLayout *layout;
	GtkWidget *widget = (GtkWidget *)graph;
	GtkStyle *style;
	cairo_t *cr;
	gdouble value;
	gdouble x;
	gdouble y;
	gchar *text;
	gchar label[32];
	guint n_lines;
	gint i;
	gint height;
	gint width;

	g_return_if_fail(PPG_IS_RT_GRAPH(graph));

	priv = graph->priv;

	/*
	 * Retrieve required resources.
	 */
	style = gtk_widget_get_style(widget);
	state = gtk_widget_get_state(widget);
	cr = cairo_create(priv->background);

	/*
	 * Set background color to the styles light color.
	 */
	gdk_cairo_set_source_color(cr, &style->light[state]);
	cairo_rectangle(cr,
	                priv->content_area.x + 0.5,
	                priv->content_area.y + 0.5,
	                priv->content_area.width - 1.0,
	                priv->content_area.height - 1.0);
	cairo_fill(cr);

	/*
	 * Stroke the outer line or the graph to the styles foreground
	 * color.
	 */
	gdk_cairo_set_source_color(cr, &style->fg[state]);
	cairo_set_line_width(cr, 1.0);
	cairo_set_dash(cr, dashes, G_N_ELEMENTS(dashes), 0);
	cairo_rectangle(cr,
	                priv->content_area.x + 0.5,
	                priv->content_area.y + 0.5,
	                priv->content_area.width - 1.0,
	                priv->content_area.height - 1.0);
	cairo_stroke(cr);

	layout = pango_cairo_create_layout(cr);
	pango_layout_set_font_description(layout, priv->font_desc);

	/*
	 * Stroke the inner vertical grid lines of the graph to the styles
	 * foreground color. Draw the label at the bottom.
	 */
	n_lines = ppg_rt_graph_get_n_x_lines(graph);
	for (i = 0; i <= n_lines; i++) {
		x = priv->content_area.x +
		    floor(priv->content_area.width / ((gdouble)n_lines + 1) * i) +
		    0.5;
		y = priv->content_area.y + 1.5;

		/*
		 * Don't draw the first line.
		 */
		if (i != 0) {
			cairo_move_to(cr, x, y);
			cairo_line_to(cr, x, y + priv->content_area.height - 3.0);
			cairo_stroke(cr);
		}

		/*
		 * Time labels for X axis.
		 */
		value = floor(priv->n_seconds / (n_lines + 1.0) * (n_lines + 1 - i));
		g_snprintf(label, sizeof label, "%d", (gint)value);
		pango_layout_set_text(layout, label, -1);
		y = priv->content_area.y + priv->content_area.height + LABEL_YPAD;
		cairo_move_to(cr, x, y);
		pango_cairo_show_layout(cr, layout);
	}

	/*
	 * Stroke the inner horizontal grid lines of the graph to the styles
	 * foreground color.
	 */
	n_lines = ppg_rt_graph_get_n_y_lines(graph);
	for (i = 0; i <= n_lines; i++) {
		x = priv->content_area.x + 1.5;
		y = priv->content_area.y +
		    floor(priv->content_area.height / ((gdouble)n_lines + 1) * i) +
		    0.5;

		/*
		 * Don't draw the first line.
		 */
		if (i != 0) {
			cairo_move_to(cr, x, y);
			cairo_line_to(cr, x + priv->content_area.width - 3.0, y);
			cairo_stroke(cr);
		}

		/*
		 * Time labels for Y axis.
		 */
		value = priv->upper_value -
		        ((priv->upper_value - priv->lower_value) / (n_lines + 1.0) * i);
		g_signal_emit(graph, signals[FORMAT_VALUE], 0, value, &text);
		pango_layout_set_text(layout, text, -1);
		pango_layout_get_pixel_size(layout, &width, &height);
		x = priv->content_area.x - LABEL_XPAD - width;
		y = priv->content_area.y + (priv->content_area.height / (n_lines + 1.0) * i);
		cairo_move_to(cr, x, y);
		pango_cairo_show_layout(cr, layout);
		g_free(text);
	}

	/*
	 * Cleanup resources.
	 */
	g_object_unref(layout);
	cairo_destroy(cr);
}
Пример #12
0
// Create and add a placement to the current lithograph if it doesn't overlap
// with current labels.
void
simplet_lithograph_add_placement(simplet_lithograph_t *litho,
  OGRFeatureH feature, simplet_list_t *styles, cairo_t *proj_ctx) {

  simplet_style_t *field = simplet_lookup_style(styles, "text-field");
  if(!field) return;

  OGRFeatureDefnH defn;
  if(!(defn = OGR_F_GetDefnRef(feature))) return;

  int idx = OGR_FD_GetFieldIndex(defn, (const char*) field->arg);
  if(idx < 0) return;

  // Find the largest sub geometry of a particular multi-geometry.
  OGRGeometryH super = OGR_F_GetGeometryRef(feature);
  OGRGeometryH geom = super;
  double area = 0.0;
  switch(wkbFlatten(OGR_G_GetGeometryType(super))) {
    case wkbMultiPolygon:
    case wkbGeometryCollection:
      for(int i = 0; i < OGR_G_GetGeometryCount(super); i++) {
        OGRGeometryH subgeom = OGR_G_GetGeometryRef(super, i);
        if(subgeom == NULL) continue;
        double ar = OGR_G_Area(subgeom);
        if(ar > area) {
          geom = subgeom;
          area = ar;
        }
      }
      break;
    default:
      ;
  }

  // Find the center of our geometry. This sometimes throws an invalid geometry
  // error, so there is a slight bug here somehow.
  OGRGeometryH center;
  if(!(center = OGR_G_CreateGeometry(wkbPoint))) return;
  if(OGR_G_Centroid(geom, center) == OGRERR_FAILURE) {
    OGR_G_DestroyGeometry(center);
    return;
  }

  // Turn font hinting off
  cairo_font_options_t *opts;
  if(!(opts = cairo_font_options_create())){
    OGR_G_DestroyGeometry(center);
    return;
  }

  cairo_font_options_set_hint_style(opts, CAIRO_HINT_STYLE_NONE);
  cairo_font_options_set_hint_metrics(opts, CAIRO_HINT_METRICS_OFF);
  pango_cairo_context_set_font_options(litho->pango_ctx, opts);
  cairo_font_options_destroy(opts);

  // Get the field containing the text for the label.
  char *txt = simplet_copy_string(OGR_F_GetFieldAsString(feature, idx));
  PangoLayout *layout = pango_layout_new(litho->pango_ctx);
  pango_layout_set_text(layout, txt, -1);
  free(txt);

  // Grab the font to use and apply tracking.
  simplet_style_t *font = simplet_lookup_style(styles, "font");
  simplet_apply_styles(layout, styles, "letter-spacing", NULL);

  const char *font_family;

  if(!font)
    font_family = "helvetica 12px";
  else
    font_family = font->arg;

  PangoFontDescription *desc = pango_font_description_from_string(font_family);
  pango_layout_set_font_description(layout, desc);
  pango_font_description_free(desc);

  double x = OGR_G_GetX(center, 0), y = OGR_G_GetY(center, 0);
  cairo_user_to_device(proj_ctx, &x, &y);

  // Finally try the placement and test for overlaps.
  try_and_insert_placement(litho, layout, x, y);
  OGR_G_DestroyGeometry(center);
}
Пример #13
0
static GdkPixbuf *
biji_note_obj_get_icon (BijiItem *item)
{
  GdkRGBA               note_color;
  const gchar           *text;
  cairo_t               *cr;
  PangoLayout           *layout;
  PangoFontDescription  *desc;
  GdkPixbuf             *ret = NULL;
  cairo_surface_t       *surface = NULL;
  GtkBorder              frame_slice = { 4, 3, 3, 6 };

  BijiNoteObj *note = BIJI_NOTE_OBJ (item);

  if (note->priv->icon)
    return note->priv->icon;

  /* Create & Draw surface */
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                        BIJI_ICON_WIDTH,
                                        BIJI_ICON_HEIGHT) ;
  cr = cairo_create (surface);

  /* Background */
  cairo_rectangle (cr, 0, 0, BIJI_ICON_WIDTH, BIJI_ICON_HEIGHT);
  if (biji_note_obj_get_rgba (note, &note_color))
    gdk_cairo_set_source_rgba (cr, &note_color);

  cairo_fill (cr);

  /* Text */
  text = biji_note_id_get_content (note->priv->id);
  if (text != NULL)
  {
    cairo_translate (cr, 10, 10);
    layout = pango_cairo_create_layout (cr);

    pango_layout_set_width (layout, 180000 );
    pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_height (layout, 180000 ) ;

    pango_layout_set_text (layout, text, -1);
    desc = pango_font_description_from_string (BIJI_ICON_FONT);
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);

    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    pango_cairo_update_layout (cr, layout);
    pango_cairo_show_layout (cr, layout);

    g_object_unref (layout);
  }

  cairo_destroy (cr);

  ret = gdk_pixbuf_get_from_surface (surface,
                                     0, 0,
                                     BIJI_ICON_WIDTH,
                                     BIJI_ICON_HEIGHT);
  cairo_surface_destroy (surface);

  note->priv->icon = gd_embed_image_in_frame (ret, "resource:///org/gnome/bijiben/thumbnail-frame.png",
                                              &frame_slice, &frame_slice);
  g_clear_object (&ret);

  return note->priv->icon;
}
Пример #14
0
void ExternalPortModel::setPort(const char* szPort)
{
    if(!szPort)
        return;
   
    strPort = szPort;

    PangoLayout *layout = gtk_widget_create_pango_layout((GtkWidget*)parentWindow->gobj(), 
                            szPort);
    int text_w, text_h;
    PangoFontDescription *fontdesc = pango_font_description_from_string(FONT_DESC);
    pango_layout_set_font_description (layout, fontdesc);
    pango_layout_get_pixel_size (layout, &text_w, &text_h);

    width = text_w + H_MARGINE*2 + PORT_DEPTH;
    height = text_h + V_MARGINE*2;
    
    if(type == INPUTD)
    {
        Goocanvas::Points points(5);
        points.set_coordinate(0, 0, 0);
        points.set_coordinate(1, width, 0);
        points.set_coordinate(2, width, height);
        points.set_coordinate(3, 0, height);
        points.set_coordinate(4, PORT_DEPTH, height/2.0);
        poly->property_points().set_value(points);
        shadow->property_points().set_value(points);
    }
    else
    {
        Goocanvas::Points points(5);
        points.set_coordinate(0, 0, 0);
        points.set_coordinate(1, width-PORT_DEPTH, 0);
        points.set_coordinate(2, width, height/2.0);
        points.set_coordinate(3, width-PORT_DEPTH, height);
        points.set_coordinate(4, 0, height);
        poly->property_points().set_value(points);
        shadow->property_points().set_value(points);
    }

    text->property_text() = szPort;
    text->property_x().set_value(PORT_DEPTH+H_MARGINE/2.0);
    text->property_y().set_value(height/2.0 - text_h/2.0);
    updateArrowCoordination();
    
    // updating all connections from/to this port 
    Application* application = parentWindow->manager.getKnowledgeBase()->getApplication();
    std::vector<ArrowModel*>::iterator itr;   
    if(type == OUTPUTD)
    {
        for(itr = sourceArrows.begin(); itr!= sourceArrows.end(); itr++)
        {
            Connection* pConnection = (*itr)->getConnection();
            Connection con = *pConnection;
            con.setFrom(szPort);
            parentWindow->manager.getKnowledgeBase()->updateConnectionOfApplication(application, *pConnection, con);
            pConnection->setFrom(szPort);
        }            
    }
    else
    {
        for(itr = destinationArrows.begin(); itr!= destinationArrows.end(); itr++)
        {
            Connection* pConnection = (*itr)->getConnection();
            Connection con = *pConnection;
            con.setTo(szPort);
            parentWindow->manager.getKnowledgeBase()->updateConnectionOfApplication(application, *pConnection, con);
            pConnection->setTo(szPort);
        }            
    }
}
Пример #15
0
static void
render_logo (void)
{
  ClutterActor *image;
  ClutterActor *text, *text_shadow;
  ClutterActor *desc, *desc_shadow;
  ClutterColor actor_color = {0xff,0xff,0xff,0xff};
  ClutterColor shadow_color = {0x00, 0x00, 0x00, 0x88};
  ClutterActor *text_group;
  static gint width, height;
  gint size;
  gfloat stage_w, stage_h;
  PangoFontDescription *pfd;
  PangoLayout *layout;
  PangoContext *context;

  gchar *nibbles = _("Nibbles");
  /* Translators: This string will be included in the intro screen, so don't make sure it fits! */
  gchar *description = _("A worm game for MATE.");

  logo = clutter_group_new ();
  text_group = clutter_group_new ();

  if (!logo_pixmap)
    gnibbles_load_logo (properties->tilesize);

  image = gtk_clutter_texture_new_from_pixbuf (logo_pixmap);

  stage_w = board->width * properties->tilesize;
  stage_h = board->height * properties->tilesize;

  clutter_actor_set_size (CLUTTER_ACTOR (image), stage_w, stage_h);

  clutter_actor_set_position (CLUTTER_ACTOR (image), 0, 0);
  clutter_actor_show (image);

  text = clutter_text_new ();
  clutter_text_set_color (CLUTTER_TEXT (text), &actor_color);

  context = gdk_pango_context_get ();
  layout = clutter_text_get_layout (CLUTTER_TEXT (text));
  pfd = pango_context_get_font_description (context);
  size = pango_font_description_get_size (pfd);

  pango_font_description_set_size (pfd, (size * stage_w) / 100);
  pango_font_description_set_family (pfd, "Sans");
  pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
  pango_layout_set_font_description (layout, pfd);
  pango_layout_set_text (layout, nibbles, -1);
  pango_layout_get_pixel_size (layout, &width, &height);

  text_shadow = clutter_text_new ();
  clutter_text_set_color (CLUTTER_TEXT (text_shadow), &shadow_color);

  layout = clutter_text_get_layout (CLUTTER_TEXT (text_shadow));
  pango_layout_set_font_description (layout, pfd);
  pango_layout_set_text (layout, nibbles, -1);

  clutter_actor_set_position (CLUTTER_ACTOR (text),
                              (stage_w - width) * 0.5 ,
                              stage_h * .72);
  clutter_actor_set_position (CLUTTER_ACTOR (text_shadow),
                              (stage_w - width) * 0.5 + 5,
                              stage_h * .72 + 5);

  desc = clutter_text_new ();
  layout = clutter_text_get_layout (CLUTTER_TEXT (desc));

  clutter_text_set_color (CLUTTER_TEXT (desc), &actor_color);
  pango_font_description_set_size (pfd, (size * stage_w) / 400);
  pango_layout_set_font_description (layout, pfd);
  pango_layout_set_text (layout, description, -1);
  pango_layout_get_pixel_size(layout, &width, &height);

  desc_shadow = clutter_text_new ();
  layout = clutter_text_get_layout (CLUTTER_TEXT (desc_shadow));
  clutter_text_set_color (CLUTTER_TEXT (desc_shadow), &shadow_color);

  pango_font_description_set_size (pfd, (size * stage_w) / 400);
  pango_layout_set_font_description (layout, pfd);
  pango_layout_set_text (layout, description, -1);

  clutter_actor_set_position (CLUTTER_ACTOR (desc),
                              (stage_w - width) * 0.5,
                              stage_h* .93);
  clutter_actor_set_position (CLUTTER_ACTOR (desc_shadow),
                              (stage_w - width) * 0.5 + 3,
                              stage_h * .93 + 3);

  clutter_container_add (CLUTTER_CONTAINER (text_group),
                         CLUTTER_ACTOR (text_shadow),
                         CLUTTER_ACTOR (text),
                         CLUTTER_ACTOR (desc_shadow),
                         CLUTTER_ACTOR (desc),
                         NULL);
  clutter_container_add (CLUTTER_CONTAINER (logo),
                         CLUTTER_ACTOR (image),
                         CLUTTER_ACTOR (text_group),
                         NULL);

  clutter_actor_set_opacity (CLUTTER_ACTOR (text_group), 0);
  clutter_actor_set_scale (CLUTTER_ACTOR (text_group), 0.0, 0.0);
  clutter_actor_animate (text_group, CLUTTER_EASE_OUT_CIRC, 800,
                          "opacity", 0xff,
                          "scale-x", 1.0,
                          "scale-y", 1.0,
                          "fixed::scale-center-y", stage_w / 2,
                          "fixed::scale-center-x", stage_h / 2,
                          NULL);

  clutter_container_add_actor (CLUTTER_CONTAINER (stage),
                               CLUTTER_ACTOR (logo));
}
Пример #16
0
void text_wrapper::DoLayout(void)
{
    // THE function
    // first some sanity checks
    if ( default_font == NULL ) return;
    if ( uni32_length <= 0 || utf8_length <= 0 ) return;
    // prepare the pangolayout object
    {
        //char *tc = pango_font_description_to_string(default_font->descr);
        //printf("layout with %s\n", tc);
        //free(tc);
    }
    pango_layout_set_font_description(pLayout, default_font->descr);
    pango_layout_set_text(pLayout, utf8_text, utf8_length);
    // reset the glyph string
    if ( glyph_text ) free(glyph_text);
    glyph_text = NULL;
    glyph_length = 0;

    double pango_to_ink = (1.0 / ((double)PANGO_SCALE)); // utility
    int max_g = 0;
    PangoLayoutIter *pIter = pango_layout_get_iter(pLayout); // and go!
    do {
        PangoLayoutLine *pLine = pango_layout_iter_get_line(pIter); // no need for unref
        int plOffset = pLine->start_index; // start of the line in the uni32_text
        PangoRectangle ink_r, log_r;
        pango_layout_iter_get_line_extents(pIter, &ink_r, &log_r);
        double plY = (1.0 / ((double)PANGO_SCALE)) * ((double)log_r.y); // start position of this line of the layout
        double plX = (1.0 / ((double)PANGO_SCALE)) * ((double)log_r.x);
        GSList *curR = pLine->runs; // get ready to iterate over the runs of this line
        while ( curR ) {
            PangoLayoutRun *pRun = (PangoLayoutRun*)curR->data;
            if ( pRun ) {
                int prOffset = pRun->item->offset; // start of the run in the line
                // a run has uniform font/directionality/etc...
                int o_g_l = glyph_length; // save the index of the first glyph we'll add
                for (int i = 0; i < pRun->glyphs->num_glyphs; i++) { // add glyph sequentially, reading them from the run
                    // realloc the structures
                    if ( glyph_length >= max_g ) {
                        max_g = 2 * glyph_length + 1;
                        one_glyph *newdata = static_cast<one_glyph*>(realloc(glyph_text, (max_g + 1) * sizeof(one_glyph)));
                        if (newdata != NULL)
                        {
                            glyph_text = newdata;
                        }
                        else
                        {
                            g_warning("Failed to reallocate glyph_text");
                        }
                    }
                    // fill the glyph info
                    glyph_text[glyph_length].font = pRun->item->analysis.font;
                    glyph_text[glyph_length].gl = pRun->glyphs->glyphs[i].glyph;
                    glyph_text[glyph_length].uni_st = plOffset + prOffset + pRun->glyphs->log_clusters[i];
                    // depending on the directionality, the last uni32 codepoint for this glyph is the first of the next char
                    // or the first of the previous
                    if ( pRun->item->analysis.level == 1 ) {
                        // rtl
                        if ( i < pRun->glyphs->num_glyphs - 1 ) {
                            glyph_text[glyph_length + 1].uni_en = glyph_text[glyph_length].uni_st;
                        }
                        glyph_text[glyph_length].uni_dir = 1;
                        glyph_text[glyph_length + 1].uni_dir = 1; // set the directionality for the next too, so that the last glyph in
                        // the array has the correct direction
                    } else {
                        // ltr
                        if ( i > 0 ) {
                            glyph_text[glyph_length - 1].uni_en = glyph_text[glyph_length].uni_st;
                        }
                        glyph_text[glyph_length].uni_dir = 0;
                        glyph_text[glyph_length + 1].uni_dir = 0;
                    }
                    // set the position
                    // the layout is an infinite line
                    glyph_text[glyph_length].x = plX + pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.x_offset);
                    glyph_text[glyph_length].y = plY + pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.y_offset);
                    // advance to the next glyph
                    plX += pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.width);
                    // and set the next glyph's position, in case it's the terminating glyph
                    glyph_text[glyph_length + 1].x = plX;
                    glyph_text[glyph_length + 1].y = plY;
                    glyph_length++;
                }
                // and finish filling the info
                // notably, the uni_en of the last char in ltr text and the uni_en of the first in rtl are still not set
                if ( pRun->item->analysis.level == 1 ) {
                    // rtl
                    if ( glyph_length > o_g_l ) glyph_text[o_g_l].uni_en = plOffset + prOffset + pRun->item->length;
                } else {
                    if ( glyph_length > 0 ) glyph_text[glyph_length - 1].uni_en = plOffset + prOffset + pRun->item->length;
                }
                // the terminating glyph has glyph_id=0 because it means 'no glyph'
                glyph_text[glyph_length].gl = 0;
                // and is associated with no text (but you cannot set uni_st=uni_en=0, because the termination
                // is expected to be the glyph for the termination of the uni32_text)
                glyph_text[glyph_length].uni_st = glyph_text[glyph_length].uni_en = plOffset + prOffset + pRun->item->length;
            }
            curR = curR->next;
        }
    } while ( pango_layout_iter_next_line(pIter) );
    pango_layout_iter_free(pIter);

    // grunt work done. now some additional info for layout: computing letters, mostly (one letter = several glyphs sometimes)
    PangoLogAttr *pAttrs = NULL;
    int nbAttr = 0;
    // get the layout attrs, they hold the boundaries pango computed
    pango_layout_get_log_attrs(pLayout, &pAttrs, &nbAttr);
    // feed to MakeTextBoundaries which knows what to do with these
    MakeTextBoundaries(pAttrs, nbAttr);
    // the array of boundaries is full, but out-of-order
    SortBoundaries();
    // boundary array is ready to be used, call chunktext to fill the *_start fields of the glyphs, and compute
    // the boxed version of the text for sp-typeset
    ChunkText();
    // get rid of the attributes
    if ( pAttrs ) g_free(pAttrs);

    // cleaning up
    for (int i = 0; i < glyph_length; i++) {
        glyph_text[i].uni_st = uni32_codepoint[glyph_text[i].uni_st];
        glyph_text[i].uni_en = uni32_codepoint[glyph_text[i].uni_en];
        glyph_text[i].x /= 512; // why is this not default_font->daddy->fontsize?
        glyph_text[i].y /= 512;
    }
    if ( glyph_length > 0 ) {
        glyph_text[glyph_length].x /= 512;
        glyph_text[glyph_length].y /= 512;
    }
}
			void GuiSolidLabelElementRenderer::OnElementStateChanged()
			{
				FontProperties font = element->GetFont();
				Color color = element->GetColor();
				int layoutWidth, layoutHeight;
				
				AString family = wtoa(font.fontFamily);
				pango_font_description_set_family(pangoFontDesc, family.Buffer());
				pango_font_description_set_absolute_size(pangoFontDesc, font.size * PANGO_SCALE);

				if(font.italic) pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_ITALIC);
				else pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_NORMAL);

				if(attrList)
				{
					pango_attr_list_unref(attrList);
				}

				attrList = pango_attr_list_new();
				
				pango_attr_list_insert(attrList, pango_attr_underline_new(
							font.underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE)
					);

				pango_attr_list_insert(attrList, pango_attr_strikethrough_new (
							font.strikeline ? TRUE : FALSE
							)
						);

				pango_attr_list_insert(attrList, pango_attr_weight_new (
							font.bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_MEDIUM
							)
						);

				if(layout)
				{
					g_object_unref(layout);
					layout = NULL;
				}

				if(cairoContext)
				{
					layout = pango_cairo_create_layout(cairoContext);

					WString wtext = (font.fontFamily == L"Webdings") ? helpers::WebdingsMap(element->GetText()) : element->GetText();
					AString text = wtoa(wtext);

					pango_layout_set_font_description(layout, pangoFontDesc);
					pango_layout_set_attributes(layout, attrList);
					pango_layout_set_text(layout, text.Buffer(), text.Length());
					pango_layout_set_alignment(layout, 
							element->GetHorizontalAlignment() == Alignment::Left ? PANGO_ALIGN_LEFT :
							element->GetHorizontalAlignment() == Alignment::Center ? PANGO_ALIGN_CENTER :
							element->GetHorizontalAlignment() == Alignment::Right ? PANGO_ALIGN_RIGHT :
							PANGO_ALIGN_LEFT
							);


					pango_cairo_update_layout(cairoContext, layout);


					pango_layout_get_pixel_size( layout, &layoutWidth, &layoutHeight);

					minSize.x = layoutWidth;
					minSize.y = layoutHeight;
				}
			}
Пример #18
0
static gboolean
video_area_draw_cb (GtkWidget *widget,
		    cairo_t   *cr,
		    gpointer   user_data)
{
	GthMediaViewerPage *self = user_data;
	GtkAllocation       allocation;
	GtkStyleContext    *style_context;

	if (self->priv->xwin_assigned && self->priv->has_video)
		return FALSE;

	gtk_widget_get_allocation (widget, &allocation);
	style_context = gtk_widget_get_style_context (widget);

	if (self->priv->icon == NULL) {
		char  *type;
		GIcon *icon;
		int    size;

		type = NULL;
		if (self->priv->file_data != NULL)
			type = g_content_type_from_mime_type (gth_file_data_get_mime_type (self->priv->file_data));
		if (type == NULL)
			type = g_content_type_from_mime_type ("text/plain");
		icon = g_content_type_get_icon (type);
		size = allocation.width;
		if (size > allocation.height)
			size = allocation.height;
		size = size / 3;
		self->priv->icon = _g_icon_get_pixbuf (icon, size, _gtk_widget_get_icon_theme (widget));

		g_object_unref (icon);
		g_free (type);
	}

	cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
	cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
	cairo_fill (cr);

	if (self->priv->icon != NULL) {
		int                   icon_w, icon_h;
		int                   text_w;
		int                   icon_x, icon_y;
		PangoRectangle        logical_rect;
		int                   x, y;
		PangoFontDescription *font;

		icon_w = gdk_pixbuf_get_width (self->priv->icon);
		icon_h = gdk_pixbuf_get_height (self->priv->icon);

		text_w = (icon_w * 3 / 2);
		pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * text_w);
		pango_layout_get_extents (self->priv->caption_layout, NULL, &logical_rect);

		icon_x = (allocation.width - icon_w) / 2;
		x = (allocation.width - text_w) / 2;

		icon_y = (allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
		y = icon_y + icon_h;

		gdk_cairo_set_source_pixbuf (cr, self->priv->icon, icon_x, icon_y);
		cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
		cairo_fill (cr);

		cairo_move_to (cr, x, y);
		gtk_style_context_get (style_context, gtk_widget_get_state_flags (widget), "font", &font, NULL);
		pango_layout_set_font_description (self->priv->caption_layout, font);
		pango_cairo_layout_path (cr, self->priv->caption_layout);
		cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
		cairo_fill (cr);
	}

	return TRUE;
}
Пример #19
0
int puretext_process(weed_plant_t *inst, weed_timecode_t tc) {
  int error;

  weed_plant_t *in_channel=weed_get_plantptr_value(inst,"in_channels",&error);
  weed_plant_t *out_channel=weed_get_plantptr_value(inst,"out_channels",&error);
  weed_plant_t **in_params=weed_get_plantptr_array(inst,"in_parameters",&error);

  sdata_t *sdata=(sdata_t *)weed_get_voidptr_value(inst,"plugin_internal",&error);

  guchar *bgdata=NULL;

  pt_subst_t *xsubst;

  cairo_t *cairo;

  guchar *dst=weed_get_voidptr_value(out_channel,"pixel_data",&error);

  size_t toffs;

  //int alpha_threshold = 0;

  int orowstride=weed_get_int_value(out_channel,"rowstrides",&error);

  int width=weed_get_int_value(out_channel,"width",&error);
  int height=weed_get_int_value(out_channel,"height",&error);

  int mode=weed_get_int_value(in_params[P_MODE],"value",&error);

  register int i,j;


  weed_free(in_params); // must weed free because we got an array

  if (mode!=sdata->mode) {
    sdata->timer=-1.;
    sdata->mode=mode;
    sdata->alarm_time=0.;
    if (sdata->letter_data!=NULL) letter_data_free(sdata);
  }

  // set timer data and alarm status
  if (sdata->timer==-1.||tc<sdata->last_tc) {
    sdata->timer=0.;
    sdata->length=0;
  } else {
    sdata->timer+=(double)(tc-sdata->last_tc)/100000000.;
    sdata->alarm=FALSE;
  }

  if (sdata->alarm_time>-1.&&sdata->timer>=sdata->alarm_time) {
    sdata->alarm_time=-1.;
    sdata->alarm=TRUE;
  }

  sdata->last_tc=tc;

  sdata->count=0;

  if (sdata->mode==PT_WORD_COALESCE) {
    // backup original data
    bgdata=weed_malloc(height*orowstride);
    weed_memcpy(bgdata,dst,height*orowstride);
  }



  // THINGS TO TO WITH TEXTS AND PANGO
  if ((!in_channel) || (in_channel == out_channel))
    cairo = channel_to_cairo(out_channel);
  else
    cairo = channel_to_cairo(in_channel);

  if (cairo) {
    // TODO - get real offset of start in bytes

    if (sdata->text_type==TEXT_TYPE_ASCII) {
      toffs=sdata->start;
    } else {
      toffs=utf8offs(sdata->text,sdata->start);
    }

    // loop from start char to end char
    for (i=sdata->start; i<sdata->start+(sdata->length==0?1:sdata->length); i++) {
      PangoLayout *layout = pango_cairo_create_layout(cairo);
      if (layout) {
        PangoFontDescription *font;
        char *xtext;

        font = pango_font_description_new();

        // send letter or word to proctext

        //if((num_fonts_available) && (fontnum >= 0) && (fontnum < num_fonts_available) && (fonts_available[fontnum]))
        pango_font_description_set_family(font, "Serif");

        if (sdata->length==0) {
          xtext=weed_malloc(1);
          weed_memset(xtext,0,1);
        } else {
          switch (sdata->tmode) {
          case PT_LETTER_MODE:
            // letter mode
            if (sdata->text_type==TEXT_TYPE_ASCII) {
              xtext=stringdup(&sdata->text[toffs],1);
              toffs++;
            } else {
              int xlen=mbtowc(NULL,&sdata->text[toffs],4);
              xtext=stringdup(&sdata->text[toffs],xlen);
              toffs+=xlen;
            }
            break;

          case PT_WORD_MODE:
            // word mode
            if (sdata->text_type==TEXT_TYPE_ASCII) {
              xsubst=get_nth_word_ascii(sdata->text,i);
            } else {
              xsubst=get_nth_word_utf8(sdata->text,i);
            }
            xtext=stringdup(&sdata->text[xsubst->start],xsubst->length);

            weed_free(xsubst);
            break;
          default:
            // TODO - line mode and all mode
            xtext=weed_malloc(1);
            weed_memset(xtext,0,1);
            break;
          }
        }
        pango_layout_set_font_description(layout, font);
        pango_layout_set_text(layout, (char *)xtext, -1);

        // default colour - opaque white
        sdata->fg.red=sdata->fg.green=sdata->fg.blue=255.;
        sdata->fg_alpha=1.;

        cairo_save(cairo);

        // get size, position, and colour
        proctext(sdata,tc,(char *)xtext,cairo,layout,font,width,height);

        free(xtext);

        cairo_move_to(cairo, sdata->x_text, sdata->y_text);

        cairo_set_source_rgba(cairo,sdata->fg.red/255.0, sdata->fg.green/255.0, sdata->fg.blue/255.0,
                              sdata->fg_alpha);

        pango_cairo_show_layout(cairo, layout);

        cairo_restore(cairo);

        pango_font_description_free(font);
        g_object_unref(layout);
      }

      sdata->count++;

    } // end loop

    cairo_to_channel(cairo,out_channel);
    cairo_destroy(cairo);
  }


  if (sdata->mode==PT_WORD_COALESCE) {
    if (sdata->dbl1>0.) {
      guchar *b_data=bgdata;
      int width3=width*3;
      guchar *dstx=dst=weed_get_voidptr_value(out_channel,"pixel_data",&error);

      for (i=0; i<height; i++) {
        for (j=0; j<width3; j+=3) {
          if (dst[j]!=b_data[j]||dst[j+1]!=b_data[j+1]||dst[j+2]!=b_data[j+2]) {
            // move point by sdata->dbl1 pixels
            double angle=rand_angle();
            int x=j/3+sin(angle)*sdata->dbl1;
            int y=i+cos(angle)*sdata->dbl1;
            if (x>0&&x<width&&y>0&&y<height) {
              // blur 1 pixel
              memcpy(&dstx[y*orowstride+x*3],&dst[j],3);
              // protect blurred pixel
              if (y>=i) memcpy(&bgdata[y*orowstride+x*3],&dst[j],3);
            }
            // replace original pixel
            memcpy(&dst[j],&b_data[j],3);
          }
        }
        dst+=orowstride;
        b_data+=orowstride;
      }
    }
    weed_free(bgdata);
  }

  return WEED_NO_ERROR;
}
Пример #20
0
void
xkb_cairo_draw_label (cairo_t *cr,
                      const gchar *group_name,
                      const gint panel_size,
                      const gint actual_width,
                      const gint actual_height,
                      const gint width,
                      const gint height,
                      const gint variant_markers_count,
                      const guint text_scale,
                      const GdkColor fgcolor)
{
    gchar *normalized_group_name;
    gint pango_width, pango_height;
    double layoutx, layouty, text_width, text_height;
    double xx, yy;
    double scalex, scaley;
    gint i;
    double radius, diameter;

    PangoLayout *layout;
    PangoFontDescription *desc;

    g_assert (cr != NULL);

    DBG ("actual width/height: %d/%d; markers: %d",
         actual_width, actual_height, variant_markers_count);

    layout = pango_cairo_create_layout (cr);
    normalized_group_name = xkb_util_normalize_group_name (group_name);

    if (!normalized_group_name ||
        !g_utf8_validate (normalized_group_name, -1, NULL))
    {
        g_object_unref (layout);
        g_free (normalized_group_name);
        return;
    }

    pango_layout_set_text (layout, normalized_group_name, -1);

    desc = pango_font_description_from_string ( XKB_PREFERRED_FONT );
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);

    gdk_cairo_set_source_color (cr, &fgcolor);
    pango_layout_get_pixel_size (layout, &pango_width, &pango_height);
    DBG ("pango_width/height: %d/%d", pango_width, pango_height);

    scalex = scaley = text_scale / 100.0;

    DBG ("txt size scale x/y: %.2f/%.2f", scalex, scaley);

    text_height = actual_height * scaley;
    scaley = text_height / pango_height;
    radius = (text_height < 32) ? 1.2 : 2.5;
    diameter = 2 * radius;

    text_width  = actual_width * scalex;
    if (actual_width - text_width < 3 + variant_markers_count * diameter)
    {
        text_width = actual_width - 3 - (variant_markers_count) * diameter;
    }
    else if (text_scale >= 99.5)
    {
        text_width -= 3;
    }

    scalex =  text_width/pango_width;

    layoutx = (actual_width -
               (text_width + (variant_markers_count ? 3:0) +
                variant_markers_count * diameter)) / 2;
    layouty = (actual_height - text_height) / 2;

    DBG ("text_width/height: %.2f/%.2f", text_width, text_height);
    DBG ("layout x/y: %.2f/%.2f scale x/y: %.2f/%.2f, radius: %.2f",
         layoutx, layouty, scalex, scaley, radius);

    xkb_cairo_move_to (cr, layoutx, layouty);
    cairo_save (cr);
    cairo_scale (cr, scalex, scaley);
    pango_cairo_show_layout (cr, layout);
    cairo_restore (cr);

    for (i = 0; i < variant_markers_count; i++)
    {
        cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
        cairo_set_line_width (cr, 1);
        xkb_cairo_arc_for_label (cr,
                layoutx + text_width + 3 + (diameter * i),
                layouty + text_height - (text_height / 5),
                radius, 0, 2 * G_PI
        );
        cairo_fill (cr);
    }

    g_free (normalized_group_name);
    g_object_unref (layout);
}
Пример #21
0
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;
}
Пример #22
0
static void
gth_empty_list_realize (GtkWidget *widget)
{
	GthEmptyList  *self;
	GdkWindowAttr  attributes;
	int            attributes_mask;

	g_return_if_fail (GTH_IS_EMPTY_LIST (widget));

	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);

	/**/

	attributes.window_type = GDK_WINDOW_CHILD;
	attributes.x           = widget->allocation.x;
	attributes.y           = widget->allocation.y;
	attributes.width       = widget->allocation.width;
	attributes.height      = widget->allocation.height;
	attributes.wclass      = GDK_INPUT_OUTPUT;
	attributes.visual      = gtk_widget_get_visual (widget);
	attributes.colormap    = gtk_widget_get_colormap (widget);
	attributes.event_mask  = GDK_VISIBILITY_NOTIFY_MASK;
	attributes_mask        = (GDK_WA_X
				  | GDK_WA_Y
				  | GDK_WA_VISUAL
				  | GDK_WA_COLORMAP);
	widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
					 &attributes,
					 attributes_mask);
	gdk_window_set_user_data (widget->window, widget);

	/**/

	self = (GthEmptyList*) widget;

	attributes.x = 0;
	attributes.y = 0;
	attributes.width = widget->allocation.width;
	attributes.height = widget->allocation.height;
	attributes.event_mask = (GDK_EXPOSURE_MASK
				 | GDK_SCROLL_MASK
				 | GDK_POINTER_MOTION_MASK
				 | GDK_ENTER_NOTIFY_MASK
				 | GDK_LEAVE_NOTIFY_MASK
				 | GDK_BUTTON_PRESS_MASK
				 | GDK_BUTTON_RELEASE_MASK
				 | gtk_widget_get_events (widget));

	self->priv->bin_window = gdk_window_new (widget->window,
						 &attributes,
						 attributes_mask);
	gdk_window_set_user_data (self->priv->bin_window, widget);

	/* Style */

	widget->style = gtk_style_attach (widget->style, widget->window);
	gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
	gdk_window_set_background (self->priv->bin_window, &widget->style->base[widget->state]);
	
	/* 'No Image' message Layout */

	if (self->priv->layout != NULL)
		g_object_unref (self->priv->layout);

	self->priv->layout = gtk_widget_create_pango_layout (widget, NULL);
	pango_layout_set_wrap (self->priv->layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_font_description (self->priv->layout, widget->style->font_desc);
	pango_layout_set_alignment (self->priv->layout, PANGO_ALIGN_CENTER);
}
Пример #23
0
static PangoLayout *
rsvg_text_create_layout (RsvgDrawingCtx * ctx,
                         RsvgState * state, const char *text, PangoContext * context)
{
    PangoFontDescription *font_desc;
    PangoLayout *layout;
    PangoAttrList *attr_list;
    PangoAttribute *attribute;

    if (state->lang)
        pango_context_set_language (context, pango_language_from_string (state->lang));

    if (state->unicode_bidi == UNICODE_BIDI_OVERRIDE || state->unicode_bidi == UNICODE_BIDI_EMBED)
        pango_context_set_base_dir (context, state->text_dir);

    font_desc = pango_font_description_copy (pango_context_get_font_description (context));

    if (state->font_family)
        pango_font_description_set_family_static (font_desc, state->font_family);

    pango_font_description_set_style (font_desc, state->font_style);
    pango_font_description_set_variant (font_desc, state->font_variant);
    pango_font_description_set_weight (font_desc, state->font_weight);
    pango_font_description_set_stretch (font_desc, state->font_stretch);
    pango_font_description_set_size (font_desc,
                                     _rsvg_css_normalize_font_size (state, ctx) *
                                     PANGO_SCALE / ctx->dpi_y * 72);

    layout = pango_layout_new (context);
    pango_layout_set_font_description (layout, font_desc);
    pango_font_description_free (font_desc);

    attr_list = pango_attr_list_new ();
    attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing,
                                                                           ctx, 'h') * PANGO_SCALE);
    attribute->start_index = 0;
    attribute->end_index = G_MAXINT;
    pango_attr_list_insert (attr_list, attribute); 

    if (state->has_font_decor && text) {
        if (state->font_decor & TEXT_UNDERLINE) {
            attribute = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
            attribute->start_index = 0;
            attribute->end_index = -1;
            pango_attr_list_insert (attr_list, attribute);
        }
	if (state->font_decor & TEXT_STRIKE) {
            attribute = pango_attr_strikethrough_new (TRUE);
            attribute->start_index = 0;
            attribute->end_index = -1;
            pango_attr_list_insert (attr_list, attribute);
	}
    }

    pango_layout_set_attributes (layout, attr_list);
    pango_attr_list_unref (attr_list);

    if (text)
        pango_layout_set_text (layout, text, -1);
    else
        pango_layout_set_text (layout, NULL, 0);

    pango_layout_set_alignment (layout, (state->text_dir == PANGO_DIRECTION_LTR ||
                                         state->text_dir == PANGO_DIRECTION_TTB_LTR) ?
                                PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);

    return layout;
}
Пример #24
0
void draw_clock_face(GtkWidget *clock_face, cairo_t *crt) {

	ClockFace *cf = CLOCK_FACE(clock_face);

	if (!cf->clock) {
		fprintf(stderr, "Can't draw a NULL clock\n");
		return;
	}

	pthread_mutex_lock( &mutex_drawing );

	cairo_surface_t *buffer_surf = cairo_image_surface_create(
			CAIRO_FORMAT_ARGB32, 
			clock_face->allocation.width, 
			clock_face->allocation.height);

	cairo_t *buff_crt = cairo_create(buffer_surf);

	char white[32];
	char black[32];

	clock_to_string(cf->clock, 0, white);
	clock_to_string(cf->clock, 1, black);

	PangoFontDescription *desc;
	PangoLayout *layout;

	layout = pango_cairo_create_layout (buff_crt);
	pango_layout_set_text(layout, white, -1);

	char font_str[32];

	float hi_font_size;
	float wi_font_size;
	float font_size;
	int wi = clock_face->allocation.width;
	int hi = clock_face->allocation.height;

	// Create and Set font description

	/* *
	 * Find Optimal Font Size in points
	 * the initial guessed size is an average from experiments 
	 * but is adjusted for the current display if too big
	 * */
	hi_font_size = hi/1.58;
	wi_font_size = wi/17.45;
	font_size = (hi_font_size < wi_font_size)? hi_font_size : wi_font_size;

	sprintf(font_str, "%s %.1f", FONT_FACE, font_size);
	desc = pango_font_description_from_string (font_str);
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);

	int pix_width, pix_height;
	pango_layout_get_pixel_size (layout, &pix_width, &pix_height);

	/* Check that pixel width is no larger than a half-clock width
	 * and that pixel height is no larger than a clock height */
	while ( (pix_height > hi || pix_width > wi) && font_size > 0) {
		font_size -= .1;
		sprintf(font_str, "%s %.2f", FONT_FACE, font_size);
		desc = pango_font_description_from_string (font_str);
		pango_layout_set_font_description (layout, desc);
		pango_font_description_free (desc);
		pango_layout_get_pixel_size (layout, &pix_width, &pix_height);
	}

	int wa = is_active(cf->clock, 0);
	int ba = is_active(cf->clock, 1);
	int my_color = -1;
	int warn_me = 0;
	static int warn_toggle = 1;

	if (cf->clock->relation > 0) {
		my_color = 0;
	}
	else if (cf->clock->relation < 0) {
		my_color = 1;
	}

	if (my_color > -1) {
		if (my_color ? ba : wa) {
			warn_me = am_low_on_time(cf->clock);
			warn_toggle++; warn_toggle %= 4;
		}
	}

	cairo_save(buff_crt);

	// paint white's clock background
	if (wa) {
		if (warn_me && warn_toggle < 2) {
			cairo_set_source_rgb(buff_crt, .86, 0, 0); // bright red
		}
		else {
			cairo_set_source_rgb(buff_crt, 0, .4, .7);
		}
	}
	else {
		cairo_set_source_rgb(buff_crt, 1, 1, 1);
	}
	cairo_rectangle(buff_crt, 0, 0, ((double)wi/2.0f), hi);
	cairo_fill(buff_crt);

	// paint white's clock text
	if (wa) {
		cairo_set_source_rgb(buff_crt, 1, 1, 1);
	}
	else {
		cairo_set_source_rgb(buff_crt, 0, .4, .7);
	}

	double tx = .5*(wi/2.0f - pix_width);
	double ty = .5*(hi - pix_height);

	cairo_translate (buff_crt, tx, ty);
	pango_cairo_show_layout (buff_crt, layout);


	cairo_restore(buff_crt);

	// paint black's clock background
	cairo_translate (buff_crt, ((double)wi/2.0f), 0);

	if (ba) {
		if (warn_me && warn_toggle < 2) {
			cairo_set_source_rgb(buff_crt, .86, 0, 0); // bright red
		}
		else {
			cairo_set_source_rgb(buff_crt, 0, .4, .7);
		}
	}
	else {
		cairo_set_source_rgb(buff_crt, 1, 1, 1);
	}
	cairo_rectangle(buff_crt, 0, 0, ((double)wi/2.0f), hi);
	cairo_fill(buff_crt);

	// paint black's clock text
	if (ba) {
		cairo_set_source_rgb(buff_crt, 1, 1, 1);
	}
	else {
		cairo_set_source_rgb(buff_crt, 0, .4, .7);
	}

	pango_layout_set_text(layout, black, -1);
	pango_layout_get_pixel_size (layout, &pix_width, &pix_height);
	tx = .5*(wi/2.0f - pix_width);
	cairo_translate (buff_crt, tx, ty);
	pango_cairo_show_layout (buff_crt, layout);

	g_object_unref (layout);

	cairo_destroy(buff_crt);

	// Apply cache surface to crt
	cairo_set_source_surface (crt, buffer_surf, 0.0f, 0.0f);
	cairo_paint(crt);

	cairo_surface_destroy(buffer_surf);

	pthread_mutex_unlock( &mutex_drawing );
}
Пример #25
0
void shoes_plot_draw_legend(cairo_t *cr, shoes_plot *plot)
{
  int top, left, bottom, right; 
  int width, height;   
  left = plot->place.x; top = plot->graph_h + 5;
  right = plot->place.w; bottom = top + plot->legend_h; 
  width = right - left; 
  height = bottom - top;
  // TODO: Can some of this done in add/delete series ?
  // One Ugly Mess. 
  int i, legend_width = 0;
  int x, y;
  int white_space = 0;
  PangoLayout *layouts[6];
  PangoLayout *space_layout = pango_cairo_create_layout (cr);
  pango_layout_set_font_description (space_layout , plot->legend_pfd);
  pango_layout_set_text (space_layout, "  ", -1);
  PangoRectangle space_rect;
  pango_layout_get_pixel_extents (space_layout, NULL, &space_rect);
  white_space = space_rect.width;
  char *strary[6];
  int widary[6];
  for (i = 0; i <  6; i++) {
    strary[i] = NULL;
    widary[i] = 0;
    //layouts[i] = NULL;
  }
  for (i = 0; i < plot->seriescnt; i++) {
    if (i > 1) {
      legend_width += white_space;
    }
    VALUE cs = rb_ary_entry(plot->series, i);
    shoes_chart_series *ser;
    Data_Get_Struct(cs, shoes_chart_series, ser);
    //rbstr = rb_ary_entry(plot->long_names, i);
    strary[i] = RSTRING_PTR(ser->desc);   
    layouts[i] = pango_cairo_create_layout (cr);
    pango_layout_set_font_description (layouts[i], plot->legend_pfd);
    pango_layout_set_text (layouts[i], strary[i], -1);
    PangoRectangle logical;
    pango_layout_get_pixel_extents (layouts[i], NULL, &logical);
    widary[i] = logical.width;
    legend_width += logical.width;
  }
  int xoffset = (plot->place.w / 2) - (legend_width / 2);
  x = xoffset - (plot->place.dx);
  int yhalf = (plot->legend_h / 2 ); 
  int yoffset = yhalf; 
  y = yoffset;
 
  //int pos_x = plot->place.ix + x;
  int baseline = bottom - 5; //TODO: compute baseline better
  // printf("middle? w: %i, l: %i  pos_x: %i, strw: %i\n", width, left, pos_x, legend_width);
  cairo_move_to(cr, x, baseline);
  for (i = 0; i < plot->seriescnt; i++) {
    VALUE cs = rb_ary_entry(plot->series, i);
    shoes_chart_series *ser;
    Data_Get_Struct(cs, shoes_chart_series, ser);
    VALUE rbcolor = ser->color;
    shoes_color *color;
    Data_Get_Struct(rbcolor, shoes_color, color);
    cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
       color->b / 255.0, color->a / 255.0); 
    pango_cairo_show_layout(cr, layouts[i]);
    g_object_unref(layouts[i]);
    x += (widary[i] +  white_space);
    cairo_move_to(cr, x , baseline);
  }
  g_object_unref(space_layout);  
}
Пример #26
0
void _HYConsoleWindow::_PaintStatusBar(Ptr,bool force)
{
    if (GTK_WIDGET_MAPPED (theWindow)) {
        _Parameter      vL;
        checkParameter (VerbosityLevelString, vL, 0.0);

        if (vL<-0.5 && !force) {
            clock_t curMeasure = clock();
            _Parameter diff = 1.0/CLOCKS_PER_SEC*(curMeasure-lastMeasure);
            if (diff < -vL) {
                return;
            }
            lastMeasure = curMeasure;
        }

        if (!stripedFillGC) {
            SetUpStatusBarStuff (theWindow);
        }

        GdkRectangle wRC  = {0,0,theWindow->allocation.width,HY_SCROLLER_WIDTH},
                     w2RC;

        if (!_hyConsoleWindowGC) {
            _hyConsoleWindowGC   = gdk_gc_new     (theWindow->window);
            gdk_gc_set_tile (_hyConsoleWindowGC, stripedFill);
            gdk_gc_set_line_attributes(_hyConsoleWindowGC,1,GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
            _hyConsoleLayout = pango_layout_new (screenPContext);
            pango_layout_set_width (_hyConsoleLayout, -1);
            statusBarBold = pango_font_description_new ();
            statusBarNormal = pango_font_description_new ();
            _HYFont         consoleFont = {_HY_MONO_FONT,9,HY_FONT_PLAIN};
            HYFont2PangoFontDesc (consoleFont,statusBarNormal);
            consoleFont.style = HY_FONT_BOLD;
            HYFont2PangoFontDesc (consoleFont,statusBarBold);
        }

        GdkPixmap * offBitmap        = gdk_pixmap_new (theWindow->window, wRC.width, wRC.height,-1);

        if (offBitmap) {
            gdk_gc_set_fill         (_hyConsoleWindowGC,GDK_TILED);
            gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,true,-1,-1,wRC.width+2,wRC.height+2);
            gdk_gc_set_fill         (_hyConsoleWindowGC,GDK_SOLID);
            gdk_gc_set_foreground   (_hyConsoleWindowGC,&_BLACKBRUSH_);
            gdk_draw_line(offBitmap,_hyConsoleWindowGC,0,0,wRC.width,0);

            pango_layout_set_font_description(_hyConsoleLayout,statusBarNormal);
            pango_layout_set_text(_hyConsoleLayout,fileName.getStr(),fileName.sLength);
            gdk_draw_layout(offBitmap,_hyConsoleWindowGC,33,wRC.height-13,_hyConsoleLayout);

            if (inputStatus == 1) {
                pango_layout_set_text(_hyConsoleLayout,cInput.getStr(),cInput.sLength);
            } else {
                pango_layout_set_text(_hyConsoleLayout,action.getStr(),action.sLength);
            }

            gdk_draw_layout(offBitmap,_hyConsoleWindowGC,193,wRC.height-13,_hyConsoleLayout);

            gdk_gc_set_foreground   (_hyConsoleWindowGC,&_DARKGREYBRUSH_);

            gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,true,0,1,30,wRC.height-1);
            gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,true,150,1,40,wRC.height-1);
            gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,true,wRC.width-55,1,55,wRC.height-1);

            gdk_gc_set_foreground   (_hyConsoleWindowGC,&_WHITEBRUSH_);
            pango_layout_set_font_description(_hyConsoleLayout,statusBarBold);

            pango_layout_set_text(_hyConsoleLayout,cState.getStr(),cState.sLength);
            gdk_draw_layout(offBitmap,_hyConsoleWindowGC,3,wRC.height-13,_hyConsoleLayout);
            pango_layout_set_text(_hyConsoleLayout,cTask.getStr(),cTask.sLength);
            gdk_draw_layout(offBitmap,_hyConsoleWindowGC,151,wRC.height-13,_hyConsoleLayout);

            pango_layout_set_font_description(_hyConsoleLayout,statusBarNormal);

            pango_layout_set_text(_hyConsoleLayout,timer.getStr(),timer.sLength);
            gdk_draw_layout(offBitmap,_hyConsoleWindowGC,wRC.width-53,wRC.height-13,_hyConsoleLayout);

            if (percentDone>0 || percentDone == -HY_SL_DONE) {
                GdkColor blackBrush = HYColorToGDKColor((_HYColor) {
                    80,80,80
                }),
                orangeBrush = HYColorToGDKColor((_HYColor) {
                    255,153,102
                });

                gdk_gc_set_foreground   (_hyConsoleWindowGC,&orangeBrush);
                gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,true,wRC.width-135,wRC.height-14,(percentDone>=0?percentDone:100.)*0.75,12);

                gdk_gc_set_foreground   (_hyConsoleWindowGC,&blackBrush);
                gdk_draw_rectangle      (offBitmap,_hyConsoleWindowGC,false,wRC.width-135,wRC.height-14,75,12);

                //gdk_gc_set_foreground (_hyConsoleWindowGC,&_WHITEBRUSH_);
                _String pLine;
                if (percentDone>=0) {
                    pLine = _String(percentDone)&"%";
                } else {
                    pLine = "DONE";
                }

                pango_layout_set_text(_hyConsoleLayout,pLine.getStr(),pLine.sLength);
                gdk_draw_layout(offBitmap,_hyConsoleWindowGC,wRC.width-107,wRC.height-13,_hyConsoleLayout);
            }
        }

        gdk_draw_drawable (theWindow->window, _hyConsoleWindowGC, offBitmap, 0, 0, theWindow->allocation.x, theWindow->allocation.y+theWindow->allocation.height-wRC.height, -1, -1);
        g_object_unref (offBitmap);
    }
}
Пример #27
0
void
set_font (struct font *fp)
{
	pango_layout_set_font_description (layout, fp->desc);
}
Пример #28
0
void ttext::recalculate(const bool force) const
{
	if(calculation_dirty_ || force) {
		assert(layout_);

		calculation_dirty_ = false;
		surface_dirty_ = true;

		tfont font(get_font_families(font_class_), font_size_, font_style_);
		pango_layout_set_font_description(layout_, font.get());

		if(font_style_ & ttext::STYLE_UNDERLINE) {
			PangoAttrList *attribute_list = pango_attr_list_new();
			pango_attr_list_insert(attribute_list
					, pango_attr_underline_new(PANGO_UNDERLINE_SINGLE));

			pango_layout_set_attributes (layout_, attribute_list);
			pango_attr_list_unref(attribute_list);
		}

		int maximum_width = 0;
		if(characters_per_line_ != 0) {
			PangoFont* f = pango_font_map_load_font(
					  pango_cairo_font_map_get_default()
					, context_
					, font.get());

			PangoFontMetrics* m = pango_font_get_metrics(f, nullptr);

			int w = pango_font_metrics_get_approximate_char_width(m);
			w *= characters_per_line_;

			maximum_width = ceil(pango_units_to_double(w));
		} else {
			maximum_width = maximum_width_;
		}

		if(maximum_width_ != -1) {
			maximum_width = std::min(maximum_width, maximum_width_);
		}

		/*
		 * See set_maximum_width for some more background info as well.
		 * In order to fix the problem first set a width which seems to render
		 * correctly then lower it to fit. For the campaigns the 4 does "the
		 * right thing" for the terrain labels it should use the value 0 to set
		 * the ellipse properly. Need to see whether this is a bug in pango or
		 * a bug in my understanding of the pango api.
		 */
		int hack = 4;
		do {
			pango_layout_set_width(layout_, maximum_width == -1
					? -1
					: (maximum_width + hack) * PANGO_SCALE);
			pango_layout_get_pixel_extents(layout_, nullptr, &rect_);

			DBG_GUI_L << "ttext::" << __func__
					<< " text '" << gui2::debug_truncate(text_)
					<< "' maximum_width " << maximum_width
					<< " hack " << hack
					<< " width " << rect_.x + rect_.width
					<< ".\n";

			--hack;
		} while(maximum_width != -1
				&& hack >= 0 && rect_.x + rect_.width > maximum_width);

		DBG_GUI_L << "ttext::" << __func__
				<< " text '" << gui2::debug_truncate(text_)
				<< "' font_size " << font_size_
				<< " markedup_text " << markedup_text_
				<< " font_style " << std::hex << font_style_ << std::dec
				<< " maximum_width " << maximum_width
				<< " maximum_height " << maximum_height_
				<< " result " <<  rect_
				<< ".\n";
		if(maximum_width != -1 && rect_.x + rect_.width > maximum_width) {
			DBG_GUI_L << "ttext::" << __func__
					<< " text '" << gui2::debug_truncate(text_)
					<< " ' width " << rect_.x + rect_.width
					<< " greater as the wanted maximum of " << maximum_width
					<< ".\n";
		}
	}
}
Пример #29
0
void _HYPlatformGraphicPane::_SetFontSize (long s)
{
	pango_font_description_set_size   (theFont, s*PANGO_SCALE);
	pango_layout_set_font_description (textLayout, theFont ); // ref ?
	_ResetCharGlyphs ();
}
Пример #30
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;

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

	PROGRESS_DEBUG ("Producing gallery of %u screenshots, taken at %" G_GINT64_FORMAT " millisecond intervals throughout a %" G_GINT64_FORMAT " millisecond-long stream.",
			gallery, screenshot_interval, stream_length);

	/* Calculate how to arrange the screenshots so we don't get ones orphaned on the last row.
	 * At this point, only deal with arrangements of 3, 4 or 5 columns. */
	y = G_MAXUINT;
	for (x = 3; x <= 5; x++) {
		if (gallery % x == 0 || x - gallery % x < y) {
			y = x - gallery % x;
			columns = x;

			/* Have we found an optimal solution already? */
			if (y == x)
				break;
		}
	}

	rows = ceil ((gfloat) gallery / (gfloat) columns);

	PROGRESS_DEBUG ("Outputting as %u rows and %u columns.", rows, columns);

	/* Take the screenshots and composite them into a pixbuf */
	current_column = current_row = x = y = 0;
	for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
		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);

			PROGRESS_DEBUG ("Scaling each screenshot by %f.", scale);

			/* Create our massive pixbuf */
			pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
						 columns * output_size + (columns + 1) * x_padding,
						 (guint) (rows * scale * screenshot_height + (rows + 1) * y_padding));
			gdk_pixbuf_fill (pixbuf, 0x000000ff);

			PROGRESS_DEBUG ("Created output pixbuf (%ux%u).", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
		}

		/* Composite the screenshot into our gallery */
		gdk_pixbuf_composite (screenshot, pixbuf,
				      x, y, output_size, scale * screenshot_height,
				      (gdouble) x, (gdouble) y, scale, scale,
				      GDK_INTERP_BILINEAR, 255);
		g_object_unref (screenshot);

		PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " milliseconds (address %u) at (%u,%u).",
				pos, GPOINTER_TO_UINT (screenshot), x, y);

		/* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */
		PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));

		current_column = (current_column + 1) % columns;
		x += output_size + x_padding;
		if (current_column == 0) {
			x = x_padding;
			y += scale * screenshot_height + y_padding;
			current_row++;
		}
	}

	PROGRESS_DEBUG ("Converting pixbuf to a Cairo surface.");

	/* Load the pixbuf into a Cairo surface and overlay the text. The height is the height of
	 * the gallery plus the necessary height for 3 lines of header (at ~18px each), plus some
	 * extra padding. */
	surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf),
					      gdk_pixbuf_get_height (pixbuf) + GALLERY_HEADER_HEIGHT + y_padding);
	cr = cairo_create (surface);
	cairo_surface_destroy (surface);

	/* First, copy across the gallery pixbuf */
	gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, GALLERY_HEADER_HEIGHT + y_padding);
	cairo_rectangle (cr, 0.0, GALLERY_HEADER_HEIGHT + y_padding, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf));
	cairo_fill (cr);
	g_object_unref (pixbuf);

	/* Build the header information */
	duration_text = xplayer_time_to_string (stream_length);
	filename = NULL;
	if (strstr (app->input, "://")) {
		char *local;
		local = g_filename_from_uri (app->input, NULL, NULL);
		filename = g_path_get_basename (local);
		g_free (local);
	}
	if (filename == NULL)
		filename = g_path_get_basename (app->input);

	/* Translators: The first string is "Filename" (as translated); the second is an actual filename.
			The third string is "Resolution" (as translated); the fourth and fifth are screenshot height and width, respectively.
			The sixth string is "Duration" (as translated); the seventh is the movie duration in words. */
	header_text = g_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);

	PROGRESS_DEBUG ("Writing header text with Pango.");

	/* Write out some header information */
	layout = pango_cairo_create_layout (cr);
	font_desc = pango_font_description_from_string ("Sans 18px");
	pango_layout_set_font_description (layout, font_desc);
	pango_font_description_free (font_desc);

	pango_layout_set_markup (layout, header_text, -1);
	g_free (header_text);

	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
	cairo_move_to (cr, (gdouble) x_padding, (gdouble) y_padding);
	pango_cairo_show_layout (cr, layout);

	/* Go through each screenshot and write its timestamp */
	current_column = current_row = 0;
	x = x_padding + output_size;
	y = y_padding * 2 + GALLERY_HEADER_HEIGHT + scale * screenshot_height;

	font_desc = pango_font_description_from_string ("Sans 10px");
	pango_layout_set_font_description (layout, font_desc);
	pango_font_description_free (font_desc);

	PROGRESS_DEBUG ("Writing screenshot timestamps with Pango.");

	for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) {
		gchar *timestamp_text;
		gint layout_width, layout_height;

		timestamp_text = xplayer_time_to_string (pos);

		pango_layout_set_text (layout, timestamp_text, -1);
		pango_layout_get_pixel_size (layout, &layout_width, &layout_height);

		/* Display the timestamp in the bottom-right corner of the current screenshot */
		cairo_move_to (cr, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height);

		/* We have to stroke the text so it's visible against screenshots of the same
		 * foreground color. */
		pango_cairo_layout_path (cr, layout);
		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
		cairo_stroke_preserve (cr);
		cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
		cairo_fill (cr);

		PROGRESS_DEBUG ("Writing timestamp \"%s\" at (%f,%f).", timestamp_text,
				x - layout_width - 0.02 * output_size,
				y - layout_height - 0.02 * scale * screenshot_height);

		/* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */
		PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));

		g_free (timestamp_text);

		current_column = (current_column + 1) % columns;
		x += output_size + x_padding;
		if (current_column == 0) {
			x = x_padding + output_size;
			y += scale * screenshot_height + y_padding;
			current_row++;
		}
	}

	g_object_unref (layout);

	PROGRESS_DEBUG ("Converting Cairo surface back to pixbuf.");

	/* Create a new pixbuf from the Cairo context */
	pixbuf = cairo_surface_to_pixbuf (cairo_get_target (cr));
	cairo_destroy (cr);

	return pixbuf;
}