Как я могу динамически изменить цвет элемента в изображении SVG в GTK? - PullRequest
2 голосов
/ 24 марта 2012

Следующие две строки кода загружают изображение из файла SVG и устанавливают его в качестве значка для окна:

GdkPixbuf *icon = gdk_pixbuf_new_from_file("icon.svg", NULL);
gtk_window_set_icon(GTK_WINDOW(win), icon);

Этот файл SVG содержит, помимо прочего, прямоугольник, определенный как:

<rect
   style="fill:#000000"
   id="screen"
   ... />

Я хотел бы динамически изменить цвет этого элемента rect после того, как я загрузил файл, но перед тем, как установить его в качестве значка для окна.

Если я вручную изменю атрибут style в этом элементе файла на диске перед тем, как запустить программу, это даст желаемый эффект. Но я бы хотел, чтобы она была установлена ​​самой программой, чтобы она соответствовала выбранному цвету.

(Это позволяет различать несколько похожих окон в меню переключателя окон среди других мест)

1 Ответ

3 голосов
/ 25 марта 2012

Я нашел ответ на этот вопрос из IRC (# gtk + на irc.gnome.org) и чтения собственного исходного кода GTK.

Ответ включает в себя создание строки, которая устанавливает таблицу стилей ииспользует xinclude XML для извлечения исходного изображения.

GdkPixbuf *load_icon(char *background)
{
  /* This technique stolen from 
   *   http://git.gnome.org/browse/gtk+/tree/gtk/gtkicontheme.c#n3180
   */

  gchar *str = g_strconcat(
      "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
      "<svg version=\"1.1\"\n"
      "     xmlns=\"http://www.w3.org/2000/svg\"\n"
      "     xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n"
      "     width=\"64\"\n"
      "     height=\"64\">\n"
      "  <style type=\"text/css\">\n"
      "    #screen {\n"
      "      fill: ", background, " !important;\n"
      "    }\n"
      "  </style>\n"
      "  <xi:include href=\"" PANGOTERM_SHAREDIR "/pangoterm.svg" "\"/>\n"
      "</svg>",
    NULL);

  GInputStream *stream = g_memory_input_stream_new_from_data(str, -1, g_free);

  GdkPixbuf *ret = gdk_pixbuf_new_from_stream(stream, NULL, NULL);

  g_object_unref(stream);

  return ret;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...