1 /**
2  * @file   gui-preview.h
3  * @brief
4  *
5  * Copyright (C) 2009 Gummi Developers
6  * All Rights reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation
10  * files (the "Software"), to deal in the Software without
11  * restriction, including without limitation the rights to use,
12  * copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following
15  * conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29 
30 #ifndef __GUMMI_GUI_PREVIEW_H__
31 #define __GUMMI_GUI_PREVIEW_H__
32 
33 #include <gtk/gtk.h>
34 #include <poppler.h>
35 
36 #define PAGE_MARGIN 14
37 #define DOCUMENT_MARGIN (PAGE_MARGIN/2)
38 #define PAGE_SHADOW_WIDTH 4
39 #define PAGE_SHADOW_OFFSET 4
40 
41 #define ASCROLL_STEPS 25
42 #define ASCROLL_CONST_C (1.5)
43 #define ASCROLL_CONST_B (-2*ASCROLL_CONST_C + 5./2)
44 #define ASCROLL_CONST_A (ASCROLL_CONST_C - 3./2)
45 
46 
47 #define BYTES_PER_PIXEL 4
48 
49 /**
50  *  These "Layered" Rectangles are just like normal GdkRectangles, except the
51  *  have a layer assigned. 2 Rectangles can only intersect or be unioned if they
52  *  are on the same layer.
53  *
54  *  In the future these structs should be used to describe the position of a
55  *  page. In continuous mode all pages are on the same layer (0). In Paged mode,
56  *  they are on different layers. The field of view (fov) rectangle, that
57  *  describes the portion of the preview that is currently visible is on the
58  *  layer/page that should currently be displayed (0 in continuous mode).
59  */
60 typedef struct _LayeredRectangle LayeredRectangle;
61 struct _LayeredRectangle {
62     gint x;
63     gint y;
64     gint width;
65     gint height;
66     gint layer;
67 };
68 
69 enum GuPreviewFitModes {
70     FIT_BOTH = 0,       // Best Fit
71     FIT_WIDTH,          // Fit Page Width
72     FIT_NUMERIC         // 50,85,100 .. 400 %
73 };
74 
75 
76 #define GU_PREVIEW_PAGE(x) ((GuPreviewPage*)(x))
77 typedef struct _GuPreviewPage GuPreviewPage;
78 
79 struct _GuPreviewPage {
80     cairo_surface_t* rendering;
81 
82     double height;
83     double width;
84 
85     LayeredRectangle inner; // Position of the page itself
86     LayeredRectangle outer; // Position of the page + border & shadow
87 
88 };
89 
90 #define GU_PREVIEW_GUI(x) ((GuPreviewGui*)x)
91 typedef struct _GuPreviewGui GuPreviewGui;
92 
93 struct _GuPreviewGui {
94     PopplerDocument* doc;
95 
96     GtkWidget* scrollw;
97     GtkViewport* viewport;
98     GtkWidget* drawarea;
99     GtkWidget* toolbar;
100 
101     GtkWidget* page_next;
102     GtkWidget* page_prev;
103     GtkWidget* page_label;
104     GtkWidget* page_input;
105     GtkToggleToolButton* preview_pause;
106 
107     GtkWidget* errorpanel;
108     GtkComboBox* combo_sizes;
109 
110     gulong page_input_changed_handler;
111     gulong combo_sizes_changed_handler;
112     gulong on_resize_handler;
113     gulong on_draw_handler;
114     gulong hvalue_changed_handler;
115     gulong vvalue_changed_handler;
116     gulong hchanged_handler;
117     gulong vchanged_handler;
118 
119     GtkRadioMenuItem *page_layout_single_page;
120     GtkRadioMenuItem *page_layout_one_column;
121 
122     gchar *uri;
123     guint update_timer;
124     gboolean preview_on_idle;
125     gboolean errormode;
126 
127     GtkAdjustment* hadj;
128     GtkAdjustment* vadj;
129     gdouble prev_x;
130     gdouble prev_y;
131 
132     gint n_pages;
133     gint current_page;
134     gdouble max_page_height;
135     gdouble height_pages;
136     gdouble width_pages;
137     gdouble height_scaled;
138     gdouble width_scaled;
139     gdouble width_left;
140     gdouble width_no_scale;
141     gdouble scale;
142     PopplerPageLayout pageLayout;
143     GuPreviewPage *pages;
144     gint cache_size;
145 
146     gint document_width_scaling;
147     gint document_height_scaling;
148     gint document_width_non_scaling;
149     gint document_height_non_scaling;
150 
151     gint next_page;
152     gint prev_page;
153 
154     gint ascroll_steps_left;
155     gint ascroll_end_x;
156     gint ascroll_end_y;
157     gint ascroll_dist_x;
158     gint ascroll_dist_y;
159 
160     GSList *sync_nodes;
161 };
162 
163 GuPreviewGui* previewgui_init (GtkBuilder * builder);
164 void previewgui_set_pdffile (GuPreviewGui* prev, const gchar *uri);
165 void previewgui_refresh (GuPreviewGui* prev, GtkTextIter *sync_to, gchar* tex_file);
166 void previewgui_set_pagedata (GuPreviewGui* prev);
167 void previewgui_goto_page (GuPreviewGui* prev, int page_number);
168 void previewgui_scroll_to_page (GuPreviewGui* pc, int page);
169 void previewgui_goto_xy (GuPreviewGui* pc, gdouble x, gdouble y);
170 void previewgui_scroll_to_xy (GuPreviewGui* pc, gdouble x, gdouble y);
171 void previewgui_save_position (GuPreviewGui* pc);
172 void previewgui_restore_position (GuPreviewGui* pc);
173 void previewgui_reset (GuPreviewGui* pc);
174 void previewgui_cleanup_fds (GuPreviewGui* pc);
175 void previewgui_start_preview (GuPreviewGui* pc);
176 void previewgui_drawarea_resize (GuPreviewGui* pc);
177 void previewgui_stop_preview (GuPreviewGui* pc);
178 void on_page_input_changed (GtkEntry* entry, void* user);
179 void on_next_page_clicked (GtkWidget* widget, void* user);
180 void on_prev_page_clicked (GtkWidget* widget, void* user);
181 void on_preview_pause_toggled (GtkWidget *widget, void * user);
182 void on_combo_sizes_changed (GtkWidget* widget, void* user);
183 gboolean on_draw (GtkWidget* w, cairo_t* cr, void* user);
184 gboolean on_scroll (GtkWidget* w, GdkEventScroll* e, void* user);
185 gboolean on_motion (GtkWidget* w, GdkEventMotion* e, void* user);
186 gboolean on_resize (GtkWidget* w, GdkRectangle* r, void* user);
187 gboolean on_scroll_child(GtkScrolledWindow *scrolledwindow, GtkScrollType type,
188                          gboolean isHorizontal, gpointer *user);
189 void on_adj_changed(GtkAdjustment *adjustment, gpointer user);
190 void previewgui_page_layout_radio_changed(GtkMenuItem *radioitem,gpointer data);
191 void previewgui_set_page_layout(GuPreviewGui* pc, PopplerPageLayout pageLayout);
192 
193 void previewgui_start_errormode (GuPreviewGui *pc, const gchar *msg);
194 void previewgui_stop_errormode (GuPreviewGui *pc);
195 gboolean on_document_compiled (gpointer data);
196 gboolean on_document_error (gpointer data);
197 
198 gboolean run_garbage_collector(GuPreviewGui* pc);
199 
200 
201 #endif /* __GUMMI_GUI_PREVIEW_H__ */
202