Beispiel #1
0
static void
gnm_notebook_button_ensure_layout (GnmNotebookButton *nbb)
{
	const char *text = gtk_label_get_text (GTK_LABEL (nbb));

	if (nbb->layout) {
		if (strcmp (text, pango_layout_get_text (nbb->layout)) == 0)
			return;
		pango_layout_set_text (nbb->layout, text, -1);
		pango_layout_set_text (nbb->layout_active, text, -1);
	} else {
		PangoAttrList *attrs, *attrs_active;
		PangoAttribute *attr;
		PangoFontDescription *desc;
		GtkWidget *widget = GTK_WIDGET (nbb);
		GtkStyleContext *context =
			gtk_widget_get_style_context (widget);

		nbb->layout = gtk_widget_create_pango_layout (widget, text);
		nbb->layout_active = gtk_widget_create_pango_layout (widget, text);

		/* Common */
		attrs = pango_attr_list_new ();
		if (nbb->bg) {
			attr = go_color_to_pango
				(go_color_from_gdk_rgba (nbb->bg, NULL),
				 FALSE);
			attr->start_index = 0;
			attr->end_index = -1;
			pango_attr_list_insert (attrs, attr);
		}
		attrs_active = pango_attr_list_copy (attrs);

		/* Normal */
		gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL,
				       "font", &desc, NULL);
		attr = pango_attr_font_desc_new (desc);
		attr->start_index = 0;
		attr->end_index = -1;
		pango_attr_list_insert (attrs, attr);
		pango_font_description_free (desc);
		pango_layout_set_attributes (nbb->layout, attrs);
		pango_attr_list_unref (attrs);

		/* Active */
		gtk_style_context_get (context, GTK_STATE_FLAG_ACTIVE,
				       "font", &desc, NULL);
		attr = pango_attr_font_desc_new (desc);
		attr->start_index = 0;
		attr->end_index = -1;
		pango_attr_list_insert (attrs_active, attr);
		pango_font_description_free (desc);
		pango_layout_set_attributes (nbb->layout_active, attrs_active);
		pango_attr_list_unref (attrs_active);
	}

	pango_layout_get_extents (nbb->layout, NULL, &nbb->logical);
	pango_layout_get_extents (nbb->layout_active, NULL, &nbb->logical_active);
}
Beispiel #2
0
void
CoordWinSetFont(const char *font)
{
#if GTK_CHECK_VERSION(3, 16, 0)
  if (NgraphApp.CoordWin.data.text && font) {
    set_widget_font(NgraphApp.CoordWin.data.text, font);
  }
#else  /* GTK_CHECK_VERSION(3, 16, 0) */
  const char *ptr;
  PangoAttrList *pattr;
  PangoFontDescription *desc;
  GtkLabel *label;

  label = GTK_LABEL(NgraphApp.CoordWin.data.text);

  if (label == NULL)
    return;

  pattr = gtk_label_get_attributes(label);
  if (pattr == NULL) {
    pattr = pango_attr_list_new();
    gtk_label_set_attributes(GTK_LABEL(label), pattr);
  }

  ptr = (font) ? font : "Monospace";

  desc = pango_font_description_from_string(ptr);
  pango_attr_list_change(pattr, pango_attr_font_desc_new(desc));
  pango_font_description_free(desc);
#endif
}
void _HYPlatformGraphicPane::_BuildCharGlyphs(void)
{
	char c[] = "ACGT";
	PangoAttrList*  natl = pango_attr_list_new          ();
	PangoAttribute* pafd = pango_attr_font_desc_new    (theFont);
	pango_attr_list_insert (natl, pafd);
	charCachePangoItems = pango_itemize (screenPContext, c, 0, 4, natl,NULL);
	pango_attr_list_unref (natl);
}
Beispiel #4
0
static void
gimp_combo_tag_entry_style_set (GtkWidget *widget,
                                GtkStyle  *previous_style)
{
  GimpComboTagEntry *entry = GIMP_COMBO_TAG_ENTRY (widget);
  GtkStyle          *style = gtk_widget_get_style (widget);
  GdkColor           color;
  PangoAttribute    *attribute;

  if (GTK_WIDGET_CLASS (parent_class)->style_set)
    GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);

  if (entry->normal_item_attr)
    pango_attr_list_unref (entry->normal_item_attr);
  entry->normal_item_attr = pango_attr_list_new ();

  if (style->font_desc)
    {
      attribute = pango_attr_font_desc_new (style->font_desc);
      pango_attr_list_insert (entry->normal_item_attr, attribute);
    }
  color = style->text[GTK_STATE_NORMAL];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->normal_item_attr, attribute);

  if (entry->selected_item_attr)
    pango_attr_list_unref (entry->selected_item_attr);
  entry->selected_item_attr = pango_attr_list_copy (entry->normal_item_attr);

  color = style->text[GTK_STATE_SELECTED];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->selected_item_attr, attribute);
  color = style->base[GTK_STATE_SELECTED];
  attribute = pango_attr_background_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->selected_item_attr, attribute);

  if (entry->insensitive_item_attr)
    pango_attr_list_unref (entry->insensitive_item_attr);
  entry->insensitive_item_attr = pango_attr_list_copy (entry->normal_item_attr);

  color = style->text[GTK_STATE_INSENSITIVE];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->insensitive_item_attr, attribute);
  color = style->base[GTK_STATE_INSENSITIVE];
  attribute = pango_attr_background_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->insensitive_item_attr, attribute);

  entry->selected_item_color = style->base[GTK_STATE_SELECTED];

  if (entry->arrow_pixbuf)
    {
      g_object_unref (entry->arrow_pixbuf);
      entry->arrow_pixbuf = NULL;
    }
}
void            gwrgtk_button_set_label_font( GtkWidget* _button, const gchar* _fontname, PangoStyle _style, PangoWeight _weight, guint32 _absolute_size_in_device_units)
{
    GtkWidget               *   l   =   gtk_bin_get_child( GTK_BIN(_button) );

    PangoAttrList           *   pal =   pango_attr_list_new();

    PangoFontDescription    *   pfd =   pango_font_description_new();
    pango_font_description_set_family       (pfd, _fontname );
    pango_font_description_set_style        (pfd, _style );
    pango_font_description_set_weight       (pfd, _weight );
    pango_font_description_set_absolute_size(pfd, _absolute_size_in_device_units * PANGO_SCALE);

    PangoAttribute          *   pat =   pango_attr_font_desc_new( pfd );
    pango_attr_list_insert( pal, pat );

    gtk_label_set_attributes( GTK_LABEL(l), pal );
}
void QPushButton::setFont(const QFont &font)
{
    //g_warning("QPushButton::setFont: size:%d, family:%s, text: %s", font.pixelSize(), font.family().latin1(),text().latin1());
    QButton::setFont(font);

#if 0
    GtkWidget *button = getGtkWidget();

    if (button) {
        PangoFontDescription *fd;
        GtkWidget *child,*newchild;
        PangoAttrList* al;
        PangoAttribute* afd;

        child = gtk_bin_get_child(GTK_BIN(button));
        newchild = gtk_label_new(text().utf8());
        fd = createPangoFontDescription(&font);
        gtk_widget_modify_font(button, fd);
        gtk_widget_modify_font(child, fd);
        gtk_container_remove(GTK_CONTAINER(button),child);
        gtk_container_add(GTK_CONTAINER(button),newchild);
        child = newchild;



        afd  = pango_attr_font_desc_new(fd);

        al = gtk_label_get_attributes( GTK_LABEL(child) );
        if (al == NULL)
        {
            al = pango_attr_list_new();
            pango_attr_list_insert(al,afd);
        } else
        {
            pango_attr_list_change(al,afd);
        }

        gtk_label_set_attributes( GTK_LABEL(child), al );
        gtk_widget_show( child );
        //g_warning("child:%x fd,%x",child,fd);
        pango_font_description_free(fd);
    }
#endif
}
Beispiel #7
0
PangoLayout*
dia_font_build_layout(const char* string, DiaFont* font, real height)
{
  PangoLayout* layout;
  PangoAttrList* list;
  PangoAttribute* attr;
  guint length;
  PangoFontDescription *pfd;
  real factor;

  layout = pango_layout_new(dia_font_get_context());

  length = string ? strlen(string) : 0;
  pango_layout_set_text(layout, string, length);

  list = pango_attr_list_new();

  pfd = pango_font_description_copy (font->pfd);
  /* account for difference between size and height as well as between font height and given one */
  factor = dia_font_get_size(font) / dia_font_get_height (font);
  pango_font_description_set_absolute_size (pfd, dcm_to_pdu (height) * factor);
  attr = pango_attr_font_desc_new(pfd);
  pango_font_description_free (pfd);

  attr->start_index = 0;
  attr->end_index = length;
  pango_attr_list_insert(list,attr); /* eats attr */

  pango_layout_set_attributes(layout,list);
  pango_attr_list_unref(list);

  pango_layout_set_indent(layout,0);
  pango_layout_set_justify(layout,FALSE);
  pango_layout_set_alignment(layout,PANGO_ALIGN_LEFT);

  return layout;
}
Beispiel #8
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??? */
  }
}
Beispiel #9
0
static gboolean
span_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;
  const char *gravity_hint = NULL;

  g_markup_parse_context_get_position (context,
				       &line_number, &char_number);

