Beispiel #1
0
static GSList *
attrs_at_byte (PangoAttrList *alist, gint bytepos)
{
	PangoAttrIterator *iter = pango_attr_list_get_iterator (alist);
	GSList *attrs = NULL;

	do {
		gint start, end;
		pango_attr_iterator_range (iter, &start, &end);
		if (start <= bytepos && bytepos < end) {
			attrs = pango_attr_iterator_get_attrs (iter);
			break;
		}
	} while (pango_attr_iterator_next (iter));
	pango_attr_iterator_destroy (iter);

	return attrs;
}
Beispiel #2
0
char *
go_pango_attrs_to_markup (PangoAttrList *attrs, char const *text)
{
	PangoAttrIterator * iter;
	int handled = 0;
	int from, to;
	int len;
	GString *gstr;

	if (text == NULL)
		return NULL;
	if (attrs == NULL || go_pango_attr_list_is_empty (attrs))
		return g_strdup (text);

	len = strlen (text);
	gstr = g_string_sized_new (len + 1);

	iter = pango_attr_list_get_iterator (attrs);
	do {
		GSList *list, *l;
		int spans = 0;

		pango_attr_iterator_range (iter, &from, &to);
		to = (to > len) ? len : to;       /* Since "to" can be really big! */
		from = (from > len) ? len : from; /* Since "from" can also be really big! */
		if (from > handled)
			g_string_append_len (gstr, text + handled, from - handled);
		list = pango_attr_iterator_get_attrs (iter);
		for (l = list; l != NULL; l = l->next)
			spans += go_pango_attr_as_markup_string (l->data, gstr);
		g_slist_free (list);
		if (to > from)
			g_string_append_len (gstr, text + from, to - from);
		while (spans-- > 0)
			g_string_append (gstr, "</span>");
		handled = to;
	} while (pango_attr_iterator_next (iter));

	pango_attr_iterator_destroy (iter);

	return g_string_free (gstr, FALSE);
}
Beispiel #3
0
static VALUE
rg_attrs(VALUE self)
{
    GSList* list = pango_attr_iterator_get_attrs(_SELF(self));
    GSList* base = list;
    GSList* old = list;
    VALUE ary = rb_ary_new();

    while (list) {
        rb_ary_push(ary, ATTR2RVAL(list->data));
        list = list->next;
    }
    while (old) {
        pango_attribute_destroy((PangoAttribute*)old);
        old = old->next;
    }
    g_slist_free(base);

    return ary;
}  
Beispiel #4
0
static void
html_new_markup (GsfOutput *output, const PangoAttrList *markup, char const *text,
		 html_version_t version)
{
	int handled = 0;
	PangoAttrIterator * iter;
	int from, to;
	int len = strlen (text);
	GString *closure = g_string_new ("");

	iter = pango_attr_list_get_iterator ((PangoAttrList *) markup);

	do {
		GSList *list, *l;

		g_string_erase (closure, 0, -1);
		pango_attr_iterator_range (iter, &from, &to);
		from = (from > len) ? len : from; /* Since "from" can be really big! */
		to = (to > len) ? len : to;       /* Since "to" can be really big!   */
		if (from > handled)
			cb_html_add_chars (output, text + handled, from - handled);
		list = pango_attr_iterator_get_attrs (iter);
		for (l = list; l != NULL; l = l->next) {
			char const *result = cb_html_attrs_as_string (output, l->data, version);
			if (result != NULL)
				g_string_prepend (closure, result);
		}
		g_slist_free (list);
		if (to > from)
			cb_html_add_chars (output, text + from, to - from);
		gsf_output_puts (output, closure->str);
		handled = to;
	} while (pango_attr_iterator_next (iter));

	g_string_free (closure, TRUE);
	pango_attr_iterator_destroy (iter);

	return;
}
Beispiel #5
0
static void
dump_attrs (PangoAttrList *attrs, GString *string)
{
  PangoAttrIterator *iter;

  iter = pango_attr_list_get_iterator (attrs);
  do {
    gint start, end;
    GSList *list, *l;

    pango_attr_iterator_range (iter, &start, &end);
    g_string_append_printf (string, "range %d %d\n", start, end);
    list = pango_attr_iterator_get_attrs (iter);
    for (l = list; l; l = l->next)
      {
        PangoAttribute *attr = l->data;
        print_attr (attr, string);
      }
    g_slist_free_full (list, (GDestroyNotify)pango_attribute_destroy);
  } while (pango_attr_iterator_next (iter));

  pango_attr_iterator_destroy (iter);
}
Beispiel #6
0
static void
go_pango_translate_here (PangoAttrIterator *state_iter,
			 PangoAttrIterator *attr_iter, PangoAttrList *attrs)
{
	double font_scale = 1.;
	double scale = 1.;
	int rise = 0;
	PangoAttribute *pa;
	PangoFontDescription *desc = pango_font_description_new ();
	GSList *the_attrs, *l;
	gint range_start, range_end;

	pango_attr_iterator_range (attr_iter, &range_start, &range_end);

	if (range_start == range_end)
		return;

	desc = pango_font_description_new ();
	pango_attr_iterator_get_font (state_iter, desc, NULL, NULL);
	font_scale = pango_font_description_get_size (desc)/
		(double)PANGO_SCALE/10.;
	pango_font_description_free (desc);

	pa = pango_attr_iterator_get
		(state_iter, PANGO_ATTR_SCALE);
	if (pa)
		scale = ((PangoAttrFloat *)pa)->value;
	pa = pango_attr_iterator_get
		(state_iter, PANGO_ATTR_RISE);
	if (pa)
		rise = ((PangoAttrInt *)pa)->value;

	/* We should probably figured out the default font size used */
	/* rather than assuming it is 10 pts * scale */
	if (font_scale == 0)
		font_scale = scale;

	the_attrs = pango_attr_iterator_get_attrs (attr_iter);
	for (l = the_attrs; l != NULL; l = l->next) {
		PangoAttribute *attribute = l->data;
		PangoAttrType type = attribute->klass->type;
		if (type == go_pango_attr_superscript_get_attr_type ()) {
			GOPangoAttrSuperscript *attr = (GOPangoAttrSuperscript *)attribute;
			if (attr->val) {
				scale *= GO_SUPERSCRIPT_SCALE;
				rise += GO_SUPERSCRIPT_RISE * font_scale;
				font_scale *= GO_SUPERSCRIPT_SCALE;
			}
		} else { /* go_pango_attr_subscript_type */
			GOPangoAttrSubscript *attr = (GOPangoAttrSubscript *)attribute;
			if (attr->val) {
				scale *= GO_SUBSCRIPT_SCALE;
				rise += GO_SUBSCRIPT_RISE * font_scale;
				font_scale *= GO_SUBSCRIPT_SCALE;
			}
		}
	}

	if (the_attrs != NULL) {
		PangoAttribute *attr = pango_attr_scale_new (scale);
		attr->start_index = range_start;
		attr->end_index = range_end;
		pango_attr_list_insert (attrs, attr);
		attr = pango_attr_rise_new (rise);
		attr->start_index = range_start;
		attr->end_index = range_end;
		pango_attr_list_insert (attrs, attr);
	}
	g_slist_free_full (the_attrs, (GDestroyNotify)pango_attribute_destroy);
}
Beispiel #7
0
void
go_load_pango_attributes_into_buffer (PangoAttrList  *markup, GtkTextBuffer *buffer, gchar const *str)
{
	PangoAttrIterator * iter;
	PangoAttrList  *copied_markup;
	PangoAttrList  *our_markup;

	if (markup == NULL)
		return;

/* For some styles we create named tags. The names are taken from the Pango enums */

	copied_markup = pango_attr_list_copy (markup);
	our_markup = pango_attr_list_filter (copied_markup,
					     go_load_pango_attributes_into_buffer_named_filter,
					     NULL);
	pango_attr_list_unref (copied_markup);
	if (our_markup != NULL) {
		iter = pango_attr_list_get_iterator (our_markup);

		do {
			GSList *attr = pango_attr_iterator_get_attrs (iter);
			if (attr != NULL) {
				GSList *ptr;
				gint start, end;
				GtkTextIter start_iter, end_iter;
				char const *name;

				pango_attr_iterator_range (iter, &start, &end);
				start = go_load_pango_byte_to_char (str, start);
				end = go_load_pango_byte_to_char (str, end);
				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);

				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
					PangoAttribute *attribute = ptr->data;
					GtkTextTag *tag;
					int val;

					switch (attribute->klass->type) {
					case PANGO_ATTR_STYLE:
						name = (((PangoAttrInt *)attribute)->value
							== PANGO_STYLE_NORMAL)
							? "PANGO_STYLE_NORMAL" :
							"PANGO_STYLE_ITALIC";
						tag = gtk_text_tag_table_lookup
							(gtk_text_buffer_get_tag_table (buffer),
							 name);
						gtk_text_buffer_apply_tag (buffer, tag,
									   &start_iter, &end_iter);
						break;
					case PANGO_ATTR_STRIKETHROUGH:
						name = (((PangoAttrInt *)attribute)->value) ?
							"PANGO_STRIKETHROUGH_TRUE" :
							"PANGO_STRIKETHROUGH_FALSE";
						tag = gtk_text_tag_table_lookup
							(gtk_text_buffer_get_tag_table (buffer),
							 name);
						gtk_text_buffer_apply_tag (buffer, tag,
									   &start_iter, &end_iter);
						break;
					case PANGO_ATTR_UNDERLINE:
						val = ((PangoAttrInt *)attribute)->value;
						if (val == PANGO_UNDERLINE_NONE)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_UNDERLINE_NONE",
											   &start_iter, &end_iter);
						else if (val == PANGO_UNDERLINE_SINGLE)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_UNDERLINE_SINGLE",
											   &start_iter, &end_iter);
						else if (val == PANGO_UNDERLINE_DOUBLE)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_UNDERLINE_DOUBLE",
											   &start_iter, &end_iter);
						else if (val == PANGO_UNDERLINE_LOW)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_UNDERLINE_LOW",
											   &start_iter, &end_iter);
						else if (val == PANGO_UNDERLINE_ERROR)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_UNDERLINE_ERROR",
											   &start_iter, &end_iter);
						break;
					case PANGO_ATTR_WEIGHT:
						val = ((PangoAttrInt *)attribute)->value;
						if (val < (PANGO_WEIGHT_THIN + PANGO_WEIGHT_ULTRALIGHT)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_THIN",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRALIGHT",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_BOOK)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_LIGHT",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_BOOK + PANGO_WEIGHT_NORMAL)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOOK",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_MEDIUM)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_NORMAL",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_MEDIUM + PANGO_WEIGHT_SEMIBOLD)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_MEDIUM",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_SEMIBOLD + PANGO_WEIGHT_BOLD)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_SEMIBOLD",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_BOLD",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRABOLD",
											   &start_iter, &end_iter);
						else if (val < (PANGO_WEIGHT_HEAVY + PANGO_WEIGHT_ULTRAHEAVY)/2)
							gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_HEAVY",
											   &start_iter, &end_iter);
						else gtk_text_buffer_apply_tag_by_name (buffer,"PANGO_WEIGHT_ULTRAHEAVY",
											&start_iter, &end_iter);
						break;
					default:
						break;
					}
				}
				g_slist_free_full (attr, (GDestroyNotify)pango_attribute_destroy);
			}
		} while (pango_attr_iterator_next (iter));
		pango_attr_iterator_destroy (iter);
		pango_attr_list_unref (our_markup);
	}

