Esempio n. 1
0
static void
gtk_switch_get_preferred_width (GtkWidget *widget,
                                gint      *minimum,
                                gint      *natural)
{
  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_style_context_get_state (context);

  gtk_style_context_save (context);

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

  slider_width = MAX (slider_width, 3 * (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;
}
Esempio n. 2
0
static void font_measure_full(const RrFont *f, const gchar *str,
                              gint *x, gint *y, gint shadow_x, gint shadow_y,
                              gboolean flow, gint maxwidth)
{
    PangoRectangle rect;

    pango_layout_set_text(f->layout, str, -1);
    if (flow) {
        pango_layout_set_single_paragraph_mode(f->layout, FALSE);
        pango_layout_set_width(f->layout, maxwidth * PANGO_SCALE);
        pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_NONE);
    }
    else {
        /* single line mode */
        pango_layout_set_single_paragraph_mode(f->layout, TRUE);
        pango_layout_set_width(f->layout, -1);
        pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_MIDDLE);
    }

    /* pango_layout_get_pixel_extents lies! this is the right way to get the
       size of the text's area */
    pango_layout_get_extents(f->layout, NULL, &rect);
#if PANGO_VERSION_MAJOR > 1 || \
    (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16)
    /* pass the logical rect as the ink rect, this is on purpose so we get the
       full area for the text */
    pango_extents_to_pixels(&rect, NULL);
#else
    rect.width = (rect.width + PANGO_SCALE - 1) / PANGO_SCALE;
    rect.height = (rect.height + PANGO_SCALE - 1) / PANGO_SCALE;
#endif
    *x = rect.width + ABS(shadow_x) + 4 /* we put a 2 px edge on each side */;
    *y = rect.height + ABS(shadow_y);
}
Esempio n. 3
0
void
ge_cairo_transform_for_layout (cairo_t *cr,
                               PangoLayout *layout,
                               int x,
                               int y)
{
        const PangoMatrix *matrix;

        matrix = pango_context_get_matrix (pango_layout_get_context (layout));
        if (matrix)
        {
                cairo_matrix_t cairo_matrix;
                PangoRectangle rect;
                
                cairo_matrix_init (&cairo_matrix,
                                   matrix->xx, matrix->yx,
                                   matrix->xy, matrix->yy,
                                   matrix->x0, matrix->y0);

                pango_layout_get_extents (layout, NULL, &rect);
                pango_matrix_transform_rectangle (matrix, &rect);
                pango_extents_to_pixels (&rect, NULL);
                                                    
                cairo_matrix.x0 += x - rect.x;
                cairo_matrix.y0 += y - rect.y;

                cairo_set_matrix (cr, &cairo_matrix);
        }
        else
                cairo_translate (cr, x, y);
}
/* Draws a rounded rectangle with text inside. */
static gboolean
numbers_draw_cb (GtkWidget *widget, cairo_t *ctx, gpointer data)
{
	double x, y, w, h;
	PangoLayout * layout;
	gint font_size = gtk_widget_get_font_size (widget);

	#if (INDICATOR_MESSAGES_HAS_LOZENGE == 1)
	gboolean is_lozenge = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "is-lozenge"));
	/* let the label handle the drawing if it's not a lozenge */
	if (!is_lozenge)
		return FALSE;
	#endif

	if (!GTK_IS_WIDGET (widget)) return FALSE;

	/* get style + arrow position / dimensions */
	double red, green, blue;
	GtkStyleContext *style = gtk_widget_get_style_context (widget);
	GdkRGBA color;
	gtk_style_context_get_color (style, gtk_widget_get_state(widget), &color);
	red = color.red;
	green = color.green;
	blue = color.blue;
	GtkAllocation allocation;
	gtk_widget_get_allocation (widget, &allocation);
	w = allocation.width;
	h = allocation.height;
	x = y = 0;

	layout = gtk_label_get_layout (GTK_LABEL(widget));
	PangoRectangle layout_extents;
	pango_layout_get_extents (layout, NULL, &layout_extents);
	pango_extents_to_pixels (&layout_extents, NULL);

	if (layout_extents.width == 0)
		return TRUE;

	cairo_set_line_width (ctx, 1.0);

	cairo_set_fill_rule (ctx, CAIRO_FILL_RULE_EVEN_ODD);

	/* cairo drawing code */
	custom_cairo_rounded_rectangle (ctx, x - font_size/2.0, y, w + font_size, h);

	cairo_set_source_rgba (ctx, red,
	                           green,
	                           blue, 0.5);

	x += (allocation.width - layout_extents.width) / 2.0;
	y += (allocation.height - layout_extents.height) / 2.0;
	cairo_move_to (ctx, floor (x), floor (y));
	pango_cairo_layout_path (ctx, layout);
	cairo_fill (ctx);

	return TRUE;
}
Esempio n. 5
0
static void
ensure_measurements (GcrDisplayView *self)
{
	PangoLayout *layout;
	PangoRectangle extents;
	gint icon_width;
	gint icon_height;
	GHashTableIter iter;
	GcrDisplayItem *item;
	gpointer value;
	gboolean expanded;

	if (self->pv->have_measurements)
		return;

	/* See if anything is expanded? */
	expanded = FALSE;
	g_hash_table_iter_init (&iter, self->pv->items);
	while (g_hash_table_iter_next (&iter, NULL, &value)) {
		item = value;
		if (item->expanded) {
			expanded = TRUE;
			break;
		}
	}

	/*
	 * We use a string in our widget font as the basis for our measurements.
	 * These are just estimates of what we need, and what looks goodish.
	 * There's room here for improvement. If this is causes problems for
	 * you or bothers you, scratch that itch:
	 */

	layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "0123456789");
	pango_layout_get_extents (layout, NULL, &extents);
	pango_extents_to_pixels (&extents, NULL);
	g_object_unref (layout);

	if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &icon_width, &icon_height)) {
		icon_width = 48;
		icon_height = 48;
	}

	if (expanded) {
		/* If expanded, display more 10 lines at least */
		self->pv->minimal_height = extents.height * 14;
		self->pv->natural_height = extents.height * 25;
	} else {
		/* If not expanded we can get by with 9 lines */
		self->pv->minimal_height = extents.height * 8;
		self->pv->natural_height = extents.height * 9;
	}

	self->pv->minimal_width = icon_width + (extents.width * 5);
	self->pv->natural_width = icon_width + (extents.width * 8);
	self->pv->have_measurements = TRUE;
}
Esempio n. 6
0
void
_gcr_display_view_append_value (GcrDisplayView *self, GcrRenderer *renderer, const gchar *field,
                                const gchar *value, gboolean monospace)
{
	GcrDisplayItem *item;
	PangoRectangle extents;
	PangoTabArray *tabs;
	PangoLayout *layout;
	GtkTextIter iter;
	gchar *text;

	g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
	g_return_if_fail (field);

	item = lookup_display_item (self, renderer);
	g_return_if_fail (item);

	if (item->details && !item->expanded)
		return;

	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 > item->field_width) {
		item->field_width = extents.width + COLUMN_MARGIN;
		tabs = pango_tab_array_new (1, TRUE);
		pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, item->field_width);
		g_object_set (item->field_tag,
		              "left-margin", FIELD_MARGIN,
		              "indent", 0 - item->field_width,
		              "tabs", tabs,
		              NULL);
		pango_tab_array_free (tabs);
	}

	gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
	gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, text, -1,
	                                  item->field_tag, item->extra_tag, NULL);
	gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\t", 1,
	                                  item->extra_tag, NULL);
	gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, value, -1, item->field_tag,
	                                  monospace ? self->pv->monospace_tag : item->extra_tag,
	                                  monospace ? item->extra_tag : NULL, NULL);
	gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
	                                  item->extra_tag, NULL);

	g_free (text);
}
Esempio n. 7
0
static void
gtk_switch_get_preferred_height (GtkWidget *widget,
                                 gint      *minimum,
                                 gint      *natural)
{
  GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
  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);

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

  height = padding.top + padding.bottom;

  gtk_style_context_restore (context);

  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;
}
Esempio n. 8
0
Rect TextRenderer::RawCursorPos()
{
    Pango::Rectangle w_rct, s_rct;
    panLay->get_cursor_pos(ByteCursorPos(), w_rct, s_rct);
    pango_extents_to_pixels(0, w_rct.gobj());

    double curs_rat = CursAspectRatio();
    int curs_wdh = int(w_rct.get_height()*curs_rat + 1);

    int curs_lft = w_rct.get_x() - curs_wdh/2;
    return Rect(curs_lft,            w_rct.get_y(),
                curs_lft + curs_wdh, w_rct.get_y() + w_rct.get_height());
}
Esempio n. 9
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, slider_width, min_height;
  PangoLayout *layout;
  PangoRectangle logical_rect;
  gchar *str;

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

  gtk_style_context_save (context);

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

  height = padding.top + padding.bottom;

  gtk_style_context_restore (context);

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

  min_height = MAX (slider_width * 0.6, 3 * (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 (min_height, logical_rect.height);

  g_object_unref (layout);
  g_free (str);

  if (minimum)
    *minimum = height;

  if (natural)
    *natural = height;
}
Esempio n. 10
0
bool PangoFontInfo::GetSpacingProperties(const string& utf8_char,
                                         int* x_bearing, int* x_advance) const {
  // Convert to equivalent PangoFont structure
  PangoFont* font = ToPangoFont();
  // Find the glyph index in the font for the supplied utf8 character.
  int total_advance = 0;
  int min_bearing = 0;
  // Handle multi-unicode strings by reporting the left-most position of the
  // x-bearing, and right-most position of the x-advance if the string were to
  // be rendered.
  const UNICHAR::const_iterator it_begin = UNICHAR::begin(utf8_char.c_str(),
                                                          utf8_char.length());
  const UNICHAR::const_iterator it_end = UNICHAR::end(utf8_char.c_str(),
                                                      utf8_char.length());
  for (UNICHAR::const_iterator it = it_begin; it != it_end; ++it) {
    PangoGlyph glyph_index = pango_fc_font_get_glyph(
        reinterpret_cast<PangoFcFont*>(font), *it);
    if (!glyph_index) {
      // Glyph for given unicode character doesn't exist in font.
      return false;
    }
    // Find the ink glyph extents for the glyph
    PangoRectangle ink_rect, logical_rect;
    pango_font_get_glyph_extents(font, glyph_index, &ink_rect, &logical_rect);
    pango_extents_to_pixels(&ink_rect, NULL);
    pango_extents_to_pixels(&logical_rect, NULL);

    int bearing = total_advance + PANGO_LBEARING(ink_rect);
    if (it == it_begin || bearing < min_bearing) {
      min_bearing = bearing;
    }
    total_advance += PANGO_RBEARING(logical_rect);
  }
  *x_bearing = min_bearing;
  *x_advance = total_advance;
  return true;
}
Esempio n. 11
0
static void
gtk_label_accessible_get_character_extents (AtkText      *text,
                                            gint          offset,
                                            gint         *x,
                                            gint         *y,
                                            gint         *width,
                                            gint         *height,
                                            AtkCoordType  coords)
{
  GtkWidget *widget;
  GtkLabel *label;
  PangoRectangle char_rect;
  const gchar *label_text;
  gint index, x_layout, y_layout;
  GdkWindow *window;
  gint x_window, y_window;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
  if (widget == NULL)
    return;

  label = GTK_LABEL (widget);

  gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
  label_text = gtk_label_get_text (label);
  index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
  pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect);
  pango_extents_to_pixels (&char_rect, NULL);

  window = gtk_widget_get_window (widget);
  gdk_window_get_origin (window, &x_window, &y_window);

  *x = x_window + x_layout + char_rect.x;
  *y = x_window + y_layout + char_rect.y;
  *width = char_rect.width;
  *height = char_rect.height;

  if (coords == ATK_XY_WINDOW)
    {
      window = gdk_window_get_toplevel (window);
      gdk_window_get_origin (window, &x_window, &y_window);

      *x -= x_window;
      *y -= y_window;
    }
}
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);
}
Esempio n. 13
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;
}
Esempio n. 14
0
static void
draw_text (Cairo::RefPtr<Cairo::Context> cr, int wdh, int hgt)
{
    RefPtr<Pango::Layout> layout = Pango::Layout::create(cr);
    //layout->set_single_paragraph_mode(true);
    layout->set_text("MTextTextM\nAbc\nff");


    Pango::FontDescription dsc(FONT);
    layout->set_font_description(dsc);

    int t_wdh, t_hgt;
    layout->get_size(t_wdh, t_hgt);

    double t_sz = (double)dsc.get_size()/t_wdh;
    double new_sz = wdh * t_sz ;

    io::cout << "new_sz " << new_sz << io::endl;
    io::cout << "wdh " << wdh << io::endl;

    dsc.set_size( int(new_sz*PANGO_SCALE) );
    layout->set_font_description(dsc);

    layout->get_size(t_wdh, t_hgt);
    io::cout << "t_wdh " << t_wdh/(double)PANGO_SCALE << io::endl;

    // для наглядности
    cr->set_line_width(1.0);
    cr->rectangle(0, 0, wdh, hgt);
    cr->stroke();


    cr->save();

    cr->move_to(0, 0);
    cr->scale( 1.0, hgt / ((double)t_hgt/PANGO_SCALE) );
    //cr->scale( wdh / ((double)t_wdh/PANGO_SCALE), hgt / ((double)t_hgt/PANGO_SCALE) );

    layout->update_from_cairo_context(cr);

    pango_cairo_show_layout(cr->cobj(), layout->gobj());

    {
        Pango::Rectangle w_rct, s_rct;
        int cur_pos;

        cur_pos = 1;
        layout->get_cursor_pos(cur_pos, w_rct, s_rct);
        pango_extents_to_pixels(0, w_rct.gobj());

        io::cout << "curs - x, y, hgt " << w_rct.get_x() << " " << w_rct.get_y() << " " << w_rct.get_height() << io::endl;
        cr->move_to(w_rct.get_x()+5, w_rct.get_y());
        cr->line_to(w_rct.get_x()+5, w_rct.get_y()+w_rct.get_height());
        cr->stroke();


        cur_pos = 11;
        layout->get_cursor_pos(cur_pos, w_rct, s_rct);
        pango_extents_to_pixels(0, w_rct.gobj());

        io::cout << "curs - x, y, hgt " << w_rct.get_x() << " " << w_rct.get_y() << " " << w_rct.get_height() << io::endl;
        cr->move_to(w_rct.get_x()+5, w_rct.get_y());
        cr->line_to(w_rct.get_x()+5, w_rct.get_y()+w_rct.get_height());
        cr->stroke();

    }


    cr->restore();
}
Esempio n. 15
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;
}
Esempio n. 16
0
File: gtkswitch.c Progetto: BYC/gtk
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;
  GtkStateFlags state;
  GtkBorder padding;
  gint focus_width, focus_pad;
  gint x, y, width, height;

  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_get_padding (context, state, &padding);

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

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

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

  /* XXX the +1/-1 it's pixel wriggling after checking with the default
   * theme and xmag
   */
  handle.y = y + padding.top + 1;
  handle.width = (width - padding.left - padding.right) / 2;
  handle.height = (height - padding.top - padding.bottom) - 1;

  /* 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 + padding.left
          + ((width / 2) - rect.width - padding.left - padding.right) / 2;
  label_y = y + padding.top
          + (height - rect.height - padding.top - padding.bottom) / 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 + padding.left
          + (width / 2)
          + ((width / 2) - rect.width - padding.left - padding.right) / 2;
  label_y = y + padding.top
          + (height - rect.height - padding.top - padding.bottom) / 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 - padding.right;
  else
    handle.x = x + padding.left;

  gtk_style_context_restore (context);

  gtk_switch_paint_handle (widget, cr, &handle);

  return FALSE;
}
Esempio n. 17
0
void doDrawGlyphs(PangoRenderer* renderer, PangoFont* font, PangoGlyphString* glyphs, int px, int py) {
    Renderer* ren = RENDERER(renderer);
    if (!ren->m_runs) return;
    std::vector<ViewdoTextRun>& runs = *(ren->m_runs);
    const float s = ren->m_scale;

    PangoColor* fg = pango_renderer_get_color(renderer, PANGO_RENDER_PART_FOREGROUND);
    //PangoColor* bg = pango_renderer_get_color(renderer, PANGO_RENDER_PART_BACKGROUND);

    float red = !fg ? 0.0f : fg->red / 65536.0f;
    float green = !fg ? 0.0f : fg->green / 65536.0f;
    float blue = !fg ? 0.0f : fg->blue / 65536.0f;

    PangoFontDescription* desc = pango_font_describe(font);
    unsigned int fontHash = pango_font_description_hash(desc);
    pango_font_description_free(desc);

    FT_Face face = pango_fc_font_lock_face((PangoFcFont*) font);

    PangoGlyphUnit layoutX = px;
    PangoGlyphUnit layoutY = py;
    ViewdoGlyphCache& cache = ViewdoGlyphCache::instance();

    for (int i = 0; i < glyphs->num_glyphs; i++) {
        PangoGlyphInfo* gi = glyphs->glyphs + i;

        if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG) {
            // XXX: Draw the fallback square.
            continue;
        }

        unsigned int glyph = gi->glyph;
        PangoRectangle r;
        
        pango_font_get_glyph_extents(font, glyph, &r, 0);
        pango_extents_to_pixels(&r, 0);

        float w = r.width;
        float h = r.height;

        if (w <= 0.f && h <= 0.f) {
            // Space.
            layoutX += gi->geometry.width;
            continue;
        }

        // Load and render the glyph. We probably need to just tell the font to cache it
        // and then grab the coordinates of it.
        const ViewdoGlyph& cachedGlyph = cache.findOrCreate(gi->glyph, fontHash, face);
        
        // Walk our existing runs and try to find one with the same color and page.
        // XXX: Fastpath try and use the run from the last glyph.
        ViewdoTextRun* run = nullptr;
        for (auto i = runs.begin(); i != runs.end(); i++) {
            if (i->m_page == cachedGlyph.m_page && i->m_red == red && i->m_green == green && i->m_blue == blue) {
                run = &(*i);
                break;
            }
        }
        if (!run) {
            runs.push_back(ViewdoTextRun(cachedGlyph.m_page, red, green, blue));
            run = &(runs[runs.size() - 1]);
        }

        float x = PANGO_PIXELS(layoutX + gi->geometry.x_offset) + cachedGlyph.m_offsetLeft;
        float y = PANGO_PIXELS(layoutY + gi->geometry.y_offset) - cachedGlyph.m_offsetTop;

        // Append ourselves onto this run.
        addPoint(run->m_geometry,
            x, y,
            cachedGlyph.m_x0, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y,
            cachedGlyph.m_x1, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x, y + cachedGlyph.m_height,
            cachedGlyph.m_x0, cachedGlyph.m_y1,
            s);

        // Triangle 2.
        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y,
            cachedGlyph.m_x1, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x, y + cachedGlyph.m_height,
            cachedGlyph.m_x0, cachedGlyph.m_y1,
            s);

        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y + cachedGlyph.m_height,
            cachedGlyph.m_x1, cachedGlyph.m_y1,
            s);

        layoutX += gi->geometry.width;
    }

    pango_fc_font_unlock_face((PangoFcFont*) font);
}
Esempio n. 18
0
CoglPangoGlyphCacheValue *
cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache,
                               CoglBool             create,
                               PangoFont           *font,
                               PangoGlyph           glyph)
{
  CoglPangoGlyphCacheKey lookup_key;
  CoglPangoGlyphCacheValue *value;

  lookup_key.font = font;
  lookup_key.glyph = glyph;

  value = g_hash_table_lookup (cache->hash_table, &lookup_key);

  if (create && value == NULL)
    {
      CoglPangoGlyphCacheKey *key;
      PangoRectangle ink_rect;

      value = g_slice_new (CoglPangoGlyphCacheValue);
      value->texture = NULL;

      pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
      pango_extents_to_pixels (&ink_rect, NULL);

      value->draw_x = ink_rect.x;
      value->draw_y = ink_rect.y;
      value->draw_width = ink_rect.width;
      value->draw_height = ink_rect.height;

      /* If the glyph is zero-sized then we don't need to reserve any
         space for it and we can just avoid painting anything */
      if (ink_rect.width < 1 || ink_rect.height < 1)
        value->dirty = FALSE;
      else
        {
          /* Try adding the glyph to the global atlas... */
          if (!cogl_pango_glyph_cache_add_to_global_atlas (cache,
                                                           font,
                                                           glyph,
                                                           value) &&
              /* If it fails try the local atlas */
              !cogl_pango_glyph_cache_add_to_local_atlas (cache,
                                                          font,
                                                          glyph,
                                                          value))
            {
              cogl_pango_glyph_cache_value_free (value);
              return NULL;
            }

          value->dirty = TRUE;
          cache->has_dirty_glyphs = TRUE;
        }

      key = g_slice_new (CoglPangoGlyphCacheKey);
      key->font = g_object_ref (font);
      key->glyph = glyph;

      g_hash_table_insert (cache->hash_table, key, value);
    }

  return value;
}
static PangoClutterGlyphCacheValue *
pango_clutter_renderer_get_cached_glyph (PangoRenderer *renderer,
					 PangoFont     *font,
					 PangoGlyph     glyph)
{
  PangoClutterRenderer *priv = PANGO_CLUTTER_RENDERER (renderer);
  PangoClutterGlyphCacheValue *value;
  PangoClutterGlyphCache *glyph_cache;

  glyph_cache = priv->use_mipmapping
    ? priv->mipmapped_glyph_cache : priv->glyph_cache;

  if ((value = pango_clutter_glyph_cache_lookup (glyph_cache,
						 font,
						 glyph)) == NULL)
    {
      cairo_surface_t *surface;
      cairo_t *cr;
      cairo_scaled_font_t *scaled_font;
      PangoRectangle ink_rect;
      cairo_glyph_t cairo_glyph;

      pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
      pango_extents_to_pixels (&ink_rect, NULL);

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

      scaled_font = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
      cairo_set_scaled_font (cr, scaled_font);

      cairo_glyph.x = -ink_rect.x;
      cairo_glyph.y = -ink_rect.y;
      /* The PangoCairo glyph numbers directly map to Cairo glyph
	 numbers */
      cairo_glyph.index = glyph;
      cairo_show_glyphs (cr, &cairo_glyph, 1);

      cairo_destroy (cr);
      cairo_surface_flush (surface);

      /* Copy the glyph to the cache */
      value = pango_clutter_glyph_cache_set
	(glyph_cache, font, glyph,
	 cairo_image_surface_get_data (surface),
	 cairo_image_surface_get_width (surface),
	 cairo_image_surface_get_height (surface),
	 cairo_image_surface_get_stride (surface),
	 ink_rect.x, ink_rect.y);

      cairo_surface_destroy (surface);

      CLUTTER_NOTE (PANGO, "cache fail    %i", glyph);
    }
  else
    CLUTTER_NOTE (PANGO, "cache success %i", glyph);

  return value;
}