1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <sal/types.h>
12 #define LOK_USE_UNSTABLE_API
13 #include <LibreOfficeKit/LibreOfficeKit.h>
15 #include "lokdocview_quad.h"
17 static void lok_docview_quad_class_init( LOKDocViewQuadClass
* pClass
);
18 static void lok_docview_quad_init( LOKDocViewQuad
* pDocView
);
20 // We specifically need to destroy the document when closing in order to ensure
21 // that lock files etc. are cleaned up.
22 void lcl_onDestroy( LOKDocViewQuad
* pDocView
, gpointer pData
)
25 if ( pDocView
->pDocument
)
26 pDocView
->pDocument
->pClass
->destroy( pDocView
->pDocument
);
27 pDocView
->pDocument
= NULL
;
30 SAL_DLLPUBLIC_EXPORT guint
lok_docview_quad_get_type()
32 static guint lok_docview_quad_type
= 0;
34 if (!lok_docview_quad_type
)
36 GtkTypeInfo lok_docview_quad_info
=
39 sizeof( LOKDocViewQuad
),
40 sizeof( LOKDocViewQuadClass
),
41 (GtkClassInitFunc
) lok_docview_quad_class_init
,
42 (GtkObjectInitFunc
) lok_docview_quad_init
,
45 (GtkClassInitFunc
) NULL
48 lok_docview_quad_type
= gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_quad_info
);
50 return lok_docview_quad_type
;
53 static void lok_docview_quad_class_init( LOKDocViewQuadClass
* pClass
)
55 pClass
->lok_docview_quad
= NULL
;
58 static void lok_docview_quad_init( LOKDocViewQuad
* pDocView
)
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 gtk_scrolled_window_set_hadjustment( GTK_SCROLLED_WINDOW( pDocView
), NULL
);
66 gtk_scrolled_window_set_vadjustment( GTK_SCROLLED_WINDOW( pDocView
), NULL
);
68 pDocView
->pEventBox
= gtk_event_box_new();
69 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView
),
70 pDocView
->pEventBox
);
72 pDocView
->pGrid
= gtk_table_new( 2, 2, TRUE
);
73 gtk_container_add( GTK_CONTAINER( pDocView
->pEventBox
), pDocView
->pGrid
);
75 for ( x
= 0; x
< 2; x
++ )
77 for ( y
= 0; y
< 2; y
++ )
79 pDocView
->pCanvas
[x
][y
] = gtk_image_new();
80 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 gtk_widget_show( pDocView
->pCanvas
[x
][y
] );
84 pDocView
->pPixBuf
[x
][y
] = 0;
88 gtk_widget_show( pDocView
->pGrid
);
89 gtk_widget_show( pDocView
->pEventBox
);
91 // TODO: figure out a clever view of getting paths set up.
92 pDocView
->pOffice
= 0;
93 pDocView
->pDocument
= 0;
97 gtk_signal_connect( GTK_OBJECT(pDocView
), "destroy",
98 GTK_SIGNAL_FUNC(lcl_onDestroy
), NULL
);
101 SAL_DLLPUBLIC_EXPORT GtkWidget
* lok_docview_quad_new( LibreOfficeKit
* pOffice
)
103 LOKDocViewQuad
* pDocView
= gtk_type_new( lok_docview_quad_get_type() );
104 pDocView
->pOffice
= pOffice
;
105 return GTK_WIDGET( pDocView
);
108 void renderDocument( LOKDocViewQuad
* pDocView
)
110 long nWidth
, nHeight
;
111 int nRenderWidth
, nRenderHeight
;
116 g_assert( pDocView
->pDocument
);
118 for ( x
= 0; x
< 2; x
++ )
120 for ( y
= 0; y
< 2; y
++ )
122 if ( pDocView
->pPixBuf
[x
][y
] )
124 g_object_unref( G_OBJECT( pDocView
->pPixBuf
[x
][y
] ) );
129 pDocView
->pDocument
->pClass
->getDocumentSize( pDocView
->pDocument
, &nWidth
, &nHeight
);
131 // Draw the whole document at once (for now)
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 nRenderWidth
= nWidth
* pDocView
->fZoom
/ 10;
136 nRenderHeight
= nHeight
* pDocView
->fZoom
/ 10;
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 pDocView
->pPixBuf
[0][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB
,
144 nRenderWidth
/ 2, nRenderHeight
/ 2 );
145 pDocView
->pDocument
->pClass
->paintTile( pDocView
->pDocument
,
146 gdk_pixbuf_get_pixels( pDocView
->pPixBuf
[0][0] ),
147 nRenderWidth
/ 2, nRenderHeight
/ 2,
150 nWidth
/ 2, nHeight
/ 2 );
152 pDocView
->pPixBuf
[1][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB
,
154 nRenderWidth
, nRenderHeight
);
155 pDocView
->pDocument
->pClass
->paintTile( pDocView
->pDocument
,
156 gdk_pixbuf_get_pixels( pDocView
->pPixBuf
[1][0] ),
157 nRenderWidth
, nRenderHeight
,
160 nWidth
/ 2, nHeight
/ 2 );
161 pTempBuf
= gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView
->pPixBuf
[1][0] ),
164 GDK_INTERP_BILINEAR
);
165 g_object_unref( G_OBJECT( pDocView
->pPixBuf
[1][0] ) );
166 pDocView
->pPixBuf
[1][0] = pTempBuf
;
169 pDocView
->pPixBuf
[0][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB
,
171 nRenderWidth
/ 4, nRenderHeight
/ 4 );
172 pDocView
->pDocument
->pClass
->paintTile( pDocView
->pDocument
,
173 gdk_pixbuf_get_pixels( pDocView
->pPixBuf
[0][1] ),
174 nRenderWidth
/ 4, nRenderHeight
/ 4,
177 nWidth
/ 2, nHeight
/ 2 );
178 pTempBuf
= gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView
->pPixBuf
[0][1] ),
181 GDK_INTERP_BILINEAR
);
182 g_object_unref( G_OBJECT( pDocView
->pPixBuf
[0][1] ) );
183 pDocView
->pPixBuf
[0][1] = pTempBuf
;
185 pDocView
->pPixBuf
[1][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB
,
187 nRenderWidth
/ 8, nRenderHeight
/ 8 );
188 pDocView
->pDocument
->pClass
->paintTile( pDocView
->pDocument
,
189 gdk_pixbuf_get_pixels( pDocView
->pPixBuf
[1][1] ),
190 nRenderWidth
/ 8, nRenderHeight
/ 8,
192 nWidth
/ 2, nHeight
/ 2,
193 nWidth
/ 2, nHeight
/ 2 );
194 pTempBuf
= gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView
->pPixBuf
[1][1] ),
197 GDK_INTERP_BILINEAR
);
198 g_object_unref( G_OBJECT( pDocView
->pPixBuf
[1][1] ) );
199 pDocView
->pPixBuf
[1][1] = pTempBuf
;
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
208 // gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf );
209 for ( x
= 0; x
< 2; x
++ )
211 for ( y
= 0; y
< 2; y
++ )
213 gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView
->pCanvas
[x
][y
] ), pDocView
->pPixBuf
[x
][y
] );
218 SAL_DLLPUBLIC_EXPORT gboolean
lok_docview_quad_open_document( LOKDocViewQuad
* pDocView
, char* pPath
)
220 if ( pDocView
->pDocument
)
222 pDocView
->pDocument
->pClass
->destroy( pDocView
->pDocument
);
223 pDocView
->pDocument
= NULL
;
226 pDocView
->pDocument
= pDocView
->pOffice
->pClass
->documentLoad( pDocView
->pOffice
,
228 if ( !pDocView
->pDocument
)
230 // FIXME: should have a GError parameter and populate it.
231 char *pError
= pDocView
->pOffice
->pClass
->getError( pDocView
->pOffice
);
232 fprintf( stderr
, "Error opening document '%s'\n", pError
);
236 renderDocument( pDocView
);
241 SAL_DLLPUBLIC_EXPORT
void lok_docview_quad_set_zoom ( LOKDocViewQuad
* pDocView
, float fZoom
)
243 pDocView
->fZoom
= fZoom
;
244 renderDocument( pDocView
);
245 // TODO: maybe remember and reset positiong?
248 SAL_DLLPUBLIC_EXPORT
float lok_docview_quad_get_zoom ( LOKDocViewQuad
* pDocView
)
250 return pDocView
->fZoom
;
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */