summaryrefslogtreecommitdiff
path: root/libreofficekit
diff options
context:
space:
mode:
authorAndrzej Hunt <andrzej.hunt@collabora.com>2014-07-08 08:54:13 +0200
committerAndrzej Hunt <andrzej.hunt@collabora.com>2014-07-12 05:19:12 +0200
commita864ab2ef17e02930df5ae91112b5104bdea1e39 (patch)
treeecd53e8aa034a7eb02197795be6bf9923a7206f4 /libreofficekit
parentdfdc9f5ba4493369a0c6fb3a1d7c5781deeb5bc2 (diff)
Implement a (qa-only) quad-tiled viewer.
I.e. we subdivide the document into 4 tiles: one at 100% scaling, one at 200%, one at 50%, one at 25% -- these are then post-scaled in gdk) and assembled to show as one document again. This is specifically a test only widget, primarily to be able to quickly spot any tile positioning/border-transition issues. We could theoretically make this widget inherit from the original widget, however that would mean having to introduce virtual methods etc., which is not something that we'd want in production -- in the longer run that widget will hopefully be extended to have proper tile composition etc., which would then break this widget too if it were inheriting from there. Change-Id: Ib880a1614f89724135e753013cf91aec25973e39
Diffstat (limited to 'libreofficekit')
-rw-r--r--libreofficekit/Executable_gtktiledviewer.mk4
-rw-r--r--libreofficekit/qa/lokdocview_quad/lokdocview_quad.c253
-rw-r--r--libreofficekit/qa/lokdocview_quad/lokdocview_quad.h66
3 files changed, 323 insertions, 0 deletions
diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk
index 0ce922288165..d4ef643693d1 100644
--- a/libreofficekit/Executable_gtktiledviewer.mk
+++ b/libreofficekit/Executable_gtktiledviewer.mk
@@ -42,6 +42,10 @@ $(eval $(call gb_Executable_add_libs,gtktiledviewer,\
))
endif
+$(eval $(call gb_Executable_add_cobjects,gtktiledviewer,\
+ libreofficekit/qa/lokdocview_quad/lokdocview_quad \
+))
+
$(eval $(call gb_Executable_add_exception_objects,gtktiledviewer,\
libreofficekit/qa/gtktiledviewer/gtktiledviewer \
))
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