Line data Source code
1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <sal/types.h>
11 :
12 : #define LOK_USE_UNSTABLE_API
13 : #include <LibreOfficeKit/LibreOfficeKit.h>
14 :
15 : #include "lokdocview_quad.h"
16 :
17 : static void lok_docview_quad_class_init( LOKDocViewQuadClass* pClass );
18 : static void lok_docview_quad_init( LOKDocViewQuad* pDocView );
19 :
20 : // We specifically need to destroy the document when closing in order to ensure
21 : // that lock files etc. are cleaned up.
22 0 : void lcl_onDestroy( LOKDocViewQuad* pDocView, gpointer pData )
23 : {
24 : (void) pData;
25 0 : if ( pDocView->pDocument )
26 0 : pDocView->pDocument->pClass->destroy( pDocView->pDocument );
27 0 : pDocView->pDocument = NULL;
28 0 : }
29 :
30 0 : SAL_DLLPUBLIC_EXPORT guint lok_docview_quad_get_type()
31 : {
32 : static guint lok_docview_quad_type = 0;
33 :
34 0 : if (!lok_docview_quad_type)
35 : {
36 0 : GtkTypeInfo lok_docview_quad_info =
37 : {
38 : "LokDocViewQuad",
39 : sizeof( LOKDocViewQuad ),
40 : sizeof( LOKDocViewQuadClass ),
41 : (GtkClassInitFunc) lok_docview_quad_class_init,
42 : (GtkObjectInitFunc) lok_docview_quad_init,
43 : NULL,
44 : NULL,
45 : (GtkClassInitFunc) NULL
46 : };
47 :
48 0 : lok_docview_quad_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_quad_info );
49 : }
50 0 : return lok_docview_quad_type;
51 : }
52 :
53 0 : static void lok_docview_quad_class_init( LOKDocViewQuadClass* pClass )
54 : {
55 0 : pClass->lok_docview_quad = NULL;
56 0 : }
57 :
58 0 : static void lok_docview_quad_init( LOKDocViewQuad* pDocView )
59 : {
60 : int x, y;
61 :
62 : // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically
63 : // have to set the [hv]adjustment to prevent GTK assertions from firing, see
64 : // https://bugzilla.gnome.org/show_bug.cgi?id=438114 for more info.
65 0 : gtk_scrolled_window_set_hadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL );
66 0 : gtk_scrolled_window_set_vadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL );
67 :
68 0 : pDocView->pEventBox = gtk_event_box_new();
69 0 : gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView),
70 : pDocView->pEventBox );
71 :
72 0 : pDocView->pGrid = gtk_table_new( 2, 2, TRUE );
73 0 : gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pGrid );
74 :
75 0 : for ( x = 0; x < 2; x++ )
76 : {
77 0 : for ( y = 0; y < 2; y++ )
78 : {
79 0 : pDocView->pCanvas[x][y] = gtk_image_new();
80 0 : gtk_table_attach_defaults( GTK_TABLE( pDocView->pGrid ), pDocView->pCanvas[x][y], x, x+1, y, y+1 );
81 : //gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pCanvas );
82 0 : gtk_widget_show( pDocView->pCanvas[x][y] );
83 :
84 0 : pDocView->pPixBuf[x][y] = 0;
85 : }
86 : }
87 :
88 0 : gtk_widget_show( pDocView->pGrid );
89 0 : gtk_widget_show( pDocView->pEventBox );
90 :
91 : // TODO: figure out a clever view of getting paths set up.
92 0 : pDocView->pOffice = 0;
93 0 : pDocView->pDocument = 0;
94 :
95 0 : pDocView->fZoom = 1;
96 :
97 0 : gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
98 : GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
99 0 : }
100 :
101 0 : SAL_DLLPUBLIC_EXPORT GtkWidget* lok_docview_quad_new( LibreOfficeKit* pOffice )
102 : {
103 0 : LOKDocViewQuad* pDocView = gtk_type_new( lok_docview_quad_get_type() );
104 0 : pDocView->pOffice = pOffice;
105 0 : return GTK_WIDGET( pDocView );
106 : }
107 :
108 0 : void renderDocument( LOKDocViewQuad* pDocView )
109 : {
110 : long nWidth, nHeight;
111 : int nRenderWidth, nRenderHeight;
112 : int nRowStride;
113 : int x, y;
114 : GdkPixbuf* pTempBuf;
115 :
116 0 : g_assert( pDocView->pDocument );
117 :
118 0 : for ( x = 0; x < 2; x++ )
119 : {
120 0 : for ( y = 0; y < 2; y++ )
121 : {
122 0 : if ( pDocView->pPixBuf[x][y] )
123 : {
124 0 : g_object_unref( G_OBJECT( pDocView->pPixBuf[x][y] ) );
125 : }
126 : }
127 : }
128 :
129 0 : pDocView->pDocument->pClass->getDocumentSize( pDocView->pDocument, &nWidth, &nHeight );
130 :
131 : // Draw the whole document at once (for now)
132 :
133 : // TODO: we really should scale by screen DPI here -- 10 seems to be a vaguely
134 : // correct factor for my screen at least.
135 0 : nRenderWidth = nWidth * pDocView->fZoom / 10;
136 0 : nRenderHeight = nHeight * pDocView->fZoom / 10;
137 :
138 : // TOP-LEFT: standard
139 : // TOP-RIGHT: 2x resolution rendered (post-scaled to 50%)
140 : // BOTTOM-LEFT: 1/2 resolution rendered (post-scaled 200%)
141 : // BOTTOM-RIGHT: 1/2 resolution rendered (post-scaled 400%)
142 0 : pDocView->pPixBuf[0][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
143 : TRUE, 8,
144 : nRenderWidth / 2, nRenderHeight / 2 );
145 0 : pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
146 0 : gdk_pixbuf_get_pixels( pDocView->pPixBuf[0][0] ),
147 : nRenderWidth / 2, nRenderHeight / 2,
148 : &nRowStride,
149 : 0, 0, // origin
150 0 : nWidth / 2, nHeight / 2 );
151 :
152 0 : pDocView->pPixBuf[1][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
153 : TRUE, 8,
154 : nRenderWidth, nRenderHeight );
155 0 : pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
156 0 : gdk_pixbuf_get_pixels( pDocView->pPixBuf[1][0] ),
157 : nRenderWidth, nRenderHeight,
158 : &nRowStride,
159 0 : nWidth / 2, 0,
160 0 : nWidth / 2, nHeight / 2 );
161 0 : pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[1][0] ),
162 : nRenderWidth / 2,
163 : nRenderHeight / 2,
164 : GDK_INTERP_BILINEAR );
165 0 : g_object_unref( G_OBJECT( pDocView->pPixBuf[1][0] ) );
166 0 : pDocView->pPixBuf[1][0] = pTempBuf;
167 :
168 :
169 0 : pDocView->pPixBuf[0][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
170 : TRUE, 8,
171 : nRenderWidth / 4, nRenderHeight / 4 );
172 0 : pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
173 0 : gdk_pixbuf_get_pixels( pDocView->pPixBuf[0][1] ),
174 : nRenderWidth / 4, nRenderHeight / 4,
175 : &nRowStride,
176 0 : 0, nHeight / 2,
177 0 : nWidth / 2, nHeight / 2 );
178 0 : pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[0][1] ),
179 : nRenderWidth / 2,
180 : nRenderHeight / 2,
181 : GDK_INTERP_BILINEAR );
182 0 : g_object_unref( G_OBJECT( pDocView->pPixBuf[0][1] ) );
183 0 : pDocView->pPixBuf[0][1] = pTempBuf;
184 :
185 0 : pDocView->pPixBuf[1][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
186 : TRUE, 8,
187 : nRenderWidth / 8, nRenderHeight / 8 );
188 0 : pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
189 0 : gdk_pixbuf_get_pixels( pDocView->pPixBuf[1][1] ),
190 : nRenderWidth / 8, nRenderHeight / 8,
191 : &nRowStride,
192 0 : nWidth / 2, nHeight / 2,
193 0 : nWidth / 2, nHeight / 2 );
194 0 : pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[1][1] ),
195 : nRenderWidth / 2,
196 : nRenderHeight / 2,
197 : GDK_INTERP_BILINEAR );
198 0 : g_object_unref( G_OBJECT( pDocView->pPixBuf[1][1] ) );
199 0 : pDocView->pPixBuf[1][1] = pTempBuf;
200 :
201 :
202 :
203 : // TODO: double check that the rowstride really matches what we expected,
204 : // although presumably we'd already be crashing by now if things were
205 : // wrong.
206 : (void) nRowStride;
207 :
208 : // gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf );
209 0 : for ( x = 0; x < 2; x++ )
210 : {
211 0 : for ( y = 0; y < 2; y++ )
212 : {
213 0 : gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas[x][y] ), pDocView->pPixBuf[x][y] );
214 : }
215 : }
216 0 : }
217 :
218 0 : SAL_DLLPUBLIC_EXPORT gboolean lok_docview_quad_open_document( LOKDocViewQuad* pDocView, char* pPath )
219 : {
220 0 : if ( pDocView->pDocument )
221 : {
222 0 : pDocView->pDocument->pClass->destroy( pDocView->pDocument );
223 0 : pDocView->pDocument = NULL;
224 : }
225 :
226 0 : pDocView->pDocument = pDocView->pOffice->pClass->documentLoad( pDocView->pOffice,
227 : pPath );
228 0 : if ( !pDocView->pDocument )
229 : {
230 : // FIXME: should have a GError parameter and populate it.
231 0 : char *pError = pDocView->pOffice->pClass->getError( pDocView->pOffice );
232 0 : fprintf( stderr, "Error opening document '%s'\n", pError );
233 0 : return FALSE;
234 : }
235 : else
236 0 : renderDocument( pDocView );
237 :
238 0 : return TRUE;
239 : }
240 :
241 0 : SAL_DLLPUBLIC_EXPORT void lok_docview_quad_set_zoom ( LOKDocViewQuad* pDocView, float fZoom )
242 : {
243 0 : pDocView->fZoom = fZoom;
244 0 : if ( pDocView->pDocument )
245 : {
246 0 : renderDocument( pDocView );
247 : }
248 : // TODO: maybe remember and reset positiong?
249 0 : }
250 :
251 0 : SAL_DLLPUBLIC_EXPORT float lok_docview_quad_get_zoom ( LOKDocViewQuad* pDocView )
252 : {
253 0 : return pDocView->fZoom;
254 : }
255 :
256 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|