/* For other styles (that are not at true/false type styles) we use unnamed styles */

	copied_markup = pango_attr_list_copy (markup);
	our_markup = pango_attr_list_filter (copied_markup,
					     go_load_pango_attributes_into_buffer_filter,
					     NULL);
	pango_attr_list_unref (copied_markup);
	if (our_markup != NULL) {
		iter = pango_attr_list_get_iterator (our_markup);

		do {
			GSList *attr = pango_attr_iterator_get_attrs (iter);
			if (attr != NULL) {
				char *string;
				GSList *ptr;
				gint start, end;
				GtkTextIter start_iter, end_iter;
				GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
				for (ptr = attr; ptr != NULL; ptr = ptr->next) {
					PangoAttribute *attribute = ptr->data;
					switch (attribute->klass->type) {
					case PANGO_ATTR_FOREGROUND:
						string = pango_color_to_string
							(&((PangoAttrColor *)attribute)->color);
						g_object_set (G_OBJECT (tag),
							      "foreground", string,
							      "foreground-set", TRUE,
							      NULL);
						g_free (string);
						break;
					case PANGO_ATTR_RISE:
						g_object_set (G_OBJECT (tag),
							      "rise",
							      ((PangoAttrInt *)attribute)->value,
							      "rise-set", TRUE,
							      NULL);
						break;
					default:
						break;
					}
				}
				pango_attr_iterator_range (iter, &start, &end);
				start = go_load_pango_byte_to_char (str, start);
				end = go_load_pango_byte_to_char (str, end);
				gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
				gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
				gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
				g_slist_free_full (attr, (GDestroyNotify)pango_attribute_destroy);
			}
		} while (pango_attr_iterator_next (iter));
		pango_attr_iterator_destroy (iter);
		pango_attr_list_unref (our_markup);
	}
}
Beispiel #8
0
/* Shapes the ellipsis using the font and is_cjk information computed by
 * update_ellipsis_shape() from the first character in the gap.
 */