#define CHECK_DUPLICATE(var) G_STMT_START{                              \
	  if ((var) != NULL) {                                          \
	    g_set_error (error, G_MARKUP_ERROR,                         \
			 G_MARKUP_ERROR_INVALID_CONTENT,                \
			 _("Attribute '%s' occurs twice on <span> tag " \
			   "on line %d char %d, may only occur once"),  \
			 names[i], line_number, char_number);           \
	    return FALSE;                                               \
	  }}G_STMT_END
#define CHECK_ATTRIBUTE2(var, name) \
	if (attr_strcmp (names[i], (name)) == 0) { \
	  CHECK_DUPLICATE (var); \
	  (var) = values[i]; \
	  found = TRUE; \
	  break; \
	}
#define CHECK_ATTRIBUTE(var) CHECK_ATTRIBUTE2 (var, G_STRINGIFY (var))

  i = 0;
  while (names[i])
    {
      gboolean found = FALSE;

      switch (names[i][0]) {
      case 'f':
	CHECK_ATTRIBUTE (fallback);
	CHECK_ATTRIBUTE2(desc, "font");
	CHECK_ATTRIBUTE2(desc, "font_desc");
	CHECK_ATTRIBUTE2(family, "face");

	CHECK_ATTRIBUTE2(family, "font_family");
	CHECK_ATTRIBUTE2(size, "font_size");
	CHECK_ATTRIBUTE2(stretch, "font_stretch");
	CHECK_ATTRIBUTE2(style, "font_style");
	CHECK_ATTRIBUTE2(variant, "font_variant");
	CHECK_ATTRIBUTE2(weight, "font_weight");

	CHECK_ATTRIBUTE (foreground);
	CHECK_ATTRIBUTE2 (foreground, "fgcolor");
	break;
      case 's':
	CHECK_ATTRIBUTE (size);
	CHECK_ATTRIBUTE (stretch);
	CHECK_ATTRIBUTE (strikethrough);
	CHECK_ATTRIBUTE (strikethrough_color);
	CHECK_ATTRIBUTE (style);
	break;
      case 'g':
	CHECK_ATTRIBUTE (gravity);
	CHECK_ATTRIBUTE (gravity_hint);
	break;
      case 'l':
	CHECK_ATTRIBUTE (lang);
	CHECK_ATTRIBUTE (letter_spacing);
	break;
      case 'u':
	CHECK_ATTRIBUTE (underline);
	CHECK_ATTRIBUTE (underline_color);
	break;
      default:
	CHECK_ATTRIBUTE (background);
	CHECK_ATTRIBUTE2 (background, "bgcolor");
	CHECK_ATTRIBUTE2(foreground, "color");
	CHECK_ATTRIBUTE (rise);
	CHECK_ATTRIBUTE (variant);
	CHECK_ATTRIBUTE (weight);
	break;
      }

      if (!found)
	{
	  g_set_error (error, G_MARKUP_ERROR,
		       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
		       _("Attribute '%s' is not allowed on the <span> tag "
			 "on line %d char %d"),
		       names[i], line_number, char_number);
	  return FALSE;
	}

      ++i;
    }

  /* Parse desc first, then modify it with other font-related attributes. */
  if (G_UNLIKELY (desc))
    {
      PangoFontDescription *parsed;

      parsed = pango_font_description_from_string (desc);
      if (parsed)
	{
	  add_attribute (tag, pango_attr_font_desc_new (parsed));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, pango_font_description_get_size (parsed));
	  pango_font_description_free (parsed);
	}
    }

  if (G_UNLIKELY (family))
    {
      add_attribute (tag, pango_attr_family_new (family));
    }

  if (G_UNLIKELY (size))
    {
      if (g_ascii_isdigit (*size))
	{
	  const char *end;
	  gint n;

/* cap size from the top at an arbitrary 2048 */
#define MAX_SIZE (2048 * PANGO_SCALE)

	  if ((end = size, !pango_scan_int (&end, &n)) || *end != '\0' || n < 0 || n > MAX_SIZE)
	    {
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Value of 'size' attribute on <span> tag on line %d "
			     "could not be parsed; should be an integer less than %d, or a "
			     "string such as 'small', not '%s'"),
			   line_number, MAX_SIZE+1, size);
	      goto error;
	    }

	  add_attribute (tag, pango_attr_size_new (n));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, n);
	}
      else if (strcmp (size, "smaller") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta -= 1;
	      tag->scale_level -= 1;
	    }
	}
      else if (strcmp (size, "larger") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta += 1;
	      tag->scale_level += 1;
	    }
	}
      else if (parse_absolute_size (tag, size))
	; /* nothing */
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Value of 'size' attribute on <span> tag on line %d "
			 "could not be parsed; should be an integer, or a "
			 "string such as 'small', not '%s'"),
		       line_number, size);
	  goto error;
	}
    }

  if (G_UNLIKELY (style))
    {
      PangoStyle pango_style;

      if (pango_parse_style (style, &pango_style, FALSE))
	add_attribute (tag, pango_attr_style_new (pango_style));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'style' attribute "
			 "on <span> tag, line %d; valid values are "
			 "'normal', 'oblique', 'italic'"),
		       style, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (weight))
    {
      PangoWeight pango_weight;

      if (pango_parse_weight (weight, &pango_weight, FALSE))
	add_attribute (tag,
		       pango_attr_weight_new (pango_weight));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'weight' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'light', 'ultrabold' or a number"),
		       weight, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (variant))
    {
      PangoVariant pango_variant;

      if (pango_parse_variant (variant, &pango_variant, FALSE))
	add_attribute (tag, pango_attr_variant_new (pango_variant));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'variant' "
			 "attribute on <span> tag, line %d; valid values are "
			 "'normal', 'smallcaps'"),
		       variant, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (stretch))
    {
      PangoStretch pango_stretch;

      if (pango_parse_stretch (stretch, &pango_stretch, FALSE))
	add_attribute (tag, pango_attr_stretch_new (pango_stretch));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'stretch' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'condensed', "
			 "'ultraexpanded', 'normal'"),
		       stretch, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (foreground))
    {
      PangoColor color;

      if (!span_parse_color ("foreground", foreground, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (background))
    {
      PangoColor color;

      if (!span_parse_color ("background", background, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (underline))
    {
      PangoUnderline ul = PANGO_UNDERLINE_NONE;

      if (!span_parse_enum ("underline", underline, PANGO_TYPE_UNDERLINE, &ul, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_new (ul));
    }

  if (G_UNLIKELY (underline_color))
    {
      PangoColor color;

      if (!span_parse_color ("underline_color", underline_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (gravity))
    {
      PangoGravity gr = PANGO_GRAVITY_SOUTH;

      if (!span_parse_enum ("gravity", gravity, PANGO_TYPE_GRAVITY, &gr, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_new (gr));
    }

  if (G_UNLIKELY (gravity_hint))
    {
      PangoGravityHint hint = PANGO_GRAVITY_HINT_NATURAL;

      if (!span_parse_enum ("gravity_hint", gravity_hint, PANGO_TYPE_GRAVITY_HINT, &hint, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_hint_new (hint));
    }

  if (G_UNLIKELY (strikethrough))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_new (b));
    }

  if (G_UNLIKELY (strikethrough_color))
    {
      PangoColor color;

      if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (fallback))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("fallback", fallback, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_fallback_new (b));
    }

  if (G_UNLIKELY (rise))
    {
      gint n = 0;

      if (!span_parse_int ("rise", rise, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_rise_new (n));
    }

  if (G_UNLIKELY (letter_spacing))
    {
      gint n = 0;

      if (!span_parse_int ("letter_spacing", letter_spacing, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_letter_spacing_new (n));
    }

  if (G_UNLIKELY (lang))
    {
      add_attribute (tag,
		     pango_attr_language_new (pango_language_from_string (lang)));
    }

  return TRUE;

 error:

  return FALSE;
}
Beispiel #10
0
/**
 * 填充群组数据(grpinf)到数据集(model)指定位置(iter).
 * @param model model
 * @param iter iter
 * @param grpinf class GroupInfo
 */
void palTreeModelFillFromGroupInfo(GtkTreeModel *model,
                                   GtkTreeIter *iter,
                                   const GroupInfo *grpinf,
                                   const char* font) {
  GtkIconTheme *theme;
  GdkPixbuf *cpixbuf, *opixbuf= nullptr;
  PangoAttrList *attrs;
  PangoAttribute *attr;
  gchar *info, *extra;
  PalInfo *pal;
  GError* error = nullptr;

  /* 创建图标 */
  theme = gtk_icon_theme_get_default();
  if (grpinf->type == GROUP_BELONG_TYPE_REGULAR) {
    pal = static_cast<PalInfo *>(grpinf->member->data);
    auto file = iptux_erase_filename_suffix(pal->iconfile);
    cpixbuf = gtk_icon_theme_load_icon(theme, file, MAX_ICONSIZE,
                                       GtkIconLookupFlags(0), &error);
    if(cpixbuf == nullptr) {
      LOG_WARN("gtk_icon_theme_load_icon failed: [%d] %s", error->code, error->message);
      g_error_free(error);
      error = nullptr;
    } else {
      opixbuf = GDK_PIXBUF(g_object_ref(cpixbuf));
    }
    g_free(file);
  } else {
    cpixbuf = gtk_icon_theme_load_icon(theme, "tip-hide", MAX_ICONSIZE,
                                       GtkIconLookupFlags(0), NULL);
    opixbuf = gtk_icon_theme_load_icon(theme, "tip-show", MAX_ICONSIZE,
                                       GtkIconLookupFlags(0), NULL);
  }

  /* 创建主信息 */
  if (grpinf->type == GROUP_BELONG_TYPE_REGULAR) {
    char ipstr[INET_ADDRSTRLEN];
    pal = static_cast<PalInfo *>(grpinf->member->data);
    inet_ntop(AF_INET, &pal->ipv4, ipstr, INET_ADDRSTRLEN);
    info = g_strdup_printf("%s\n%s", pal->name, ipstr);
  } else
    info = g_strdup(grpinf->name);

  /* 创建扩展信息 */
  if (grpinf->type == GROUP_BELONG_TYPE_REGULAR)
    extra = NULL;
  else
    extra = g_strdup_printf("(%u)", g_slist_length(grpinf->member));

  /* 创建字体风格 */
  attrs = pango_attr_list_new();
  if (grpinf->type == GROUP_BELONG_TYPE_REGULAR) {
    auto dspt = pango_font_description_from_string(font);
    attr = pango_attr_font_desc_new(dspt);
    pango_attr_list_insert(attrs, attr);
    pango_font_description_free(dspt);
  } else {
    attr = pango_attr_size_new(8192);
    pango_attr_list_insert(attrs, attr);
    attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
    pango_attr_list_insert(attrs, attr);
    attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
    pango_attr_list_insert(attrs, attr);
  }

  /* 设置相应的数据 */
  gtk_tree_store_set(GTK_TREE_STORE(model), iter,
                     PalTreeModelColumn ::CLOSED_EXPANDER, cpixbuf,
                     PalTreeModelColumn ::OPEN_EXPANDER, opixbuf,
                     PalTreeModelColumn ::INFO, info,
                     PalTreeModelColumn ::EXTRAS, extra,
                     PalTreeModelColumn ::STYLE, attrs,
                     PalTreeModelColumn ::COLOR, &color,
                     PalTreeModelColumn ::DATA, grpinf,
                     -1);

  /* 释放资源 */
  if (cpixbuf) g_object_unref(cpixbuf);
  if (opixbuf) g_object_unref(opixbuf);
  g_free(info);
  g_free(extra);
  pango_attr_list_unref(attrs);
}