Exemple #1
0
static void
draw_page (GtkPrintOperation *operation,
	   GtkPrintContext *context,
	   int page_nr,
	   PrintData *print_data)
{
  cairo_t *cr;
  GList *pagebreak;
  int start, end, i;
  PangoLayoutIter *iter;
  double start_pos;

  if (page_nr == 0)
    start = 0;
  else
    {
      pagebreak = g_list_nth (print_data->page_breaks, page_nr - 1);
      start = GPOINTER_TO_INT (pagebreak->data);
    }

  pagebreak = g_list_nth (print_data->page_breaks, page_nr);
  if (pagebreak == NULL)
    end = pango_layout_get_line_count (print_data->layout);
  else
    end = GPOINTER_TO_INT (pagebreak->data);
    
  cr = gtk_print_context_get_cairo_context (context);

  cairo_set_source_rgb (cr, 0, 0, 0);
  
  i = 0;
  start_pos = 0;
  iter = pango_layout_get_iter (print_data->layout);
  do
    {
      PangoRectangle   logical_rect;
      PangoLayoutLine *line;
      int              baseline;

      if (i >= start)
	{
	  line = pango_layout_iter_get_line (iter);

	  pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
	  baseline = pango_layout_iter_get_baseline (iter);
	  
	  if (i == start)
	    start_pos = logical_rect.y / 1024.0;
	  
	  cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
	  
	  pango_cairo_show_layout_line  (cr, line);
	}
      i++;
    }
  while (i < end &&
	 pango_layout_iter_next_line (iter));

  pango_layout_iter_free (iter);
}
Exemple #2
0
static PyObject *
pango_GetLayoutLinePos(PyObject *self, PyObject *args) {

	int i, len;
	double baseline, dy;
	void *LayoutObj;
	PangoLayout *layout;
	PangoLayoutIter *iter;
	PyObject *ret;

	if (!PyArg_ParseTuple(args, "O", &LayoutObj)) {
		return NULL;
	}

	layout = PyCObject_AsVoidPtr(LayoutObj);

	len = pango_layout_get_line_count(layout);
	ret = PyTuple_New(len);
	iter = pango_layout_get_iter(layout);
	dy = ((double) pango_layout_iter_get_baseline(iter)) / PANGO_SCALE;

	for (i = 0; i < len; i++) {
		baseline = -1.0 * ((double) pango_layout_iter_get_baseline(iter))
				/ PANGO_SCALE + dy;
		PyTuple_SetItem(ret, i, PyFloat_FromDouble(baseline));
		pango_layout_iter_next_line(iter);
	}

	pango_layout_iter_free(iter);

	return ret;
}
Exemple #3
0
static void
test_file (const gchar *filename, GString *string)
{
  gchar *contents;
  gchar *markup;
  gsize  length;
  GError *error = NULL;
  PangoLayout *layout;
  gchar *p;
  gint width = 0;
  gint ellipsize_at = 0;
  PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_NONE;
  PangoWrapMode wrap = PANGO_WRAP_WORD;
  PangoFontDescription *desc;

  if (!g_file_get_contents (filename, &contents, &length, &error))
    {
      fprintf (stderr, "%s\n", error->message);
      g_error_free (error);
      return;
    }

  p = strchr (contents, '\n');
  g_assert (p);
  markup = p + 1;
  *p = '\0';

  parse_params (contents, &width, &ellipsize_at, &ellipsize, &wrap);

  layout = pango_layout_new (context);

  desc = pango_font_description_from_string ("Cantarell 11");
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free (desc); 

  pango_layout_set_markup (layout, markup, length);
  g_free (contents);

  if (width != 0)
    pango_layout_set_width (layout, width * PANGO_SCALE);
  pango_layout_set_ellipsize (layout, ellipsize);
  pango_layout_set_wrap (layout, wrap);

  g_string_append (string, pango_layout_get_text (layout));
  g_string_append (string, "\n---\n\n");
  g_string_append_printf (string, "wrapped: %d\n", pango_layout_is_wrapped (layout));
  g_string_append_printf (string, "ellipsized: %d\n", pango_layout_is_ellipsized (layout));
  g_string_append_printf (string, "lines: %d\n", pango_layout_get_line_count (layout));
  if (width != 0)
    g_string_append_printf (string, "width: %d\n", pango_layout_get_width (layout));
  g_string_append (string, "\n---\n\n");
   dump_attrs (pango_layout_get_attributes (layout), string);
  g_string_append (string, "\n---\n\n");
  dump_lines (layout, string);
  g_string_append (string, "\n---\n\n");
  dump_runs (layout, string);

  g_object_unref (layout);
}
Exemple #4
0
static void
begin_print (GtkPrintOperation *operation,
	     GtkPrintContext *context,
	     PrintData *print_data)
{
  PangoFontDescription *desc;
  PangoLayoutLine *layout_line;
  double width, height;
  double page_height;
  GList *page_breaks;
  int num_lines;
  int line;

  width = gtk_print_context_get_width (context);
  height = gtk_print_context_get_height (context);

  print_data->layout = gtk_print_context_create_pango_layout (context);

  desc = pango_font_description_from_string (print_data->font);
  pango_layout_set_font_description (print_data->layout, desc);
  pango_font_description_free (desc);

  pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
  
  pango_layout_set_text (print_data->layout, print_data->text, -1);

  num_lines = pango_layout_get_line_count (print_data->layout);

  page_breaks = NULL;
  page_height = 0;

  for (line = 0; line < num_lines; line++)
    {
      PangoRectangle ink_rect, logical_rect;
      double line_height;
      
      layout_line = pango_layout_get_line (print_data->layout, line);
      pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);

      line_height = logical_rect.height / 1024.0;

      if (page_height + line_height > height)
	{
	  page_breaks = g_list_prepend (page_breaks, GINT_TO_POINTER (line));
	  page_height = 0;
	}

      page_height += line_height;
    }

  page_breaks = g_list_reverse (page_breaks);
  gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
  
  print_data->page_breaks = page_breaks;
}
Exemple #5
0
static void _draw_page_results (GtkPrintContext *context, GwPageInfo *page, GwPrintData *data)
{
    //Declarations
    GtkTextView *view;
    GtkTextBuffer *buffer;
    PangoLayout *layout;
    char *text;
    PangoFontDescription *desc;
    int width;
    int height;
    gdouble drawable_width, drawable_height;
    cairo_t *cr;
    gint line_start;
    gint line_end;

    //Initializations
    view = gw_searchwindow_get_current_textview (data->window);
    buffer = gtk_text_view_get_buffer (view);
    text = gtk_text_buffer_get_text (buffer, &(page->start), &(page->end), FALSE);
    layout = gtk_print_context_create_pango_layout (context);
    desc = pango_font_description_from_string ("sans 10");
    drawable_width = gtk_print_context_get_width (context);
    drawable_height = gtk_print_context_get_height (context);
    cr = gtk_print_context_get_cairo_context (context);
    line_start = 0;
    line_end = 0;

    //Draw
    if (text != NULL)
    {
      cairo_move_to (cr, 5, 10);
      pango_layout_set_font_description (layout, desc);
      pango_layout_set_markup (layout, text, -1);
      pango_layout_set_width (layout, drawable_width * PANGO_SCALE);
      pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
      pango_layout_set_height (layout, drawable_height * PANGO_SCALE);
      pango_layout_get_size (layout, &width, &height);
      pango_cairo_show_layout (cr, layout);
      
      //Adjust the end GtkTextIter to the cutoff in the visible cairo context
      line_start = gtk_text_iter_get_line (&page->start);
      line_end = line_start + pango_layout_get_line_count (layout) - 1;
      gtk_text_buffer_get_iter_at_line (buffer, &(page->end), line_end);
    }

    //Cleanup
    if (text != NULL) g_free (text);
    if (layout != NULL) g_object_unref (layout);
    if (desc != NULL) pango_font_description_free (desc);
}
Exemple #6
0
void buffer_to_pdf (Ebook * ebook)
{
	GtkTextBuffer * buffer;
	GtkTextIter start, end;
	Pqueue queue;
	gchar * size, *editor_font;

	/* A4 initial */
	queue.ebook = ebook;
	queue.pos = 0;
	queue.page_count = 1;
	queue.width = 8.3 * POINTS;
	queue.height = 11.7 * POINTS;
	queue.page_height = 40.0;
	g_return_if_fail (ebook);
	g_return_if_fail (ebook->filename);
	size = gconf_client_get_string (ebook->client, ebook->paper_size.key, NULL);
	buffer = GTK_TEXT_BUFFER(gtk_builder_get_object (ebook->builder, "textbuffer1"));
	queue.progressbar = GTK_PROGRESS_BAR(gtk_builder_get_object (ebook->builder, "progressbar"));
	queue.statusbar = GTK_STATUSBAR(gtk_builder_get_object (ebook->builder, "statusbar"));
	gtk_text_buffer_get_bounds (buffer, &start, &end);
	queue.text = g_strdup(gtk_text_buffer_get_text (buffer, &start, &end, TRUE));
	editor_font = gconf_client_get_string(ebook->client, ebook->editor_font.key, NULL);
	if (0 == g_strcmp0 (size, "A5"))
	{
		queue.width = a5_width * POINTS;
		queue.height = a5_height * POINTS;
	}
	if (0 == g_strcmp0 (size, "B5"))
	{
		queue.width = b5_width * POINTS;
		queue.height = b5_height * POINTS;
	}
	queue.surface = cairo_pdf_surface_create (ebook->filename, queue.width, queue.height);
	queue.cr = cairo_create (queue.surface);
	queue.context = pango_cairo_create_context (queue.cr);
	/* pango_cairo_create_layout is wasteful with a lot of text. */
	queue.desc = pango_font_description_from_string (editor_font);
	queue.layout = make_new_page (queue.context, queue.desc, queue.height, queue.width);
	pango_layout_set_text (queue.layout, queue.text, -1);
	cairo_move_to (queue.cr, SIDE_MARGIN / 2, EDGE_MARGIN / 2);
	gtk_progress_bar_set_fraction (queue.progressbar, 0.0);
	queue.lines_per_page = pango_layout_get_line_count (queue.layout);
	queue.iter = pango_layout_get_iter (queue.layout);
	create_pages (&queue);
}
Exemple #7
0
static void
real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
{
	GdauiEntryString *mgstr;
	GdaDataHandler *dh;

	PangoLayout *layout;
	gchar *text;
	
	g_return_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap));
	mgstr = GDAUI_ENTRY_STRING (mgwrap);
	GdauiEntryStringPrivate *priv = gdaui_entry_string_get_instance_private (mgstr);

	dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgwrap));

	/* do we need to go into multi line mode ? */
	text = gda_data_handler_get_str_from_value (dh, value);
	layout = gtk_widget_create_pango_layout (GTK_WIDGET (mgwrap), text);
	if (pango_layout_get_line_count (layout) > 1) 
		g_object_set (G_OBJECT (mgwrap), "multiline", TRUE, NULL);
	g_object_unref (G_OBJECT (layout));
	
	/* fill the single line widget */
	if (value) {
		if (gda_value_is_null ((GValue *) value))
			gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), NULL);
		else 
			gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), text);
	}
	else
		gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), NULL);

	/* fill the multiline widget */
	if (value) {
		if (gda_value_is_null ((GValue *) value) || !text)
                        gtk_text_buffer_set_text (priv->buffer, "", -1);
		else 
			gtk_text_buffer_set_text (priv->buffer, text, -1);
	}
	else 
		gtk_text_buffer_set_text (priv->buffer, "", -1);

	g_free (text);
}
/* force to wrap truncated label by setting explicit size request
 * see N#27000 and G#329646 */
static void 
force_to_wrap_truncated                         (HildonBanner *banner)
{
    PangoLayout *layout;
    int lines;
    int width;
    int height = -1;
    PangoRectangle logical;
    GtkRequisition requisition;
    HildonBannerPrivate *priv = HILDON_BANNER_GET_PRIVATE (banner);

    g_return_if_fail (priv);

    width = priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
        : HILDON_BANNER_LABEL_MAX_PROGRESS;

    /* Force the label to compute its layout using the maximum
     * available width rather than its default one.
     */
    gtk_widget_set_size_request (priv->label, width, height);
    gtk_widget_size_request (priv->label, &requisition);

    layout = gtk_label_get_layout (GTK_LABEL (priv->label));
    pango_layout_get_extents (layout, NULL, &logical);

    /* Now get the actual width needed by the pango layout */
    width = PANGO_PIXELS (logical.width);

    /* If the layout has now been wrapped and exceeds 3 lines, we truncate
     * the rest of the label according to spec.
     */
    lines = pango_layout_get_line_count (layout);
    if (pango_layout_is_wrapped (layout) && lines > 3) {
        /* This calculation assumes that the same font is used
         * throughout the banner -- this is usually the case on maemo
         *
         * FIXME: Pango >= 1.20 has pango_layout_set_height().
         */
        height = (PANGO_PIXELS (logical.height) * 3) / lines + 1;
    }

    /* Set the final width/height */
    gtk_widget_set_size_request (priv->label, width, height);
}
Exemple #9
0
gui2::tpoint ttext::get_cursor_position(
		const unsigned column, const unsigned line) const
{
	recalculate();

	// First we need to determine the byte offset, if more routines need it it
	// would be a good idea to make it a separate function.
	titor itor(layout_);

	// Go the wanted line.
	if(line != 0) {
		if(pango_layout_get_line_count(layout_) >= static_cast<int>(line)) {
			return gui2::tpoint(0, 0);
		}

		for(size_t i = 0; i < line; ++i) {
			pango_layout_iter_next_line(itor);
		}
	}

	// Go the wanted column.
	for(size_t i = 0; i < column; ++i) {
		if(!pango_layout_iter_next_char(itor)) {
			// It seems that the documentation is wrong and causes and off by
			// one error... the result should be false if already at the end of
			// the data when started.
			if(i + 1 == column) {
				break;
			}
			// We are beyond data.
			return gui2::tpoint(0, 0);
		}
	}

	// Get the byte offset
	const int offset = pango_layout_iter_get_index(itor);

	// Convert the byte offset in a position.
	PangoRectangle rect;
	pango_layout_get_cursor_pos(layout_, offset, &rect, nullptr);

	return gui2::tpoint(PANGO_PIXELS(rect.x), PANGO_PIXELS(rect.y));
}
Exemple #10
0
/* Split a list of paragraphs into a list of lines.
 */
gchar *paps_layout_to_postscript_strdup(paps_t *paps_,
					double pos_x,
					double pos_y,
					PangoLayout *layout)
{
  paps_private_t *paps = (paps_private_t*)paps_;
  GString *layout_str = g_string_new("");
  gchar *ret_str;
  int para_num_lines, line_idx;
  double scale = 72.0 / PANGO_SCALE  / PAPS_DPI;

  para_num_lines = pango_layout_get_line_count(layout);

  for (line_idx=0; line_idx<para_num_lines; line_idx++)
    {
      PangoRectangle logical_rect, ink_rect;
      PangoLayoutLine *pango_line = pango_layout_get_line(layout, line_idx);

      pango_layout_line_get_extents(pango_line,
				    &ink_rect, &logical_rect);

      
      add_line_to_postscript(paps,
			     layout_str,
			     pos_x,
			     pos_y,
			     pango_line);

      pos_y -= logical_rect.height * scale;
    }

  ret_str = layout_str->str;
  g_string_free(layout_str, FALSE);

  return ret_str;
}
Exemple #11
0
static void cb_begin_print(GtkPrintOperation *op,
		GtkPrintContext *ctx, gpointer data)
{
	gint layout_height;
	gchar *text;
	GtkTextIter start, end;
	GtkTextBuffer *buffer = gtk_text_view_get_buffer(data);
	PangoTabArray *tabs;
	
	gtk_text_buffer_get_bounds(buffer, &start, &end);
	text = g_strchomp(gtk_text_buffer_get_text(buffer, &start, &end, FALSE));
	
	page_width = gtk_print_context_get_width(ctx);
	page_height = gtk_print_context_get_height(ctx);
	font_desc = gtk_widget_get_style(data)->font_desc;
	layout = gtk_print_context_create_pango_layout(ctx);
	pango_layout_set_width(layout, page_width * PANGO_SCALE);
	pango_layout_set_font_description(layout, font_desc);
	pango_layout_set_text(layout, text, -1);
	
	get_tab_array(&tabs, ctx, data);
	if (tabs) {
		pango_layout_set_tabs(layout, tabs);
		pango_tab_array_free(tabs);
	}
	pango_layout_get_size(layout, NULL, &layout_height);
	
	line_count = pango_layout_get_line_count(layout);
	text_height = pango_font_description_get_size(font_desc) / PANGO_SCALE;
	lines_per_page = page_height / text_height;
	
	n_pages = (line_count - 1) / lines_per_page + 1;
	gtk_print_operation_set_n_pages(op, n_pages);
	
	g_free(text);
}
Exemple #12
0
static void
draw_text_line(DiaRenderer *self,
	       TextLine *text_line,
	       Point *pos, Alignment alignment, Color *color)
{
  DiaPsFt2Renderer *renderer = DIA_PS_FT2_RENDERER(self);
  PangoLayout *layout;
  int line, linecount;
  double xpos = pos->x, ypos = pos->y;
  char *text = text_line_get_string(text_line);
  /* TODO: we could probably pass the alignment down to the PS file? */
  xpos -= text_line_get_alignment_adjustment (text_line, alignment);

/* Using the global PangoContext does not allow to have renderer specific 
 * different ones. Or it implies the push/pop _context mess. Anyway just 
 * get rid of warnings for now. But the local code may be resurreted 
 * sooner or later...                                               --hb
 */
#define USE_GLOBAL_CONTEXT
#ifndef USE_GLOBAL_CONTEXT
  PangoAttrList* list;
  PangoAttribute* attr;
  guint length;
#endif

  if ((!text)||(text == (const char *)(1))) return;

  lazy_setcolor(DIA_PS_RENDERER(renderer),color);

#define ANNOYING_SCALE_FACTOR 5.9

  /* Make sure the letters aren't too wide. */
#ifdef USE_GLOBAL_CONTEXT
  layout = dia_font_build_layout(text, text_line_get_font(text_line),
				 text_line_get_height(text_line)*ANNOYING_SCALE_FACTOR);
#else
  /* approximately what would be required but w/o dia_font_get_context() */
  dia_font_set_height(text_line_get_font(text_line),
		      text_line_get_height(text_line));
  layout = pango_layout_new(dia_font_get_context());

  length = text ? strlen(text) : 0;
  pango_layout_set_text(layout,text,length);
        
  list = pango_attr_list_new();

  attr = pango_attr_font_desc_new(dia_font_get_description(text_line_get_font(text_line)));
  attr->start_index = 0;
  attr->end_index = length;
  pango_attr_list_insert(list,attr);
    
  pango_layout_set_attributes(layout,list);
  pango_attr_list_unref(list);

  pango_layout_set_indent(layout,0);
  pango_layout_set_justify(layout,FALSE);
#endif

  pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
    
  linecount = pango_layout_get_line_count(layout);
  for (line = 0; line < linecount; line++) {
    PangoLayoutLine *layoutline = pango_layout_get_line(layout, line);

    /* Not sure scale is the right one here.  */
    text_line_adjust_layout_line(text_line, layoutline, ANNOYING_SCALE_FACTOR);

    postscript_draw_contour(DIA_PS_RENDERER(renderer),
			    DPI, /* dpi_x */
			    layoutline, xpos, ypos);
    ypos += 10;/* Some line height thing??? */
  }
}
void
gnm_rendered_value_remeasure (GnmRenderedValue *rv)
{
	if (rv->rotation) {
		GnmRenderedRotatedValue *rrv = (GnmRenderedRotatedValue *)rv;
		PangoContext *context = pango_layout_get_context (rv->layout);
		double sin_a, abs_sin_a, cos_a;
		int sdx = 0;
		int x0 = 0, x1 = 0;
		PangoLayoutIter *iter;
		int l = 0;
		int lwidth;

		sin_a = rrv->rotmat.xy;
		abs_sin_a = fabs (sin_a);
		cos_a = rrv->rotmat.xx;
		pango_context_set_matrix (context, &rrv->rotmat);
		pango_layout_context_changed (rv->layout);

		rrv->linecount = pango_layout_get_line_count (rv->layout);
		rrv->lines = g_new (struct GnmRenderedRotatedValueInfo, rrv->linecount);
		pango_layout_get_size (rv->layout, &lwidth, NULL);

		rv->layout_natural_height = 0;

		iter = pango_layout_get_iter (rv->layout);
		do {
			PangoRectangle logical;
			int x, dx, dy, indent;
			int h, ytop, ybot, baseline;

			pango_layout_iter_get_line_extents (iter, NULL, &logical);
			pango_layout_iter_get_line_yrange (iter, &ytop, &ybot);
			baseline = pango_layout_iter_get_baseline (iter);
			indent = logical.x;
			if (sin_a < 0)
				indent -= lwidth;

			if (l == 0 && rv->noborders)
				sdx = (int)(baseline * sin_a - ybot / sin_a);
			dx = sdx + (int)(ybot / sin_a + indent * cos_a);
			dy = (int)((baseline - ybot) * cos_a - indent * sin_a);

			rrv->lines[l].dx = dx;
			rrv->lines[l].dy = dy;

			/* Left edge.  */
			x = dx - (int)((baseline - ytop) * sin_a);
			x0 = MIN (x0, x);

			/* Right edge.  */
			x = dx + (int)(logical.width * cos_a + (ybot - baseline) * sin_a);
			x1 = MAX (x1, x);

			h = logical.width * abs_sin_a + logical.height * cos_a;
			if (h > rv->layout_natural_height)
				rv->layout_natural_height = h;

			l++;
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);

		rv->layout_natural_width = x1 - x0;
		if (sin_a < 0) {
			int dx = rv->layout_natural_width;
			for (l = 0; l < rrv->linecount; l++)
				rrv->lines[l].dx += dx;
		}
		for (l = 0; l < rrv->linecount; l++)
			rrv->lines[l].dy += rv->layout_natural_height;

#if 0
		g_print ("Natural size: %d x %d\n", rv->layout_natural_width, rv->layout_natural_height);
#endif

		pango_context_set_matrix (context, NULL);
		pango_layout_context_changed (rv->layout);
	} else
Exemple #14
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;
}
Exemple #15
0
/*
 * update_window_decoration_name
 *
 * Returns: void
 * Description: frees the last window name and gets the new one from
 * wnck. Also checks to see if the name has a length (slight optimization)
 * and re-creates the pango context to re-render the name
 */
