Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2004:
[Freeciv-Dev] (PR#10778) demo: SVG in the code
Home

[Freeciv-Dev] (PR#10778) demo: SVG in the code

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10778) demo: SVG in the code
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 28 Oct 2004 23:14:39 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=10778 >

This patch demonstrates how SVG can be used in the code.

A load_svgfile() function is added to graphics.c.  In gui-gtk-2.0 this 
uses librsvg (which loads SVG files into pixbufs).  As always finding an 
implementation for other clients will be the trick.

All flag graphics are loaded and rendered directly from SVG.  This takes 
about 4 seconds on my 500 mhz machine.  Of course the black borders 
aren't present but adding these wouldn't be too hard.

Using this for flags may be overkill.  In most cases the tileset knows 
what dimensions it wants its flags to be.  It would be more useful to 
use it for theme graphics like the intro gfx.

When we have more data being loaded we need some sort of dynamic loading 
mechanism.  This is needed for SVG files, to ammortize the cost of 
loading, as well as for animation graphics just because there are so 
many of them.

jason

Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.208
diff -u -r1.208 tilespec.c
--- client/tilespec.c   23 Oct 2004 19:10:26 -0000      1.208
+++ client/tilespec.c   29 Oct 2004 06:09:46 -0000
@@ -1813,11 +1813,16 @@
 ***********************************************************************/
 void tilespec_setup_nation_flag(int id)
 {
-  struct nation_type *this_nation = get_nation_by_idx(id);
+  struct nation_type *nation = get_nation_by_idx(id);
+  char filename_base[strlen(nation->flag_graphic_str) + 10], *filename;
 
-  this_nation->flag_sprite = 
lookup_sprite_tag_alt(this_nation->flag_graphic_str, 
-                                           this_nation->flag_graphic_alt,
-                                           TRUE, "nation", this_nation->name);
+
+  assert(strlen(nation->flag_graphic_str) > 2);
+  my_snprintf(filename_base, sizeof(filename_base), "flags/%s.svg",
+             nation->flag_graphic_str + 2);
+  filename = datafilename_required(filename_base);
+  nation->flag_sprite = load_svgfile(filename, 28, 200);
+  assert(nation->flag_sprite != NULL);
 
   /* should probably do something if NULL, eg generic default? */
 }
Index: client/gui-gtk-2.0/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.c,v
retrieving revision 1.26
diff -u -r1.26 graphics.c
--- client/gui-gtk-2.0/graphics.c       3 Jun 2004 13:53:42 -0000       1.26
+++ client/gui-gtk-2.0/graphics.c       29 Oct 2004 06:09:47 -0000
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include <gtk/gtk.h>
+#include <librsvg-2/librsvg/rsvg.h>
 
 #include "gtkpixcomm.h"
 
@@ -330,6 +331,25 @@
   return ext;
 }
 
+static struct Sprite *pixbuf_to_sprite(GdkPixbuf *im)
+{
+  int w, h;
+  SPRITE *mysprite = fc_malloc(sizeof(*mysprite));
+
+  w = gdk_pixbuf_get_width(im);
+  h = gdk_pixbuf_get_height(im);
+  gdk_pixbuf_render_pixmap_and_mask(im, &mysprite->pixmap,
+                                   &mysprite->mask, 1);
+
+  mysprite->has_mask  = (mysprite->mask != NULL);
+  mysprite->width     = w;
+  mysprite->height    = h;
+
+  mysprite->pixbuf    = NULL; /* ??? */
+
+  return mysprite;
+}
+
 /***************************************************************************
 ...
 ***************************************************************************/
@@ -337,23 +357,34 @@
 {
   GdkPixbuf *im;
   SPRITE    *mysprite;
-  int       w, h;
 
   if (!(im = gdk_pixbuf_new_from_file(filename, NULL))) {
     freelog(LOG_FATAL, "Failed reading graphics file: %s", filename);
     exit(EXIT_FAILURE);
   }
 
-  mysprite=fc_malloc(sizeof(struct Sprite));
+  mysprite = pixbuf_to_sprite(im);
 
-  w = gdk_pixbuf_get_width(im); h = gdk_pixbuf_get_height(im);
-  gdk_pixbuf_render_pixmap_and_mask(im, &mysprite->pixmap, &mysprite->mask, 1);
+  g_object_unref(im);
 
-  mysprite->has_mask  = (mysprite->mask != NULL);
-  mysprite->width     = w;
-  mysprite->height    = h;
+  return mysprite;
+}
 
