Line data Source code
1 : /* File: image_format_writer.c; Copyright and License: see below */
2 :
3 : #include "image/image_format_writer.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_log.h"
6 : #include <gtk/gtk.h>
7 : #include <cairo-svg.h>
8 : #include <cairo-pdf.h>
9 : #include <cairo-ps.h>
10 : #include <stdio.h>
11 : #include <stdbool.h>
12 : #include <assert.h>
13 :
14 0 : void image_format_writer_init( image_format_writer_t *this_,
15 : data_database_reader_t *db_reader,
16 : data_visible_set_t *input_data,
17 : data_profile_part_t *profile )
18 : {
19 0 : U8_TRACE_BEGIN();
20 0 : assert( NULL != db_reader );
21 0 : assert( NULL != input_data );
22 0 : assert( NULL != profile );
23 :
24 0 : (*this_).db_reader = db_reader;
25 0 : (*this_).input_data = input_data;
26 0 : (*this_).profile = profile;
27 0 : geometry_rectangle_init( &((*this_).bounds), 0.0, 0.0, 1680.0, 1260.0 );
28 0 : pencil_diagram_maker_init( &((*this_).painter), input_data, profile );
29 :
30 0 : U8_TRACE_END();
31 0 : }
32 :
33 0 : void image_format_writer_destroy( image_format_writer_t *this_ )
34 : {
35 0 : U8_TRACE_BEGIN();
36 :
37 0 : pencil_diagram_maker_destroy( &((*this_).painter) );
38 0 : geometry_rectangle_destroy(&((*this_).bounds));
39 0 : (*this_).input_data = NULL;
40 0 : (*this_).profile = NULL;
41 0 : (*this_).db_reader = NULL;
42 :
43 0 : U8_TRACE_END();
44 0 : }
45 :
46 : #ifndef CAIRO_HAS_SVG_SURFACE
47 : #error "no svg"
48 : #endif
49 :
50 : #ifndef CAIRO_HAS_PNG_FUNCTIONS
51 : #error "no png"
52 : #endif
53 :
54 0 : u8_error_t image_format_writer_render_diagram_to_file( image_format_writer_t *this_,
55 : data_id_t diagram_id,
56 : io_file_format_t export_type,
57 : const char* target_filename,
58 : data_stat_t *io_render_stat )
59 : {
60 0 : U8_TRACE_BEGIN();
61 0 : assert( NULL != target_filename );
62 0 : assert( NULL != io_render_stat );
63 0 : assert( IO_FILE_FORMAT_TXT != export_type );
64 0 : assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
65 0 : const data_row_id_t diagram_row_id = data_id_get_row_id( &diagram_id );
66 0 : u8_error_t result = U8_ERROR_NONE;
67 :
68 0 : data_visible_set_init( (*this_).input_data );
69 0 : result |= data_visible_set_load( (*this_).input_data, diagram_row_id, (*this_).db_reader );
70 0 : assert(result == U8_ERROR_NONE);
71 0 : assert( data_visible_set_is_valid ( (*this_).input_data ) );
72 0 : data_profile_part_init( (*this_).profile );
73 0 : result |= data_profile_part_load( (*this_).profile, (*this_).input_data, (*this_).db_reader );
74 0 : assert(result == U8_ERROR_NONE);
75 0 : result |= image_format_writer_private_render_surface_to_file( this_, export_type, target_filename, io_render_stat );
76 0 : data_profile_part_destroy( (*this_).profile );
77 0 : data_visible_set_destroy( (*this_).input_data );
78 :
79 0 : U8_TRACE_END_ERR( result );
80 0 : return result;
81 : }
82 :
83 0 : u8_error_t image_format_writer_private_render_surface_to_file( image_format_writer_t *this_,
84 : io_file_format_t export_type,
85 : const char* target_filename,
86 : data_stat_t *io_render_stat )
87 : {
88 0 : U8_TRACE_BEGIN();
89 0 : assert( NULL != target_filename );
90 0 : assert( IO_FILE_FORMAT_TXT != export_type );
91 0 : u8_error_t result = U8_ERROR_NONE;
92 :
93 : /* create surface */
94 : cairo_surface_t *surface;
95 0 : if ( IO_FILE_FORMAT_SVG == export_type )
96 : {
97 0 : surface = (cairo_surface_t *) cairo_svg_surface_create( target_filename,
98 0 : geometry_rectangle_get_width( &((*this_).bounds) ),
99 0 : geometry_rectangle_get_height( &((*this_).bounds) )
100 : );
101 : }
102 0 : else if ( IO_FILE_FORMAT_PDF == export_type )
103 : {
104 0 : surface = (cairo_surface_t *) cairo_pdf_surface_create ( target_filename,
105 0 : geometry_rectangle_get_width( &((*this_).bounds) ),
106 0 : geometry_rectangle_get_height( &((*this_).bounds) )
107 : );
108 : }
109 0 : else if ( IO_FILE_FORMAT_PS == export_type )
110 : {
111 0 : surface = (cairo_surface_t *) cairo_ps_surface_create ( target_filename,
112 0 : geometry_rectangle_get_width( &((*this_).bounds) ),
113 0 : geometry_rectangle_get_height( &((*this_).bounds) )
114 : );
115 : }
116 : else /*if ( IO_FILE_FORMAT_PNG == export_type )*/
117 : {
118 0 : surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
119 0 : (uint32_t) geometry_rectangle_get_width( &((*this_).bounds) ),
120 0 : (uint32_t) geometry_rectangle_get_height( &((*this_).bounds) )
121 : );
122 : }
123 :
124 : /* draw on surface */
125 0 : if ( CAIRO_STATUS_SUCCESS != cairo_surface_status( surface ) )
126 : {
127 0 : U8_LOG_ERROR_INT( "surface could not be created", cairo_surface_status( surface ) );
128 0 : result = ( IO_FILE_FORMAT_PNG == export_type ) ? U8_ERROR_LIB_NO_MEMORY : U8_ERROR_LIB_FILE_WRITE;
129 : }
130 : else
131 : {
132 : cairo_t *cr;
133 0 : cr = cairo_create (surface);
134 :
135 : /* draw diagram */
136 : /* draw paper */
137 0 : cairo_set_source_rgba( cr, 1.0, 1.0, 1.0, 1.0 );
138 0 : cairo_rectangle ( cr,
139 0 : geometry_rectangle_get_left( &((*this_).bounds) ),
140 0 : geometry_rectangle_get_top( &((*this_).bounds) ),
141 0 : geometry_rectangle_get_width( &((*this_).bounds) ),
142 0 : geometry_rectangle_get_height( &((*this_).bounds) )
143 : );
144 0 : cairo_fill (cr);
145 :
146 : /* layout diagram */
147 : data_stat_t temp_stat;
148 0 : data_stat_init( &temp_stat );
149 0 : pencil_diagram_maker_define_grid ( &((*this_).painter), (*this_).bounds, cr );
150 0 : pencil_diagram_maker_layout_elements ( &((*this_).painter), &temp_stat, cr );
151 : #ifdef NDEBUG
152 : /* in release mode, do not report layouting warnings to the user */
153 : data_stat_reset_series( &temp_stat, DATA_STAT_SERIES_WARNING );
154 : #endif
155 0 : data_stat_add( io_render_stat, &temp_stat );
156 0 : data_stat_destroy( &temp_stat );
157 :
158 : /* draw the current diagram */
159 : data_id_t void_id;
160 0 : data_id_init_void( &void_id );
161 : data_small_set_t void_set;
162 0 : data_small_set_init( &void_set );
163 0 : pencil_diagram_maker_draw ( &((*this_).painter),
164 : void_id,
165 : void_id,
166 : &void_set,
167 : cr
168 : );
169 :
170 : /* finish drawing context */
171 0 : cairo_destroy (cr);
172 :
173 : /* finish surface */
174 0 : if ( IO_FILE_FORMAT_PNG == export_type )
175 : {
176 : cairo_status_t png_result;
177 0 : png_result = cairo_surface_write_to_png ( surface, target_filename );
178 0 : if ( CAIRO_STATUS_SUCCESS != png_result )
179 : {
180 0 : U8_LOG_ERROR("error writing png.");
181 0 : result = U8_ERROR_LIB_FILE_WRITE;
182 : }
183 : }
184 : else
185 : {
186 0 : cairo_surface_finish ( surface );
187 : }
188 : }
189 :
190 0 : cairo_surface_destroy ( surface );
191 :
192 0 : U8_TRACE_END_ERR( result );
193 0 : return result;
194 : }
195 :
196 :
197 : /*
198 : Copyright 2016-2024 Andreas Warnke
199 :
200 : Licensed under the Apache License, Version 2.0 (the "License");
201 : you may not use this file except in compliance with the License.
202 : You may obtain a copy of the License at
203 :
204 : http://www.apache.org/licenses/LICENSE-2.0
205 :
206 : Unless required by applicable law or agreed to in writing, software
207 : distributed under the License is distributed on an "AS IS" BASIS,
208 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
209 : See the License for the specific language governing permissions and
210 : limitations under the License.
211 : */
|