static void setup_font_sample(GtkWidget* darea, Antialiasing antialiasing, Hinting hinting)
{
	const char *str = "<span font=\"18\" style=\"normal\">abcfgop AO </span>"
					  "<span font=\"20\" style=\"italic\">abcfgop</span>";

	PangoContext *context;
	PangoLayout *layout;
	PangoFontDescription *fd;
	PangoRectangle extents;
	cairo_surface_t *surface;
	cairo_t *cr;
	int width, height;

	context = gtk_widget_get_pango_context (darea);
	set_fontoptions (context, antialiasing, hinting);
	layout = pango_layout_new (context);

	fd = pango_font_description_from_string ("Serif");
	pango_layout_set_font_description (layout, fd);
	pango_font_description_free (fd);

	pango_layout_set_markup (layout, str, -1);

	pango_layout_get_extents (layout, NULL, &extents);
	width = PANGO_PIXELS(extents.width) + 4;
	height = PANGO_PIXELS(extents.height) + 2;

	surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
	cr = cairo_create (surface);

	cairo_move_to (cr, 2, 1);
	pango_cairo_show_layout (cr, layout);
	g_object_unref (layout);
	cairo_destroy (cr);

	g_object_set_data_full(G_OBJECT(darea), "sample-surface", surface, (GDestroyNotify) cairo_surface_destroy);

	gtk_widget_set_size_request (GTK_WIDGET(darea), width + 2, height + 2);
#if GTK_CHECK_VERSION (3, 0, 0)
	g_signal_connect(darea, "draw", G_CALLBACK(sample_draw), NULL);
#else
	g_signal_connect(darea, "expose_event", G_CALLBACK(sample_expose), NULL);
#endif
}
/* subfunction of gtk_plot_gdk_draw_string(). */
static gint
drawstring(GtkPlotPC *pc,
	   GdkDrawable *drawable,
	   GdkGC *gc,
           gint angle,
	   gint dx, gint dy,
	   GtkPSFont *psfont, gint height,
	   const gchar *text)
{
  PangoFontDescription *font;
  PangoRectangle rect;
  const gchar *aux = text;
  gint ret_value;

  if(!text || strlen(text) == 0) return 0;
  font = gtk_psfont_get_font_description(psfont, height);
  pango_layout_set_font_description(GTK_PLOT_GDK(pc)->layout, font);

  pango_layout_set_text(GTK_PLOT_GDK(pc)->layout, text, strlen(text));
  pango_layout_get_extents(GTK_PLOT_GDK(pc)->layout, NULL, &rect);

  if (psfont->i18n_latinfamily && psfont->vertical) {
    /* vertical-writing CJK postscript fonts. */
    return rect.height;
  }
  else
  {
    /* horizontal writing */
    if(angle == 90)
      gdk_draw_layout (drawable, gc, dx, dy-PANGO_PIXELS(rect.width), GTK_PLOT_GDK(pc)->layout);
    else if(angle == 180)
      gdk_draw_layout (drawable, gc, dx-PANGO_PIXELS(rect.width), dy, GTK_PLOT_GDK(pc)->layout);
    else
      gdk_draw_layout (drawable, gc, dx, dy, GTK_PLOT_GDK(pc)->layout);

/*
    gdk_draw_layout (GTK_PLOT_GDK(pc)->drawable, gc, dx, dy, GTK_PLOT_GDK(pc)->layout);
*/

  }
  pango_font_description_free(font);
  ret_value = (angle == 0 || angle == 180) ? rect.width : rect.height;
  return PANGO_PIXELS(rect.width);
}
Exemple #3
0
static void
gtk_switch_get_preferred_height (GtkWidget *widget,
                                 gint      *minimum,
                                 gint      *natural)
{
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkBorder padding;
  gint height, focus_width, focus_pad;
  PangoLayout *layout;
  PangoRectangle logical_rect;
  gchar *str;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);
  gtk_style_context_get_padding (context, state, &padding);

  height = padding.top + padding.bottom;

  gtk_widget_style_get (widget,
                        "focus-line-width", &focus_width,
                        "focus-padding", &focus_pad,
                        NULL);

  height += 2 * (focus_width + focus_pad);

  str = g_strdup_printf ("%s%s",
                         C_("switch", "ON"),
                         C_("switch", "OFF"));

  layout = gtk_widget_create_pango_layout (widget, str);
  pango_layout_get_extents (layout, NULL, &logical_rect);
  pango_extents_to_pixels (&logical_rect, NULL);
  height += MAX (DEFAULT_SLIDER_HEIGHT, logical_rect.height);

  g_object_unref (layout);
  g_free (str);

  if (minimum)
    *minimum = height;

  if (natural)
    *natural = height;
}
Exemple #4
0
static void
_pango_xft_TextSize(TextState * ts, const char *text, int len __UNUSED__,
		    int *width, int *height, int *ascent)
{
   FontCtxPangoXft    *fdc = (FontCtxPangoXft *) ts->fdc;
   PangoLayout        *layout;
   PangoRectangle      logical_rect;

   layout = pango_layout_new(_pango_ctx);
   pango_layout_set_text(layout, text, -1);
   pango_layout_set_font_description(layout, fdc->font);
   pango_layout_get_extents(layout, NULL, &logical_rect);

   *width = PANGO_PIXELS(logical_rect.x + logical_rect.width);
   *height = PANGO_PIXELS(logical_rect.height);
   *ascent = PANGO_PIXELS(-logical_rect.y);

   g_object_unref(layout);
}
Exemple #5
0
static void
text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr)
{
	PangoRectangle extents;
	PangoRectangle cursor_pos;

	if (entry->preedit.text && entry->preedit.cursor < 0)
		return;

	pango_layout_get_extents(entry->layout, &extents, NULL);
	pango_layout_get_cursor_pos(entry->layout,
				    entry->cursor + entry->preedit.cursor,
				    &cursor_pos, NULL);

	cairo_set_line_width(cr, 1.0);
	cairo_move_to(cr, PANGO_PIXELS(cursor_pos.x), PANGO_PIXELS(extents.height) + 2);
	cairo_line_to(cr, PANGO_PIXELS(cursor_pos.x), - 2);
	cairo_stroke(cr);
}
Exemple #6
0
void  
hack_max_combo_width_cb (GtkWidget *widget,
							GtkStyle *previous_style,
                            gpointer user_data)
{
  PangoRectangle logical_rect, ink_rect;
  GtkWidget *tmp_entry;
	
  if (!GTK_IS_ENTRY(widget))
	  return;
  tmp_entry = gtk_entry_new();
  gtk_widget_set_style(tmp_entry, gtk_style_copy(widget->style));
  gtk_entry_set_text(GTK_ENTRY(tmp_entry), "00:00:00.0000.");
  
  pango_layout_get_extents (gtk_entry_get_layout (GTK_ENTRY(tmp_entry)), &ink_rect, &logical_rect);
  gtk_widget_destroy(tmp_entry);
  
  gtk_widget_set_usize(GTK_WIDGET(GTK_ENTRY(widget)),  PANGO_PIXELS (ink_rect.width), -1);
}
Exemple #7
0
/*
 * Prime the label with the largest string then fetch the width.
 * now we can lock the width via gtk_widget_set_usize() to prevent
 * the wobble wobble caused by using a variable width font.
 * Just a hackish replacement for the belated gtk_label_set_width_chars()
 * don't try this at home kids, karma will get you. (oh well.. it works.) 
 */
