libreofficekit/source/gtk/lokdocview.cxx | 67 ++++++++++--------------------- libreofficekit/source/gtk/tilebuffer.cxx | 15 ++++++ libreofficekit/source/gtk/tilebuffer.hxx | 10 ++++ 3 files changed, 48 insertions(+), 44 deletions(-)
New commits: commit 7e129d994bb268715168daee306b792bc9a3a6c3 Author: Michael Meeks <[email protected]> AuthorDate: Tue Nov 12 21:19:25 2019 +0000 Commit: Michael Meeks <[email protected]> CommitDate: Wed Nov 13 11:16:35 2019 +0100 lokdocview: refresh tile buffer on resize to avoid UI breakage. Otherwise we get tiles in the wrong locations based on incorrrect widths. Change-Id: I1c76bc6eaabd8af4c283e421bf8901e7d64b4efa Reviewed-on: https://gerrit.libreoffice.org/82557 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Meeks <[email protected]> diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 6f12438fde57..f8815e673458 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -351,22 +351,6 @@ struct CallbackData }; static void -payloadToSize(const char* pPayload, long& rWidth, long& rHeight) -{ - rWidth = rHeight = 0; - gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); - gchar** ppCoordinate = ppCoordinates; - if (!*ppCoordinate) - return; - rWidth = atoi(*ppCoordinate); - ++ppCoordinate; - if (!*ppCoordinate) - return; - rHeight = atoi(*ppCoordinate); - g_strfreev(ppCoordinates); -} - -static void LOKPostCommand (LOKDocView* pDocView, const gchar* pCommand, const gchar* pArguments, @@ -862,6 +846,25 @@ static std::string getAuthorRenderingArgument(LOKDocViewPrivate& priv) /// Author string <-> View ID map static std::map<std::string, int> g_aAuthorViews; +static void refreshSize(LOKDocView* pDocView) +{ + LOKDocViewPrivate& priv = getPrivate(pDocView); + + priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); + float zoom = priv->m_fZoom; + long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; + long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; + long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); + long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); + // Total number of columns in this document. + guint nColumns = ceil(static_cast<double>(nDocumentWidthPixels) / nTileSizePixels); + + priv->m_pTileBuffer = std::unique_ptr<TileBuffer>(new TileBuffer(nColumns)); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +} + /// Set up LOKDocView after the document is loaded, invoked on the main thread by openDocumentInThread() running in a thread. static gboolean postDocumentLoad(gpointer pData) { @@ -873,23 +876,12 @@ static gboolean postDocumentLoad(gpointer pData) priv->m_nViewId = priv->m_pDocument->pClass->getView(priv->m_pDocument); g_aAuthorViews[getAuthorRenderingArgument(priv)] = priv->m_nViewId; priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); - priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); priv->m_nParts = priv->m_pDocument->pClass->getParts(priv->m_pDocument); aGuard.unlock(); priv->m_nTimeoutId = g_timeout_add(600, handleTimeout, pLOKDocView); - float zoom = priv->m_fZoom; - long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; - long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; - long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); - long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); - // Total number of columns in this document. - guint nColumns = ceil(static_cast<double>(nDocumentWidthPixels) / nTileSizePixels); + refreshSize(pLOKDocView); - priv->m_pTileBuffer = std::unique_ptr<TileBuffer>(new TileBuffer(nColumns)); - gtk_widget_set_size_request(GTK_WIDGET(pLOKDocView), - nDocumentWidthPixels, - nDocumentHeightPixels); gtk_widget_set_can_focus(GTK_WIDGET(pLOKDocView), TRUE); gtk_widget_grab_focus(GTK_WIDGET(pLOKDocView)); lok_doc_view_set_zoom(pLOKDocView, 1.0); @@ -1215,15 +1207,7 @@ callback (gpointer pData) break; case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: { - if (!pCallback->m_aPayload.empty()) - payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); - else - priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); - - gtk_widget_set_size_request(GTK_WIDGET(pDocView), - twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom), - twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom)); - + refreshSize(pDocView); g_signal_emit(pDocView, doc_view_signals[SIZE_CHANGED], 0, nullptr); } break; commit 52f1f622d742bd6064375484e40d3105d0110e87 Author: Michael Meeks <[email protected]> AuthorDate: Tue Nov 12 21:18:16 2019 +0000 Commit: Michael Meeks <[email protected]> CommitDate: Wed Nov 13 11:16:26 2019 +0100 lokdocview: encapsulate tile buffer properly. Change-Id: I59d690fbde67f4985246f13b992e962d11b7b07f Reviewed-on: https://gerrit.libreoffice.org/82556 Reviewed-by: Michael Meeks <[email protected]> Tested-by: Michael Meeks <[email protected]> diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 1e989d03f5ae..6f12438fde57 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -1533,7 +1533,6 @@ paintTileCallback(GObject* sourceObject, GAsyncResult* res, gpointer userData) LOKDocViewPrivate& priv = getPrivate(pDocView); LOEvent* pLOEvent = static_cast<LOEvent*>(userData); std::unique_ptr<TileBuffer>& buffer = priv->m_pTileBuffer; - int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; GError* error; error = nullptr; @@ -1550,8 +1549,7 @@ paintTileCallback(GObject* sourceObject, GAsyncResult* res, gpointer userData) return; } - buffer->m_mTiles[index].setSurface(pSurface); - buffer->m_mTiles[index].valid = true; + buffer->setTile(pLOEvent->m_nPaintTileX, pLOEvent->m_nPaintTileY, pSurface); gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); cairo_surface_destroy(pSurface); @@ -2338,9 +2336,7 @@ paintTileInThread (gpointer data) return; } std::unique_ptr<TileBuffer>& buffer = priv->m_pTileBuffer; - int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; - if (buffer->m_mTiles.find(index) != buffer->m_mTiles.end() && - buffer->m_mTiles[index].valid) + if (buffer->hasValidTile(pLOEvent->m_nPaintTileX, pLOEvent->m_nPaintTileY)) return; cairo_surface_t *pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nTileSizePixels, nTileSizePixels); @@ -3511,7 +3507,6 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, fZoom); // Total number of columns in this document. guint nColumns = ceil(static_cast<double>(nDocumentWidthPixels) / nTileSizePixels); - priv->m_pTileBuffer = std::unique_ptr<TileBuffer>(new TileBuffer(nColumns)); gtk_widget_set_size_request(GTK_WIDGET(pDocView), nDocumentWidthPixels, diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx index 9085ba06ac2c..82f0253d9e82 100644 --- a/libreofficekit/source/gtk/tilebuffer.cxx +++ b/libreofficekit/source/gtk/tilebuffer.cxx @@ -109,6 +109,21 @@ Tile& TileBuffer::getTile(int x, int y, GTask* task, return m_mTiles[index]; } +void TileBuffer::setTile(int x, int y, cairo_surface_t *surface) +{ + int index = x * m_nWidth + y; + + m_mTiles[index].setSurface(surface); + m_mTiles[index].valid = true; +} + +bool TileBuffer::hasValidTile(int x, int y) +{ + int index = x * m_nWidth + y; + auto it = m_mTiles.find(index); + return (it != m_mTiles.end()) && it->second.valid; +} + void LOEvent::destroy(void* pMemory) { LOEvent* pLOEvent = static_cast<LOEvent*>(pMemory); diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx index 88961cc1f44d..fccc6211acc3 100644 --- a/libreofficekit/source/gtk/tilebuffer.hxx +++ b/libreofficekit/source/gtk/tilebuffer.hxx @@ -116,6 +116,15 @@ class TileBuffer @return the tile at the mentioned position (x, y) */ Tile& getTile(int x, int y, GTask* task, GThreadPool* pool); + + /* + Takes ownership of the surface and sets it on a tile at a given location + */ + void setTile(int x, int y, cairo_surface_t *surface); + + /// Returns true if a valid tile exists at this location + bool hasValidTile(int x, int y); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated /// for all the Tile objects. void resetAllTiles(); @@ -133,6 +142,7 @@ class TileBuffer */ void setInvalid(int x, int y, float zoom, GTask* task, GThreadPool*); +private: /// Stores all the tiles cached by this tile buffer. std::map<int, Tile> m_mTiles; /// Width of the current tile buffer (number of columns) _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
