[Gtk-sharp-list] Simple Custom Image Support (SVG too)

José Alexandre Antunes Faria spigaz@gmail.com
Fri, 08 Apr 2005 10:10:32 +0100


--=-L5hkkIL+3ras/jAUfIt4
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi there guys,

This is my first experiment in trying to submit a patch.

The purpose is to extend the funcionallity of Gdk.Pixbuf and Rsvg.Pixbuf
to allow more easily the creation of images of custom sizes, specially
when they are resources, streams or byte[].

As you will soon see, I just extended the existing interfaces, therefor
compatibility remains ;).

When you give a filename to rsvg it can guess the file type by its
ending svg or svgz, but when you feed him a stream or a buffer, there is
no file name, there for I introduced a test that when its not able to
read svg, it then tries to read an svgz.

I could have done that to Gdk.Pixbuf also, but that would imply that Gdk
would depend on Rsvg, I know that under the hood thats what happens, but
on top (Gdk.Pixbuf) can't read svgz (but it reads svg fine). You can
feed it to him and then it borks.

Most likelly they will fix this under the hood, for now I could use rsvg
to read it, but I don't think you would like that, besides it introduces
a circular dependency, doesn't it?

I know that I'm not alone in wanting this to be submited for your
aproval, but I made it, so here I am awaiting you decision.

In the patch there are lines //changed // added, those lines are for
rookies like me that prefer to read the source file and not the diff.

Thanks Guys,

Keep up the good work, and be gentle,

SpigaZ Out

--=-L5hkkIL+3ras/jAUfIt4
Content-Disposition: attachment; filename=custom_size_image.patch
Content-Type: text/x-patch; name=custom_size_image.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

Index: rsvg/Handle.custom
===================================================================
--- rsvg/Handle.custom	(revision 0)
+++ rsvg/Handle.custom	(revision 0)
@@ -0,0 +1,60 @@
+// Rsvg.Pixbuf.custom - Rsvg Pixbuf class customizations
+//
+// Author: John Luke  <jluke@cfl.rr.com>
+//
+// Copyright (C) 2004 Novell, Inc.
+//
+// This code is inserted after the automatically generated code.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of version 2 of the Lesser GNU General
+// Public License as published by the Free Software Foundation.
+//
+// This program 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+	// added
+	public Handle(uint width, uint height) : this()
+	{
+		HandleSize size = new HandleSize(width, height);
+		SetSizeCallback(new Rsvg.SizeFunc(size.OnSizeRequest));
+	}
+	public static Handle NewGz(uint width, uint height)
+	{
+		Handle handle = NewGz();
+
+		HandleSize size = new HandleSize(width, height);
+		handle.SetSizeCallback(new Rsvg.SizeFunc(size.OnSizeRequest));
+
+		return handle;
+	}
+	// added
+	public void SetSizeCallback(Rsvg.SizeFunc size_func) 
+	{
+			RsvgSharp.SizeFuncWrapper size_func_wrapper = new RsvgSharp.SizeFuncWrapper (size_func);
+			rsvg_handle_set_size_callback(Handle, size_func_wrapper.NativeDelegate, System.IntPtr.Zero, System.IntPtr.Zero);
+	}
+	// added
+	public class HandleSize
+	{
+		public uint _width;
+		public uint _height;
+		
+		public HandleSize(uint width, uint height)
+		{
+			_width = width;
+			_height = height;
+		}
+		public void OnSizeRequest(out int width, out int height) 
+		{
+			width = (int)_width;
+			height = (int)_height;
+		}
+	}
Index: rsvg/Pixbuf.custom
===================================================================
--- rsvg/Pixbuf.custom	(revision 42674)
+++ rsvg/Pixbuf.custom	(working copy)
@@ -20,21 +20,47 @@
 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 // Boston, MA 02111-1307, USA.
 