void  
hack_max_label_width_cb (GtkWidget *widget,
							GtkStyle *previous_style,
                            gpointer user_data)
{
  PangoRectangle logical_rect, ink_rect;
  const gchar *saved;
	
  if (!GTK_IS_LABEL(widget))
	  return;
  saved = strdup(gtk_label_get_text(GTK_LABEL(widget)));
  gtk_label_set_text(GTK_LABEL(widget), "00:00:00.0000");
  pango_layout_get_extents (gtk_label_get_layout (GTK_LABEL(widget)), &ink_rect, &logical_rect);
  gtk_label_set_text(GTK_LABEL(widget), saved);
  
  if(saved != NULL)
  g_free((gpointer)saved);
  gtk_widget_set_usize(GTK_WIDGET(widget),  PANGO_PIXELS (ink_rect.width), -1);
}
static PangoFontMetrics *
pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font,
                                                            PangoContext   *context)
{
  PangoCoreTextFont *cfont = (PangoCoreTextFont *) font;
  PangoFontMetrics *metrics;
  PangoFontDescription *font_desc;
  PangoLayout *layout;
  PangoRectangle extents;
  PangoLanguage *language = pango_context_get_language (context);
  const char *sample_str = pango_language_get_sample_string (language);
  CTFontRef ctfont;

  metrics = pango_font_metrics_new ();

  ctfont = pango_core_text_font_get_ctfont (cfont);

  metrics->ascent = CTFontGetAscent (ctfont) * PANGO_SCALE;
  metrics->descent = CTFontGetDescent (ctfont) * PANGO_SCALE;

  metrics->underline_position = CTFontGetUnderlinePosition (ctfont) * PANGO_SCALE;
  metrics->underline_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;

  metrics->strikethrough_position = metrics->ascent / 3;
  metrics->strikethrough_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;

  layout = pango_layout_new (context);
  font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font);
  pango_layout_set_font_description (layout, font_desc);
  pango_layout_set_text (layout, sample_str, -1);
  pango_layout_get_extents (layout, NULL, &extents);

  metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);

  pango_layout_set_text (layout, "0123456789", -1);
  metrics->approximate_digit_width = max_glyph_width (layout);

  pango_font_description_free (font_desc);
  g_object_unref (layout);

  return metrics;
}
Exemple #9
0
void gtk_glwidget_create_font(){
	PangoFontDescription *font_desc;
	PangoLayout *layout;
	PangoRectangle log_rect;
	int font_ascent_pango_units;
	int font_descent_pango_units;

	if ( _debug_font_created ) {
		Error( "Programming error: gtk_glwidget_create_font() was already called; "
			   "you must call gtk_glwidget_destroy_font() before creating font again" );
	}
	_debug_font_created = 1;

	font_map = pango_ft2_font_map_new();
	pango_ft2_font_map_set_resolution( PANGO_FT2_FONT_MAP( font_map ), 72, 72 );
	ft2_context = pango_font_map_create_context( PANGO_FONT_MAP( font_map ));

	font_desc = pango_font_description_from_string( font_string );
	pango_font_description_set_size( font_desc, font_height * PANGO_SCALE );
	pango_context_set_font_description( ft2_context, font_desc );
	pango_font_description_free( font_desc );

	layout = pango_layout_new( ft2_context );

	// I don't believe that's standard preprocessor syntax?
#if !PANGO_VERSION_CHECK( 1,22,0 )
	PangoLayoutIter *iter;
	iter = pango_layout_get_iter( layout );
	font_ascent_pango_units = pango_layout_iter_get_baseline( iter );
	pango_layout_iter_free( iter );
#else
	font_ascent_pango_units = pango_layout_get_baseline( layout );
#endif

	pango_layout_get_extents( layout, NULL, &log_rect );
	g_object_unref( G_OBJECT( layout ) );
	font_descent_pango_units = log_rect.height - font_ascent_pango_units;

	font_ascent = PANGO_PIXELS_CEIL( font_ascent_pango_units );
	font_descent = PANGO_PIXELS_CEIL( font_descent_pango_units );
	y_offset_bitmap_render_pango_units = ( font_ascent * PANGO_SCALE ) - font_ascent_pango_units;
}
static void
append_field_and_value (GcrCertificateDetailsWidget *self, const gchar *field, 
                        const gchar *value, gboolean monospace)
{
	PangoRectangle extents;
	PangoTabArray *tabs;
	PangoLayout *layout;
	GtkTextIter iter;
	gchar *text;
	
	text = g_strdup_printf ("%s:", field);
	if (value == NULL)
		value = "";
	
	/* Measure the width of the field */
	layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), text);
	pango_layout_get_extents (layout, NULL, &extents);
	pango_extents_to_pixels (&extents, NULL);
	g_object_unref (layout);
	
	/* Make the tab wide enough to accomodate */
	if (extents.width > self->pv->field_width) {
		self->pv->field_width = extents.width + COLUMN_MARGIN;
		tabs = pango_tab_array_new (1, TRUE);
		pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, self->pv->field_width);
		g_object_set (self->pv->field_tag, 
		              "left-margin", FIELD_MARGIN,
		              "indent", 0 - self->pv->field_width,
		              "tabs", tabs,
		              NULL);
		pango_tab_array_free (tabs);
	}
	
	gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
	gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, text, -1, "field", NULL);
	gtk_text_buffer_insert (self->pv->buffer, &iter, "\t", 1);
	gtk_text_buffer_insert_with_tags_by_name (self->pv->buffer, &iter, value, -1, "field", 
	                                          monospace ? "monospace" : NULL, NULL);
	gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1);
	
	g_free (text);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents
  (JNIEnv *env, jobject self, jdoubleArray javaInkExtents, jdoubleArray javaLogExtents)
{
  struct textlayout *tl;
  PangoRectangle pangoInkExtents, pangoLogExtents;
  jdouble *nativeInkExtents, *nativeLogExtents;

  gdk_threads_enter ();

  g_assert(self != NULL);
  g_assert(javaInkExtents != NULL);
  g_assert(javaLogExtents != NULL);

  tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
  g_assert(tl != NULL);
  g_assert(tl->pango_layout != NULL);
  
  g_assert((*env)->GetArrayLength (env, javaInkExtents) == 4);
  g_assert((*env)->GetArrayLength (env, javaLogExtents) == 4);

  nativeInkExtents = (*env)->GetDoubleArrayElements (env, javaInkExtents, NULL);    
  nativeLogExtents = (*env)->GetDoubleArrayElements (env, javaLogExtents, NULL);  

  pango_layout_get_extents (tl->pango_layout, 
			    &pangoInkExtents, &pangoLogExtents);

  nativeInkExtents[0] = (jdouble) pangoInkExtents.x;
  nativeInkExtents[1] = (jdouble) pangoInkExtents.y;
  nativeInkExtents[2] = (jdouble) pangoInkExtents.width;
  nativeInkExtents[3] = (jdouble) pangoInkExtents.height;

  nativeLogExtents[0] = (jdouble) pangoLogExtents.x;
  nativeLogExtents[1] = (jdouble) pangoLogExtents.y;
  nativeLogExtents[2] = (jdouble) pangoLogExtents.width;
  nativeLogExtents[3] = (jdouble) pangoLogExtents.height;

  (*env)->ReleaseDoubleArrayElements (env, javaInkExtents, nativeInkExtents, 0);
  (*env)->ReleaseDoubleArrayElements (env, javaLogExtents, nativeLogExtents, 0);

  gdk_threads_leave ();    
}
Exemple #12
0
static void anim_label_create_pixmap(GtkAnimLabel * anim_label
)
{

	PangoRectangle prect;
	GtkWidget *widget = GTK_WIDGET(anim_label);

	if (anim_label->pixmap)
		return;

	/* tworze bitmape pod ten tekst */
	pango_layout_get_extents(anim_label->layout, NULL, &prect);
	anim_label->pixmap = gdk_pixmap_new(widget->window, PANGO_PIXELS(prect.width) + 5, PANGO_PIXELS(prect.height), -1);

	/* czyscze pixmape */
	gdk_draw_rectangle(anim_label->pixmap, widget->style->bg_gc[widget->state], TRUE, 0, 0, PANGO_PIXELS(prect.width) + 5, PANGO_PIXELS(prect.height));

	/* maluje na niej tekst */
	gdk_draw_layout(anim_label->pixmap, widget->style->fg_gc[widget->state], anim_label->misc.xpad, anim_label->misc.ypad, anim_label->layout);

}
Exemple #13
0
gdouble
planner_print_job_get_extents (PlannerPrintJob *job, char *text)
{
	PangoLayout *layout = gtk_print_context_create_pango_layout (job->pc);
	PlannerPrintJobPriv *priv;
	PangoRectangle ink;

	priv = job->priv;

	pango_layout_set_font_description (layout, priv->current_font);
	pango_layout_set_text (layout, text, -1);

        pango_cairo_update_layout (gtk_print_context_get_cairo_context(job->pc), layout);
	pango_layout_context_changed (layout);

	pango_layout_get_extents (layout, &ink, NULL);

	g_object_unref (layout);

	return ((gdouble)ink.width / PANGO_SCALE);
}
Exemple #14
0
static VALUE
rg_get_extents(int argc, VALUE *argv, VALUE self)
{
    VALUE ink_rect, logical_rect;
    PangoRectangle rink, rlog;

    rb_scan_args(argc, argv, "02", &ink_rect, &logical_rect);

    if (NIL_P(ink_rect)){
        rink.x = 0;
        rink.y = 0;
        rink.width = 0;
        rink.height = 0;
    } else {
        PangoRectangle* rect = (PangoRectangle*)RVAL2BOXED(ink_rect, PANGO_TYPE_RECTANGLE);
        rink.x = rect->x;
        rink.y = rect->y;
        rink.width = rect->width;
        rink.height = rect->height;
    }
    if (NIL_P(logical_rect)){
        rlog.x = 0;
        rlog.y = 0;
        rlog.width = 0;
        rlog.height = 0;
    } else {
        PangoRectangle* rect = (PangoRectangle*)RVAL2BOXED(logical_rect, PANGO_TYPE_RECTANGLE);
        rlog.x = rect->x;
        rlog.y = rect->y;
        rlog.width = rect->width;
        rlog.height = rect->height;
    }   

    pango_layout_get_extents(_SELF(self), &rink, &rlog);

    return rb_assoc_new(BOXED2RVAL(&rink, PANGO_TYPE_RECTANGLE),
                        BOXED2RVAL(&rlog, PANGO_TYPE_RECTANGLE));
}
Exemple #15
0
static void gtk_anim_label_size_request(GtkWidget * widget, GtkRequisition * requisition
)
{
	GtkAnimLabel *anim_label = NULL;
	PangoRectangle prect;

	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_ANIM_LABEL(widget));
	g_return_if_fail(requisition != NULL);

	anim_label = GTK_ANIM_LABEL(widget);

	requisition->width = anim_label->misc.xpad * 2;
	requisition->height = anim_label->misc.ypad * 2;

	if (anim_label->layout && GTK_WIDGET_MAPPED(widget) && (anim_label->txt) && (strlen(anim_label->txt) > 0))
	{
		pango_layout_get_extents(anim_label->layout, NULL, &prect);
		requisition->height += PANGO_PIXELS(prect.height);
		return;
	}

}
Exemple #16
0
void font_engine_draw_string
                        (GdkDrawable                    *drawable,
                         struct font_engine_font_t      *font,
                         GdkGC                          *gc,
                         gint                           x,
                         gint                           y,
                         const gchar                    *string)
{
if(!font->is_pango)
	{
	gdk_draw_string(drawable, font->gdkfont, gc, x, y, string);
	}
#if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0)
	else
	{
	PangoRectangle ink,logical;

	pango_layout_set_text(GLOBALS->fonts_layout, string, -1);
	pango_layout_set_font_description(GLOBALS->fonts_layout, font->desc);
	pango_layout_get_extents(GLOBALS->fonts_layout,&ink,&logical);
	gdk_draw_layout(drawable, gc, x, y-font->ascent, GLOBALS->fonts_layout);
	}
#endif
}
Exemple #17
0
static void
gtk_switch_get_preferred_width (GtkWidget *widget,
                                gint      *minimum,
                                gint      *natural)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkBorder padding;
  gint width, slider_width, focus_width, focus_pad;
  PangoLayout *layout;
  PangoRectangle logical_rect;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  if (priv->is_active)
    state |= GTK_STATE_FLAG_ACTIVE;

  gtk_style_context_save (context);

  gtk_style_context_set_state (context, state);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
  gtk_style_context_get_padding (context, state, &padding);

  width = padding.left + padding.right;

  gtk_style_context_restore (context);

  gtk_widget_style_get (widget,
                        "slider-width", &slider_width,
                        "focus-line-width", &focus_width,
                        "focus-padding", &focus_pad,
                        NULL);

  width += 2 * (focus_width + focus_pad);

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));
  pango_layout_get_extents (layout, NULL, &logical_rect);
  pango_extents_to_pixels (&logical_rect, NULL);
  width += MAX (logical_rect.width, slider_width);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  pango_layout_set_text (layout, C_("switch", "OFF"), -1);
  pango_layout_get_extents (layout, NULL, &logical_rect);
  pango_extents_to_pixels (&logical_rect, NULL);
  width += MAX (logical_rect.width, slider_width);

  g_object_unref (layout);

  if (minimum)
    *minimum = width;

  if (natural)
    *natural = width;
}
Exemple #18
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;
}
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;
}
Exemple #20
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d P A N G O I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadPANGOImage() reads an image in the Pango Markup Language Format.
%
%  The format of the ReadPANGOImage method is:
%
%      Image *ReadPANGOImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadPANGOImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  cairo_font_options_t
    *font_options;

  cairo_surface_t
    *surface;

  char
    *caption,
    *property;

  cairo_t
    *cairo_image;

  const char
    *option;

  DrawInfo
    *draw_info;

  Image
    *image;

  MagickBooleanType
    status;

  PangoAlignment
    align;

  PangoContext
    *context;

  PangoFontMap
    *fontmap;

  PangoGravity
    gravity;

  PangoLayout
    *layout;

  PangoRectangle
    extent;

  PixelInfo
    fill_color;

  RectangleInfo
    page;

  register unsigned char
    *p;

  size_t
    stride;

  ssize_t
    y;

  unsigned char
    *pixels;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info,exception);
  (void) ResetImagePage(image,"0x0+0+0");
  /*
    Format caption.
  */
  option=GetImageArtifact(image,"filename");
  if (option == (const char *) NULL)
    property=InterpretImageProperties(image_info,image,image_info->filename,
      exception);
  else
    if (LocaleNCompare(option,"pango:",6) == 0)
      property=InterpretImageProperties(image_info,image,option+6,exception);
    else
      property=InterpretImageProperties(image_info,image,option,exception);
  (void) SetImageProperty(image,"caption",property,exception);
  property=DestroyString(property);
  caption=ConstantString(GetImageProperty(image,"caption",exception));
  /*
    Get context.
  */
  fontmap=pango_cairo_font_map_new();
  pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap),
    image->resolution.x == 0.0 ? 90.0 : image->resolution.x);
  font_options=cairo_font_options_create();
  option=GetImageArtifact(image,"pango:hinting");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"none") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE);
      if (LocaleCompare(option,"full") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL);
    }
  context=pango_font_map_create_context(fontmap);
  pango_cairo_context_set_font_options(context,font_options);
  cairo_font_options_destroy(font_options);
  option=GetImageArtifact(image,"pango:language");
  if (option != (const char *) NULL)
    pango_context_set_language(context,pango_language_from_string(option));
  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
  pango_context_set_base_dir(context,draw_info->direction ==
    RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
  switch (draw_info->gravity)
  {
    case NorthGravity:
    {
      gravity=PANGO_GRAVITY_NORTH;
      break;
    }
    case NorthWestGravity:
    case WestGravity:
    case SouthWestGravity:
    {
      gravity=PANGO_GRAVITY_WEST;
      break;
    }
    case NorthEastGravity:
    case EastGravity:
    case SouthEastGravity:
    {
      gravity=PANGO_GRAVITY_EAST;
      break;
    }
    case SouthGravity:
    {
      gravity=PANGO_GRAVITY_SOUTH;
      break;
    }
    default:
    {
      gravity=PANGO_GRAVITY_AUTO;
      break;
    }
  }
  pango_context_set_base_gravity(context,gravity);
  option=GetImageArtifact(image,"pango:gravity-hint");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"line") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE);
      if (LocaleCompare(option,"natural") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL);
      if (LocaleCompare(option,"strong") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG);
    }
  /*
    Configure layout.
  */
  layout=pango_layout_new(context);
  option=GetImageArtifact(image,"pango:auto-dir");
  if (option != (const char *) NULL)
    pango_layout_set_auto_dir(layout,1);
  option=GetImageArtifact(image,"pango:ellipsize");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"end") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END);
      if (LocaleCompare(option,"middle") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE);
      if (LocaleCompare(option,"none") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE);
      if (LocaleCompare(option,"start") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
    }
  option=GetImageArtifact(image,"pango:justify");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_justify(layout,1);
  option=GetImageArtifact(image,"pango:single-paragraph");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_single_paragraph_mode(layout,1);
  option=GetImageArtifact(image,"pango:wrap");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_CHAR);
      if (LocaleCompare(option,"word") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD);
      if (LocaleCompare(option,"word-char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);
    }
  option=GetImageArtifact(image,"pango:indent");
  if (option != (const char *) NULL)
    pango_layout_set_indent(layout,(int) ((StringToLong(option)*
      (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/
      90.0+0.5));
  switch (draw_info->align)
  {
    case CenterAlign: align=PANGO_ALIGN_CENTER; break;
    case RightAlign: align=PANGO_ALIGN_RIGHT; break;
    case LeftAlign: align=PANGO_ALIGN_LEFT; break;
    default:
    {
      if (draw_info->gravity == CenterGravity)
        {
          align=PANGO_ALIGN_CENTER;
          break;
        }
      align=PANGO_ALIGN_LEFT;
      break;
    }
  }
  if ((align != PANGO_ALIGN_CENTER) &&
      (draw_info->direction == RightToLeftDirection))
    align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align);
  pango_layout_set_alignment(layout,align);
  if (draw_info->font != (char *) NULL)
    {
      PangoFontDescription
        *description;

      /*
        Set font.
      */
      description=pango_font_description_from_string(draw_info->font);
      pango_font_description_set_size(description,(int) (PANGO_SCALE*
        draw_info->pointsize+0.5));
      pango_layout_set_font_description(layout,description);
      pango_font_description_free(description);
    }
  option=GetImageArtifact(image,"pango:markup");
  if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse))
    pango_layout_set_text(layout,caption,-1);
  else
    {
      GError
        *error;

      error=(GError *) NULL;
      if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0)
        (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
          error->message,"`%s'",image_info->filename);
      pango_layout_set_markup(layout,caption,-1);
    }
  pango_layout_context_changed(layout);
  page.x=0;
  page.y=0;
  if (image_info->page != (char *) NULL)
    (void) ParseAbsoluteGeometry(image_info->page,&page);
  if (image->columns == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x;
    }
  else
    {
      image->columns-=2*page.x;
      pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns*
        (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+
        0.5));
    }
  if (image->rows == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y;
    }
  else
    {
      image->rows-=2*page.y;
      pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows*
        (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+
        0.5));
    }
  /*
    Render markup.
  */
  stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
    image->columns);
  pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride*
    sizeof(*pixels));
  if (pixels == (unsigned char *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      caption=DestroyString(caption);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32,
    image->columns,image->rows,stride);
  cairo_image=cairo_create(surface);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR);
  cairo_paint(cairo_image);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER);
  cairo_translate(cairo_image,page.x,page.y);
  pango_cairo_show_layout(cairo_image,layout);
  cairo_destroy(cairo_image);
  cairo_surface_destroy(surface);
  g_object_unref(layout);
  g_object_unref(fontmap);
  /*
    Convert surface to image.
  */
  (void) SetImageBackgroundColor(image,exception);
  p=pixels;
  GetPixelInfo(image,&fill_color);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register Quantum
      *q;

    register ssize_t
      x;

    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      double
        gamma;

      fill_color.blue=(double) ScaleCharToQuantum(*p++);
      fill_color.green=(double) ScaleCharToQuantum(*p++);
      fill_color.red=(double) ScaleCharToQuantum(*p++);
      fill_color.alpha=(double) ScaleCharToQuantum(*p++);
      /*
        Disassociate alpha.
      */
      gamma=1.0-QuantumScale*fill_color.alpha;
      gamma=PerceptibleReciprocal(gamma);
      fill_color.blue*=gamma;
      fill_color.green*=gamma;
      fill_color.red*=gamma;
      CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double)
        GetPixelAlpha(image,q),q);
      q+=GetPixelChannels(image);
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    if (image->previous == (Image *) NULL)
      {
        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
        image->rows);
        if (status == MagickFalse)
          break;
      }
  }
  /*
    Relinquish resources.
  */
  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  draw_info=DestroyDrawInfo(draw_info);
  caption=DestroyString(caption);
  return(GetFirstImageInList(image));
}
Exemple #21
0
static void
_cairo_render_text (CairoRenderer *renderer,
                    PinPointPoint *point)
{
  PangoLayout          *layout;
  PangoFontDescription *desc;
  PangoRectangle        logical_rect = { 0, };
  ClutterColor          text_color,
                        shading_color;

  float text_x,    text_y,    text_width,    text_height,   text_scale;
  float shading_x, shading_y, shading_width, shading_height;
  if (point == NULL)
    return;

  layout = pango_cairo_create_layout (renderer->ctx);
  desc = pango_font_description_from_string (point->font);
  pango_layout_set_font_description (layout, desc);
  if (point->use_markup)
    pango_layout_set_markup (layout, point->text, -1);
  else
    pango_layout_set_text (layout, point->text, -1);
  pango_layout_set_alignment (layout, point->text_align);

  pango_layout_get_extents (layout, NULL, &logical_rect);
  text_width = (logical_rect.x + logical_rect.width) / 1024;
  text_height = (logical_rect.y + logical_rect.height) / 1024;
  if (text_width < 1)
    goto out;

  pp_get_text_position_scale (point,
                              renderer->width, renderer->height,
                              text_width, text_height,
                              &text_x, &text_y,
                              &text_scale);

  pp_get_shading_position_size (renderer->height, renderer->width, /* XXX: is this right order?? */
                                text_x, text_y,
                                text_width, text_height,
                                text_scale,
                                &shading_x, &shading_y,
                                &shading_width, &shading_height);

  clutter_color_from_string (&text_color, point->text_color);
  clutter_color_from_string (&shading_color, point->shading_color);

  cairo_set_source_rgba (renderer->ctx,
                         shading_color.red / 255.f,
                         shading_color.green / 255.f,
                         shading_color.blue / 255.f,
                         shading_color.alpha / 255.f * point->shading_opacity);
  cairo_rectangle (renderer->ctx,
                   shading_x, shading_y, shading_width, shading_height);
  cairo_fill (renderer->ctx);

  cairo_save (renderer->ctx);
  cairo_translate (renderer->ctx, text_x, text_y);
  cairo_scale (renderer->ctx, text_scale, text_scale);
  cairo_set_source_rgba (renderer->ctx,
                         text_color.red / 255.f,
                         text_color.green / 255.f,
                         text_color.blue / 255.f,
                         text_color.alpha / 255.f);
  pango_cairo_show_layout (renderer->ctx, layout);
  cairo_restore (renderer->ctx);

out:
  pango_font_description_free (desc);
  g_object_unref (layout);
}
Exemple #22
0
static void
gimp_ruler_draw_ticks (GimpRuler *ruler)
{
  GtkWidget        *widget = GTK_WIDGET (ruler);
  GtkStyle         *style  = gtk_widget_get_style (widget);
  GimpRulerPrivate *priv   = GIMP_RULER_GET_PRIVATE (ruler);
  GtkStateType      state  = gtk_widget_get_state (widget);
  GtkAllocation     allocation;
  cairo_t          *cr;
  gint              i;
  gint              width, height;
  gint              xthickness;
  gint              ythickness;
  gint              length, ideal_length;
  gdouble           lower, upper;  /* Upper and lower limits, in ruler units */
  gdouble           increment;     /* Number of pixels per unit */
  gint              scale;         /* Number of units per major unit */
  gdouble           start, end, cur;
  gchar             unit_str[32];
  gint              digit_height;
  gint              digit_offset;
  gint              text_size;
  gint              pos;
  gdouble           max_size;
  GimpUnit          unit;
  PangoLayout      *layout;
  PangoRectangle    logical_rect, ink_rect;

  if (! gtk_widget_is_drawable (widget))
    return;

  gtk_widget_get_allocation (widget, &allocation);

  xthickness = style->xthickness;
  ythickness = style->ythickness;

  layout = gimp_ruler_get_layout (widget, "0123456789");
  pango_layout_get_extents (layout, &ink_rect, &logical_rect);

  digit_height = PANGO_PIXELS (ink_rect.height) + 2;
  digit_offset = ink_rect.y;

  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      width  = allocation.width;
      height = allocation.height - ythickness * 2;
    }
  else
    {
      width  = allocation.height;
      height = allocation.width - ythickness * 2;
    }

  cr = cairo_create (priv->backing_store);
  gdk_cairo_set_source_color (cr, &style->bg[state]);

