diff options
Diffstat (limited to 'libreofficekit/qa')
-rw-r--r-- | libreofficekit/qa/lokdocview_quad/lokdocview_quad.c | 253 | ||||
-rw-r--r-- | libreofficekit/qa/lokdocview_quad/lokdocview_quad.h | 66 |
2 files changed, 319 insertions, 0 deletions
diff --git a/libreofficekit/qa/lokdocview_quad/lokdocview_quad.c b/libreofficekit/qa/lokdocview_quad/lokdocview_quad.c new file mode 100644 index 000000000000..cbff8856a70e --- /dev/null +++ b/libreofficekit/qa/lokdocview_quad/lokdocview_quad.c @@ -0,0 +1,253 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/types.h> + +#define LOK_USE_UNSTABLE_API +#include <LibreOfficeKit/LibreOfficeKit.h> + +#include "lokdocview_quad.h" + +static void lok_docview_quad_class_init( LOKDocViewQuadClass* pClass ); +static void lok_docview_quad_init( LOKDocViewQuad* pDocView ); + +// We specifically need to destroy the document when closing in order to ensure +// that lock files etc. are cleaned up. +void lcl_onDestroy( LOKDocViewQuad* pDocView, gpointer pData ) +{ + (void) pData; + if ( pDocView->pDocument ) + pDocView->pDocument->pClass->destroy( pDocView->pDocument ); + pDocView->pDocument = NULL; +} + +SAL_DLLPUBLIC_EXPORT guint lok_docview_quad_get_type() +{ + static guint lok_docview_quad_type = 0; + + if (!lok_docview_quad_type) + { + GtkTypeInfo lok_docview_quad_info = + { + "LokDocViewQuad", + sizeof( LOKDocViewQuad ), + sizeof( LOKDocViewQuadClass ), + (GtkClassInitFunc) lok_docview_quad_class_init, + (GtkObjectInitFunc) lok_docview_quad_init, + NULL, + NULL, + (GtkClassInitFunc) NULL + }; + + lok_docview_quad_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_quad_info ); + } + return lok_docview_quad_type; +} + +static void lok_docview_quad_class_init( LOKDocViewQuadClass* pClass ) +{ + pClass->lok_docview_quad = NULL; +} + +static void lok_docview_quad_init( LOKDocViewQuad* pDocView ) +{ + int x, y; + + // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically + // have to set the [hv]adjustment to prevent GTK assertions from firing, see + // https://bugzilla.gnome.org/show_bug.cgi?id=438114 for more info. + gtk_scrolled_window_set_hadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL ); + gtk_scrolled_window_set_vadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL ); + + pDocView->pEventBox = gtk_event_box_new(); + gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), + pDocView->pEventBox ); + + pDocView->pGrid = gtk_table_new( 2, 2, TRUE ); + gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pGrid ); + + for ( x = 0; x < 2; x++ ) + { + for ( y = 0; y < 2; y++ ) + { + pDocView->pCanvas[x][y] = gtk_image_new(); + gtk_table_attach_defaults( GTK_TABLE( pDocView->pGrid ), pDocView->pCanvas[x][y], x, x+1, y, y+1 ); + //gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pCanvas ); + gtk_widget_show( pDocView->pCanvas[x][y] ); + + pDocView->pPixBuf[x][y] = 0; + } + } + + gtk_widget_show( pDocView->pGrid ); + gtk_widget_show( pDocView->pEventBox ); + + // TODO: figure out a clever view of getting paths set up. + pDocView->pOffice = 0; + pDocView->pDocument = 0; + + pDocView->fZoom = 1; + + gtk_signal_connect( GTK_OBJECT(pDocView), "destroy", + GTK_SIGNAL_FUNC(lcl_onDestroy), NULL ); +} + +SAL_DLLPUBLIC_EXPORT GtkWidget* lok_docview_quad_new( LibreOfficeKit* pOffice ) +{ + LOKDocViewQuad* pDocView = gtk_type_new( lok_docview_quad_get_type() ); + pDocView->pOffice = pOffice; + return GTK_WIDGET( pDocView ); +} + +void renderDocument( LOKDocViewQuad* pDocView ) +{ + long nWidth, nHeight; + int nRenderWidth, nRenderHeight; + int nRowStride; + int x, y; + GdkPixbuf* pTempBuf; + + g_assert( pDocView->pDocument ); + + for ( x = 0; x < 2; x++ ) + { + for ( y = 0; y < 2; y++ ) + { + if ( pDocView->pPixBuf[x][y] ) + { + g_object_unref( G_OBJECT( pDocView->pPixBuf[x][y] ) ); + } + } + } + + pDocView->pDocument->pClass->getDocumentSize( pDocView->pDocument, &nWidth, &nHeight ); + + // Draw the whole document at once (for now) + + // TODO: we really should scale by screen DPI here -- 10 seems to be a vaguely + // correct factor for my screen at least. + nRenderWidth = nWidth * pDocView->fZoom / 10; + nRenderHeight = nHeight * pDocView->fZoom / 10; + + // TOP-LEFT: standard + // TOP-RIGHT: 2x resolution rendered (post-scaled to 50%) + // BOTTOM-LEFT: 1/2 resolution rendered (post-scaled 200%) + // BOTTOM-RIGHT: 1/2 resolution rendered (post-scaled 400%) + pDocView->pPixBuf[0][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB, + TRUE, 8, + nRenderWidth / 2, nRenderHeight / 2 ); + pDocView->pDocument->pClass->paintTile( pDocView->pDocument, + gdk_pixbuf_get_pixels( pDocView->pPixBuf[0][0] ), + nRenderWidth / 2, nRenderHeight / 2, + &nRowStride, + 0, 0, // origin + nWidth / 2, nHeight / 2 ); + + pDocView->pPixBuf[1][0] = gdk_pixbuf_new( GDK_COLORSPACE_RGB, + TRUE, 8, + nRenderWidth, nRenderHeight ); + pDocView->pDocument->pClass->paintTile( pDocView->pDocument, + gdk_pixbuf_get_pixels( pDocView->pPixBuf[1][0] ), + nRenderWidth, nRenderHeight, + &nRowStride, + nWidth / 2, 0, + nWidth / 2, nHeight / 2 ); + pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[1][0] ), + nRenderWidth / 2, + nRenderHeight / 2, + GDK_INTERP_BILINEAR ); + g_object_unref( G_OBJECT( pDocView->pPixBuf[1][0] ) ); + pDocView->pPixBuf[1][0] = pTempBuf; + + + pDocView->pPixBuf[0][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB, + TRUE, 8, + nRenderWidth / 4, nRenderHeight / 4 ); + pDocView->pDocument->pClass->paintTile( pDocView->pDocument, + gdk_pixbuf_get_pixels( pDocView->pPixBuf[0][1] ), + nRenderWidth / 4, nRenderHeight / 4, + &nRowStride, + 0, nHeight / 2, + nWidth / 2, nHeight / 2 ); + pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[0][1] ), + nRenderWidth / 2, + nRenderHeight / 2, + GDK_INTERP_BILINEAR ); + g_object_unref( G_OBJECT( pDocView->pPixBuf[0][1] ) ); + pDocView->pPixBuf[0][1] = pTempBuf; + + pDocView->pPixBuf[1][1] = gdk_pixbuf_new( GDK_COLORSPACE_RGB, + TRUE, 8, + nRenderWidth / 8, nRenderHeight / 8 ); + pDocView->pDocument->pClass->paintTile( pDocView->pDocument, + gdk_pixbuf_get_pixels( pDocView->pPixBuf[1][1] ), + nRenderWidth / 8, nRenderHeight / 8, + &nRowStride, + nWidth / 2, nHeight / 2, + nWidth / 2, nHeight / 2 ); + pTempBuf = gdk_pixbuf_scale_simple( GDK_PIXBUF( pDocView->pPixBuf[1][1] ), + nRenderWidth / 2, + nRenderHeight / 2, + GDK_INTERP_BILINEAR ); + g_object_unref( G_OBJECT( pDocView->pPixBuf[1][1] ) ); + pDocView->pPixBuf[1][1] = pTempBuf; + + + + // TODO: double check that the rowstride really matches what we expected, + // although presumably we'd already be crashing by now if things were + // wrong. + (void) nRowStride; + + // gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf ); + for ( x = 0; x < 2; x++ ) + { + for ( y = 0; y < 2; y++ ) + { + gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas[x][y] ), pDocView->pPixBuf[x][y] ); + } + } +} + +SAL_DLLPUBLIC_EXPORT gboolean lok_docview_quad_open_document( LOKDocViewQuad* pDocView, char* pPath ) +{ + if ( pDocView->pDocument ) + { + pDocView->pDocument->pClass->destroy( pDocView->pDocument ); + pDocView->pDocument = NULL; + } + + pDocView->pDocument = pDocView->pOffice->pClass->documentLoad( pDocView->pOffice, + pPath ); + if ( !pDocView->pDocument ) + { + // FIXME: should have a GError parameter and populate it. + char *pError = pDocView->pOffice->pClass->getError( pDocView->pOffice ); + fprintf( stderr, "Error opening document '%s'\n", pError ); + return FALSE; + } + else + renderDocument( pDocView ); + + return TRUE; +} + +SAL_DLLPUBLIC_EXPORT void lok_docview_quad_set_zoom ( LOKDocViewQuad* pDocView, float fZoom ) +{ + pDocView->fZoom = fZoom; + renderDocument( pDocView ); + // TODO: maybe remember and reset positiong? +} + +SAL_DLLPUBLIC_EXPORT float lok_docview_quad_get_zoom ( LOKDocViewQuad* pDocView ) +{ + return pDocView->fZoom; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/lokdocview_quad/lokdocview_quad.h b/libreofficekit/qa/lokdocview_quad/lokdocview_quad.h new file mode 100644 index 000000000000..3124e5f6fd2f --- /dev/null +++ b/libreofficekit/qa/lokdocview_quad/lokdocview_quad.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_LOK_QA_INC_LIBREOFFICEKITGTK_H +#define INCLUDED_LOK_QA_INC_LIBREOFFICEKITGTK_H + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +#define LOK_USE_UNSTABLE_API +#include <LibreOfficeKit/LibreOfficeKit.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define LOK_DOCVIEW_QUAD(obj) GTK_CHECK_CAST (obj, lok_docview_quad_get_type(), LOKDocViewQuad) +#define LOK_DOCVIEW_QUAD_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_docview_quad_get_type(), LOKDocViewQuadClass) +#define IS_LOK_DOCVIEW_QUAD(obj) GTK_CHECK_TYPE (obj, lok_docview_quad_get_type()) + + +typedef struct _LOKDocViewQuad LOKDocViewQuad; +typedef struct _LOKDocViewQuadClass LOKDocViewQuadClass; + +struct _LOKDocViewQuad +{ + GtkScrolledWindow scrollWindow; + + GtkWidget* pEventBox; + GtkWidget* pGrid; + GtkWidget* pCanvas[2][2]; + GdkPixbuf* pPixBuf[2][2]; + + float fZoom; + + LibreOfficeKit* pOffice; + LibreOfficeKitDocument* pDocument; +}; + +struct _LOKDocViewQuadClass +{ + GtkScrolledWindowClass parent_class; + + void (*lok_docview_quad) (LOKDocViewQuad* pDocView); +}; + +guint lok_docview_quad_get_type (void); +GtkWidget* lok_docview_quad_new ( LibreOfficeKit* pOffice ); +gboolean lok_docview_quad_open_document (LOKDocViewQuad* pDocView, + char* pPath); +void lok_docview_quad_set_zoom (LOKDocViewQuad* pDocView, + float fZoom); +float lok_docview_quad_get_zoom (LOKDocViewQuad* pDocView); + +#ifdef __cplusplus +} +#endif + +#endif |