void
update_window_decoration_name (WnckWindow *win)
{
    decor_t	    *d = g_object_get_data (G_OBJECT (win), "decor");
    const gchar	    *name;
    glong	    name_length;
    PangoLayoutLine *line;

    if (d->name)
    {
	g_free (d->name);
	d->name = NULL;
    }

    /* Only operate if the window name has a length */
    name = wnck_window_get_name (win);
    if (name && (name_length = strlen (name)))
    {
	gint w;

	/* Cairo mode: w = SHRT_MAX */
	if (theme_draw_window_decoration != draw_window_decoration)
	{
	    w = SHRT_MAX;
	}
	/* Need to get a minimum width for the name */
	else
	{
	    gint width;

	    wnck_window_get_client_window_geometry (win, NULL, NULL,
						    &width, NULL);

	    w = width - ICON_SPACE - 2 - d->button_width;
	    if (w < 1)
		w = 1;
	}

	/* Set the maximum width for the layout (in case
	 * decoration size < text width) since we
	 * still need to show the buttons and the window name */
	pango_layout_set_auto_dir (d->layout, FALSE);
	pango_layout_set_width (d->layout, w * PANGO_SCALE);
	pango_layout_set_text (d->layout, name, name_length);

	line = pango_layout_get_line (d->layout, 0);

	name_length = line->length;
	if (pango_layout_get_line_count (d->layout) > 1)
	{
	    if (name_length < 4)
	    {
		pango_layout_set_text (d->layout, NULL, 0);
		return;
	    }

	    d->name = g_strndup (name, name_length);
	    strcpy (d->name + name_length - 3, "...");
	}
	else
	    d->name = g_strndup (name, name_length);

	/* Truncate the text */
	pango_layout_set_text (d->layout, d->name, name_length);
    }
}
Exemple #16
0
static void
_paint_lyrics (OlScrollWindow *scroll, cairo_t *cr)
{
  ol_assert (OL_IS_SCROLL_WINDOW (scroll));
  GtkWidget *widget = GTK_WIDGET (scroll);
  ol_assert (GTK_WIDGET_REALIZED (widget));
  OlScrollWindowPrivate *priv = OL_SCROLL_WINDOW_GET_PRIVATE (scroll);
  int line_height = ol_scroll_window_get_font_height (scroll) + priv->line_margin;
  int count = ol_scroll_window_compute_line_count (scroll);
  gint width, height;
  gdk_drawable_get_size (gtk_widget_get_window (GTK_WIDGET (scroll)),
                         &width, &height);
  
  /* set the font */
  PangoLayout *layout = _get_pango (scroll, cr);
  pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
  pango_layout_set_width (layout, (width - priv->padding_x*2) * PANGO_SCALE);
  pango_layout_set_indent (layout, -20 * PANGO_SCALE);
  /* paint the lyrics*/
  cairo_save (cr);
  cairo_new_path (cr);
  cairo_rectangle (cr,
                   priv->padding_x, 0,
                   width - priv->padding_x * 2,
                   height - priv->padding_y * 2);
  cairo_close_path (cr);
  cairo_clip (cr);
  int i;
  gint current_lyric_id;
  gint lrc_y;
  _calc_paint_pos (scroll,
                   &current_lyric_id,
                   &lrc_y);
  int begin = current_lyric_id - count / 2;
  int end = current_lyric_id + count / 2 + 1;
  int ypos = height / 2  - lrc_y - (count / 2 + 1) * line_height;
  cairo_set_source_rgb(cr,
                       priv->inactive_color.r,
                       priv->inactive_color.g,
                       priv->inactive_color.b);
  if (scroll->whole_lyrics != NULL) {
    for (i = begin; i < end; i++) {
      ypos += line_height;
      if (i < 0) continue;
      if (i >= scroll->whole_lyrics->len)
        break;
      pango_layout_set_text (layout,
                             g_ptr_array_index (scroll->whole_lyrics, i),
                             -1);
      cairo_save (cr);
      double ratio = _get_active_color_ratio (scroll, i);
      double alpha = 1.0;
      if (ypos < line_height / 2.0 + priv->padding_y)
        alpha = 1.0 - (line_height / 2.0 + priv->padding_y - ypos) * 1.0 / line_height * 2;
      else if (ypos > height - line_height * 1.5 - priv->padding_y)
        alpha = (height - line_height - priv->padding_y - ypos) * 1.0 / line_height * 2;
      if (alpha < 0.0) alpha = 0.0;
      cairo_set_source_rgba (cr,
                             priv->active_color.r * ratio + 
                             priv->inactive_color.r * (1 - ratio),
                             priv->active_color.g * ratio +
                             priv->inactive_color.g * (1 - ratio),
                             priv->active_color.b * ratio +
                             priv->inactive_color.b * (1 - ratio),
                             alpha);
      cairo_move_to (cr, priv->padding_x, ypos);
      pango_cairo_update_layout (cr, layout);
      pango_cairo_show_layout (cr, layout);
      cairo_restore (cr);

      if (pango_layout_is_wrapped (layout)) {
        // There is more than one line, offset ypos according to the number of
        // additional lines
        ypos += (pango_layout_get_line_count (layout) - 1)
                * ol_scroll_window_get_font_height (scroll);
      }
    }
  }
  g_object_unref (layout);
  cairo_reset_clip (cr);
  cairo_restore (cr);
}
GpStatus
pango_MeasureString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc,
	GDIPCONST GpStringFormat *format, RectF *boundingBox, int *codepointsFitted, int *linesFilled)
{
	PangoLayout *layout;
	PangoLayoutLine *line;
	PangoRectangle logical;
	PangoLayoutIter *iter;
	int *charsRemoved = NULL;

	cairo_save (graphics->ct);

	layout = gdip_pango_setup_layout (graphics, stringUnicode, length, font, rc, boundingBox, format, &charsRemoved);
	if (!layout) {
		cairo_restore (graphics->ct);
		return OutOfMemory;
	}

	if (codepointsFitted) {
		int charsFitted;
		int lastIndex;
		int y0;
		int y1;
		double min_x;
		double max_x;
		double max_y;
		const char *layoutText;
		if (boundingBox && format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = boundingBox->Y;
			max_x = boundingBox->Y + boundingBox->Height;
			max_y = boundingBox->X + boundingBox->Width;
		} else if (boundingBox) {
			min_x = boundingBox->X;
			max_x = boundingBox->X + boundingBox->Width;
			max_y = boundingBox->Y + boundingBox->Height;
		} else if (format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = rc->Y;
			max_x = rc->Y + rc->Height;
			max_y = rc->X + rc->Width;
		} else {
			min_x = rc->X;
			max_x = rc->X + rc->Width;
			max_y = rc->Y + rc->Height;
		}
		lastIndex = 0;
		iter = pango_layout_get_iter (layout);
		do {
			if (iter == NULL)
				break;
			pango_layout_iter_get_line_yrange (iter, &y0, &y1);
			if (y0 / PANGO_SCALE >= max_y)
				break;
			if (pango_layout_iter_at_last_line (iter)) {
				do {
					pango_layout_iter_get_char_extents (iter, &logical);
					/* check both max and min to catch right-to-left text, also width may be negative */
					if ((logical.x / PANGO_SCALE > max_x || (logical.x + logical.width) / PANGO_SCALE > max_x) || (logical.x / PANGO_SCALE < min_x || (logical.x + logical.width) / PANGO_SCALE < min_x))
						break;
					lastIndex = pango_layout_iter_get_index (iter);
				} while (pango_layout_iter_next_char (iter));
				break;
			} else {
				line = pango_layout_iter_get_line_readonly (iter);
				lastIndex = line->start_index + line->length - 1;
			}
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);
		layoutText = pango_layout_get_text (layout);
		/* this can happen when the string ends in a newline */
		if (lastIndex >= strlen (layoutText))
			lastIndex = strlen (layoutText) - 1;
		/* Add back in any & characters removed and the final newline characters (if any) */
		charsFitted = g_utf8_strlen (layoutText, lastIndex + 1) + charsRemoved [lastIndex];
		//g_warning("lastIndex: %d\t\tcharsRemoved: %d", lastIndex, charsRemoved[lastIndex]);
		/* safe because of null termination */
		switch (layoutText [lastIndex + 1]) {
			case '\r':
				charsFitted++;
				if (layoutText [lastIndex + 2] == '\n')
					charsFitted++;
				break;
			case '\n':
				charsFitted++;
				break;
		}
		*codepointsFitted = charsFitted;
	}

	GdipFree (charsRemoved);

	if (linesFilled) {
		*linesFilled = pango_layout_get_line_count (layout);
// g_warning ("linesFilled %d", *linesFilled);
	}
// else g_warning ("linesFilled %d", pango_layout_get_line_count (layout));

	g_object_unref (layout);
	cairo_restore (graphics->ct);
	return Ok;
}
Exemple #18
0
static void
gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
                            GtkMovementStep  step,
                            gint             count,
                            gboolean         extend_selection)
{
  GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
  GtkTextIter    cursor;
  GtkTextIter    selection;
  GtkTextIter   *sel_start;
  gboolean       cancel_selection = FALSE;
  gint           x_pos  = -1;

  GIMP_LOG (TEXT_EDITING, "%s count = %d, select = %s",
            g_enum_get_value (g_type_class_ref (GTK_TYPE_MOVEMENT_STEP),
                              step)->value_name,
            count,
            extend_selection ? "TRUE" : "FALSE");

  gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
                                    gtk_text_buffer_get_insert (buffer));
  gtk_text_buffer_get_iter_at_mark (buffer, &selection,
                                    gtk_text_buffer_get_selection_bound (buffer));

  if (extend_selection)
    {
      sel_start = &selection;
    }
  else
    {
      /*  when there is a selection, moving the cursor without
       *  extending it should move the cursor to the end of the
       *  selection that is in moving direction
       */
      if (count > 0)
        gtk_text_iter_order (&selection, &cursor);
      else
        gtk_text_iter_order (&cursor, &selection);

      sel_start = &cursor;

      /* if we actually have a selection, just move *to* the beginning/end
       * of the selection and not *from* there on LOGICAL_POSITIONS
       * and VISUAL_POSITIONS movement
       */
      if (! gtk_text_iter_equal (&cursor, &selection))
        cancel_selection = TRUE;
    }

  switch (step)
    {
    case GTK_MOVEMENT_LOGICAL_POSITIONS:
      if (! cancel_selection)
        gtk_text_iter_forward_visible_cursor_positions (&cursor, count);
      break;

    case GTK_MOVEMENT_VISUAL_POSITIONS:
      if (! cancel_selection)
        {
          PangoLayout *layout;
          const gchar *text;

          if (! gimp_text_tool_ensure_layout (text_tool))
            break;

          layout = gimp_text_layout_get_pango_layout (text_tool->layout);
          text = pango_layout_get_text (layout);

          while (count != 0)
            {
              const gunichar word_joiner = 8288; /*g_utf8_get_char(WORD_JOINER);*/
              gint index;
              gint trailing = 0;
              gint new_index;

              index = gimp_text_buffer_get_iter_index (text_tool->buffer,
                                                       &cursor, TRUE);

              if (count > 0)
                {
                  if (g_utf8_get_char (text + index) == word_joiner)
                    pango_layout_move_cursor_visually (layout, TRUE,
                                                       index, 0, 1,
                                                       &new_index, &trailing);
                  else
                    new_index = index;

                  pango_layout_move_cursor_visually (layout, TRUE,
                                                     new_index, trailing, 1,
                                                     &new_index, &trailing);
                  count--;
                }
              else
                {
                  pango_layout_move_cursor_visually (layout, TRUE,
                                                     index, 0, -1,
                                                     &new_index, &trailing);

                  if (new_index != -1 && new_index != G_MAXINT &&
                      g_utf8_get_char (text + new_index) == word_joiner)
                    {
                      pango_layout_move_cursor_visually (layout, TRUE,
                                                         new_index, trailing, -1,
                                                         &new_index, &trailing);
                    }

                  count++;
                }

              if (new_index != G_MAXINT && new_index != -1)
                index = new_index;
              else
                break;

              gimp_text_buffer_get_iter_at_index (text_tool->buffer,
                                                  &cursor, index, TRUE);
              gtk_text_iter_forward_chars (&cursor, trailing);
            }
        }
      break;

    case GTK_MOVEMENT_WORDS:
      if (count < 0)
        {
          gtk_text_iter_backward_visible_word_starts (&cursor, -count);
        }
      else if (count > 0)
        {
	  if (! gtk_text_iter_forward_visible_word_ends (&cursor, count))
	    gtk_text_iter_forward_to_line_end (&cursor);
        }
      break;

    case GTK_MOVEMENT_DISPLAY_LINES:
      {
        GtkTextIter      start;
        GtkTextIter      end;
        gint             cursor_index;
        PangoLayout     *layout;
        PangoLayoutLine *layout_line;
        PangoLayoutIter *layout_iter;
        PangoRectangle   logical;
        gint             line;
        gint             trailing;
        gint             i;

        gtk_text_buffer_get_bounds (buffer, &start, &end);

        cursor_index = gimp_text_buffer_get_iter_index (text_tool->buffer,
                                                        &cursor, TRUE);

        if (! gimp_text_tool_ensure_layout (text_tool))
          break;

        layout = gimp_text_layout_get_pango_layout (text_tool->layout);

        pango_layout_index_to_line_x (layout, cursor_index, FALSE,
                                      &line, &x_pos);

        layout_iter = pango_layout_get_iter (layout);
        for (i = 0; i < line; i++)
          pango_layout_iter_next_line (layout_iter);

        pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);

        x_pos += logical.x;

        pango_layout_iter_free (layout_iter);

        /*  try to go to the remembered x_pos if it exists *and* we are at
         *  the beginning or at the end of the current line
         */
        if (text_tool->x_pos != -1 && (x_pos <= logical.x ||
                                       x_pos >= logical.x + logical.width))
          x_pos = text_tool->x_pos;

        line += count;

        if (line < 0)
          {
            cursor = start;
            break;
          }
        else if (line >= pango_layout_get_line_count (layout))
          {
            cursor = end;
            break;
          }

        layout_iter = pango_layout_get_iter (layout);
        for (i = 0; i < line; i++)
          pango_layout_iter_next_line (layout_iter);

        layout_line = pango_layout_iter_get_line_readonly (layout_iter);
        pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);

        pango_layout_iter_free (layout_iter);

        pango_layout_line_x_to_index (layout_line, x_pos - logical.x,
                                      &cursor_index, &trailing);

        gimp_text_buffer_get_iter_at_index (text_tool->buffer, &cursor,
                                            cursor_index, TRUE);

        while (trailing--)
          gtk_text_iter_forward_char (&cursor);
      }
      break;

    case GTK_MOVEMENT_PAGES: /* well... */
    case GTK_MOVEMENT_BUFFER_ENDS:
      if (count < 0)
        {
          gtk_text_buffer_get_start_iter (buffer, &cursor);
        }
      else if (count > 0)
        {
          gtk_text_buffer_get_end_iter (buffer, &cursor);
        }
      break;

    case GTK_MOVEMENT_PARAGRAPH_ENDS:
      if (count < 0)
        {
          gtk_text_iter_set_line_offset (&cursor, 0);
        }
      else if (count > 0)
        {
          if (! gtk_text_iter_ends_line (&cursor))
            gtk_text_iter_forward_to_line_end (&cursor);
        }
      break;

    case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
      if (count < 0)
        {
          gtk_text_iter_set_line_offset (&cursor, 0);
        }
      else if (count > 0)
        {
          if (! gtk_text_iter_ends_line (&cursor))
            gtk_text_iter_forward_to_line_end (&cursor);
        }
      break;

    default:
      return;
    }

  text_tool->x_pos = x_pos;

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));

  gimp_text_tool_reset_im_context (text_tool);

  gtk_text_buffer_select_range (buffer, &cursor, sel_start);

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
}
Exemple #19
0
static VALUE
rg_line_count(VALUE self)
{
    return INT2NUM(pango_layout_get_line_count(_SELF(self)));
}