#if 0
  gtk_paint_box (style, priv->backing_store,
                 GTK_STATE_NORMAL, GTK_SHADOW_OUT,
                 NULL, widget,
                 priv->orientation == GTK_ORIENTATION_HORIZONTAL ?
                 "hruler" : "vruler",
                 0, 0,
                 allocation.width, allocation.height);
#else
  cairo_paint (cr);
#endif

  gdk_cairo_set_source_color (cr, &style->fg[state]);

  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      cairo_rectangle (cr,
                       xthickness,
                       height + ythickness,
                       allocation.width - 2 * xthickness,
                       1);
    }
  else
    {
      cairo_rectangle (cr,
                       height + xthickness,
                       ythickness,
                       1,
                       allocation.height - 2 * ythickness);
    }

  gimp_ruler_get_range (ruler, &lower, &upper, &max_size);

  if ((upper - lower) == 0)
    goto out;

  increment = (gdouble) width / (upper - lower);

  /* determine the scale
   *   use the maximum extents of the ruler to determine the largest
   *   possible number to be displayed.  Calculate the height in pixels
   *   of this displayed text. Use this height to find a scale which
   *   leaves sufficient room for drawing the ruler.
   *
   *   We calculate the text size as for the vruler instead of
   *   actually measuring the text width, so that the result for the
   *   scale looks consistent with an accompanying vruler.
   */
  scale = ceil (max_size);
  g_snprintf (unit_str, sizeof (unit_str), "%d", scale);
  text_size = strlen (unit_str) * digit_height + 1;

  for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++)
    if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size)
      break;

  if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale))
    scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1;

  unit = gimp_ruler_get_unit (ruler);

  /* drawing starts here */
  length = 0;
  for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--)
    {
      gdouble subd_incr;

      /* hack to get proper subdivisions at full pixels */
      if (unit == GIMP_UNIT_PIXEL && scale == 1 && i == 1)
        subd_incr = 1.0;
      else
        subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] /
                     (gdouble) ruler_metric.subdivide[i]);

      if (subd_incr * fabs (increment) <= MINIMUM_INCR)
        continue;

      /* don't subdivide pixels */
      if (unit == GIMP_UNIT_PIXEL && subd_incr < 1.0)
        continue;

      /* Calculate the length of the tickmarks. Make sure that
       * this length increases for each set of ticks
       */
      ideal_length = height / (i + 1) - 1;
      if (ideal_length > ++length)
        length = ideal_length;

      if (lower < upper)
        {
          start = floor (lower / subd_incr) * subd_incr;
          end   = ceil  (upper / subd_incr) * subd_incr;
        }
      else
        {
          start = floor (upper / subd_incr) * subd_incr;
          end   = ceil  (lower / subd_incr) * subd_incr;
        }

      for (cur = start; cur <= end; cur += subd_incr)
        {
          pos = ROUND ((cur - lower) * increment);

          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
            {
              cairo_rectangle (cr,
                               pos, height + ythickness - length,
                               1,   length);
            }
          else
            {
              cairo_rectangle (cr,
                               height + xthickness - length, pos,
                               length,                       1);
            }

          /* draw label */
          if (i == 0)
            {
              g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur);

              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
                {
                  pango_layout_set_text (layout, unit_str, -1);
                  pango_layout_get_extents (layout, &logical_rect, NULL);

#if 0
                  gtk_paint_layout (style,
                                    priv->backing_store,
                                    state,
                                    FALSE,
                                    NULL,
                                    widget,
                                    "hruler",
                                    pos + 2,
                                    ythickness + PANGO_PIXELS (logical_rect.y - digit_offset),
                                    layout);
#else
                  cairo_move_to (cr,
                                 pos + 2,
                                 ythickness + PANGO_PIXELS (logical_rect.y - digit_offset));
                  pango_cairo_show_layout (cr, layout);
#endif
                }
              else
                {
                  gint j;

                  for (j = 0; j < (int) strlen (unit_str); j++)
                    {
                      pango_layout_set_text (layout, unit_str + j, 1);
                      pango_layout_get_extents (layout, NULL, &logical_rect);

#if 0
                      gtk_paint_layout (style,
                                        priv->backing_store,
                                        state,
                                        FALSE,
                                        NULL,
                                        widget,
                                        "vruler",
                                        xthickness + 1,
                                        pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset),
                                        layout);
#else
                      cairo_move_to (cr,
                                     xthickness + 1,
                                     pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset));
                      pango_cairo_show_layout (cr, layout);
#endif

                    }
                }
            }
        }
    }

  cairo_fill (cr);
