Пример #1
0
void pango_printf(cairo_t *cairo, const char *font,
		double scale, bool markup, const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	// Add one since vsnprintf excludes null terminator.
	int length = vsnprintf(NULL, 0, fmt, args) + 1;
	va_end(args);

	char *buf = malloc(length);
	if (buf == NULL) {
		sway_log(SWAY_ERROR, "Failed to allocate memory");
		return;
	}
	va_start(args, fmt);
	vsnprintf(buf, length, fmt, args);
	va_end(args);

	PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_get_font_options(cairo, fo);
	pango_cairo_context_set_font_options(pango_layout_get_context(layout), fo);
	cairo_font_options_destroy(fo);
	pango_cairo_update_layout(cairo, layout);
	pango_cairo_show_layout(cairo, layout);
	g_object_unref(layout);
	free(buf);
}
Пример #2
0
void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
		int *baseline, double scale, bool markup, const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	// Add one since vsnprintf excludes null terminator.
	int length = vsnprintf(NULL, 0, fmt, args) + 1;
	va_end(args);

	char *buf = malloc(length);
	if (buf == NULL) {
		sway_log(SWAY_ERROR, "Failed to allocate memory");
		return;
	}
	va_start(args, fmt);
	vsnprintf(buf, length, fmt, args);
	va_end(args);

	PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
	pango_cairo_update_layout(cairo, layout);
	pango_layout_get_pixel_size(layout, width, height);
	if (baseline) {
		*baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
	}
	g_object_unref(layout);
	free(buf);
}
Пример #3
0
void pango_printf(cairo_t *cairo, const char *font, int32_t scale, bool markup, const char *fmt, ...) {
	char *buf = malloc(2048);

	va_list args;
	va_start(args, fmt);
	if (vsnprintf(buf, 2048, fmt, args) >= 2048) {
		strcpy(buf, "[buffer overflow]");
	}
	va_end(args);

	PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
	pango_cairo_update_layout(cairo, layout);

	pango_cairo_show_layout(cairo, layout);

	g_object_unref(layout);

	free(buf);
}
Пример #4
0
static void
gtk_numerable_icon_ensure_emblem (GtkNumerableIcon *self)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  PangoLayout *layout;
  GEmblem *emblem;
  gint width, height;
  gdouble scale;
  PangoAttrList *attr_list;
  PangoAttribute *attr;
  GdkPixbuf *pixbuf;

  /* don't draw anything if the count is zero */
  if (self->priv->rendered_string == NULL)
    {
      g_emblemed_icon_clear_emblems (G_EMBLEMED_ICON (self));
      return;
    }

  surface = get_image_surface (self);
  cr = cairo_create (surface);

  layout = get_pango_layout (self);
  pango_layout_get_pixel_size (layout, &width, &height);

  /* scale the layout to be 0.75 of the size still available for drawing */
  scale = ((get_surface_size (surface) - 2 * get_border_size (self)) * 0.75) / (MAX (height, width));
  attr_list = pango_attr_list_new ();

  attr = pango_attr_scale_new (scale);
  pango_attr_list_insert (attr_list, attr);

  attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
  pango_attr_list_insert (attr_list, attr);

  pango_layout_set_attributes (layout, attr_list);

  /* update these values */
  pango_layout_get_pixel_size (layout, &width, &height);

  /* move to the center */
  cairo_move_to (cr,
                 get_surface_size (surface) / 2. - (gdouble) width / 2.,
                 get_surface_size (surface) / 2. - (gdouble) height / 2.);

  gdk_cairo_set_source_rgba (cr, self->priv->foreground);
  pango_cairo_show_layout (cr, layout);

  cairo_destroy (cr);

  pixbuf =
    gdk_pixbuf_get_from_surface (surface, 0, 0,
                                 get_surface_size (surface), get_surface_size (surface));

  emblem = g_emblem_new (G_ICON (pixbuf));
  g_emblemed_icon_clear_emblems (G_EMBLEMED_ICON (self));
  g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (self), emblem);

  g_object_unref (layout);
  g_object_unref (emblem);
  g_object_unref (pixbuf);

  cairo_surface_destroy (surface);
  pango_attr_list_unref (attr_list);
}
Пример #5
0
static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag,
		uint32_t y) {
	uint32_t width = swaynag->width * swaynag->scale;

	int border = swaynag->type->details_border_thickness * swaynag->scale;
	int padding = swaynag->type->message_padding * swaynag->scale;
	int decor = padding + border;

	swaynag->details.x = decor;
	swaynag->details.y = y * swaynag->scale + decor;
	swaynag->details.width = width - decor * 2;

	PangoLayout *layout = get_pango_layout(cairo, swaynag->type->font,
			swaynag->details.message, swaynag->scale, false);
	pango_layout_set_width(layout,
			(swaynag->details.width - padding * 2) * PANGO_SCALE);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_single_paragraph_mode(layout, false);
	pango_cairo_update_layout(cairo, layout);
	swaynag->details.total_lines = pango_layout_get_line_count(layout);

	PangoLayoutLine *line;
	line = pango_layout_get_line_readonly(layout, swaynag->details.offset);
	gint offset = line->start_index;
	const char *text = pango_layout_get_text(layout);
	pango_layout_set_text(layout, text + offset, strlen(text) - offset);

	int text_width, text_height;
	pango_cairo_update_layout(cairo, layout);
	pango_layout_get_pixel_size(layout, &text_width, &text_height);

	bool show_buttons = swaynag->details.offset > 0;
	int button_width = get_detailed_scroll_button_width(cairo, swaynag);
	if (show_buttons) {
		swaynag->details.width -= button_width;
		pango_layout_set_width(layout,
				(swaynag->details.width - padding * 2) * PANGO_SCALE);
	}

	uint32_t ideal_height;
	do {
		ideal_height = swaynag->details.y + text_height + decor + padding * 2;
		if (ideal_height > SWAYNAG_MAX_HEIGHT) {
			ideal_height = SWAYNAG_MAX_HEIGHT;

			if (!show_buttons) {
				show_buttons = true;
				swaynag->details.width -= button_width;
				pango_layout_set_width(layout,
						(swaynag->details.width - padding * 2) * PANGO_SCALE);
			}
		}

		swaynag->details.height = ideal_height - swaynag->details.y - decor;
		pango_layout_set_height(layout,
				(swaynag->details.height - padding * 2) * PANGO_SCALE);
		pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
		pango_cairo_update_layout(cairo, layout);
		pango_layout_get_pixel_size(layout, &text_width, &text_height);
	} while (text_height != (swaynag->details.height - padding * 2));

	swaynag->details.visible_lines = pango_layout_get_line_count(layout);

	if (show_buttons) {
		swaynag->details.button_up.x =
			swaynag->details.x + swaynag->details.width;
		swaynag->details.button_up.y = swaynag->details.y;
		swaynag->details.button_up.width = button_width;
		swaynag->details.button_up.height = swaynag->details.height / 2;
		render_details_scroll_button(cairo, swaynag,
				&swaynag->details.button_up);

		swaynag->details.button_down.x =
			swaynag->details.x + swaynag->details.width;
		swaynag->details.button_down.y =
			swaynag->details.button_up.y + swaynag->details.button_up.height;
		swaynag->details.button_down.width = button_width;
		swaynag->details.button_down.height = swaynag->details.height / 2;
		render_details_scroll_button(cairo, swaynag,
				&swaynag->details.button_down);
	}

	cairo_set_source_u32(cairo, swaynag->type->border);
	cairo_rectangle(cairo, swaynag->details.x, swaynag->details.y,
			swaynag->details.width, swaynag->details.height);
	cairo_fill(cairo);

	cairo_move_to(cairo, swaynag->details.x + padding,
			swaynag->details.y + padding);
	cairo_set_source_u32(cairo, swaynag->type->text);
	pango_cairo_show_layout(cairo, layout);
	g_object_unref(layout);

	return ideal_height / swaynag->scale;
}