From 0ad2976627386e126ae310d85aa6d771b3df1353 Mon Sep 17 00:00:00 2001 From: Pranav Kant Date: Thu, 4 Jun 2015 22:09:57 +0530 Subject: [PATCH 017/398] lokdocview, tilebuffer: clean up Improve documentation, style fixes Change-Id: I5000e32e90cd8e3b75e8df2907673efc303a55fd (cherry picked from commit c074cfa4d48736d1703949ccfe1a6c534a2742ae) --- libreofficekit/source/gtk/lokdocview.cxx | 59 ++++++++++------- libreofficekit/source/gtk/tilebuffer.cxx | 104 +++++++++++++++++------------- libreofficekit/source/gtk/tilebuffer.hxx | 107 +++++++++++++++++++++++++------ 3 files changed, 182 insertions(+), 88 deletions(-) diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index cfa71a357f22..2181dc9a21b1 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -177,12 +177,12 @@ struct LOKDocView_Impl /// Implementation of the timeout handler, invoked by handleTimeout(). gboolean handleTimeoutImpl(); /** - * Renders the document to a number of tiles. + * Renders the document to a number of visible tiles. * * This method is invoked only manually, not when some Gtk signal is * emitted. * - * @param pPartial if 0, then the full document is rendered, otherwise only + * @param pPartial if 0, then the full visible document is rendered, otherwise only * the tiles that intersect with pPartial. */ void renderDocument(GdkRectangle* pPartial); @@ -665,7 +665,7 @@ void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle) for (int i = aStart.x; i < aEnd.x; i++) for (int j = aStart.y; j < aEnd.y; j++) - m_pTileBuffer->tile_buffer_set_invalid(i, j); + m_pTileBuffer->setInvalid(i, j); } void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle) @@ -801,7 +801,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) GdkRectangle aTileRectangleTwips, aTileRectanglePixels; bool bPaint = true; - // Determine size of the tile: the rightmost/bottommost tiles may be smaller and we need the size to decide if we need to repaint. + // Determine size of the tile: the rightmost/bottommost tiles may + // be smaller, and we need the size to decide if we need to repaint. if (nColumn == nColumns - 1) aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; else @@ -811,7 +812,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) else aTileRectanglePixels.height = nTileSizePixels; - // Determine size and position of the tile in document coordinates, so we can decide if we can skip painting for partial rendering. + // Determine size and position of the tile in document coordinates, + // so we can decide if we can skip painting for partial rendering. aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); @@ -824,12 +826,14 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) if (bPaint) { - // g_info("gettile: (%d %d)", nRow, nColumn); + g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); - Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn); - GdkPixbuf* pPixBuf = currentTile.tile_get_buffer(); + Tile& currentTile = m_pTileBuffer->getTile(nRow, nColumn); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); - gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x, m_fZoom), twipToPixel(aTileRectangleTwips.y, m_fZoom)); + gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, m_fZoom), + twipToPixel(aTileRectangleTwips.y, m_fZoom)); cairo_paint(pcairo); } } @@ -942,7 +946,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) } else { - m_pTileBuffer->tile_buffer_reset_all_tiles(); + m_pTileBuffer->resetAllTiles(); renderDocument(0); } } @@ -1148,21 +1152,28 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), pDocView->m_pImpl->m_pDrawingArea ); - g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "expose-event", - GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView); - g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + G_CALLBACK(LOKDocView_Impl::on_exposed), pDocView); + g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "expose-event", - GTK_SIGNAL_FUNC(LOKDocView_Impl::renderOverlay), pDocView); + G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); gtk_widget_add_events(pDocView->m_pImpl->m_pDrawingArea, - GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_BUTTON_MOTION_MASK); - g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-press-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); - g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-release-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); - g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "motion-notify-event", G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); - - gtk_signal_connect(GTK_OBJECT(pDocView), "destroy", GTK_SIGNAL_FUNC(LOKDocView_Impl::destroy), 0); + GDK_BUTTON_PRESS_MASK + |GDK_BUTTON_RELEASE_MASK + |GDK_BUTTON_MOTION_MASK); + + g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "button-press-event", + G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); + g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "button-release-event", + G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); + g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "motion-notify-event", + G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); + + g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); } SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type() @@ -1253,7 +1264,7 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZo guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); - pDocView->m_pImpl->m_pTileBuffer->tile_buffer_set_zoom(fZoom, nRows, nColumns); + pDocView->m_pImpl->m_pTileBuffer->setZoom(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 index 3e5e01f8d686..338038078ab3 100644 --- a/libreofficekit/source/gtk/tilebuffer.cxx +++ b/libreofficekit/source/gtk/tilebuffer.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -9,6 +9,10 @@ #include "tilebuffer.hxx" +/* ------------------ + Utility functions + ------------------ +*/ float pixelToTwip(float fInput, float zoom) { return (fInput / DPI / zoom) * 1440.0f; @@ -19,84 +23,96 @@ float twipToPixel(float fInput, float zoom) return fInput / 1440.0f * DPI * zoom; } -GdkPixbuf* Tile::tile_get_buffer() +/* ---------------------------- + Tile class member functions + ---------------------------- +*/ +GdkPixbuf* Tile::getBuffer() { return m_pBuffer; } -void Tile::tile_release() +void Tile::release() { g_object_unref (m_pBuffer); m_pBuffer = NULL; } -void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns) +void Tile::setPixbuf(GdkPixbuf *buffer) +{ + m_pBuffer = buffer; +} + +/* ---------------------------------- + TileBuffer class member functions + ---------------------------------- +*/ +void TileBuffer::setZoom(float newZoomFactor, int rows, int columns) { m_fZoomFactor = newZoomFactor; - tile_buffer_reset_all_tiles(); + resetAllTiles(); // set new buffer width and height m_nWidth = columns; m_nHeight = rows; } -void TileBuffer::tile_buffer_reset_all_tiles() +void TileBuffer::resetAllTiles() { std::map::iterator it = m_mTiles.begin(); for (; it != m_mTiles.end(); it++) - { - it->second.tile_release(); - } + { + it->second.release(); + } m_mTiles.clear(); } -void TileBuffer::tile_buffer_set_invalid(int x, int y) +void TileBuffer::setInvalid(int x, int y) { int index = x * m_nWidth + y; - g_info("setting invalid : %d %d",x, y); + g_info("Setting tile invalid (%d, %d)", x, y); if (m_mTiles.find(index) != m_mTiles.end()) - { - m_mTiles[index].valid = 0; - m_mTiles[index].tile_release(); - m_mTiles.erase(index); - } + { + m_mTiles[index].valid = 0; + m_mTiles[index].release(); + m_mTiles.erase(index); + } } -Tile& TileBuffer::tile_buffer_get_tile(int x, int y) +Tile& TileBuffer::getTile(int x, int y) { int index = x * m_nWidth + y; if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[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)); - - //create a mapping for it - m_mTiles[index].tile_set_pixbuf(pPixBuf); - m_mTiles[index].valid = 1; + GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); + if (!pPixBuf) + { + g_info ("Error allocating memory to pixbuf"); + return m_mTiles[index]; } + 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, + pBuffer, + m_nTileSize, m_nTileSize, + aTileRectangle.x, aTileRectangle.y, + pixelToTwip(m_nTileSize, m_fZoomFactor), + pixelToTwip(m_nTileSize, m_fZoomFactor)); + + //create a mapping for it + m_mTiles[index].setPixbuf(pPixBuf); + m_mTiles[index].valid = 1; + } + return m_mTiles[index]; } -void Tile::tile_set_pixbuf(GdkPixbuf *buffer) -{ - m_pBuffer = buffer; -} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx index 15b276f238aa..7e2132f4d512 100644 --- a/libreofficekit/source/gtk/tilebuffer.hxx +++ b/libreofficekit/source/gtk/tilebuffer.hxx @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -24,32 +24,60 @@ const int DPI = 96; // Lets use a square of side 256 pixels for each tile. const int nTileSizePixels = 256; +/** + Converts the pixel value to zoom independent twip value. + + @param fInput value to convert + @param zoom the current zoom level + + @return the pixels value corresponding to given twip value +*/ float pixelToTwip(float fInput, float zoom); +/** + Converts the zoom independent twip value pixel value. + + @param fInput value to convert + @param zoom the current zoom level + + @return the twip value corresponding to given pixel value +*/ float twipToPixel(float fInput, float zoom); -/* - This class represents a single tile in the tile buffer. - TODO: Extend it to support features like double buffering +/** + This class represents a single tile in the tile buffer. + It encloses a reference to GdkPixBuf containing the pixel data of the tile. */ class Tile { public: - Tile() : valid(0) {} - ~Tile() { - } + Tile() : valid(0) {} + ~Tile() { } - GdkPixbuf* tile_get_buffer(); - void tile_release(); - void tile_set_pixbuf(GdkPixbuf*); + /** + Tells if this tile is valid or not. Initialised to 0 (invalid) during + object creation. + */ bool valid; - private: + + /// Function to get the pointer to enclosing GdkPixbuf + GdkPixbuf* getBuffer(); + /// Destroys the enclosing GdkPixbuf object pointed to by m_pBuffer + void release(); + /// Used to set the pixel buffer of this object + void setPixbuf(GdkPixbuf*); + +private: + /// Pixel buffer data for this tile GdkPixbuf *m_pBuffer; }; -/* - TileBuffer is the buffer caching all the recently rendered tiles. - The buffer is set to invalid when zoom factor changes. +/** + This class represents the tile buffer which is responsible for managing, + reusing and caching all the already rendered tiles. If the given tile is not + present in the buffer, call to LOK Document's (m_pLOKDocument) paintTile + method is made which fetches the rendered tile from LO core and store it in + buffer for future reuse. */ class TileBuffer { @@ -67,19 +95,58 @@ class TileBuffer ~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(); - void tile_buffer_set_invalid(int x, int y); + /** + Sets the zoom factor (m_fZoomFactor) for this tile buffer. Setting the + zoom factor invalidates whole of the tile buffer, destroys all tiles + contained within it, and sets new width, height values for tile + buffer. The width, height value of tile buffer is the width and height of + the table containing all possible tiles (rendered and non-rendered) that + this buffer can have. + + @param zoomFactor the new zoom factor value to set + */ + void setZoom(float zoomFactor, int rows, int columns); + /** + Gets the underlying Tile object for given position. The position (0, 0) + points to the left top most tile of the buffer. + + If the tile is not cached by the tile buffer, it makes a paintTile call + to LO core asking to render the given tile. It then stores the tile for + future reuse. + + @param x the tile along the x-axis of the buffer + @param y the tile along the y-axis of the buffer + + @return the tile at the mentioned position (x, y) + */ + Tile& getTile(int x, int y); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); + /** + Marks the tile as invalid. The tile (0, 0) is the left topmost tile in + the tile buffer. + + @param x the position of tile along x-axis + @param y the position of tile along y-axis + */ + void setInvalid(int x, int y); + private: + /// Contains the reference to the LOK Document that this tile buffer is for. LibreOfficeKitDocument *m_pLOKDocument; + /// The side of each squared tile in pixels. int m_nTileSize; + /// The zoom factor that the tile buffer is currently rendered to. float m_fZoomFactor; + /// Stores all the tiles cached by this tile buffer. std::map m_mTiles; - //TODO: Also set width and height when document size changes + /// Width of the current tile buffer (number of columns) int m_nWidth; + /// Height of the current tile buffer (numbero of rows) int m_nHeight; }; #endif // INCLUDED_TILEBUFFER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- 2.12.0