out:
  cairo_destroy (cr);
}
PangoFontMetrics *
_pango_cairo_font_get_metrics (PangoFont     *font,
			       PangoLanguage *language)
{
  PangoCairoFont *cfont = (PangoCairoFont *) font;
  PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font);
  PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */
  GSList *tmp_list;

  const char *sample_str = pango_language_get_sample_string (language);

  tmp_list = cf_priv->metrics_by_lang;
  while (tmp_list)
    {
      info = tmp_list->data;

      if (info->sample_str == sample_str)    /* We _don't_ need strcmp */
	break;

      tmp_list = tmp_list->next;
    }

  if (!tmp_list)
    {
      PangoFontMap *fontmap;
      PangoContext *context;
      cairo_font_options_t *font_options;
      PangoLayout *layout;
      PangoRectangle extents;
      PangoFontDescription *desc;
      cairo_scaled_font_t *scaled_font;
      cairo_matrix_t cairo_matrix;
      PangoMatrix pango_matrix;
      PangoMatrix identity = PANGO_MATRIX_INIT;

      int height, shift;

      /* XXX this is racy.  need a ref'ing getter... */
      fontmap = pango_font_get_font_map (font);
      if (!fontmap)
        return pango_font_metrics_new ();
      fontmap = g_object_ref (fontmap);

      info = g_slice_new0 (PangoCairoFontMetricsInfo);

      cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info);

      info->sample_str = sample_str;

      scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv);

      context = pango_font_map_create_context (fontmap);
      pango_context_set_language (context, language);

      font_options = cairo_font_options_create ();
      cairo_scaled_font_get_font_options (scaled_font, font_options);
      pango_cairo_context_set_font_options (context, font_options);
      cairo_font_options_destroy (font_options);

      info->metrics = (* PANGO_CAIRO_FONT_GET_IFACE (font)->create_base_metrics_for_context) (cfont, context);

      /* We now need to adjust the base metrics for ctm */
      cairo_scaled_font_get_ctm (scaled_font, &cairo_matrix);
      pango_matrix.xx = cairo_matrix.xx;
      pango_matrix.yx = cairo_matrix.yx;
      pango_matrix.xy = cairo_matrix.xy;
      pango_matrix.yy = cairo_matrix.yy;
      pango_matrix.x0 = 0;
      pango_matrix.y0 = 0;
      if (G_UNLIKELY (0 != memcmp (&identity, &pango_matrix, 4 * sizeof (double))))
        {
	  double xscale = pango_matrix_get_font_scale_factor (&pango_matrix);
	  if (xscale) xscale = 1 / xscale;

	  info->metrics->ascent *= xscale;
	  info->metrics->descent *= xscale;
	  info->metrics->underline_position *= xscale;
	  info->metrics->underline_thickness *= xscale;
	  info->metrics->strikethrough_position *= xscale;
	  info->metrics->strikethrough_thickness *= xscale;
	}


      /* Set the matrix on the context so we don't have to adjust the derived
       * metrics. */
      pango_context_set_matrix (context, &pango_matrix);

      /* Update approximate_*_width now */
      layout = pango_layout_new (context);
      desc = pango_font_describe_with_absolute_size (font);
      pango_layout_set_font_description (layout, desc);
      pango_font_description_free (desc);

      pango_layout_set_text (layout, sample_str, -1);
      pango_layout_get_extents (layout, NULL, &extents);

      info->metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);

      pango_layout_set_text (layout, "0123456789", -1);
      info->metrics->approximate_digit_width = max_glyph_width (layout);

      g_object_unref (layout);


      /* We may actually reuse ascent/descent we got from cairo here.  that's
       * in cf_priv->font_extents.
       */
      height = info->metrics->ascent + info->metrics->descent;
      switch (cf_priv->gravity)
	{
	  default:
	  case PANGO_GRAVITY_AUTO:
	  case PANGO_GRAVITY_SOUTH:
	    break;
	  case PANGO_GRAVITY_NORTH:
	    info->metrics->ascent = info->metrics->descent;
	    break;
	  case PANGO_GRAVITY_EAST:
	  case PANGO_GRAVITY_WEST:
	    {
	      int ascent = height / 2;
	      if (cf_priv->is_hinted)
	        ascent = PANGO_UNITS_ROUND (ascent);
	      info->metrics->ascent = ascent;
	    }
	}
      shift = (height - info->metrics->ascent) - info->metrics->descent;
      info->metrics->descent += shift;
      info->metrics->underline_position -= shift;
      info->metrics->strikethrough_position -= shift;
      info->metrics->ascent = height - info->metrics->descent;

      g_object_unref (context);
      g_object_unref (fontmap);
    }

  return pango_font_metrics_ref (info->metrics);
}
static gboolean
video_area_expose_event_cb (GtkWidget      *widget,
			    GdkEventExpose *event,
			    gpointer        user_data)
{
	GthMediaViewerPage *self = user_data;

	if (event->count > 0)
		return FALSE;

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

	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 = widget->allocation.width;
		if (size > widget->allocation.height)
			size = widget->allocation.height;
		size = size / 3;
		self->priv->icon = _g_icon_get_pixbuf (icon, size, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)));

		g_object_unref (icon);
		g_free (type);
	}

	gdk_draw_rectangle (gtk_widget_get_window (widget),
			    self->priv->has_video ? widget->style->black_gc : widget->style->text_gc[GTK_WIDGET_STATE (widget)],
			    TRUE,
			    event->area.x,
			    event->area.y,
			    event->area.width,
			    event->area.height);

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

		icon_w = gdk_pixbuf_get_width (self->priv->icon);
		icon_h = gdk_pixbuf_get_height (self->priv->icon);
		pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * (icon_w * 3 / 2));
		pango_layout_get_extents (self->priv->caption_layout, NULL, &logical_rect);
		icon_x = (widget->allocation.width - icon_w) / 2;
		x = (widget->allocation.width - PANGO_PIXELS (logical_rect.width)) / 2 + PANGO_PIXELS (logical_rect.x);
		icon_y = (widget->allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
		y = icon_y + icon_h;

		gdk_draw_pixbuf (gtk_widget_get_window (widget),
				 widget->style->base_gc[GTK_WIDGET_STATE (widget)],
				 self->priv->icon,
				 0, 0,
				 icon_x, icon_y,
				 icon_w, icon_h,
				 GDK_RGB_DITHER_NORMAL,
				 0, 0);
		gdk_draw_layout (gtk_widget_get_window (widget),
				 widget->style->base_gc[GTK_WIDGET_STATE (widget)],
				 x, y,
				 self->priv->caption_layout);
	}

	return FALSE;
}
Exemple #25
0
static void 
gtk_plot_cairo_draw_string                        (GtkPlotPC *pc,
                                                   gint tx, gint ty,
                                                   gint angle,
                                                   const GdkColor *fg,
                                                   const GdkColor *bg,
                                                   gboolean transparent,
                                                   gint border,
                                                   gint border_space,
                                                   gint border_width,
                                                   gint shadow_width,
                                                   const gchar *font_name,
                                                   gint font_height,
                                                   GtkJustification just,
                                                   const gchar *text)
{
  cairo_t *cairo = GTK_PLOT_CAIRO(pc)->cairo;
  GList *family = NULL;
  gint x0, y0;
  gint old_width, old_height;
  gboolean bold, italic;
  gint fontsize;
  gint ascent, descent;
  gint numf;
  gint width, height;
  gint x, y;
  gint i;
  PangoFontDescription *font = NULL, *latin_font = NULL;
  GtkPSFont *psfont, *base_psfont, *latin_psfont;
  gchar subs[2], insert_char;
  const gchar *aux = text;
  const gchar *lastchar = text;
  const gchar *wtext = text;
  const gchar *xaux = text;
  gchar *new_text; /* Support Tiny C compiler : Original : gchar new_text[strlen(text)+1];*/
  gchar num[4];
  PangoRectangle rect;
  PangoLayout *layout = NULL;
  gint real_x, real_y, real_width, real_height;
  GdkColor real_fg = *fg;
  GdkColor real_bg = *bg;
  gint sign_x = 1, sign_y = 0;
  gint old_tx = tx, old_ty = ty;

  if (!cairo)
    return;

  layout = GTK_PLOT_CAIRO(pc)->layout;
  cairo_save(cairo);
  gtk_plot_cairo_set_color(pc, fg);
/*
  font_name = "sans";
  desc = pango_font_description_from_string(font_name);

  // Since the name does not contain the size yet... Also there is some
  // factor that I have to figure out...
  pango_font_description_set_size (desc, font_height *0.9 * PANGO_SCALE);

  pango_layout_set_font_description(layout, desc);
  pango_layout_set_text(layout, text, -1);
  cairo_save(cairo);
  cairo_translate(cairo, tx, ty);
  cairo_rotate(cairo, angle * G_PI / 180);
  gtk_plot_cairo_set_color(pc, fg);
  pango_cairo_update_layout(cairo, layout);
  PangoFontMetrics *metrics = NULL;

  metrics = pango_context_get_metrics(pango_layout_get_context(layout), desc, gtk_get_default_language());

  pango_layout_get_size (layout, &width, &height);

  ascent = pango_font_metrics_get_ascent(metrics);
  descent = pango_font_metrics_get_descent(metrics);

  if (just == GTK_JUSTIFY_RIGHT) 
    cairo_move_to(cairo, -PANGO_PIXELS(width),
                  -PANGO_PIXELS(ascent)
                  );
  else if (just == GTK_JUSTIFY_CENTER) 
    cairo_move_to(cairo, -PANGO_PIXELS(width)/2.0,
                  -PANGO_PIXELS(ascent)
                  );
  else if (just == GTK_JUSTIFY_LEFT)
    cairo_move_to(cairo, 0,
                  -PANGO_PIXELS(ascent)
                  );
  
  pango_cairo_show_layout(cairo, layout);
  cairo_restore(cairo);
*/


  gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent);

  if(height == 0 || width == 0) return;

  old_width = width;
  old_height = height;
  if(angle == 90 || angle == 270)
    {
      old_width = height;
      old_height = width;
    }
  switch(angle){
    case 90:
      sign_x = 0;
      sign_y = -1;
      break;
    case 180:
      sign_x = -1;
      sign_y = 0;
      break;
    case 270:
      sign_x = 0;
      sign_y = 1;
      break;
    case 0:
    default:
      sign_x = 1;
      sign_y = 0;
      break;
  }

  switch(just){
    case GTK_JUSTIFY_LEFT:
      switch(angle){
        case 0:
            ty -= ascent;
            break;
        case 90:
            ty -= height;
            tx -= ascent;
            break;
        case 180:
            tx -= width;
            ty -= descent;
            break;
        case 270:
            tx -= descent;
            break;
      }
      old_tx = tx;
      old_ty = ty;
      break;
    case GTK_JUSTIFY_RIGHT:
      switch(angle){
        case 0:
            tx -= width;
            ty -= ascent;
            old_tx -= width;
            old_ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height;
            old_tx -= ascent;
            break;
        case 180:
            tx += width;
            ty -= descent;
            old_ty -= descent;
            break;
        case 270:
            tx -= descent;
            old_tx -= descent;
            old_ty -= height;
            break;
      }
      break;
    case GTK_JUSTIFY_CENTER:
    default:
      switch(angle){
        case 0:
            tx -= width / 2.;
            ty -= ascent;
            old_tx -= width / 2.;
            old_ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height / 2.;
            old_tx -= ascent;
            old_ty -= height / 2.;
            break;
        case 180:
            tx += width / 2.;
            ty -= descent;
            old_tx -= width / 2.;
            old_ty -= descent;
            break;
        case 270:
            tx -= descent;
            ty -= height / 2.;
            old_tx -= descent;
            old_ty -= height / 2.;
            break;
      }
  }

  real_x = tx;
  real_y = ty;
  real_width = width;
  real_height = height;

  if(!transparent){
    gtk_plot_cairo_set_color(pc, &real_bg);
    gtk_plot_cairo_draw_rectangle(pc, TRUE, old_tx, old_ty, old_width, old_height);
  }
  gtk_psfont_get_families(&family, &numf);
  base_psfont = psfont = gtk_psfont_get_by_name(font_name);
  font = gtk_psfont_get_font_description(psfont, font_height);
  italic = psfont->italic;
  bold = psfont->bold;
  fontsize = font_height;
  x0 = x = 0;
  y0 = y = 0;

  if (psfont->i18n_latinfamily) {
    latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic,
                                             bold);
    if(latin_font) pango_font_description_free(latin_font);
    latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
  } else {
    latin_psfont = NULL;
    latin_font = NULL;
  }

  gtk_plot_cairo_set_color(pc, &real_fg);
  aux = text;
  while(aux && *aux != '\0' && *aux != '\n'){
   if(*aux == '\\'){
     aux = g_utf8_next_char(aux);
     switch(*aux){
       case '0': case '1': case '2': case '3':
       case '4': case '5': case '6': case '7': case '9':
           psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           aux = g_utf8_next_char(aux);
           break;
       case '8': case 'g':
           psfont = gtk_psfont_get_by_family("Symbol", italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           aux = g_utf8_next_char(aux);
           break;
       case 'B':
           bold = TRUE;
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(latin_font){
             latin_font = NULL;
           }
           if (psfont->i18n_latinfamily) {
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
                                                      italic, bold);
             if(latin_font) pango_font_description_free(latin_font);
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case 'x':
           xaux = aux + 1;
           for (i=0; i<3; i++){
            if (xaux[i] >= '0' && xaux[i] <= '9')
              num[i] = xaux[i];
            else
              break;
           }
           if (i < 3){
              aux = g_utf8_next_char(aux);
              break;
           }
           num[3] = '\0';
           insert_char = (gchar)atoi(num);
           subs[0] = insert_char;
           subs[1] = '\0';
           pango_layout_set_font_description(layout, font);
           pango_layout_set_text(layout, subs, 1);
           pango_layout_get_extents(layout, NULL, &rect);
           x += sign_x*PANGO_PIXELS(rect.width);
           y += sign_y*PANGO_PIXELS(rect.width);
           aux += 4;
           lastchar = aux - 1;
           break;
       case 'i':
           italic = TRUE;
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
                                                      italic, bold);
             if(latin_font) pango_font_description_free(latin_font);
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case 'S': case '^':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           if(angle == 180)
             y = y0 + fontsize;
           else if(angle == 270)
             x = x0 + sign_y*fontsize;
           aux = g_utf8_next_char(aux);
           break;
       case 's': case '_':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(angle == 0)
             y = y0 + fontsize;
           else if(angle == 90)
             x = x0 - sign_y*fontsize;
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case '+':
           fontsize += 3;
           y -= sign_x*3;
           x += sign_y*3;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case '-':
           fontsize -= 3;
           y += sign_x*3;
           x -= sign_y*3;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case 'N':
           psfont = base_psfont;
           fontsize = font_height;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(angle == 0 || angle == 180)
             y = y0;
           else
             x = x0;
           italic = psfont->italic;
           bold = psfont->bold;
           aux = g_utf8_next_char(aux);
           break;
       case 'b':
           if (lastchar) {
             const gchar *aux2 = lastchar;
             gint i = g_utf8_prev_char(lastchar) != --aux2 ? 2 : 1;
             pango_layout_set_text(layout, lastchar, i);
             pango_layout_get_extents(layout, NULL, &rect);
             x -= sign_x*PANGO_PIXELS(rect.width);
             y -= sign_y*PANGO_PIXELS(rect.width);

             if (lastchar == wtext)
               lastchar = NULL;
             else
               lastchar = g_utf8_prev_char(lastchar);
           } else {
             pango_layout_set_text(layout, "X", 1);
             pango_layout_get_extents(layout, NULL, &rect);
             x -= sign_x*PANGO_PIXELS(rect.width);
             y -= sign_y*PANGO_PIXELS(rect.width);
           }
           aux = g_utf8_next_char(aux);
           break;
       default:
           if(aux && *aux != '\0' && *aux !='\n'){
             gint new_width = 0;
             new_width = drawstring(pc, angle, tx+x, ty+y,
                             psfont, fontsize, aux);
             x += sign_x * new_width;
             y += sign_y * new_width;
             lastchar = aux;
             aux = g_utf8_next_char(aux);
           }
           break;
     }
   } else {
     gint new_len = 0;
     gint new_width = 0;
     lastchar = aux;
     while(aux && *aux != '\0' && *aux !='\n' && *aux != '\\'){
       xaux = aux;
       new_len += g_utf8_next_char(aux) != ++xaux ? 2 : 1;
       aux = g_utf8_next_char(aux);
     }
     xaux = lastchar;

     new_text = (gchar *) g_new0(gchar , strlen(text)+1); /* Tiny C Compiler support */
     for(i = 0; i < new_len; i++) new_text[i] = *xaux++;
     new_text[new_len] = '\0';
     new_width = drawstring(pc, angle, tx+x, ty+y,
                 psfont, fontsize, new_text);
     x += sign_x * new_width;
     y += sign_y * new_width;
     lastchar = aux;

     g_free (new_text);
   }
  }

  if(latin_font) pango_font_description_free(latin_font);

