[Libreoffice-commits] core.git: Branch 'feature/tiled-editing' - include/LibreOfficeKit libreofficekit/Library_libreofficekitgtk.mk libreofficekit/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Jan 14 09:26:12 PST 2015


 include/LibreOfficeKit/LibreOfficeKitGtk.h  |    4 -
 libreofficekit/Library_libreofficekitgtk.mk |    1 
 libreofficekit/source/gtk/lokdocview.c      |  102 ++++++++++++++++++----------
 3 files changed, 70 insertions(+), 37 deletions(-)

New commits:
commit 1c8e015ecc624fd0d574eeb850c9cc2fcf60ee69
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 17:57:47 2015 +0100

    lokdocview: stop rendering a single huge tile
    
    The primary purpose of gtktiledviewer is to see the same features / bugs
    than on mobile devices. On Android we already render 256x256px tiles, do
    the same in gtktiledviewer instead of a single huge tile.
    
    Change-Id: I377dcab59e7019dcf1d15a27ccba117eb53d0d5b

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 3fd0c4a..b3cd304 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -34,8 +34,8 @@ struct _LOKDocView
     GtkScrolledWindow scrollWindow;
 
     GtkWidget* pEventBox;
-    GtkWidget* pCanvas;
-    GdkPixbuf* pPixBuf;
+    GtkWidget* pTable;
+    GtkWidget** pCanvas;
 
     float fZoom;
 
diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk
index bcf1a5b..4757359 100644
--- a/libreofficekit/Library_libreofficekitgtk.mk
+++ b/libreofficekit/Library_libreofficekitgtk.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_Library_add_cobjects,libreofficekitgtk,\
 ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,libreofficekitgtk,\
     -ldl \
+    -lm \
 ))
 endif
 
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index c0262a2..91ebd76 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -8,6 +8,7 @@
  */
 
 #include <sal/types.h>
+#include <math.h>
 
 #define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
@@ -74,13 +75,10 @@ static void lok_docview_init( LOKDocView* pDocView )
     // Allow reacting to button press events.
     gtk_widget_set_events(pDocView->pEventBox, GDK_BUTTON_PRESS_MASK);
 
-    pDocView->pCanvas = gtk_image_new();
-    gtk_container_add( GTK_CONTAINER( pDocView->pEventBox ), pDocView->pCanvas );
-
-    gtk_widget_show( pDocView->pCanvas );
     gtk_widget_show( pDocView->pEventBox );
 
-    pDocView->pPixBuf = 0;
+    pDocView->pTable = 0;
+    pDocView->pCanvas = 0;
 
     // TODO: figure out a clever view of getting paths set up.
     pDocView->pOffice = 0;
@@ -109,41 +107,75 @@ static float twipToPixel(float nInput)
     return nInput / 1440.0f * g_nDPI;
 }
 
-void renderDocument( LOKDocView* pDocView )
+/// Converts from screen pixels to document coordinates
+static float pixelToTwip(float nInput)
 {
-    long nDocumentWidthTwips, nDocumentHeightTwips, nBufferWidthPixels, nBufferHeightPixels;
-    unsigned char* pBuffer;
-    int nRowStride;
+    return (nInput / g_nDPI) * 1440.0f;
+}
 
