[ease/pdf] Start of a PDF exporter: slide backgrounds and image elements.



commit bff5a481b529c07008eb4f7c4e08b326e6942f35
Author: Nate Stedman <natesm gmail com>
Date:   Mon May 31 04:16:39 2010 -0400

    Start of a PDF exporter: slide backgrounds and image elements.

 Makefile.am           |    1 +
 src/EditorWindow.vala |    4 ++
 src/Element.vala      |   26 ++++++++++++
 src/MainToolbar.vala  |    8 ++--
 src/PDFExporter.vala  |  107 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/Slide.vala        |    8 ++++
 6 files changed, 150 insertions(+), 4 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 667d64f..7582234 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,6 +30,7 @@ ease_SOURCES = \
 	src/MainToolbar.vala \
 	src/Main.vala \
 	src/OpenDialog.vala \
+	src/PDFExporter.vala \
 	src/Player.vala \
 	src/ScrollableEmbed.vala \
 	src/SlideActor.vala \
diff --git a/src/EditorWindow.vala b/src/EditorWindow.vala
index 451a1a6..29fb5d6 100644
--- a/src/EditorWindow.vala
+++ b/src/EditorWindow.vala
@@ -179,6 +179,10 @@ public class Ease.EditorWindow : Gtk.Window
 			document.export_to_html(this);
 		});
 		
+		main_toolbar.pdf.clicked.connect(() => {
+			PDFExporter.export(document, this);
+		});
+		
 		// change the embed's zoom when the zoom slider is moved
 		zoom_slider.value_changed.connect(() => {
 			embed.set_zoom((float)zoom_slider.get_value());
diff --git a/src/Element.vala b/src/Element.vala
index ea1408c..ba4f383 100644
--- a/src/Element.vala
+++ b/src/Element.vala
@@ -157,6 +157,32 @@ public class Ease.Element : GLib.Object
 		// advance the progress bar
 		exporter.add_progress(amount);
 	}
+	
+	public void pdf_render(Cairo.Context context) throws Error
+	{
+		switch (data.get("element_type"))
+		{
+			case "image":
+				pdf_render_image(context);
+				break;
+		}
+	}
+	
+	private void pdf_render_image(Cairo.Context context) throws Error
+	{
+		var filename = parent.parent.path + "/" + data.get("filename");
+		
+		// load the image
+		var pixbuf = new Gdk.Pixbuf.from_file_at_scale(filename,
+		                                               (int)width,
+		                                               (int)height,
+		                                               false);
+		
+		Gdk.cairo_set_source_pixbuf(context, pixbuf, x, y);
+		
+		context.rectangle(x, y, width, height);
+		context.fill();
+	}
 
 	// convenience properties
 
diff --git a/src/MainToolbar.vala b/src/MainToolbar.vala
index 5718650..512a80a 100644
--- a/src/MainToolbar.vala
+++ b/src/MainToolbar.vala
@@ -36,6 +36,7 @@ public class Ease.MainToolbar : Gtk.Toolbar
 	public Gtk.ToolButton slides;
 	public Gtk.ToolButton fonts;
 	public Gtk.ToolButton colors;
+	public Gtk.ToolButton pdf;
 	
 	/**
 	 * Builds the main toolbar of an { link EditorWindow}.
@@ -58,11 +59,8 @@ public class Ease.MainToolbar : Gtk.Toolbar
 		inspector = new Gtk.ToolButton.from_stock("gtk-info");
 		colors = new Gtk.ToolButton.from_stock("gtk-select-color");
 		fonts = new Gtk.ToolButton.from_stock("gtk-select-font");
+		pdf = new Gtk.ToolButton.from_stock("gtk-dnd");
 		
-		// add buttons
-		insert(new_slide, -1);
-		insert(play, -1);
-		insert(new Gtk.SeparatorToolItem(), -1);
 		insert(new_presentation, -1);
 		insert(open, -1);
 		insert(save, -1);
@@ -75,6 +73,8 @@ public class Ease.MainToolbar : Gtk.Toolbar
 		insert(new Gtk.SeparatorToolItem(), -1);
 		insert(fonts, -1);
 		insert(colors, -1);
+		insert(new Gtk.SeparatorToolItem(), -1);
+		insert(pdf, -1);
 		
 		// format toolbar
 		toolbar_style = Gtk.ToolbarStyle.ICONS;
diff --git a/src/PDFExporter.vala b/src/PDFExporter.vala
new file mode 100644
index 0000000..c5a917f
--- /dev/null
+++ b/src/PDFExporter.vala
@@ -0,0 +1,107 @@
+/*  Ease, a GTK presentation application
+    Copyright (C) 2010 Nate Stedman
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+public static class Ease.PDFExporter : Object
+{
+	public static void export(Document document, Gtk.Window win)
+	{
+		string path;
+		
+		var dialog = new Gtk.FileChooserDialog(_("Export to PDF"),
+		                                       win,
+		                                       Gtk.FileChooserAction.SAVE,
+		                                       "gtk-save",
+		                                       Gtk.ResponseType.ACCEPT,
+		                                       "gtk-cancel",
+		                                       Gtk.ResponseType.CANCEL,
+		                                       null);
+		
+		if (dialog.run() == Gtk.ResponseType.ACCEPT)
+		{
+			// clean up the file dialog
+			path = dialog.get_filename();
+			dialog.destroy();
+		}
+		else
+		{
+			dialog.destroy();
+			return;
+		}
+		
+		try
+		{
+			// create a PDF surface
+			var surface = new Cairo.PdfSurface(path,
+				                               document.width, document.height);
+		
+			var context = new Cairo.Context(surface);
+		
+			foreach (var s in document.slides)
+			{
+				write_slide(s, context);
+				context.show_page();
+			}
+		
+			surface.flush();
+			surface.finish();
+		}
+		catch (Error e)
+		{
+			var error = new Gtk.MessageDialog(null,
+			                                  0,
+			                                   Gtk.MessageType.ERROR,
+			                                   Gtk.ButtonsType.CLOSE,
+			                                   _("Error exporting: %s"),
+			                                   e.message);
+			
+			error.title = _("Error Exporting to PDF");
+			error.run();
+		}
+	}
+	
+	private static void write_slide(Slide s, Cairo.Context context) throws Error
+	{
+		// write the background color if there is no image
+		if (s.background_image == null)
+		{
+			context.rectangle(0, 0, s.parent.width, s.parent.height);
+			context.set_source_rgb(s.background_color.red / 255f,
+			                       s.background_color.green / 255f,
+			                       s.background_color.blue / 255f);
+			context.fill();
+		}
+		
+		// otherwise, write the image
+		else
+		{
+			var pixbuf = new Gdk.Pixbuf.from_file_at_scale(s.background_abs,
+			                                               s.parent.width,
+			                                               s.parent.height,
+			                                               false);
+		
+			Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0);
+		
+			context.rectangle(0, 0, s.parent.width, s.parent.height);
+			context.fill();
+		}
+		
+		foreach (var e in s.elements)
+		{
+			e.pdf_render(context);
+		}
+	}
+}
diff --git a/src/Slide.vala b/src/Slide.vala
index 6ffdfa2..8ca68a0 100644
--- a/src/Slide.vala
+++ b/src/Slide.vala
@@ -55,6 +55,14 @@ public class Ease.Slide
 	public string background_image { get; set; }
 	
 	/**
+	 * The absolute path of the background image, if one is set.
+	 */
+	public string background_abs
+	{
+		owned get { return parent.path + "/" + background_image; }
+	}
+	
+	/**
 	 * The { link Document} that this Slide is part of
 	 */
 	public Document parent { get; set; }



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