/* border */

  gtk_plot_cairo_set_color(pc, &real_fg);
  gtk_plot_pc_set_dash(pc, 0, NULL, 0);
  gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0);
  switch(border){
    case GTK_PLOT_BORDER_SHADOW:
      gtk_plot_pc_draw_rectangle(pc,
                         TRUE,
                         old_tx - border_space + shadow_width,
                         old_ty + height + border_space,
                         width + 2 * border_space, shadow_width);
      gtk_plot_pc_draw_rectangle(pc,
                         TRUE,
                         old_tx + width + border_space,
                         old_ty - border_space + shadow_width,
                         shadow_width, height + 2 * border_space);
    case GTK_PLOT_BORDER_LINE:
      gtk_plot_pc_draw_rectangle(pc,
                         FALSE,
                         old_tx - border_space, old_ty - border_space,
                         width + 2*border_space, height + 2*border_space);
    case GTK_PLOT_BORDER_NONE:
    default:
        break;
  }

  cairo_restore(cairo);
  return;
}
Exemple #26
0
// Renders the input text at the current location with the current color.
// The X position of the current location is used to place the left edge of the text image,
// where the text image bounds are defined as the logical extents of the line of text.
// The Y position of the current location is used to place the bottom of the text image.
// You should offset the Y position by the amount returned by gtk_glwidget_font_descent()
// if you want to place the baseline of the text image at the current Y position.
// Note: A problem with this function is that if the lower left corner of the text falls
// just a hair outside of the viewport (meaning the current raster position is invalid),
// then no text will be rendered.  The solution to this is a very hacky one.  You can search
// Google for "glDrawPixels clipping".
void gtk_glwidget_print_string( const char *s ){
	// The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt.

	PangoLayout *layout;
	PangoRectangle log_rect;
	FT_Bitmap bitmap;
	unsigned char *begin_bitmap_buffer;
	GLfloat color[4];
	GLint previous_unpack_alignment;
	GLboolean previous_blend_enabled;
	GLint previous_blend_func_src;
	GLint previous_blend_func_dst;
	GLfloat previous_red_bias;
	GLfloat previous_green_bias;
	GLfloat previous_blue_bias;
	GLfloat previous_alpha_scale;

	if ( !_debug_font_created ) {
		Error( "Programming error: gtk_glwidget_print_string() called but font does not exist; "
			   "you should have called gtk_glwidget_create_font() first" );
	}

	layout = pango_layout_new( ft2_context );
	pango_layout_set_width( layout, -1 ); // -1 no wrapping.  All text on one line.
	pango_layout_set_text( layout, s, -1 ); // -1 null-terminated string.
	pango_layout_get_extents( layout, NULL, &log_rect );

	if ( log_rect.width > 0 && log_rect.height > 0 ) {
		bitmap.rows = font_ascent + font_descent;
		bitmap.width = PANGO_PIXELS_CEIL( log_rect.width );
		bitmap.pitch = -bitmap.width; // Rendering it "upside down" for OpenGL.
		begin_bitmap_buffer = (unsigned char *) g_malloc( bitmap.rows * bitmap.width );
		memset( begin_bitmap_buffer, 0, bitmap.rows * bitmap.width );
		bitmap.buffer = begin_bitmap_buffer + ( bitmap.rows - 1 ) * bitmap.width; // See pitch above.
		bitmap.num_grays = 0xff;
		bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
		pango_ft2_render_layout_subpixel( &bitmap, layout, -log_rect.x,
										  y_offset_bitmap_render_pango_units );
		qglGetFloatv( GL_CURRENT_COLOR, color );

		// Save state.  I didn't see any OpenGL push/pop operations for these.
		// Question: Is saving/restoring this state necessary?  Being safe.
		qglGetIntegerv( GL_UNPACK_ALIGNMENT, &previous_unpack_alignment );
		previous_blend_enabled = qglIsEnabled( GL_BLEND );
		qglGetIntegerv( GL_BLEND_SRC, &previous_blend_func_src );
		qglGetIntegerv( GL_BLEND_DST, &previous_blend_func_dst );
		qglGetFloatv( GL_RED_BIAS, &previous_red_bias );
		qglGetFloatv( GL_GREEN_BIAS, &previous_green_bias );
		qglGetFloatv( GL_BLUE_BIAS, &previous_blue_bias );
		qglGetFloatv( GL_ALPHA_SCALE, &previous_alpha_scale );

		qglPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
		qglEnable( GL_BLEND );
		qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
		qglPixelTransferf( GL_RED_BIAS, color[0] );
		qglPixelTransferf( GL_GREEN_BIAS, color[1] );
		qglPixelTransferf( GL_BLUE_BIAS, color[2] );
		qglPixelTransferf( GL_ALPHA_SCALE, color[3] );

		qglDrawPixels( bitmap.width, bitmap.rows,
					   GL_ALPHA, GL_UNSIGNED_BYTE, begin_bitmap_buffer );
		g_free( begin_bitmap_buffer );

		// Restore state in reverse order of how we set it.
		qglPixelTransferf( GL_ALPHA_SCALE, previous_alpha_scale );
		qglPixelTransferf( GL_BLUE_BIAS, previous_blue_bias );
		qglPixelTransferf( GL_GREEN_BIAS, previous_green_bias );
		qglPixelTransferf( GL_RED_BIAS, previous_red_bias );
		qglBlendFunc( previous_blend_func_src, previous_blend_func_dst );
		if ( !previous_blend_enabled ) {
			qglDisable( GL_BLEND );
		}
		qglPixelStorei( GL_UNPACK_ALIGNMENT, previous_unpack_alignment );
	}

	g_object_unref( G_OBJECT( layout ) );
}
Exemple #27
0
static gboolean
gtk_switch_draw (GtkWidget *widget,
                 cairo_t   *cr)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GdkRectangle handle;
  PangoLayout *layout;
  PangoRectangle rect;
  gint label_x, label_y;
  GtkBorder padding;
  GtkStateFlags state;
  gint x, y, width, height;

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  gtk_style_context_save (context);

  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);

  gtk_style_context_get_padding (context, state, &padding);

  gtk_style_context_restore (context);

  x = 0;
  y = 0;
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);

  gtk_render_background (context, cr, x, y, width, height);
  gtk_render_frame (context, cr, x, y, width, height);

  width -= padding.left + padding.right;
  height -= padding.top + padding.bottom;

  x += padding.left;
  y += padding.top;

  handle.y = y;
  handle.width = width / 2;
  handle.height = height;

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  (width / 2) + ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  if (priv->is_dragging)
    handle.x = x + priv->handle_x;
  else if (priv->is_active)
    handle.x = x + width - handle.width;
  else
    handle.x = x;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  if (gtk_widget_has_visible_focus (widget))
    {
      gint focus_width, focus_pad, pad;

      gtk_widget_style_get (widget,
                            "focus-line-width", &focus_width,
                            "focus-padding", &focus_pad,
                            NULL);

      pad = focus_pad + focus_width;

      gtk_render_focus (context, cr,
                        handle.x + pad, handle.y + pad,
                        handle.width - pad*2, handle.height - pad*2);
    }

  return FALSE;
}
Exemple #28
0
static gboolean
gtk_switch_draw (GtkWidget *widget,
                 cairo_t   *cr)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  GtkStyleContext *context;
  GdkRectangle handle;
  PangoLayout *layout;
  PangoFontDescription *desc;
  const PangoFontDescription *style_desc;
  PangoRectangle rect;
  gint label_x, label_y;
  GtkStateFlags state;
  GtkBorder padding;
  gint focus_width, focus_pad;
  gint x, y, width, height;
  gint font_size, style_font_size;

  gtk_widget_style_get (widget,
                        "focus-line-width", &focus_width,
                        "focus-padding", &focus_pad,
                        NULL);

  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);

  if (priv->is_active)
    state |= GTK_STATE_FLAG_ACTIVE;

  gtk_style_context_save (context);

  gtk_style_context_set_state (context, state);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);

  gtk_style_context_get_padding (context, state, &padding);

  gtk_style_context_restore (context);

  x = 0;
  y = 0;
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  if (gtk_widget_has_focus (widget))
    gtk_render_focus (context, cr, x, y, width, height);

  x += focus_width + focus_pad;
  y += focus_width + focus_pad;
  width -= 2 * (focus_width + focus_pad);
  height -= 2 * (focus_width + focus_pad);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
  gtk_style_context_set_state (context, state);

  gtk_render_background (context, cr, x, y, width, height);
  gtk_render_frame (context, cr, x, y, width, height);

  width -= padding.left + padding.right;
  height -= padding.top + padding.bottom;

  x += padding.left;
  y += padding.top;

  handle.y = y;
  handle.width = width / 2;
  handle.height = height;

  /* Translators: if the "on" state label requires more than three
   * glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
   * the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));

  /* FIXME: this should be really done in the theme, but overriding font size
   * from it doesn't currently work. So we have to hardcode this here and
   * below for the "OFF" label.
   */
  desc = pango_font_description_new ();

  style_desc = gtk_style_context_get_font (context, state);
  style_font_size = pango_font_description_get_size (style_desc);
  font_size = MAX (style_font_size - 1 * PANGO_SCALE, ceil (style_font_size * PANGO_SCALE_SMALL));

  pango_font_description_set_size (desc, font_size);

  pango_layout_set_font_description (layout, desc);

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  /* Translators: if the "off" state label requires more than three
   * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
   */
  layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));
  pango_layout_set_font_description (layout, desc);

  pango_layout_get_extents (layout, NULL, &rect);
  pango_extents_to_pixels (&rect, NULL);

  label_x = x +  (width / 2) + ((width / 2) - rect.width) / 2;
  label_y = y + (height - rect.height) / 2;

  gtk_render_layout (context, cr, label_x, label_y, layout);

  g_object_unref (layout);

  if (priv->is_dragging)
    handle.x = x + priv->handle_x;
  else if (priv->is_active)
    handle.x = x + width - handle.width;
  else
    handle.x = x;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  pango_font_description_free (desc);

  return FALSE;
}
Exemple #29
0
void render_glyph(
	cairo_t* cr,
	PangoFontDescription* font_desc,
	PangoFont* font,
	const guint code_point,
	const size_t cell_x,
	const size_t cell_y,
	const size_t cell_size,
	const double tex_size,
	const int ascent,
	const int descent,
	std::ostream& bgm_out
)
{
	PangoLayout *layout = pango_cairo_create_layout(cr);

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

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

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

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

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


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

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

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

	g_object_unref(layout);
}
Exemple #30
0
static GLboolean
glgdGraphNodeDrawLabel(glgdGraph *graph, glgdNode *node)
{
    int                     i;
    GLint                   width;
    GLuint                  texture;
    GLfloat                 s0, s1, t0, t1;
    GLfloat                 a;
    guint32                 alpha, rgb, *t;
    guint8                  *row, *row_end;
    PangoContext            *pangoContext;
    PangoFontDescription    *fontDesc;
    PangoLayout             *layout;
    PangoRectangle          extents;
    FT_Bitmap               bitmap;
    glgdVec2                center, pnt[2];
    glgdStroke              *stroke;
    glgdTexture             *tex;
    
    if (graph && graph->pangoFT2Context)
    {
        stroke = &graph->stroke;
        tex = &graph->textTexture;
        if (tex->width <= 0 || tex->height <= 0)
        {
            glgdTrace(1, "Invalid texture dimension (%d,%d)\n", tex->width,
                tex->height);
                
            return GL_FALSE;
        }

        /* Pango font description */
        width = 10 * _PANGO_SCALE;
        pangoContext = gtk_widget_get_pango_context(graph->gtkWindow);
        fontDesc = pango_context_get_font_description(pangoContext);
        pango_font_description_set_size(fontDesc, PANGO_SCALE * width);
        pango_font_description_set_weight(fontDesc, PANGO_WEIGHT_NORMAL);
        pango_context_set_font_description(graph->pangoFT2Context, fontDesc);
        
        /* Text layout */
        width = (int)graph->dim[0] * _PANGO_SCALE;
        layout = graph->layout;
        pango_layout_set_width(layout, PANGO_SCALE * width);
        pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
        pango_layout_set_text(layout, node->label, -1);
        pango_layout_get_extents(layout, NULL, &extents);
        if (extents.width == 0 || extents.height == 0)
        {
            glgdTrace(1, "Invalid extents (%d,%d)\n", extents.width,
                extents.height);
                
            return GL_FALSE;
        }

        /* Bitmap creation */
        bitmap.rows = PANGO_PIXELS(extents.height);
        bitmap.width = PANGO_PIXELS(extents.width);
        if (bitmap.width > tex->width || bitmap.rows > tex->height)
        {
            return GL_FALSE;
        }

        bitmap.pitch = bitmap.width;
        bitmap.buffer = GLGD_MALLOC(bitmap.rows * bitmap.width);
        bitmap.num_grays = 256;
        bitmap.pixel_mode = ft_pixel_mode_grays;

        memset(bitmap.buffer, 0, bitmap.rows * bitmap.width);
        pango_ft2_render_layout(&bitmap, layout, PANGO_PIXELS(-extents.x), 0);

#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
        rgb =((guint32)(stroke->col[0] * 255.0))         |
            (((guint32)(stroke->col[1] * 255.0)) << 8)   |
            (((guint32)(stroke->col[2] * 255.0)) << 16);
#else
        rgb =(((guint32)(stroke->col[0] * 255.0)) << 24)    |
            (((guint32)(stroke->col[1] * 255.0)) << 16) |
            (((guint32)(stroke->col[2] * 255.0)) << 8);
#endif

        /* Bitmap transfer to <glgdTexture> */
        a = stroke->col[3];
        alpha = (guint32)(255.0 * a);
        row = bitmap.buffer + bitmap.rows * bitmap.width;
        row_end = bitmap.buffer;
        t = (guint32 *)tex->texels;
        if (graph->flags & GLGDGRAPH_FLAG_PANGOBOLD)
        {
            do
            {
                row -= bitmap.width;
                for (i=0; i<bitmap.width; i++)
                {
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
                    if (row[i] > 0)
                        *t++ = rgb | (alpha << 24);
                    else
                        *t++ = rgb;
#else
                    if (row[i] > 0)
                        *t++ = rgb | alpha;
                    else
                        *t++ = rgb;
#endif
                }
            }
            while (row != row_end);
        }
        else
        {
            do
            {
                row -= bitmap.width;
                for (i=0; i<bitmap.width; i++)
                {
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
                    *t++ = rgb | ((guint32)(a * row[i]) << 24);
#else
                    *t++ = rgb | (guint32)(a * row[i]);
#endif
                }
            }
            while (row != row_end);
        }

        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
        glBindTexture(GL_TEXTURE_2D, tex->name);
#if !defined(GL_VERSION_1_2)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width, bitmap.rows,
            GL_RGBA, GL_UNSIGNED_BYTE, tex->texels);
#else
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width, bitmap.rows,
            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, tex->texels);
