[Libreoffice-commits] core.git: Branch 'feature/gsoc-tiled-rendering' - libreofficekit/Library_libreofficekitgtk.mk libreofficekit/source
Pranav Kant
pranavk at gnome.org
Wed Jun 3 11:40:01 PDT 2015
libreofficekit/Library_libreofficekitgtk.mk | 1
libreofficekit/source/gtk/lokdocview.cxx | 42 ++++++++-----
libreofficekit/source/gtk/tilebuffer.cxx | 90 ++++++++++++++++++++++++++++
libreofficekit/source/gtk/tilebuffer.hxx | 78 ++++++++++++++++++++++++
4 files changed, 196 insertions(+), 15 deletions(-)
New commits:
commit 1858a2a30dcd75698af704a7ddf8fb12c89e8112
Author: Pranav Kant <pranavk at gnome.org>
Date: Thu Jun 4 00:06:46 2015 +0530
lokdocview: add tile buffering support
The TileBuffer class now manages all the tiles.
Change-Id: Ic667a93dcf1c097e0601c0496e8a083c4742e8cb
diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk
index ff800d0..9240953 100644
--- a/libreofficekit/Library_libreofficekitgtk.mk
+++ b/libreofficekit/Library_libreofficekitgtk.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_Library_use_externals,libreofficekitgtk,\
$(eval $(call gb_Library_add_exception_objects,libreofficekitgtk,\
libreofficekit/source/gtk/lokdocview \
+ libreofficekit/source/gtk/tilebuffer \
))
ifeq ($(OS),LINUX)
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 676952c..b34a501 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -22,6 +22,8 @@
#include <LibreOfficeKit/LibreOfficeKitGtk.h>
#include <rsc/rsc-vcl-shared-types.hxx>
+#include "tilebuffer.hxx"
+
#if !GLIB_CHECK_VERSION(2,32,0)
#define G_SOURCE_REMOVE FALSE
#define G_SOURCE_CONTINUE TRUE
@@ -37,6 +39,8 @@
// We know that VirtualDevices use a DPI of 96.
static const int DPI = 96;
+// Lets use a square of side 256 pixels.
+static const int nTileSizePixels = 256;
namespace {
@@ -67,7 +71,7 @@ struct LOKDocView_Impl
GtkWidget** m_pCanvas;
GtkWidget *darea;
- TileBuffer *mTileBuffer;
+ TileBuffer *m_pTileBuffer;
float m_fZoom;
@@ -781,8 +785,6 @@ gboolean LOKDocView_Impl::handleTimeoutImpl()
void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial)
{
- const int nTileSizePixels = 256;
-
GdkRectangle visibleArea;
lok_docview_get_visarea (m_pDocView, &visibleArea);
@@ -826,20 +828,11 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial)
if (bPaint)
{
- // Index of the current tile.
- guint nTile = nRow * nColumns + nColumn;
+ g_info("gettile: (%d %d)", nRow, nColumn);
- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, aTileRectanglePixels.width, aTileRectanglePixels.height);
+ Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn);
+ GdkPixbuf* pPixBuf = currentTile.tile_get_buffer();
unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
- g_info("renderDocument: paintTile(%d, %d)", nRow, nColumn);
- m_pDocument->pClass->paintTile(m_pDocument,
- // Buffer and its size, depends on the position only.
- pBuffer,
- aTileRectanglePixels.width, aTileRectanglePixels.height,
- // Position of the tile.
- aTileRectangleTwips.x, aTileRectangleTwips.y,
- // Size of the tile, depends on the zoom factor and the tile position only.
- aTileRectangleTwips.width, aTileRectangleTwips.height);
gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x), twipToPixel(aTileRectangleTwips.y));
cairo_paint(pcairo);
@@ -1218,6 +1211,18 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c
pDocView->m_pImpl->m_pDocument->pClass->registerCallback(pDocView->m_pImpl->m_pDocument, &LOKDocView_Impl::callbackWorker, pDocView);
pDocView->m_pImpl->m_pDocument->pClass->getDocumentSize(pDocView->m_pImpl->m_pDocument, &pDocView->m_pImpl->m_nDocumentWidthTwips, &pDocView->m_pImpl->m_nDocumentHeightTwips);
g_timeout_add(600, &LOKDocView_Impl::handleTimeout, pDocView);
+
+ long nDocumentWidthTwips = pDocView->m_pImpl->m_nDocumentWidthTwips;
+ long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips;
+ long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(nDocumentWidthTwips);
+ long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(nDocumentHeightTwips);
+ // Total number of rows / columns in this document.
+ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels);
+ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
+ pDocView->m_pImpl->m_pTileBuffer = new TileBuffer(pDocView->m_pImpl->m_pDocument,
+ nTileSizePixels,
+ nRows,
+ nColumns);
pDocView->m_pImpl->renderDocument(0);
}
@@ -1232,6 +1237,13 @@ SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_docview_get_document(LOKDocView
SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZoom )
{
pDocView->m_pImpl->m_fZoom = fZoom;
+ long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips);
+ long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips);
+ // Total number of rows / columns in this document.
+ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels);
+ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
+
+ pDocView->m_pImpl->m_pTileBuffer->tile_buffer_set_zoom(fZoom, nRows, nColumns);
if ( pDocView->m_pImpl->m_pDocument )
pDocView->m_pImpl->renderDocument(0);
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
new file mode 100644
index 0000000..ca66ae90
--- /dev/null
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -0,0 +1,90 @@
+/* -*- 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 "tilebuffer.hxx"
+
+static const int DPI = 96;
+
+static float pixelToTwip(float fInput, float zoom)
+{
+ return (fInput / DPI / zoom) * 1440.0f;
+}
+
+static float twipToPixel(float fInput, float zoom)
+{
+ return fInput / 1440.0f * DPI * zoom;
+}
+
+GdkPixbuf* Tile::tile_get_buffer()
+{
+ return m_pBuffer;
+}
+
+void Tile::tile_release()
+{
+ gdk_pixbuf_unref(m_pBuffer);
+ m_pBuffer = NULL;
+}
+
+void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns)
+{
+ m_fZoomFactor = newZoomFactor;
+
+ tile_buffer_reset_all_tiles();
+
+ // set new buffer width and height
+ m_nWidth = columns;
+ m_nHeight = rows;
+ m_aTiles.resize(m_nWidth * m_nHeight);
+}
+
+void TileBuffer::tile_buffer_reset_all_tiles()
+{
+ for (size_t i = 0; i < m_aTiles.size(); i++)
+ {
+ m_aTiles[i].tile_release();
+ }
+ m_aTiles.clear();
+}
+
+Tile& TileBuffer::tile_buffer_get_tile(int x, int y)
+{
+ int index = x * m_nWidth + y;
+ if(!m_aTiles[index].valid)
+ {
+ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize);
+ if (!pPixBuf){
+ g_info ("error allocating memory to pixbuf");
+ }
+ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
+ GdkRectangle aTileRectangle;
+ aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y;
+ aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x;
+
+ g_info ("rendering (%d %d)", x, y);
+ m_pLOKDocument->pClass->paintTile(m_pLOKDocument,
+ // Buffer and its size, depends on the position only.
+ pBuffer,
+ m_nTileSize, m_nTileSize,
+ // Position of the tile.
+ aTileRectangle.x, aTileRectangle.y,
+ // Size of the tile, depends on the zoom factor and the tile position only.
+ pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor));
+
+ m_aTiles[index].tile_set_pixbuf(pPixBuf);
+ m_aTiles[index].valid = 1;
+ }
+
+ return m_aTiles[index];
+}
+
+void Tile::tile_set_pixbuf(GdkPixbuf *buffer)
+{
+ m_pBuffer = buffer;
+}
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
new file mode 100644
index 0000000..7912428
--- /dev/null
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -0,0 +1,78 @@
+/* -*- 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_TILEBUFFER_HXX
+#define INCLUDED_TILEBUFFER_HXX
+
+#include <gdk/gdkkeysyms.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <vector>
+
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKit.h>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <LibreOfficeKit/LibreOfficeKitGtk.h>
+
+/*
+ This class represents a single tile in the tile buffer.
+ TODO: Extend it to support features like double buffering
+*/
+class Tile
+{
+public:
+ Tile() : valid(0) {}
+ ~Tile() {
+ tile_release();
+ }
+
+ GdkPixbuf* tile_get_buffer();
+ void tile_release();
+ void tile_set_pixbuf(GdkPixbuf*);
+ bool valid;
+private:
+ GdkPixbuf *m_pBuffer;
+};
+
+/*
+ TileBuffer is the buffer caching all the recently rendered tiles.
+ The buffer is set to invalid when zoom factor changes.
+*/
+class TileBuffer
+{
+public:
+ TileBuffer(LibreOfficeKitDocument *document,
+ int tileSize,
+ int rows,
+ int columns)
+ : m_fZoomFactor(1)
+ , m_nTileSize(tileSize)
+ , m_pLOKDocument(document)
+ , m_nWidth(columns)
+ , m_nHeight(rows)
+ {
+ m_aTiles.resize(rows * columns);
+ }
+
+ ~TileBuffer() {}
+
+ void tile_buffer_set_zoom(float zoomFactor, int rows, int columns);
+ Tile& tile_buffer_get_tile(int x, int y);
+ void tile_buffer_update();
+ void tile_buffer_reset_all_tiles();
+private:
+ LibreOfficeKitDocument *m_pLOKDocument;
+ std::vector<Tile> m_aTiles;
+ //TODO: Also set width and height when document size changes
+ int m_nWidth;
+ int m_nHeight;
+ float m_fZoomFactor;
+ int m_nTileSize;
+};
+
+#endif // INCLUDED_TILEBUFFER_HXX
More information about the Libreoffice-commits
mailing list