static void
shape_ellipsis (EllipsizeState *state)
{
  PangoAttrList *attrs = pango_attr_list_new ();
  GSList *run_attrs;
  PangoItem *item;
  PangoGlyphString *glyphs;
  GSList *l;
  PangoAttribute *fallback;
  const char *ellipsis_text;
  int i;

  /* Create/reset state->ellipsis_run
   */
  if (!state->ellipsis_run)
    {
      state->ellipsis_run = g_slice_new (PangoGlyphItem);
      state->ellipsis_run->glyphs = pango_glyph_string_new ();
      state->ellipsis_run->item = NULL;
    }

  if (state->ellipsis_run->item)
    {
      pango_item_free (state->ellipsis_run->item);
      state->ellipsis_run->item = NULL;
    }
  
  /* Create an attribute list
   */
  run_attrs = pango_attr_iterator_get_attrs (state->gap_start_attr);
  for (l = run_attrs; l; l = l->next)
    {
      PangoAttribute *attr = l->data;
      attr->start_index = 0;
      attr->end_index = G_MAXINT;

      pango_attr_list_insert (attrs, attr);
    }

  g_slist_free (run_attrs);

  fallback = pango_attr_fallback_new (FALSE);
  fallback->start_index = 0;
  fallback->end_index = G_MAXINT;
  pango_attr_list_insert (attrs, fallback);

  /* First try using a specific ellipsis character in the best matching font
   */
  if (state->ellipsis_is_cjk)
    ellipsis_text = "\342\213\257";	/* U+22EF: MIDLINE HORIZONTAL ELLIPSIS, used for CJK */
  else
    ellipsis_text = "\342\200\246";	/* U+2026: HORIZONTAL ELLIPSIS */

  item = itemize_text (state, ellipsis_text, attrs);

  /* If that fails we use "..." in the first matching font
   */
  if (!item->analysis.font ||
      !_pango_engine_shape_covers (item->analysis.shape_engine, item->analysis.font,
				   item->analysis.language, g_utf8_get_char (ellipsis_text)))
    {
      pango_item_free (item);
      
      /* Modify the fallback iter while it is inside the PangoAttrList; Don't try this at home
       */
      ((PangoAttrInt *)fallback)->value = TRUE; 

      ellipsis_text = "...";
      item = itemize_text (state, ellipsis_text, attrs);
    }
  
  pango_attr_list_unref (attrs);
  
  state->ellipsis_run->item = item;

  /* Now shape
   */
  glyphs = state->ellipsis_run->glyphs;

  pango_shape (ellipsis_text, strlen (ellipsis_text),
	       &item->analysis, glyphs);

  state->ellipsis_width = 0;
  for (i = 0; i < glyphs->num_glyphs; i++)
    state->ellipsis_width += glyphs->glyphs[i].geometry.width;
}