-    g_assert( pDocView->pDocument );
+void renderDocument( LOKDocView* pDocView )
+{
+    long nDocumentWidthTwips, nDocumentHeightTwips, nDocumentWidthPixels, nDocumentHeightPixels;
+    const int nTileSizePixels = 256;
+    long nRow, nColumn, nRows, nColumns;
 
-    if ( pDocView->pPixBuf )
+    // Get document size and find out how many rows / columns we need.
+    pDocView->pDocument->pClass->getDocumentSize(pDocView->pDocument, &nDocumentWidthTwips, &nDocumentHeightTwips);
+    nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips) * pDocView->fZoom;
+    nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips) * pDocView->fZoom;
+    nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels);
+    nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
+
+    // Set up our table and the tile pointers.
+    if (pDocView->pTable)
+        gtk_container_remove(GTK_CONTAINER( pDocView->pEventBox ), pDocView->pTable);
+    pDocView->pTable = gtk_table_new(nRows, nColumns, FALSE);
+    gtk_container_add(GTK_CONTAINER(pDocView->pEventBox), pDocView->pTable);
+    gtk_widget_show(pDocView->pTable);
+    if (pDocView->pCanvas)
+        g_free(pDocView->pCanvas);
+    pDocView->pCanvas = g_malloc0(sizeof(GtkWidget*) * nRows * nColumns);
+
+    // Render the tiles.
+    for (nRow = 0; nRow < nRows; ++nRow)
     {
-        g_object_unref( G_OBJECT( pDocView->pPixBuf ) );
+        for (nColumn = 0; nColumn < nColumns; ++nColumn)
+        {
+            int nTileWidthPixels, nTileHeightPixels;
+            GdkPixbuf* pPixBuf;
+            unsigned char* pBuffer;
+            int nRowStride;
+
+            // The rightmost/bottommost tiles may be smaller.
+            if (nColumn == nColumns - 1)
+                nTileWidthPixels = nDocumentWidthPixels - nColumn * nTileSizePixels;
+            else
+                nTileWidthPixels = nTileSizePixels;
+            if (nRow == nRows - 1)
+                nTileHeightPixels = nDocumentHeightPixels - nRow * nTileSizePixels;
+            else
+                nTileHeightPixels = nTileSizePixels;
+
+            pPixBuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, nTileWidthPixels, nTileHeightPixels);
+            pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
+            pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
+                                                    // Buffer and its size, this is always the same.
+                                                    pBuffer,
+                                                    nTileWidthPixels, nTileHeightPixels,
+                                                    &nRowStride,
+                                                    // Position of the tile.
+                                                    pixelToTwip(nTileSizePixels) / pDocView->fZoom * nColumn, pixelToTwip(nTileSizePixels) / pDocView->fZoom * nRow,
+                                                    // Size of the tile, depends on the zoom factor and the tile position only.
+                                                    pixelToTwip(nTileWidthPixels) / pDocView->fZoom, pixelToTwip(nTileHeightPixels) / pDocView->fZoom );
+            (void) nRowStride;
+
+            pDocView->pCanvas[nRow * nColumns + nColumn] = gtk_image_new();
+            gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas[nRow * nColumns + nColumn] ), pPixBuf );
+            g_object_unref(G_OBJECT(pPixBuf));
+            gtk_table_attach_defaults(GTK_TABLE(pDocView->pTable), pDocView->pCanvas[nRow * nColumns + nColumn], nColumn, nColumn + 1, nRow, nRow + 1);
+            gtk_widget_show(pDocView->pCanvas[nRow * nColumns + nColumn]);
+        }
     }
-
-    pDocView->pDocument->pClass->getDocumentSize(pDocView->pDocument, &nDocumentWidthTwips, &nDocumentHeightTwips);
-
-    // Draw the whole document at once (for now)
-
-    nBufferWidthPixels = twipToPixel(nDocumentWidthTwips) * pDocView->fZoom;
-    nBufferHeightPixels = twipToPixel(nDocumentHeightTwips) * pDocView->fZoom;
-
-    pDocView->pPixBuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
-                                        TRUE, 8,
-                                        nBufferWidthPixels, nBufferHeightPixels);
-
-
-    pBuffer = gdk_pixbuf_get_pixels( pDocView->pPixBuf );
-    pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
-                                            pBuffer,
-                                            nBufferWidthPixels, nBufferHeightPixels,
-                                            &nRowStride,
-                                            0, 0, // origin
-                                            nDocumentWidthTwips, nDocumentHeightTwips );
-    (void) nRowStride;
-
-    gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf );
 }
 
 /// Invoked on the main thread if lok_docview_callback_worker() requests so.


More information about the Libreoffice-commits mailing list