]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Add the capability to print a dive profile
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Sep 2011 23:02:42 +0000 (16:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Sep 2011 23:02:42 +0000 (16:02 -0700)
Ok, this is the ugliest f*&$ing printout I have ever seen in my life,
but think of it as a "the concept of printing works" commit, and you'll
be able to hold your lunch down and not gouge out your eyeballs with a
spoon.  Maybe.

I'm just doing the cairo display as-is for the printout, which is a
seriously bad idea.  I need to not try to do colors etc, and instead of
having white lines on a black background I just need to make thelines be
black on white paper.

But that would involve actually changing the current "plot()" routine,
which is against the point of the exercise right now.  This really is
just a demonstration of how to add printing capabilities.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Makefile
display.h
main.c
print.c [new file with mode: 0644]
profile.c

index 7e04f8f179a44c2a894bdd8fd44a89d38c635e7c..858f4a8683321b4411dd86810ce7d6a9c627b704 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ LIBDIVECOMPUTERINCLUDES = $(LIBDIVECOMPUTERDIR)/include/libdivecomputer
 LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
 
 OBJS = main.o dive.o profile.o info.o equipment.o divelist.o \
-       parse-xml.o save-xml.o libdivecomputer.o
+       parse-xml.o save-xml.o libdivecomputer.o print.o
 
 divelog: $(OBJS)
        $(CC) $(LDFLAGS) -o divelog $(OBJS) \
@@ -39,6 +39,9 @@ equipment.o: equipment.c dive.h display.h divelist.h
 divelist.o: divelist.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c divelist.c
 
+print.o: print.c dive.h display.h
+       $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c print.c
+
 libdivecomputer.o: libdivecomputer.c dive.h display.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` \
                        -I$(LIBDIVECOMPUTERINCLUDES) \
index df701a3b988037b59bdf7ed715a0f78d091ac8d6..759f7f04e5037ffbddcbf192d441b72645c3923e 100644 (file)
--- a/display.h
+++ b/display.h
@@ -16,5 +16,23 @@ extern GtkWidget *extended_dive_info_widget(void);
 extern GtkWidget *equipment_widget(void);
 
 extern void repaint_dive(void);
+extern void do_print(void);
+
+/*
+ * Cairo scaling really is horribly horribly mis-designed.
+ *
+ * Which is sad, because I really like Cairo otherwise. But
+ * the fact that the line width is scaled with the same scale
+ * as the coordinate system is a f*&%ing disaster. So we
+ * can't use it, and instead have this butt-ugly wrapper thing..
+ */
+struct graphics_context {
+       cairo_t *cr;
+       double maxx, maxy;
+       double leftx, rightx;
+       double topy, bottomy;
+};
+
+extern void plot(struct graphics_context *gc, int w, int h, struct dive *dive);
 
 #endif
diff --git a/main.c b/main.c
index 5157c54e3e595ee0d792b9bc150830354c3f0d81..4e15de2b37b3d7a3ea2745dc97574cc1ab923e13 100644 (file)
--- a/main.c
+++ b/main.c
@@ -367,6 +367,7 @@ static GtkActionEntry menu_items[] = {
        { "FileMenuAction", GTK_STOCK_FILE, "Log", NULL, NULL, NULL},
        { "OpenFile",       GTK_STOCK_OPEN, NULL,   "<control>O", NULL, G_CALLBACK(file_open) },
        { "SaveFile",       GTK_STOCK_SAVE, NULL,   "<control>S", NULL, G_CALLBACK(file_save) },
+       { "Print",          GTK_STOCK_PRINT, NULL,  "<control>P", NULL, G_CALLBACK(do_print) },
        { "Import",         NULL, "Import", NULL, NULL, G_CALLBACK(import_dialog) },
        { "Units",          NULL, "Units",    NULL, NULL, G_CALLBACK(unit_dialog) },
        { "Renumber",       NULL, "Renumber", NULL, NULL, G_CALLBACK(renumber_dialog) },
@@ -380,6 +381,7 @@ static const gchar* ui_string = " \
                        <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
                                <menuitem name=\"Open\" action=\"OpenFile\" /> \
                                <menuitem name=\"Save\" action=\"SaveFile\" /> \
+                               <menuitem name=\"Print\" action=\"Print\" /> \
                                <separator name=\"Separator1\"/> \
                                <menuitem name=\"Import\" action=\"Import\" /> \
                                <separator name=\"Separator2\"/> \
diff --git a/print.c b/print.c
new file mode 100644 (file)
index 0000000..c2114d5
--- /dev/null
+++ b/print.c
@@ -0,0 +1,59 @@
+#include <gtk/gtk.h>
+
+#include "dive.h"
+#include "display.h"
+
+static void draw_page(GtkPrintOperation *operation,
+                       GtkPrintContext *context,
+                       gint page_nr,
+                       gpointer user_data)
+{
+       cairo_t *cr;
+       PangoLayout *layout;
+       double w, h;
+       struct graphics_context gc = { 0 };
+
+       cr = gtk_print_context_get_cairo_context(context);
+       gc.cr = cr;
+
+       layout=gtk_print_context_create_pango_layout(context);
+
+       w = gtk_print_context_get_width(context);
+       h = gtk_print_context_get_height(context);
+
+       /* Do the profile on the top third of the page.. */
+       cairo_set_source_rgb(cr, 0, 0, 0);
+       cairo_rectangle(cr, 0, 0, w, h/3);
+       cairo_fill(cr);
+       plot(&gc, w, h/3, current_dive);
+
+       pango_cairo_show_layout(cr,layout);
+       g_object_unref(layout);
+}
+
+static void begin_print(GtkPrintOperation *operation, gpointer user_data)
+{
+}
+
+static GtkPrintSettings *settings = NULL;
+
+void do_print(void)
+{
+       GtkPrintOperation *print;
+       GtkPrintOperationResult res;
+
+       print = gtk_print_operation_new();
+       if (settings != NULL)
+               gtk_print_operation_set_print_settings(print, settings);
+       gtk_print_operation_set_n_pages(print, 1);
+       g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), NULL);
+       g_signal_connect(print, "draw_page", G_CALLBACK(draw_page), NULL);
+       res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+                                        GTK_WINDOW(main_window), NULL);
+       if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
+               if (settings != NULL)
+                       g_object_unref(settings);
+               settings = g_object_ref(gtk_print_operation_get_print_settings(print));
+       }
+       g_object_unref(print);
+}
index 6d6e1ff98ff345eeca162a9ba983a93998287167..796b318e71308a0166d28ac0190908b0398a0a2f 100644 (file)
--- a/profile.c
+++ b/profile.c
 
 int selected_dive = 0;
 
-/*
- * Cairo scaling really is horribly horribly mis-designed.
- *
- * Which is sad, because I really like Cairo otherwise. But
- * the fact that the line width is scaled with the same scale
- * as the coordinate system is a f*&%ing disaster. So we
- * can't use it, and instead have this butt-ugly wrapper thing..
- */
-struct graphics_context {
-       cairo_t *cr;
-       double maxx, maxy;
-       double leftx, rightx;
-       double topy, bottomy;
-};
-
 /* Plot info with smoothing and one-, two- and three-minute minimums and maximums */
 struct plot_info {
        int nr;
@@ -645,7 +630,7 @@ static struct plot_info *depth_plot_info(struct dive *dive)
        return analyze_plot_info(pi);
 }
 
-static void plot(struct graphics_context *gc, int w, int h, struct dive *dive)
+void plot(struct graphics_context *gc, int w, int h, struct dive *dive)
 {
        double topx, topy;
        struct plot_info *pi = depth_plot_info(dive);