-  mysprite->pixbuf    = NULL;
+
+/***************************************************************************
+  Load an SVG file into a Sprite.
+***************************************************************************/
+struct Sprite *load_svgfile(const char *filename,
+                           int max_width, int max_height)
+{
+  GdkPixbuf *im;
+  SPRITE *mysprite;
+  GError *error;
+
+  im = rsvg_pixbuf_from_file_at_max_size(filename,
+                                        max_width, max_height, &error);
+
+  mysprite = pixbuf_to_sprite(im);
 
   g_object_unref(im);
 
Index: client/include/graphics_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/graphics_g.h,v
retrieving revision 1.10
diff -u -r1.10 graphics_g.h
--- client/include/graphics_g.h 24 Mar 2004 06:18:19 -0000      1.10
+++ client/include/graphics_g.h 29 Oct 2004 06:09:47 -0000
@@ -28,6 +28,8 @@
 const char **gfx_fileextensions(void);
 
 struct Sprite *load_gfxfile(const char *filename);
+struct Sprite *load_svgfile(const char *filename,
+                           int max_width, int max_height);
 struct Sprite *crop_sprite(struct Sprite *source,
                           int x, int y, int width, int height,
                           struct Sprite *mask,
Index: data/nation/swiss.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/nation/swiss.ruleset,v
retrieving revision 1.4
diff -u -r1.4 swiss.ruleset
--- data/nation/swiss.ruleset   9 Sep 2004 18:01:42 -0000       1.4
+++ data/nation/swiss.ruleset   29 Oct 2004 06:09:47 -0000
@@ -8,7 +8,7 @@
        "Christoph Blocher"
 leader_sex="Male", "Male", "Male", "Male", "Male",
   "Female", "Male", "Male"
-flag="f.switzerland"
+flag="f.swiss"
 flag_alt = "-"
 city_style = "European"
 
Index: m4/gtk2-client.m4
===================================================================
RCS file: /home/freeciv/CVS/freeciv/m4/gtk2-client.m4,v
retrieving revision 1.7
diff -u -r1.7 gtk2-client.m4
--- m4/gtk2-client.m4   27 Mar 2004 21:55:57 -0000      1.7
+++ m4/gtk2-client.m4   29 Oct 2004 06:09:47 -0000
@@ -8,14 +8,17 @@
   if test "$client" = "gtk-2.0" || test "$client" = yes ; then
     AM_PATH_GTK_2_0(2.2.1,
       [
-        client="gtk-2.0"
-        CLIENT_CFLAGS="$GTK_CFLAGS"
-        CLIENT_LIBS="$GTK_LIBS"
-        if test x"$MINGW32" = "xyes"; then
-          dnl Required to compile gtk2 on Windows platform
-          CFLAGS="$CFLAGS -mms-bitfields"
-          CLIENT_LDFLAGS="$LDFLAGS -mwindows"
-        fi
+       AC_CHECK_LIB([rsvg-2], [rsvg_pixbuf_from_file_at_max_size],
+          [
+            client="gtk-2.0"
+            CLIENT_CFLAGS="$GTK_CFLAGS"
+            CLIENT_LIBS="$GTK_LIBS -lrsvg-2"
+            if test x"$MINGW32" = "xyes"; then
+              dnl Required to compile gtk2 on Windows platform
+              CFLAGS="$CFLAGS -mms-bitfields"
+              CLIENT_LDFLAGS="$LDFLAGS -mwindows"
+            fi
+          ], [FC_NO_CLIENT([gtk-2.0], [rsvg library not found])])
       ],
       [
         FC_NO_CLIENT([gtk-2.0], [GTK+-2.0 libraries not found])

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#10778) demo: SVG in the code, Jason Short <=