Skip to content
Snippets Groups Projects
Commit 532286d2 authored by tag2y19's avatar tag2y19
Browse files

Add image export options

's' for as is, 'S' for pick an image size.  The image is drawn using the
same draw function as rendering to the screen
parent 15e52d12
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,8 @@
* language down at the bottom, so I gotta. */
#include <assert.h>
#include <cairo-pdf.h>
#include <cairo-svg.h>
#include <ctype.h>
#include <fcntl.h>
#include <gtk/gtk.h>
......@@ -41,6 +43,11 @@ struct colour {
struct context {
GtkWidget* window;
int width;
int height;
bool size_set;
char* read_buffer;
size_t read_buffer_len;
......@@ -126,6 +133,15 @@ struct fd_source {
};
struct save_size {
GtkWidget* dialogue;
GtkWidget* width;
GtkWidget* height;
struct context* context;
};
/* PROTOTYPES!!! */
static bool add_to_column_list( const char* option_name,
......@@ -143,6 +159,9 @@ static void listener_finalise( GSource* source );
static int key_callback( GtkEventControllerKey* event_controller,
unsigned int keyval, unsigned int keycode, GdkModifierType mods,
void* data );
static void save_size_ok( GtkWidget* widget, void* data );
static void save_callback( GObject* source_object,
GAsyncResult* result, void* data );
static int data_callback( void* data );
static void parse_headers( struct context* context );
static void parse_data( struct context* context );
......@@ -586,19 +605,20 @@ static void app_activate( GtkApplication* app, void* data ) {
struct context* context = (struct context*) data;
GtkWidget* window = gtk_application_window_new( app );
gtk_window_set_title( GTK_WINDOW( window ), "E-Plot" );
context->window = gtk_application_window_new( app );
gtk_window_set_title( GTK_WINDOW( context->window ), "E-Plot" );
context->plot = gtk_drawing_area_new();
gtk_drawing_area_set_draw_func(
GTK_DRAWING_AREA( context->plot ), plot_draw, context, NULL );
gtk_window_set_child( GTK_WINDOW( window ), context->plot );
gtk_window_set_child(
GTK_WINDOW( context->window ), context->plot );
GtkEventController* event_controller =
gtk_event_controller_key_new();
g_signal_connect( event_controller, "key-released",
G_CALLBACK( &key_callback ), context );
gtk_widget_add_controller( window, event_controller );
gtk_widget_add_controller( context->window, event_controller );
static GSourceFuncs listener_funks = {
.prepare = &listener_prepare,
......@@ -703,7 +723,7 @@ static void app_activate( GtkApplication* app, void* data ) {
}
}
gtk_window_present( GTK_WINDOW( window ) );
gtk_window_present( GTK_WINDOW( context->window ) );
}
......@@ -845,6 +865,61 @@ static int key_callback( GtkEventControllerKey* event_controller,
}
case 's':
case 'S': {
if ( 0 == mods || GDK_CONTROL_MASK == mods ) {
GtkFileDialog* dialogue = gtk_file_dialog_new();
gtk_file_dialog_save( dialogue,
GTK_WINDOW( context->window ), NULL,
save_callback, (void*) context );
} else if ( GDK_SHIFT_MASK == mods ||
( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) == mods ) {
GtkWidget* dialogue_window = gtk_window_new();
GtkWidget* box = gtk_box_new(
GTK_ORIENTATION_VERTICAL, 6 );
gtk_window_set_child( GTK_WINDOW( dialogue_window ),
box );
gtk_box_append( GTK_BOX( box ),
gtk_label_new( "Size (pixels for png), "
"(points for svg or pdf)" ) );
GtkWidget* width = gtk_spin_button_new_with_range(
0., 99999., 1. );
GtkWidget* height = gtk_spin_button_new_with_range(
0., 99999., 1. );
gtk_box_append( GTK_BOX( box ), width );
gtk_box_append( GTK_BOX( box ), height );
GtkWidget* ok = gtk_button_new_with_label( "OK" );
gtk_box_append( GTK_BOX( box ), ok );
struct save_size* save_size = calloc(
1, sizeof *save_size );
save_size->width = width;
save_size->height = height;
save_size->context = context;
save_size->dialogue = dialogue_window;
g_signal_connect( ok, "clicked",
G_CALLBACK( save_size_ok ), save_size );
gtk_window_set_transient_for(
GTK_WINDOW( dialogue_window ),
GTK_WINDOW( context->window ) );
gtk_window_present( GTK_WINDOW( dialogue_window ) );
}
return true;
}
default: {
return false;
......@@ -855,6 +930,111 @@ static int key_callback( GtkEventControllerKey* event_controller,
}
static void save_size_ok( GtkWidget* widget, void* data ) {
struct save_size* save_size = (struct save_size*) data;
save_size->context->width = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( save_size->width ) );
save_size->context->height = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( save_size->height ) );
save_size->context->size_set = true;
GtkFileDialog* dialogue = gtk_file_dialog_new();
gtk_file_dialog_save( dialogue,
GTK_WINDOW( save_size->context->window ), NULL,
save_callback, (void*) ( save_size->context ) );
gtk_window_destroy( GTK_WINDOW( save_size->dialogue ) );
free( save_size );
(void) widget;
}
static void save_callback( GObject* source_object,
GAsyncResult* result, void* data ) {
struct context* context = (struct context*) data;
context->size_set = false;
GFile* file = gtk_file_dialog_save_finish(
GTK_FILE_DIALOG( source_object ), result, NULL );
if ( NULL == file ) {
return;
}
const char* path = g_file_get_path( file );
#ifdef CAIRO_HAS_PNG_FUNCTIONS
if ( strlen( path ) > 4 &&
0 == strcmp( path + strlen( path ) - 4, ".png" ) ) {
cairo_surface_t* surface = cairo_image_surface_create(
CAIRO_FORMAT_RGB24, context->width, context->height );
cairo_t* cr = cairo_create( surface );
plot_draw( NULL, cr, context->width, context->height, data );
cairo_destroy( cr );
cairo_surface_write_to_png( surface, path );
cairo_surface_destroy( surface );
return;
}
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
if ( strlen( path ) > 4 &&
0 == strcmp( path + strlen( path ) - 4, ".svg" ) ) {
cairo_surface_t* surface = cairo_svg_surface_create(
path,
context->width, context->height );
cairo_t* cr = cairo_create( surface );
plot_draw( NULL, cr,
context->width, context->height,
data );
cairo_destroy( cr );
cairo_surface_finish( surface );
cairo_surface_flush( surface );
cairo_surface_destroy( surface );
return;
}
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
if ( strlen( path ) > 4 &&
0 == strcmp( path + strlen( path ) - 4, ".pdf" ) ) {
cairo_surface_t* surface = cairo_pdf_surface_create(
path,
context->width, context->height );
cairo_t* cr = cairo_create( surface );
plot_draw( NULL, cr,
context->width, context->height,
data );
cairo_destroy( cr );
cairo_surface_finish( surface );
cairo_surface_flush( surface );
cairo_surface_destroy( surface );
return;
}
#endif
fprintf( stderr, "No format supported for %s\n", path );
}
static int data_callback( void* data ) {
struct context* context = (struct context*) data;
......@@ -1243,6 +1423,11 @@ static void plot_draw( GtkDrawingArea* plot,
struct context* context = (struct context*) data;
(void) plot;
if ( !context->size_set ) {
context->width = width;
context->height = height;
}
/* Texts */
double margin_reqs[4] = { 5., 5., 5., 5. };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment