⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pango-markup.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
		  /* set next range_start to include this char */		  range_start = p;		}	      /* reset range_end */	      range_end = NULL;	    }	  else if (c == md->accel_marker)	    {	      range_end = p;	    }	  p = g_utf8_next_char (p);	}      if (range_end)	{	  g_string_append_len (md->text,			       range_start,			       range_end - range_start);	  md->index += range_end - range_start;	}      else	{	  g_string_append_len (md->text,			       range_start,			       end - range_start);	  md->index += end - range_start;	}      if (md->attr_list != NULL && uline_index >= 0)	{	  /* Add the underline indicating the accelerator */	  PangoAttribute *attr;	  attr = pango_attr_underline_new (PANGO_UNDERLINE_LOW);	  attr->start_index = uline_index;	  attr->end_index = uline_index + uline_len;	  pango_attr_list_change (md->attr_list, attr);	}    }}static gbooleanxml_isspace (char c){  return c == ' ' || c == '\t' || c == '\n' || c == '\r';}static const GMarkupParser pango_markup_parser = {  start_element_handler,  end_element_handler,  text_handler,  NULL,  NULL};/** * pango_parse_markup: * @markup_text: markup to parse (see <link linkend="PangoMarkupFormat">markup format</link>) * @length: length of @markup_text, or -1 if nul-terminated * @accel_marker: character that precedes an accelerator, or 0 for none * @attr_list: address of return location for a #PangoAttrList, or %NULL * @text: address of return location for text with tags stripped, or %NULL * @accel_char: address of return location for accelerator char, or %NULL * @error: address of return location for errors, or %NULL * * * Parses marked-up text (see * <link linkend="PangoMarkupFormat">markup format</link>) to create * a plain-text string and an attribute list. * * If @accel_marker is nonzero, the given character will mark the * character following it as an accelerator. For example, @accel_marker * might be an ampersand or underscore. All characters marked * as an accelerator will receive a %PANGO_UNDERLINE_LOW attribute, * and the first character so marked will be returned in @accel_char. * Two @accel_marker characters following each other produce a single * literal @accel_marker character. * * Return value: %FALSE if @error is set, otherwise %TRUE **/gbooleanpango_parse_markup (const char                 *markup_text,		    int                         length,		    gunichar                    accel_marker,		    PangoAttrList             **attr_list,		    char                      **text,		    gunichar                   *accel_char,		    GError                    **error){  GMarkupParseContext *context = NULL;  MarkupData *md = NULL;  gboolean needs_root = TRUE;  GSList *tmp_list;  const char *p;  const char *end;  g_return_val_if_fail (markup_text != NULL, FALSE);  md = g_slice_new (MarkupData);  /* Don't bother creating these if they weren't requested;   * might be useful e.g. if you just want to validate   * some markup.   */  if (attr_list)    md->attr_list = pango_attr_list_new ();  else    md->attr_list = NULL;  md->text = g_string_new (NULL);  if (accel_char)    *accel_char = 0;  md->accel_marker = accel_marker;  md->accel_char = 0;  md->index = 0;  md->tag_stack = NULL;  md->to_apply = NULL;  context = g_markup_parse_context_new (&pango_markup_parser,					0, md, NULL);  if (length < 0)    length = strlen (markup_text);  p = markup_text;  end = markup_text + length;  while (p != end && xml_isspace (*p))    ++p;  if (end - p >= 8 && strncmp (p, "<markup>", 8) == 0)     needs_root = FALSE;  if (needs_root)    if (!g_markup_parse_context_parse (context,				       "<markup>",				       -1,				       error))      goto error;  if (!g_markup_parse_context_parse (context,				     markup_text,				     length,				     error))    goto error;  if (needs_root)    if (!g_markup_parse_context_parse (context,				       "</markup>",				       -1,				       error))      goto error;  if (!g_markup_parse_context_end_parse (context, error))    goto error;  g_markup_parse_context_free (context);  if (md->attr_list)    {      /* The apply list has the most-recently-closed tags first;       * we want to apply the least-recently-closed tag last.       */      tmp_list = md->to_apply;      while (tmp_list != NULL)	{	  PangoAttribute *attr = tmp_list->data;	  /* Innermost tags before outermost */	  pango_attr_list_change (md->attr_list, attr);	  tmp_list = g_slist_next (tmp_list);	}      g_slist_free (md->to_apply);      md->to_apply = NULL;    }  if (attr_list)    *attr_list = md->attr_list;  if (text)    *text = g_string_free (md->text, FALSE);  else    g_string_free (md->text, TRUE);  if (accel_char)    *accel_char = md->accel_char;  g_assert (md->tag_stack == NULL);  g_slice_free (MarkupData, md);  return TRUE; error:  g_slist_foreach (md->tag_stack, (GFunc) open_tag_free, NULL);  g_slist_free (md->tag_stack);  g_slist_foreach (md->to_apply, (GFunc) pango_attribute_destroy, NULL);  g_slist_free (md->to_apply);  g_string_free (md->text, TRUE);  if (md->attr_list)    pango_attr_list_unref (md->attr_list);  g_slice_free (MarkupData, md);  if (context)    g_markup_parse_context_free (context);  return FALSE;}static voidset_bad_attribute (GError             **error,		   GMarkupParseContext *context,		   const char          *element_name,		   const char          *attribute_name){  gint line_number, char_number;  g_markup_parse_context_get_position (context,				       &line_number, &char_number);  g_set_error (error,	       G_MARKUP_ERROR,	       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,	       _("Tag '%s' does not support attribute '%s' on line %d char %d"),	       element_name,	       attribute_name,	       line_number, char_number);}static voidadd_attribute (OpenTag        *ot,	       PangoAttribute *attr){  if (ot == NULL)    pango_attribute_destroy (attr);  else    ot->attrs = g_slist_prepend (ot->attrs, attr);}#define CHECK_NO_ATTRS(elem) G_STMT_START {                    \	 if (*names != NULL) {                                 \	   set_bad_attribute (error, context, (elem), *names); \	   return FALSE;                                       \	 } }G_STMT_ENDstatic gbooleanb_parse_func        (MarkupData            *md,		     OpenTag               *tag,		     const gchar          **names,		     const gchar          **values,		     GMarkupParseContext   *context,		     GError               **error){  CHECK_NO_ATTRS("b");  add_attribute (tag, pango_attr_weight_new (PANGO_WEIGHT_BOLD));  return TRUE;}static gbooleanbig_parse_func      (MarkupData            *md,		     OpenTag               *tag,		     const gchar          **names,		     const gchar          **values,		     GMarkupParseContext   *context,		     GError               **error){  CHECK_NO_ATTRS("big");  /* Grow text one level */  if (tag)    {      tag->scale_level_delta += 1;      tag->scale_level += 1;    }  return TRUE;}static gbooleanparse_absolute_size (OpenTag               *tag,		     const char            *size){  SizeLevel level = Medium;  double factor;  if (strcmp (size, "xx-small") == 0)    level = XXSmall;  else if (strcmp (size, "x-small") == 0)    level = XSmall;  else if (strcmp (size, "small") == 0)    level = Small;  else if (strcmp (size, "medium") == 0)    level = Medium;  else if (strcmp (size, "large") == 0)    level = Large;  else if (strcmp (size, "x-large") == 0)    level = XLarge;  else if (strcmp (size, "xx-large") == 0)    level = XXLarge;  else    return FALSE;  /* This is "absolute" in that it's relative to the base font,   * but not to sizes created by any other tags   */  factor = scale_factor (level, 1.0);  add_attribute (tag, pango_attr_scale_new (factor));  if (tag)    open_tag_set_absolute_font_scale (tag, factor);  return TRUE;}/* a string compare func that ignores '-' vs '_' differences */static gintattr_strcmp (gconstpointer pa,	     gconstpointer pb){  const char *a = pa;  const char *b = pb;  int ca;  int cb;  while (*a && *b)    {      ca = *a++;      cb = *b++;      if (ca == cb)	continue;      ca = ca == '_' ? '-' : ca;      cb = cb == '_' ? '-' : cb;      if (ca != cb)	return cb - ca;    }  ca = *a;  cb = *b;  return cb - ca;}static gbooleanspan_parse_int (const char *attr_name,		const char *attr_val,		int *val,		int line_number,		GError **error){  const char *end = attr_val;  if (!pango_scan_int (&end, val) || *end != '\0')    {      g_set_error (error,		   G_MARKUP_ERROR,		   G_MARKUP_ERROR_INVALID_CONTENT,		   _("Value of '%s' attribute on <span> tag "		     "on line %d could not be parsed; "		     "should be an integer, not '%s'"),		   attr_name, line_number, attr_val);      return FALSE;    }  return TRUE;}static gbooleanspan_parse_boolean (const char *attr_name,		    const char *attr_val,		    gboolean *val,		    int line_number,		    GError **error){  const char *end = attr_val;  if (strcmp (attr_val, "true") == 0 ||      strcmp (attr_val, "yes") == 0 ||      strcmp (attr_val, "t") == 0 ||      strcmp (attr_val, "y") == 0)    *val = TRUE;  else if (strcmp (attr_val, "false") == 0 ||	   strcmp (attr_val, "no") == 0 ||	   strcmp (attr_val, "f") == 0 ||	   strcmp (attr_val, "n") == 0)    *val = FALSE;  else    {      g_set_error (error,		   G_MARKUP_ERROR,		   G_MARKUP_ERROR_INVALID_CONTENT,		   _("Value of '%s' attribute on <span> tag "		     "line %d should have one of "		     "'true/yes/t/y' or 'false/no/f/n': '%s' is not valid"),		   attr_name, line_number, attr_val);      return FALSE;    }  return TRUE;}static gbooleanspan_parse_color (const char *attr_name,		  const char *attr_val,		  PangoColor *color,		  int line_number,		  GError **error){  if (!pango_color_parse (color, attr_val))    {      g_set_error (error,		   G_MARKUP_ERROR,		   G_MARKUP_ERROR_INVALID_CONTENT,		   _("Value of '%s' attribute on <span> tag "		     "on line %d could not be parsed; "		     "should be a color specification, not '%s'"),		   attr_name, line_number, attr_val);      return FALSE;    }  return TRUE;}static gbooleanspan_parse_enum (const char *attr_name,		 const char *attr_val,		 GType type,		 int *val,		 int line_number,		 GError **error){  char *possible_values = NULL;  if (!pango_parse_enum (type, attr_val, val, FALSE, &possible_values))    {      g_set_error (error,		   G_MARKUP_ERROR,		   G_MARKUP_ERROR_INVALID_CONTENT,		   _("'%s' is not a valid value for the '%s' "		     "attribute on <span> tag, line %d; valid "		     "values are %s"),		   attr_val, attr_name, line_number, possible_values);      g_free (possible_values);      return FALSE;    }  return TRUE;}static gbooleanspan_parse_func     (MarkupData            *md,		     OpenTag               *tag,		     const gchar          **names,		     const gchar          **values,		     GMarkupParseContext   *context,		     GError               **error){  int line_number, char_number;  int i;  const char *family = NULL;  const char *size = NULL;  const char *style = NULL;  const char *weight = NULL;  const char *variant = NULL;  const char *stretch = NULL;  const char *desc = NULL;  const char *foreground = NULL;  const char *background = NULL;  const char *underline = NULL;  const char *underline_color = NULL;  const char *strikethrough = NULL;  const char *strikethrough_color = NULL;  const char *rise = NULL;  const char *letter_spacing = NULL;  const char *lang = NULL;  const char *fallback = NULL;  const char *gravity = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -