[gnome-robots] Rewrite GamesPreimage in Vala



commit 244fcf51a5e6af1e315b40f3d6473f88ced1e948
Author: Andrey Kutejko <andy128k gmail com>
Date:   Sun Aug 23 21:10:43 2020 +0200

    Rewrite GamesPreimage in Vala

 src/games-preimage.c | 475 ---------------------------------------------------
 src/games-preimage.h |  89 ----------
 src/graphics.c       |   1 -
 src/meson.build      |   2 +-
 src/preimage.vala    | 215 +++++++++++++++++++++++
 5 files changed, 216 insertions(+), 566 deletions(-)
---
diff --git a/src/graphics.c b/src/graphics.c
index 6be5b2e..7aee3d0 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -37,7 +37,6 @@
 #include "game.h"
 #include "gnome-robots.h"
 #include "properties.h"
-#include "games-preimage.h"
 
 /**********************************************************************/
 
diff --git a/src/meson.build b/src/meson.build
index 4946d13..5705dc7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -2,6 +2,7 @@ vala_sources = files(
     'image-suffix-list.vala',
     'file-list.vala',
     'find-file.vala',
+    'preimage.vala',
 )
 
 vala_lib = static_library('riiv',
@@ -27,7 +28,6 @@ sources = files(
     'game.c',
     'gameconfig.c',
     'games-controls.c',
-    'games-preimage.c',
     'gnome-robots.c',
     'graphics.c',
     'keyboard.c',
diff --git a/src/preimage.vala b/src/preimage.vala
new file mode 100644
index 0000000..e905473
--- /dev/null
+++ b/src/preimage.vala
@@ -0,0 +1,215 @@
+/*
+  Copyright © 2004 Richard Hoelscher
+  Copyright © 2007 Christian Persch
+
+  This library is free software; you can redistribute it and'or modify
+  it under the terms of the GNU Library General Public License as published
+  by the Free Software Foundation; either version 3, or (at your option)
+  any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public License
+  along with this library; if not, see <http://www.gnu.org/licenses/>.  */
+
+/* Authors:   Richard Hoelscher <rah rahga com> */
+
+/* Cache raster and vector images and render them to a specific size. */
+
+using Cairo;
+using Gdk;
+using Rsvg;
+
+public class GamesPreimage {
+    private int width = 0;
+    private int height = 0;
+
+    private Handle? rsvg_handle = null;
+    private FontOptions? font_options;
+
+    /* raster pixbuf data */
+    private Pixbuf? pixbuf;
+
+    private bool scalable = false;
+
+    public GamesPreimage () {}
+
+    public GamesPreimage.from_file (string filename) throws GLib.Error {
+        try {
+            rsvg_handle = new Handle.from_file (filename);
+        } catch (GLib.Error e) {
+            // ignore
+        }
+
+        if (rsvg_handle != null) {
+            scalable = true;
+
+            var data = rsvg_handle.get_dimensions ();
+
+            if (data.width == 0 || data.height == 0) {
+                throw new PixbufError.FAILED ("Image has zero extent");
+            }
+
+            width = data.width;
+            height = data.height;
+        } else {
+            /* Not an SVG */
+            scalable = false;
+
+            pixbuf = new Pixbuf.from_file (filename);
+            width = pixbuf.get_width ();
+            height = pixbuf.get_height ();
+        }
+    }
+
+    /**
+     * Turns on antialising of preimage, if it contains an SVG image.
+     */
+    public void set_font_options (owned FontOptions? font_options) {
+        this.font_options = (owned) font_options;
+    }
+
+    /**
+     * @width: the desired width
+     * @height: the desired height
+     *
+     * Creates a #GdkPixbuf at the specified @width and @height.
+     **/
+    public Pixbuf render (int width, int height)
+        requires (width > 0 && height > 0)
+    {
+        if (scalable) {
+            /* Render vector image */
+            return render_sub (null,
+                               width,
+                               height,
+                               0.0, 0.0,
+                               ((double) width) / ((double) this.width),
+                               ((double) height) / ((double) this.height));
+        } else {
+            /* Render raster image */
+            return pixbuf.scale_simple (width, height, InterpType.BILINEAR);
+        }
+    }
+
+    /**
+     * @width: the desired width
+     * @height: the desired height
+     *
+     * Renders from @preimage's image at the specified
+     * @width and @height to @cr.
+     **/
+    private void render_cairo (Context cr, int width, int height)
+        requires (width > 0 && height > 0)
+    {
+        if (scalable) {
+            /* Render vector image */
+            render_cairo_sub (cr,
+                              null,
+                              width,
+                              height,
+                              0.0, 0.0,
+                              ((double) width) / ((double) this.width),
+                              ((double) height) / ((double) this.height));
+        } else {
+            /* FIXMEchpe: we don't really need this fallback anymore */
+            /* Render raster image */
+            var scaled_pixbuf = pixbuf.scale_simple (width, height, InterpType.BILINEAR);
+
+            cr.save ();
+            cairo_set_source_pixbuf (cr, scaled_pixbuf, 0, 0);
+            cr.paint ();
+            cr.restore ();
+        }
+    }
+
+    /**
+     * @node: a SVG node ID (starting with "#"), or %NULL
+     * @width: the width of the clip region
+     * @height: the height of the clip region
+     * @xoffset: the x offset of the clip region
+     * @yoffset: the y offset of the clip region
+     * @xzoom: the x zoom factor
+     * @yzoom: the y zoom factor
+     *
+     * Creates a #GdkPixbuf with the dimensions @width by @height,
+     * and renders the subimage of @preimage specified by @node to it,
+     * transformed by @xzoom, @yzoom and offset by @xoffset and @yoffset,
+     * clipped to @width and @height.
+     * If @node is NULL, the whole image is rendered into tha clip region.
+     *
+     * Returns: (transfer full) (allow-none): a new #GdkPixbuf, or %NULL if there was an error or @preimage
+     * isn't a scalable SVG image
+     */
+    private Pixbuf? render_sub (string? node,
+                               int width, int height,
+                               double xoffset, double yoffset,
+                               double xzoom, double yzoom) {
+        if (!scalable)
+            return null;
+
+        var surface = new ImageSurface (Format.ARGB32, width, height);
+        var cr = new Context (surface);
+        render_cairo_sub (cr, node, width, height, xoffset, yoffset, xzoom, yzoom);
+        return Gdk.pixbuf_get_from_surface (surface, 0, 0, width, height);
+    }
+
+    /**
+     * @node: a SVG node ID (starting with "#"), or %NULL
+     * @width: the width of the clip region
+     * @height: the height of the clip region
+     * @xoffset: the x offset of the clip region
+     * @yoffset: the y offset of the clip region
+     * @xzoom: the x zoom factor
+     * @yzoom: the y zoom factor
+     **/
+    private void render_cairo_sub (Context cr,
+                                  string? node,
+                                  int width,
+                                  int height,
+                                  double xoffset,
+                                  double yoffset,
+                                  double xzoom,
+                                  double yzoom) {
+        if (!scalable)
+            return;
+
+        if (font_options != null) {
+            cr.set_antialias (font_options.get_antialias ());
+            cr.set_font_options (font_options);
+        }
+
+        Cairo.Matrix matrix = Cairo.Matrix.identity ();
+        matrix.scale (xzoom, yzoom);
+        matrix.translate (xoffset, yoffset);
+
+        cr.set_matrix (matrix);
+
+        rsvg_handle.render_cairo_sub (cr, node);
+    }
+
+    /**
+     * Returns true iff preimage contains an SVG image
+     */
+    public bool is_scalable () {
+        return scalable;
+    }
+
+    /**
+     * natural width of the image
+     */
+    public int get_width () {
+        return width;
+    }
+
+    /**
+     * natural height of the image
+     */
+    public int get_height () {
+        return height;
+    }
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]