#endif

        /* <glgdTexture> render */
        s0 = 0.0;
        s1 = (GLdouble)bitmap.width / (GLdouble)tex->width;
        t0 = 0.0;
        t1 = (GLdouble)bitmap.rows / (GLdouble)tex->height;

        center[0] = node->pos[0] + GLGD_HALF(graph->dim[0]);
        center[1] = node->pos[1] + GLGD_HALF(graph->dim[1]);
        pnt[0][0] = center[0] - GLGD_HALF(bitmap.width / _PANGO_SCALE);
        pnt[0][1] = center[1] - GLGD_HALF(bitmap.rows / _PANGO_SCALE);
        pnt[1][0] = center[0] + GLGD_HALF(bitmap.width / _PANGO_SCALE);
        pnt[1][1] = center[1] + GLGD_HALF(bitmap.rows / _PANGO_SCALE);
        GLGD_FREE(bitmap.buffer);

        glColor3d(stroke->col[0], stroke->col[1], stroke->col[2]);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBindTexture(GL_TEXTURE_2D, tex->name);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glBegin(GL_QUADS);
            glTexCoord2f(s0, t0);
            glVertex3f(pnt[0][0], pnt[0][1], 0.0);
            
            glTexCoord2f(s0, t1);
            glVertex3f(pnt[0][0], pnt[1][1], 0.0);
            
            glTexCoord2f(s1, t1);
            glVertex3f(pnt[1][0], pnt[1][1], 0.0);
            
            glTexCoord2f(s1, t0);
            glVertex3f(pnt[1][0], pnt[0][1], 0.0);
        glEnd();
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);

        return GL_TRUE;
    }
    
    return GL_FALSE;
}