+	// added
+	public static Gdk.Pixbuf LoadFromResource (System.Reflection.Assembly assembly, string resource)
+	{
+		if (resource == null)
+			throw new ArgumentNullException ("resource");
+		
+		using(System.IO.Stream s = assembly.GetManifestResourceStream (resource))
+		{
+			if (s == null)
+				throw new ArgumentException ("resource must be a valid resource name of 'assembly'.");
+
+			return LoadFromStream (s);
+		}
+	}
+	// changed
 	public static Gdk.Pixbuf LoadFromResource (string resource)
 	{
+		return LoadFromResource(System.Reflection.Assembly.GetCallingAssembly(), resource);
+	}
+	// added
+	public static Gdk.Pixbuf LoadFromResource (System.Reflection.Assembly assembly, string resource, uint width, uint height)
+	{
 		if (resource == null)
 			throw new ArgumentNullException ("resource");
 		
-		System.IO.Stream s = System.Reflection.Assembly.GetCallingAssembly ().GetManifestResourceStream (resource);
-		if (s == null)
-			throw new ArgumentException ("resource must be a valid resource name of 'assembly'.");
+		using(System.IO.Stream s = assembly.GetManifestResourceStream (resource))
+		{
+			if (s == null)
+				throw new ArgumentException ("resource must be a valid resource name of 'assembly'.");
 
-		return LoadFromStream (s);
+			return LoadFromStream (s, width, height);
+		}
 	}
-
-	public static Gdk.Pixbuf LoadFromStream (System.IO.Stream input)
+	// added
+	public static Gdk.Pixbuf LoadFromResource (string resource, uint width, uint height)
 	{
-		Handle loader = new Handle ();
+		return LoadFromResource(System.Reflection.Assembly.GetCallingAssembly(), resource, width, height);
+	}
+	// added
+	private static Gdk.Pixbuf LoadFromStreamAux(Handle loader, System.IO.Stream input)
+	{
 		byte [] buffer = new byte [8192];
 		int n;                                                                                 
 		while ((n = input.Read (buffer, 0, 8192)) != 0)
@@ -43,3 +69,63 @@
 		loader.Close ();
 		return loader.Pixbuf;
 	}
+	// added
+	public static Gdk.Pixbuf LoadFromStream(System.IO.Stream input, uint width, uint height)
+	{
+		long position = input.Position;
+
+		Gdk.Pixbuf pixbuf = LoadFromStreamAux(new Handle(width, height), input);
+		if(pixbuf!=null)
+		{
+			return pixbuf;
+		}
+		else
+		{
+			input.Position = position;
+			return LoadFromStreamAux(Handle.NewGz(width, height), input);
+		}
+	}
+	// added
+	public static Gdk.Pixbuf LoadFromStream(System.IO.Stream input)
+	{
+		long position = input.Position;
+
+		Gdk.Pixbuf pixbuf = LoadFromStreamAux(new Handle(), input);
+		if(pixbuf!=null)
+		{
+			return pixbuf;
+		}
+		else
+		{
+			input.Position = position;
+			return LoadFromStreamAux(Handle.NewGz(), input);
+		}
+	}
+	// added
+	private static Gdk.Pixbuf LoadFromBuffer(Handle loader, byte[] buffer)
+	{
+		loader.Write(buffer, (uint)buffer.Length);
+			
+		loader.Close();
+		return loader.Pixbuf;
+	}
+	// added
+	public static Gdk.Pixbuf LoadFromBuffer(byte[] buffer)
+	{
+		Gdk.Pixbuf pixbuf = LoadFromBuffer(new Handle(), buffer);
+		
+		if(pixbuf!=null)
+			return pixbuf;
+		else
+			return LoadFromBuffer(Handle.NewGz(), buffer);
+	}
+	// added
+	public static Gdk.Pixbuf LoadFromBuffer(byte[] buffer, uint width, uint height)
+	{
+		Gdk.Pixbuf pixbuf = LoadFromBuffer(new Handle(width, height), buffer);
+		
+		if(pixbuf!=null)
+			return pixbuf;
+		else
+			return LoadFromBuffer(Handle.NewGz(width, height), buffer);
+	}
Index: gdk/PixbufLoader.custom
===================================================================
--- gdk/PixbufLoader.custom	(revision 42674)
+++ gdk/PixbufLoader.custom	(working copy)
@@ -49,18 +49,49 @@
 			while ((n = input.Read (buffer, 0, 8192)) != 0)
 				Write (buffer, (uint) n);
 		}
+		// added
+		public PixbufLoader (string file, uint width, uint height) : this ()
+		{
+			SetSize((int)width, (int)height);
+			
+			using(System.IO.FileStream stream = new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read))
+			{
+				InitFromStream(stream);
+			}
+		}
 		
+		// changed
 		public PixbufLoader (System.IO.Stream stream) : this ()
 		{
+			InitFromStream(stream);
+		}
+		
+		// added
+		private void InitFromStream (System.IO.Stream stream)
+		{
 			try {
 				LoadFromStream (stream);
 			} finally {
 				Close ();
 			}
 		}
+		
+		// added
+		public PixbufLoader (System.IO.Stream stream, uint width, uint height) : this()
+		{
+			SetSize((int)width, (int)height);
+			InitFromStream(stream);
+		}
 
+		// changed
 		public PixbufLoader (System.Reflection.Assembly assembly, string resource) : this ()
 		{
+			InitFromAssemblyResource(assembly, resource);
+		}
+		
+		// added
+		private void InitFromAssemblyResource(System.Reflection.Assembly assembly, string resource)
+		{
 			try {
 				if (assembly == null)
 					assembly = System.Reflection.Assembly.GetCallingAssembly ();
@@ -77,6 +108,37 @@
 				Close ();
 			}
 		}
+		
+		// added
+		public PixbufLoader (System.Reflection.Assembly assembly, string resource, uint width, uint height) : this ()
+		{
+			SetSize((int)width, (int)height);
+			InitFromAssemblyResource(assembly, resource);
+		}
+		
+		// added
+		public PixbufLoader (byte[] buffer) : this()
+		{
+			InitFromBuffer(buffer);
+		}
+		
+		// added
+		private void InitFromBuffer (byte[] buffer)
+		{
+			try {
+				Write (buffer, (uint)buffer.Length);
+			} finally {
+				Close ();
+			}
+		}
+		
+		// added
+		public PixbufLoader (byte[] buffer, uint width, uint height) : this()
+		{
+			SetSize((int)width, (int)height);
+			InitFromBuffer(buffer);
+		}
+		
 
 		static public PixbufLoader LoadFromResource (string resource)
 		{
Index: gdk/Pixbuf.custom
===================================================================
--- gdk/Pixbuf.custom	(revision 42674)
+++ gdk/Pixbuf.custom	(working copy)
@@ -94,17 +94,47 @@
 
 		public Pixbuf (System.IO.Stream stream) : base (new PixbufLoader (stream).PixbufHandle) {}
 
+		// added
+		public Pixbuf (System.IO.Stream stream, uint width, uint height) : base(new PixbufLoader (stream, width, height).PixbufHandle) {}
+
+		// added
+		public Pixbuf(string file, uint width, uint height) : base(new PixbufLoader (file, width, height).PixbufHandle) { }
+
+		// changed
 		public Pixbuf (System.Reflection.Assembly assembly, string resource) : base (IntPtr.Zero)
 		{
+			Raw = new PixbufLoader (CheckAssembly(assembly), resource).PixbufHandle;
+		}
+		// added
+		private System.Reflection.Assembly CheckAssembly(System.Reflection.Assembly assembly)
+		{
 			if (assembly == null)
-				assembly = System.Reflection.Assembly.GetCallingAssembly ();
-			Raw = new PixbufLoader (assembly, resource).PixbufHandle;
+				return System.Reflection.Assembly.GetCallingAssembly ();
+			else
+				return assembly;
 		}
+		// added
+		public Pixbuf (System.Reflection.Assembly assembly, string resource, uint width, uint height) : base (IntPtr.Zero)
+		{
+			Raw = new PixbufLoader (CheckAssembly(assembly), resource, width, height).PixbufHandle;
+		}
+		
+		// added
+		public Pixbuf (byte[] buffer) : base(new PixbufLoader (buffer).PixbufHandle) {}
 
+		// added
+		public Pixbuf (byte[] buffer, uint width, uint height) : base(new PixbufLoader (buffer, width, height).PixbufHandle) {}
+
 		static public Pixbuf LoadFromResource (string resource)
 		{
 			return new Pixbuf (System.Reflection.Assembly.GetCallingAssembly (), resource);
 		}
+		
+		// added
+		static public Pixbuf LoadFromResource (string resource, uint width, uint height)
+		{
+			return new Pixbuf (System.Reflection.Assembly.GetCallingAssembly (), resource, width, height);
+		}
 
 		[DllImport("libgdk_pixbuf-2.0-0.dll")]
 		static extern IntPtr gdk_pixbuf_scale_simple(IntPtr raw, int dest_width, int dest_height, int interp_type);

--=-L5hkkIL+3ras/jAUfIt4--