[Libreoffice-commits] core.git: 43 commits - android/Bootstrap android/experimental android/mobile-config.py desktop/source include/LibreOfficeKit libreofficekit/Executable_gtktiledviewer.mk libreofficekit/Library_libreofficekitgtk.mk libreofficekit/qa libreofficekit/source sw/inc sw/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Jan 16 04:19:03 PST 2015


 android/Bootstrap/src/org/libreoffice/kit/DirectBufferAllocator.java                      |   12 
 android/Bootstrap/src/org/libreoffice/kit/Document.java                                   |    8 
 android/Bootstrap/src/org/libreoffice/kit/Office.java                                     |    7 
 android/experimental/LOAndroid3/Makefile                                                  |    2 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java                     |   20 +
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java                  |   39 +-
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java                 |   18 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java           |   25 +
 android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java     |   33 +
 android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java            |    5 
 android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java                |   13 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java           |   13 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/CheckerboardImage.java     |  146 -------
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java     |  112 +++--
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java      |    9 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/FixedZoomTileLayer.java    |    5 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java      |    4 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java |   44 ++
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java             |    1 
 android/mobile-config.py                                                                  |    1 
 desktop/source/lib/init.cxx                                                               |    9 
 desktop/source/lib/lokandroid.cxx                                                         |    4 
 include/LibreOfficeKit/LibreOfficeKit.h                                                   |    9 
 include/LibreOfficeKit/LibreOfficeKitGtk.h                                                |    9 
 libreofficekit/Executable_gtktiledviewer.mk                                               |    2 
 libreofficekit/Library_libreofficekitgtk.mk                                               |    1 
 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx                                       |   35 +
 libreofficekit/source/gtk/lokdocview.c                                                    |  187 ++++++----
 sw/inc/viewsh.hxx                                                                         |    4 
 sw/source/core/layout/pagechg.cxx                                                         |    6 
 sw/source/core/view/viewimp.cxx                                                           |   10 
 sw/source/core/view/viewsh.cxx                                                            |   38 +-
 sw/source/uibase/uno/unotxdoc.cxx                                                         |    8 
 33 files changed, 525 insertions(+), 314 deletions(-)

New commits:
commit 7e01796c456d7006b73ad4ec2fc502bf8fe8d2ce
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 15 15:16:48 2015 +0100

    lokdocview: add LOKDocViewCallbackData
    
    So that the callback code running on the main thread can be aware of the
    event type and payload (necessary in the future to do partial repaints).
    
    Change-Id: I790b2ce0b6f9f88ba71d94a17bf0c8fc1b567c5f

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 5e6e790..d9be2df 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -178,20 +178,30 @@ void renderDocument( LOKDocView* pDocView )
     }
 }
 
+/// Callback data, allocated in lok_docview_callback_worker(), released in lok_docview_callback().
+typedef struct
+{
+    int m_nType;
+    const char* m_pPayload;
+    LOKDocView* m_pDocView;
+}
+LOKDocViewCallbackData;
+
 /// Invoked on the main thread if lok_docview_callback_worker() requests so.
 static gboolean lok_docview_callback(gpointer pData)
 {
-    LOKDocView* pDocView = pData;
-
-#if ! GTK_CHECK_VERSION(2,12,0)
-    GDK_THREADS_ENTER();
-#endif
+    LOKDocViewCallbackData* pCallback = pData;
 
-    renderDocument(pDocView);
+    switch (pCallback->m_nType)
+    {
+    case LOK_CALLBACK_INVALIDATE_TILES:
+        renderDocument(pCallback->m_pDocView);
+        break;
+    default:
+        break;
+    }
 
-#if ! GTK_CHECK_VERSION(2,12,0)
-    GDK_THREADS_LEAVE();
-#endif
+    g_free(pCallback);
     return G_SOURCE_REMOVE;
 }
 
@@ -200,20 +210,15 @@ static void lok_docview_callback_worker(int nType, const char* pPayload, void* p
 {
     LOKDocView* pDocView = pData;
 
-    switch (nType)
-    {
-    case LOK_CALLBACK_INVALIDATE_TILES:
-        // TODO for now just always render the document.
-        (void)pPayload;
+    LOKDocViewCallbackData* pCallback = g_new0(LOKDocViewCallbackData, 1);
+    pCallback->m_nType = nType;
+    pCallback->m_pPayload = pPayload;
+    pCallback->m_pDocView = pDocView;
 #if GTK_CHECK_VERSION(2,12,0)
-        gdk_threads_add_idle(lok_docview_callback, pDocView);
+    gdk_threads_add_idle(lok_docview_callback, pCallback);
 #else
-        g_idle_add(lok_docview_callback, pDocView);
+    g_idle_add(lok_docview_callback, pDocView);
 #endif
-        break;
-    default:
-        break;
-    }
 }
 
 SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, char* pPath )
commit bd065f5abacc0c5c0b55d15b67809ebf4898c646
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 19:03:39 2015 +0900

    android: Add key events in TileProvider & pass key events to LOK
    
    Change-Id: Id0a93f1c4199082b3c67802955082d04831ec124

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 32cb43c..3b7f657 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -147,6 +147,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
             case LOEvent.TOUCH:
                 touch(event.mTouchType, event.mMotionEvent);
                 break;
+            case LOEvent.KEY_PRESS:
+                mTileProvider.keyPress(event.mKeyEvent);
+                break;
         }
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index b7dee3b..0970bbb 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -3,6 +3,7 @@ package org.libreoffice;
 import android.graphics.Bitmap;
 import android.graphics.RectF;
 import android.util.Log;
+import android.view.KeyEvent;
 
 import org.libreoffice.kit.DirectBufferAllocator;
 import org.libreoffice.kit.Document;
@@ -272,6 +273,11 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         this.tileInvalidationCallback = tileInvalidationCallback;
     }
 
+    @Override
+    public void keyPress(KeyEvent keyEvent) {
+        mOffice.postKeyEvent(Office.KEY_PRESS, keyEvent.getKeyCode());
+    }
+
 
     @Override
     protected void finalize() throws Throwable {
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
index 16772d0..15332a7 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
@@ -1,6 +1,7 @@
 package org.libreoffice;
 
 import android.graphics.Bitmap;
+import android.view.KeyEvent;
 
 import org.mozilla.gecko.gfx.BufferedCairoImage;
 import org.mozilla.gecko.gfx.CairoImage;
@@ -87,6 +88,10 @@ public class MockTileProvider implements TileProvider {
     }
 
     @Override
+    public void keyPress(KeyEvent keyEvent) {
+    }
+
+    @Override
     public void changePart(int partIndex) {
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
index faa55a8..da0d0f4 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
@@ -3,6 +3,7 @@ package org.libreoffice;
 
 import android.graphics.Bitmap;
 import android.graphics.RectF;
+import android.view.KeyEvent;
 
 import org.mozilla.gecko.gfx.CairoImage;
 import org.mozilla.gecko.gfx.IntSize;
@@ -33,6 +34,8 @@ public interface TileProvider {
 
     void registerInvalidationCallback(TileProvider.TileInvalidationCallback tileInvalidationCallback);
 
+    void keyPress(KeyEvent keyEvent);
+
     /**
      * Callback to retrieve invalidation calls
      */
commit 89d41753df7ad3e2c266c77895370deb0a4af274
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 19:01:04 2015 +0900

    android: Add needed services for editing.
    
    Change-Id: I29acea58b4e18efcf33b51361812c3f7532282ab

diff --git a/android/experimental/LOAndroid3/Makefile b/android/experimental/LOAndroid3/Makefile
index a19fadc..e700daa 100644
--- a/android/experimental/LOAndroid3/Makefile
+++ b/android/experimental/LOAndroid3/Makefile
@@ -14,7 +14,7 @@ BOOTSTRAPDIR=../../Bootstrap
 include $(BOOTSTRAPDIR)/Makefile.shared
 
 native-code.cxx: $(SRCDIR)/solenv/bin/native-code.py
-	$< -j -g core -g writer -g calc -g draw > $@
+	$< -j -g core -g writer -g calc -g draw -g edit > $@
 
 build-ant: android_version_setup copy-stuff link-so properties
 #
diff --git a/android/mobile-config.py b/android/mobile-config.py
index 9981840..93e08c6 100755
--- a/android/mobile-config.py
+++ b/android/mobile-config.py
@@ -23,7 +23,6 @@ main_xcd_discard = [
 
     # no conventional UI; reverse sorted by size
     'org.openoffice.Office.UI/GenericCommands',
-    'org.openoffice.Office/Accelerators',
     'org.openoffice.Office.UI/DrawImpressCommands',
     'org.openoffice.Office.UI/Sidebar',
     'org.openoffice.Office.UI/ChartCommands',
commit 389fae7cbafac76591fb99054f0fcaeefb441a37
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 18:06:44 2015 +0900

    android: Add some comments.
    
    Change-Id: I77372ae2b1c7c4332dc4a8c244c67a82f9551e22

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
index 03b9aaf..5206694 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
@@ -49,6 +49,9 @@ public class LOKitShell {
 
     // EVENTS
 
+    /**
+     * Make sure LOKitThread is running and send event to it.
+     */
     public static void sendEvent(LOEvent event) {
         if (LibreOfficeMainActivity.mAppContext != null && LibreOfficeMainActivity.mAppContext.getLOKitThread() != null) {
             LibreOfficeMainActivity.mAppContext.getLOKitThread().queueEvent(event);
@@ -59,10 +62,16 @@ public class LOKitShell {
         LOKitShell.sendEvent(new LOEvent(LOEvent.THUMBNAIL, task));
     }
 
+    /**
+     * Send touch event to LOKitThread.
+     */
     public static void sentTouchEvent(String touchType, MotionEvent motionEvent) {
         LOKitShell.sendEvent(new LOEvent(LOEvent.TOUCH, "SingleTap", motionEvent));
     }
 
+    /**
+     * Send key press event to LOKitThread.
+     */
     public static void sendKeyPressEvent(KeyEvent event) {
         LOKitShell.sendEvent(new LOEvent(LOEvent.KEY_PRESS, event));
     }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 7eda1f1..b7dee3b 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -15,6 +15,9 @@ import org.mozilla.gecko.gfx.IntSize;
 
 import java.nio.ByteBuffer;
 
+/**
+ * LOKit implementation of TileProvider.
+ */
 public class LOKitTileProvider implements TileProvider, Document.MessageCallback {
     private static final String LOGTAG = LOKitTileProvider.class.getSimpleName();
     private static int TILE_SIZE = 256;
@@ -261,6 +264,9 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_TEXT;
     }
 
+    /**
+     * Register the tile invalidation callback.
+     */
     @Override
     public void registerInvalidationCallback(TileInvalidationCallback tileInvalidationCallback) {
         this.tileInvalidationCallback = tileInvalidationCallback;
@@ -284,6 +290,9 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
         return mDocument.getPart();
     }
 
+    /**
+     * Process the retrieved messages from LOK
+     */
     @Override
     public void messageRetrieved(int signalNumber, String payload) {
         switch (signalNumber) {
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index b79217d..5efbc68 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -192,6 +192,10 @@ public class LibreOfficeMainActivity extends LOAbout {
         return mDocumentPartViewListAdapter;
     }
 
+    /**
+     * Show software keyboard.
+     * Force the request on main thread.
+     */
     public void showSoftKeyboard() {
         Log.i(LOGTAG, "SoftKeyboard show request..");
 
@@ -241,6 +245,10 @@ public class LibreOfficeMainActivity extends LOAbout {
         }
     }
 
+
+    /**
+     * Listen to key presses and send event to LOK.
+     */
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         LOKitShell.sendKeyPressEvent(event);
commit 376639778151e433371941487d030e157a6b75ef
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 17:45:48 2015 +0900

    android: add missing break
    
    Change-Id: I5e9598249457c62d3ccc9c5f754526c1fbe969bf

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 9334536..7eda1f1 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -305,6 +305,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                         tileInvalidationCallback.invalidate(rect);
                     }
                 }
+                break;
         }
     }
 }
commit b7469087e107f1380e01f836d06d17e9bad12f63
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 17:44:27 2015 +0900

    android: add key_press event and send them to LOKitThread
    
    Change-Id: I306fbe12e0a91e28bb2308074ded03b768173440

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
index 7ec346b..809988d 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
@@ -1,5 +1,6 @@
 package org.libreoffice;
 
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import org.mozilla.gecko.gfx.ComposedTileLayer;
@@ -17,6 +18,7 @@ public class LOEvent implements Comparable<LOEvent> {
     public static final int THUMBNAIL = 8;
     public static final int TILE_RERENDER = 9;
     public static final int TOUCH = 10;
+    public static final int KEY_PRESS = 11;
 
     public final int mType;
     public int mPriority = 0;
@@ -31,6 +33,7 @@ public class LOEvent implements Comparable<LOEvent> {
     public SubTile mTile;
     public String mTouchType;
     public MotionEvent mMotionEvent;
+    public KeyEvent mKeyEvent;
 
     public LOEvent(int type) {
         mType = type;
@@ -85,6 +88,11 @@ public class LOEvent implements Comparable<LOEvent> {
         mMotionEvent = motionEvent;
     }
 
+    public LOEvent(int type, KeyEvent keyEvent) {
+        mType = type;
+        mKeyEvent = keyEvent;
+    }
+
     public String getTypeString() {
         if (mTypeString == null) {
             return "Event type: " + mType;
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
index e894690..03b9aaf 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
@@ -3,6 +3,7 @@ package org.libreoffice;
 
 import android.os.Handler;
 import android.util.DisplayMetrics;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 
@@ -61,4 +62,8 @@ public class LOKitShell {
     public static void sentTouchEvent(String touchType, MotionEvent motionEvent) {
         LOKitShell.sendEvent(new LOEvent(LOEvent.TOUCH, "SingleTap", motionEvent));
     }
+
+    public static void sendKeyPressEvent(KeyEvent event) {
+        LOKitShell.sendEvent(new LOEvent(LOEvent.KEY_PRESS, event));
+    }
 }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index a40d78c..b79217d 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -9,6 +9,7 @@ import android.os.Handler;
 import android.support.v4.widget.DrawerLayout;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -239,6 +240,12 @@ public class LibreOfficeMainActivity extends LOAbout {
             mDrawerLayout.closeDrawer(mDrawerList);
         }
     }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        LOKitShell.sendKeyPressEvent(event);
+        return super.onKeyDown(keyCode, event);
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 56e7490ee611a746c1351d19c22a615cbf90afdf
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Jan 16 16:02:38 2015 +0900

    android: remove invalidation registration on touch for now
    
    Change-Id: I7b3acba83de0c17bd4723fb6623827dbbb82fbbf

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index ed89536..32cb43c 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -22,7 +22,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
     private TileProvider mTileProvider;
     private ImmutableViewportMetrics mViewportMetrics;
     private GeckoLayerClient mLayerClient;
-    private boolean mInvalidationCallbackRegistered = false;
 
     public LOKitThread() {
         TileProviderFactory.initialize();
@@ -99,9 +98,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         boolean isReady = mTileProvider.isReady();
         if (isReady) {
             LOKitShell.showProgressSpinner();
+            mTileProvider.registerInvalidationCallback(this);
             refresh();
             LOKitShell.hideProgressSpinner();
-            mInvalidationCallbackRegistered = false;
         }
         return isReady;
     }
@@ -153,10 +152,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
 
     private void touch(String touchType, MotionEvent motionEvent) {
         LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
-        if (!mInvalidationCallbackRegistered) {
-            mTileProvider.registerInvalidationCallback(this);
-            mInvalidationCallbackRegistered = true;
-        }
     }
 
     private void createThumbnail(final ThumbnailCreator.ThumbnailCreationTask task) {
commit db214657517648f8ade794abc276dae36376cf5d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 15 14:39:45 2015 +0100

    SwViewImp::AddPaintRect: when tiled rendering, ignore visual area
    
    With this, gtktiledviewer gets the proper invalidation rectangles after
    keypresses.
    
    Change-Id: I9bd1f5b59d05ae93a0a1d018dda8b2efc01cb38c

diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx
index b08aa42..35805bf 100644
--- a/sw/source/core/view/viewimp.cxx
+++ b/sw/source/core/view/viewimp.cxx
@@ -132,10 +132,16 @@ void SwViewImp::DelRegion()
 
 bool SwViewImp::AddPaintRect( const SwRect &rRect )
 {
-    if ( rRect.IsOver( pSh->VisArea() ) )
+    // In case of tiled rendering the visual area is the last painted tile -> not interesting.
+    if ( rRect.IsOver( pSh->VisArea() ) || pSh->isTiledRendering() )
     {
         if ( !pRegion )
-            pRegion = new SwRegionRects( pSh->VisArea() );
+        {
+            // In case of normal rendering, this makes sure only visible rectangles are painted.
+            // Otherwise get the rectangle of the full document, so all paint rectangles are invalidated.
+            const SwRect& rArea = pSh->isTiledRendering() ? pSh->GetLayout()->Frm() : pSh->VisArea();
+            pRegion = new SwRegionRects( rArea );
+        }
         (*pRegion) -= rRect;
         return true;
     }
commit d6a1db752d84acdd9c76a2d9d5d2bd5668660d74
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 18:40:49 2015 +0900

    android: register invalidtion callback on first touch
    
    Change-Id: I3a98358934b79a2ace574714aa331fdce4a421bb

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 30af98d..ed89536 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -4,6 +4,7 @@ import android.graphics.Bitmap;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.util.Log;
+import android.view.MotionEvent;
 
 import org.mozilla.gecko.gfx.CairoImage;
 import org.mozilla.gecko.gfx.ComposedTileLayer;
@@ -21,6 +22,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
     private TileProvider mTileProvider;
     private ImmutableViewportMetrics mViewportMetrics;
     private GeckoLayerClient mLayerClient;
+    private boolean mInvalidationCallbackRegistered = false;
 
     public LOKitThread() {
         TileProviderFactory.initialize();
@@ -97,11 +99,10 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         boolean isReady = mTileProvider.isReady();
         if (isReady) {
             LOKitShell.showProgressSpinner();
-            mTileProvider.registerInvalidationCallback(this);
             refresh();
             LOKitShell.hideProgressSpinner();
+            mInvalidationCallbackRegistered = false;
         }
-
         return isReady;
     }
 
@@ -143,8 +144,18 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
                 break;
             case LOEvent.THUMBNAIL:
                 createThumbnail(event.mTask);
+                break;
             case LOEvent.TOUCH:
-                LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
+                touch(event.mTouchType, event.mMotionEvent);
+                break;
+        }
+    }
+
+    private void touch(String touchType, MotionEvent motionEvent) {
+        LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
+        if (!mInvalidationCallbackRegistered) {
+            mTileProvider.registerInvalidationCallback(this);
+            mInvalidationCallbackRegistered = true;
         }
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 752e0a9..9334536 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -70,8 +70,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
 
     public void postLoad() {
         mDocument.initializeForRendering();
-        // FIXME see gtktiledviewer, this has to be registered when we enter edit mode, not right after loading.
-        // mDocument.setMessageCallback(this);
+        mDocument.setMessageCallback(this);
 
         int parts = mDocument.getParts();
         Log.i(LOGTAG, "Document parts: " + parts);
@@ -303,7 +302,6 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
                                 twipToPixel(x + width, mDPI),
                                 twipToPixel(y + height, mDPI)
                         );
-                        Log.i(LOGTAG, "Invalidate R: " + rect +" - " + getPageWidth() + " " + getPageHeight());
                         tileInvalidationCallback.invalidate(rect);
                     }
                 }
commit a81010b96575292352316a0d5897ba93521b9254
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 15 10:34:13 2015 +0100

    SwViewShell: make sure no callback is fired during PaintTile()
    
    When the invalidation callback is invoked, we call PaintTile() for each
    tile that is affected by the invalidated rectangle. Make sure
    PaintTile() doesn't result in new invalidations generated by itself,
    to avoid infinite loops.
    
    Change-Id: I593726bd7e72028f26103829831949f000665e95

diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index ba2402c..b452db5 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1778,6 +1778,8 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
     OutputDevice *pSaveOut = mpOut;
     bool bTiledRendering = mbTiledRendering;
     mbTiledRendering = true;
+    LibreOfficeKitCallback pCallback = mpLibreOfficeKitCallback;
+    mpLibreOfficeKitCallback = 0;
     mpOut = &rDevice;
 
     // resizes the virtual device so to contain the entrie context
@@ -1825,6 +1827,7 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
 
     // SwViewShell's output device tear down
     mpOut = pSaveOut;
+    mpLibreOfficeKitCallback = pCallback;
     mbTiledRendering = bTiledRendering;
 
     static bool bDebug = getenv("SW_DEBUG_TILEDRENDERING") != 0;
commit 548ed2c3322bd4455d3def980d227c50dbbf1f58
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 15 10:33:42 2015 +0100

    SwViewShell::InvalidateWindows: when tiled rendering, ignore visual area
    
    Change-Id: I9b40a32e08f4472b75a236e2720ecbe5927117fb

diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index ac49e5e..ba2402c 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -543,7 +543,9 @@ void SwViewShell::InvalidateWindows( const SwRect &rRect )
             {
                 if ( rSh.IsPreview() )
                     ::RepaintPagePreview( &rSh, rRect );
-                else if ( rSh.VisArea().IsOver( rRect ) )
+                // In case of tiled rendering, invalidation is wanted even if
+                // the rectangle is outside the visual area.
+                else if ( rSh.VisArea().IsOver( rRect ) || rSh.isTiledRendering() )
                     rSh.GetWin()->Invalidate( rRect.SVRect() );
             }
         }
commit 6263bcfd70bf76dbcdf6b7e35bb02e48e44cbd94
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 17:56:14 2015 +0900

    android: store tiles in Map for faster access to tiles
    
    Change-Id: I54c5fbe0b24ecf82de2d3d9f72d7f72d59125d58

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 6f288d5..862d2c8 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -14,14 +14,18 @@ import org.libreoffice.LOKitShell;
 import org.libreoffice.TileIdentifier;
 import org.mozilla.gecko.util.FloatUtils;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 public abstract class ComposedTileLayer extends Layer implements ComponentCallbacks2 {
     private static final String LOGTAG = ComposedTileLayer.class.getSimpleName();
 
-    protected final List<SubTile> tiles = new CopyOnWriteArrayList<SubTile>();
+    protected final ConcurrentMap<TileIdentifier, SubTile> tiles = new ConcurrentHashMap<TileIdentifier, SubTile>();
+    protected final Set<TileIdentifier> newTileIds = Collections.newSetFromMap(new ConcurrentHashMap<TileIdentifier, Boolean>());
 
     protected final IntSize tileSize;
     protected RectF currentViewport = new RectF();
@@ -38,7 +42,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     }
 
     public void invalidate() {
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             tile.invalidate();
         }
     }
@@ -46,14 +50,14 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     @Override
     public void beginTransaction() {
         super.beginTransaction();
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             tile.beginTransaction();
         }
     }
 
     @Override
     public void endTransaction() {
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             tile.endTransaction();
         }
         super.endTransaction();
@@ -61,7 +65,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
 
     @Override
     public void draw(RenderContext context) {
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             if (RectF.intersects(tile.getBounds(context), context.viewport)) {
                 tile.draw(context);
             }
@@ -72,7 +76,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     protected void performUpdates(RenderContext context) {
         super.performUpdates(context);
 
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             tile.beginTransaction();
             tile.refreshTileMetrics();
             tile.endTransaction();
@@ -83,7 +87,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     @Override
     public Region getValidRegion(RenderContext context) {
         Region validRegion = new Region();
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             validRegion.op(tile.getValidRegion(context), Region.Op.UNION);
         }
 
@@ -93,7 +97,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     @Override
     public void setResolution(float newResolution) {
         super.setResolution(newResolution);
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             tile.setResolution(newResolution);
         }
     }
@@ -163,14 +167,9 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
                 if (x > pageRect.width()) {
                     continue;
                 }
-                boolean contains = false;
-                for (SubTile tile : tiles) {
-                    if (tile.id.x == x && tile.id.y == y && tile.id.zoom == currentZoom) {
-                        contains = true;
-                    }
-                }
-                if (!contains) {
-                    TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
+                TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
+                if (!tiles.containsKey(tileId) && !newTileIds.contains(tileId)) {
+                    newTileIds.add(tileId);
                     LOEvent event = LOEventFactory.tileRequest(this, tileId, true);
                     event.mPriority = getTilePriority();
                     LOKitShell.sendEvent(event);
@@ -180,18 +179,18 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     }
 
     private void clearMarkedTiles() {
-        List<SubTile> tilesToRemove = new ArrayList<SubTile>();
-        for (SubTile tile : tiles) {
+        Iterator<Map.Entry<TileIdentifier, SubTile>> iterator;
+        for (iterator = tiles.entrySet().iterator(); iterator.hasNext();) {
+            SubTile tile = iterator.next().getValue();
             if (tile.markedForRemoval) {
                 tile.destroy();
-                tilesToRemove.add(tile);
+                iterator.remove();
             }
         }
-        tiles.removeAll(tilesToRemove);
     }
 
     private void markTiles() {
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
                 RectF tileRect = tile.id.getRect();
                 if (!RectF.intersects(currentViewport, tileRect)) {
@@ -210,7 +209,8 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
 
     public void addTile(SubTile tile) {
         tile.beginTransaction();
-        tiles.add(tile);
+        tiles.put(tile.id, tile);
+        newTileIds.remove(tile.id);
     }
 
     public boolean isStillValid(TileIdentifier tileId) {
@@ -223,7 +223,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     public void invalidateTiles(RectF rect) {
         RectF zoomedRect = RectUtils.inverseScale(rect, currentZoom);
 
-        for (SubTile tile : tiles) {
+        for (SubTile tile : tiles.values()) {
             if (RectF.intersects(rect, tile.id.getRect())) {
                 LOKitShell.sendEvent(LOEventFactory.tileRerender(this, tile));
             }
@@ -246,7 +246,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
             Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_LOW");
         } else if (level >= 15 /*TRIM_MEMORY_RUNNING_CRITICAL*/) {
             Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_CRITICAL");
-            clearAndReset();
+            //clearAndReset();
         }
     }
 }
\ No newline at end of file
commit 6b71410185900d7eea8d37f725c8f5ccb9b26d08
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 16:41:12 2015 +0900

    android: create tile outside of beginTransaction
    
    Change-Id: Iaf8339f1cadc4f77dfefb1e268126745d6ed7eaa

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index a488240..30af98d 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -28,8 +28,8 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
 
     private void tileRequest(ComposedTileLayer composedTileLayer, TileIdentifier tileId, boolean forceRedraw) {
         if (composedTileLayer.isStillValid(tileId)) {
-            mLayerClient.beginDrawing();
             CairoImage image = mTileProvider.createTile(tileId.x, tileId.y, tileId.size, tileId.zoom);
+            mLayerClient.beginDrawing();
             SubTile tile = new SubTile(image, tileId);
             composedTileLayer.addTile(tile);
             mLayerClient.endDrawing(mViewportMetrics);
@@ -43,7 +43,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         if (composedTileLayer.isStillValid(tile.id) && !tile.markedForRemoval) {
             mLayerClient.beginDrawing();
             mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
-            tile.invalidate();
             mLayerClient.endDrawing(mViewportMetrics);
             mLayerClient.forceRender();
         }
commit 24a92a4350fa22bfcccc1313682b1cac7de99b5e
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 16:12:05 2015 +0900

    android: simplify methods with currentZoom / currentViewport
    
    Change-Id: I6134d434ca34c0f3e839a3d78b67c5cefff53a48

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 512559f..6f288d5 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -132,7 +132,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
 
     public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics, DisplayPortMetrics mDisplayPort) {
         RectF newCurrentViewPort = getViewPort(viewportMetrics);
-        float newZoom = viewportMetrics.zoomFactor;
+        float newZoom = getZoom(viewportMetrics);
 
         if (!currentViewport.equals(newCurrentViewPort) || currentZoom != newZoom) {
             if (newZoom == 1.0f) {
@@ -140,10 +140,11 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
             }
             currentViewport = newCurrentViewPort;
             currentZoom = newZoom;
+            RectF pageRect = viewportMetrics.getPageRect();
 
             clearMarkedTiles();
-            addNewTiles(viewportMetrics);
-            markTiles(viewportMetrics);
+            addNewTiles(pageRect);
+            markTiles();
         }
     }
 
@@ -153,25 +154,23 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
 
     protected abstract int getTilePriority();
 
-    private void addNewTiles(ImmutableViewportMetrics viewportMetrics) {
-        float zoom = getZoom(viewportMetrics);
-
+    private void addNewTiles(RectF pageRect) {
         for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) {
-            if (y > viewportMetrics.getPageHeight()) {
+            if (y > pageRect.height()) {
                 continue;
             }
             for (float x = currentViewport.left; x < currentViewport.right; x += tileSize.width) {
-                if (x > viewportMetrics.getPageWidth()) {
+                if (x > pageRect.width()) {
                     continue;
                 }
                 boolean contains = false;
                 for (SubTile tile : tiles) {
-                    if (tile.id.x == x && tile.id.y == y && tile.id.zoom == zoom) {
+                    if (tile.id.x == x && tile.id.y == y && tile.id.zoom == currentZoom) {
                         contains = true;
                     }
                 }
                 if (!contains) {
-                    TileIdentifier tileId = new TileIdentifier((int) x, (int) y, zoom, tileSize);
+                    TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
                     LOEvent event = LOEventFactory.tileRequest(this, tileId, true);
                     event.mPriority = getTilePriority();
                     LOKitShell.sendEvent(event);
@@ -191,8 +190,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
         tiles.removeAll(tilesToRemove);
     }
 
-    private void markTiles(ImmutableViewportMetrics viewportMetrics) {
-        float zoom = getZoom(viewportMetrics);
+    private void markTiles() {
         for (SubTile tile : tiles) {
             if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
                 RectF tileRect = tile.id.getRect();
commit 4712db6bb77d4bf8135339b9de4619faa505be3d
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:57:46 2015 +0900

    android: add onTrimMemory to ComposedTileLayer
    
    Change-Id: I9c85aa5de1495e16ec67f68043784c661c2b66ab

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 37b1aeb..512559f 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -1,6 +1,9 @@
 package org.mozilla.gecko.gfx;
 
+import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.util.Log;
@@ -15,7 +18,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
-public abstract class ComposedTileLayer extends Layer {
+public abstract class ComposedTileLayer extends Layer implements ComponentCallbacks2 {
     private static final String LOGTAG = ComposedTileLayer.class.getSimpleName();
 
     protected final List<SubTile> tiles = new CopyOnWriteArrayList<SubTile>();
@@ -24,7 +27,13 @@ public abstract class ComposedTileLayer extends Layer {
     protected RectF currentViewport = new RectF();
     protected float currentZoom;
 
+    private static int getMemoryClass(Context context) {
+        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        return activityManager.getMemoryClass() * 1024 * 1024;
+    }
+
     public ComposedTileLayer(Context context) {
+        context.registerComponentCallbacks(this);
         this.tileSize = new IntSize(256, 256);
     }
 
@@ -185,7 +194,7 @@ public abstract class ComposedTileLayer extends Layer {
     private void markTiles(ImmutableViewportMetrics viewportMetrics) {
         float zoom = getZoom(viewportMetrics);
         for (SubTile tile : tiles) {
-            if (FloatUtils.fuzzyEquals(tile.id.zoom, zoom)) {
+            if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
                 RectF tileRect = tile.id.getRect();
                 if (!RectF.intersects(currentViewport, tileRect)) {
                     tile.markForRemoval();
@@ -222,4 +231,24 @@ public abstract class ComposedTileLayer extends Layer {
             }
         }
     }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+    }
+
+    @Override
+    public void onLowMemory() {
+        Log.i(LOGTAG, "onLowMemory");
+    }
+
+    @Override
+    public void onTrimMemory(int level) {
+        Log.i(LOGTAG, "Trimming memory " + level);
+        if (level >= 10 /*TRIM_MEMORY_RUNNING_LOW*/) {
+            Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_LOW");
+        } else if (level >= 15 /*TRIM_MEMORY_RUNNING_CRITICAL*/) {
+            Log.i(LOGTAG, "Trimming memory - TRIM_MEMORY_RUNNING_CRITICAL");
+            clearAndReset();
+        }
+    }
 }
\ No newline at end of file
commit 7cb282b02cc83e127485c162728650f45f75fe9d
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:50:03 2015 +0900

    android: provide context to ComposedTileLayer
    
    Change-Id: If42dc9487fe11e2950becaf6b9ec857496dc6669

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 31c7a07..37b1aeb 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -1,5 +1,6 @@
 package org.mozilla.gecko.gfx;
 
+import android.content.Context;
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.util.Log;
@@ -23,14 +24,10 @@ public abstract class ComposedTileLayer extends Layer {
     protected RectF currentViewport = new RectF();
     protected float currentZoom;
 
-    public ComposedTileLayer() {
+    public ComposedTileLayer(Context context) {
         this.tileSize = new IntSize(256, 256);
     }
 
-    public ComposedTileLayer(IntSize tileSize) {
-        this.tileSize = tileSize;
-    }
-
     public void invalidate() {
         for (SubTile tile : tiles) {
             tile.invalidate();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
index 38d6d80..ea95c03 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
@@ -1,8 +1,13 @@
 package org.mozilla.gecko.gfx;
 
+import android.content.Context;
 import android.graphics.RectF;
 
 public class DynamicTileLayer extends ComposedTileLayer {
+    public DynamicTileLayer(Context context) {
+        super(context);
+    }
+
     @Override
     protected RectF getViewPort(ImmutableViewportMetrics viewportMetrics) {
         RectF rect = viewportMetrics.getViewport();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/FixedZoomTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/FixedZoomTileLayer.java
index 2db6a1d..e86494c 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/FixedZoomTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/FixedZoomTileLayer.java
@@ -1,8 +1,13 @@
 package org.mozilla.gecko.gfx;
 
+import android.content.Context;
 import android.graphics.RectF;
 
 public class FixedZoomTileLayer extends ComposedTileLayer {
+    public FixedZoomTileLayer(Context context) {
+        super(context);
+    }
+
     @Override
     protected RectF getViewPort(ImmutableViewportMetrics viewportMetrics) {
         float zoom = getZoom(viewportMetrics);
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 1bb15bc..3e70698 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -108,8 +108,8 @@ public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
     public void notifyReady() {
         mGeckoIsReady = true;
 
-        mRootLayer = new DynamicTileLayer();
-        mLowResLayer = new FixedZoomTileLayer();
+        mRootLayer = new DynamicTileLayer(mContext);
+        mLowResLayer = new FixedZoomTileLayer(mContext);
 
         mLayerRenderer = new LayerRenderer(mView);
 
commit a5e2c361f031e1ce55c4110145a0d1011eba11b3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:33:58 2015 +0900

    android: guard buffer allocation and return null if alloc. fails
    
    Change-Id: I684c7af245cc755b94f69e175c652d161e0f643a

diff --git a/android/Bootstrap/src/org/libreoffice/kit/DirectBufferAllocator.java b/android/Bootstrap/src/org/libreoffice/kit/DirectBufferAllocator.java
index 0e30e45..670e397 100644
--- a/android/Bootstrap/src/org/libreoffice/kit/DirectBufferAllocator.java
+++ b/android/Bootstrap/src/org/libreoffice/kit/DirectBufferAllocator.java
@@ -87,4 +87,14 @@ public final class DirectBufferAllocator {
         // can't free buffer - leave this to the VM
         return null;
     }
+
+    public static ByteBuffer guardedAllocate(int size) {
+        ByteBuffer buffer = null;
+        try {
+            buffer = allocate(size);
+        } catch (OutOfMemoryError oomException) {
+            return null;
+        }
+        return buffer;
+    }
 }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 0e2db4b..752e0a9 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -4,6 +4,7 @@ import android.graphics.Bitmap;
 import android.graphics.RectF;
 import android.util.Log;
 
+import org.libreoffice.kit.DirectBufferAllocator;
 import org.libreoffice.kit.Document;
 import org.libreoffice.kit.LibreOfficeKit;
 import org.libreoffice.kit.Office;
@@ -189,7 +190,10 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
 
     @Override
     public CairoImage createTile(float x, float y, IntSize tileSize, float zoom) {
-        ByteBuffer buffer = ByteBuffer.allocateDirect(tileSize.width * tileSize.height * 4);
+        ByteBuffer buffer = DirectBufferAllocator.guardedAllocate(tileSize.width * tileSize.height * 4);
+        if (buffer == null)
+            return null;
+
         CairoImage image = new BufferedCairoImage(buffer, tileSize.width, tileSize.height, CairoImage.FORMAT_ARGB32);
         rerenderTile(image, x, y, tileSize, zoom);
         return image;
commit 1e4f6eeba42f68d2587700e45ba1362f920174a3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:20:05 2015 +0900

    android: show soft keyboard on single touch event
    
    Change-Id: I9612b0d5258bbdef81903b3a67307fe54319e9c1

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 7459580..a488240 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -144,6 +144,8 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
                 break;
             case LOEvent.THUMBNAIL:
                 createThumbnail(event.mTask);
+            case LOEvent.TOUCH:
+                LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
         }
     }
 
commit cb85026c129e4ba3bb163529ed1bbaa167fdaa44
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:19:23 2015 +0900

    android: send touch events in JavaPanZoomController
    
    Change-Id: Icc0c749a0c8687f247c4e42d74b5c839d5723503

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
index ccf6280..9440091 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
@@ -12,6 +12,7 @@ import android.util.Log;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 
+import org.libreoffice.LOEventFactory;
 import org.libreoffice.LOKitShell;
 import org.libreoffice.LibreOfficeMainActivity;
 import org.mozilla.gecko.ZoomConstraints;
@@ -902,6 +903,7 @@ public class JavaPanZoomController
 
     @Override
     public void onLongPress(MotionEvent motionEvent) {
+        LOKitShell.sentTouchEvent("LongPress", motionEvent);
     }
 
     @Override
@@ -909,6 +911,7 @@ public class JavaPanZoomController
         // When double-tapping is allowed, we have to wait to see if this is
         // going to be a double-tap.
         if (!mWaitForDoubleTap) {
+            LOKitShell.sentTouchEvent("SingleTap", motionEvent);
         }
         // return false because we still want to get the ACTION_UP event that triggers this
         return false;
@@ -918,16 +921,20 @@ public class JavaPanZoomController
     public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
         // In cases where we don't wait for double-tap, we handle this in onSingleTapUp.
         if (mWaitForDoubleTap) {
+            LOKitShell.sentTouchEvent("SingleTap", motionEvent);
         }
         return true;
     }
 
     @Override
     public boolean onDoubleTap(MotionEvent motionEvent) {
+        LOKitShell.sentTouchEvent("DoubleTap", motionEvent);
         return true;
     }
 
     private void cancelTouch() {
+        //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", "");
+        //GeckoAppShell.sendEventToGecko(e);
     }
 
     /**
commit ef73f53c85e9282b1609198d0fe84c47592367cd
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:14:46 2015 +0900

    android: show software keyboard on main view in main thread
    
    Change-Id: I2df86c2837fc6469384df5626a2d54856e96f8e7

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index b83422c..a40d78c 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -2,6 +2,7 @@ package org.libreoffice;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
 import android.os.Handler;
@@ -12,6 +13,7 @@ import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
@@ -189,6 +191,22 @@ public class LibreOfficeMainActivity extends LOAbout {
         return mDocumentPartViewListAdapter;
     }
 
+    public void showSoftKeyboard() {
+        Log.i(LOGTAG, "SoftKeyboard show request..");
+
+        LOKitShell.getMainHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                LayerView layerView = (LayerView) findViewById(R.id.layer_view);
+
+                if (layerView.requestFocus()) {
+                    InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                    inputMethodManager.showSoftInput(layerView, InputMethodManager.SHOW_FORCED);
+                }
+            }
+        });
+    }
+
     public void showProgressSpinner() {
         findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE);
     }
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
index 0d2b067..6c71eeb 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
@@ -351,15 +351,6 @@ public class LayerView extends FrameLayout {
         }
     }
 
-    public void showSoftKeyboard() {
-        View view = mSurfaceView != null ? mSurfaceView : mTextureView;
-
-        if (view.requestFocus()) {
-            InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-            inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
-        }
-    }
-
     private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
         public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
             // We don't do this for surfaceCreated above because it is always followed by a surfaceChanged,
commit a3efafeda5de111fafea822a1f61712721f98d19
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:13:02 2015 +0900

    android: add support for touch event to LOEvent
    
    Change-Id: Ie4b3e48d3f06545ebfd8638cdb8e4664ad85f493

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
index 5b13da4..7ec346b 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
@@ -1,5 +1,7 @@
 package org.libreoffice;
 
+import android.view.MotionEvent;
+
 import org.mozilla.gecko.gfx.ComposedTileLayer;
 import org.mozilla.gecko.gfx.IntSize;
 import org.mozilla.gecko.gfx.SubTile;
@@ -14,6 +16,7 @@ public class LOEvent implements Comparable<LOEvent> {
     public static final int TILE_REQUEST = 7;
     public static final int THUMBNAIL = 8;
     public static final int TILE_RERENDER = 9;
+    public static final int TOUCH = 10;
 
     public final int mType;
     public int mPriority = 0;
@@ -26,6 +29,8 @@ public class LOEvent implements Comparable<LOEvent> {
     public ComposedTileLayer mComposedTileLayer;
     public boolean mForceRedraw;
     public SubTile mTile;
+    public String mTouchType;
+    public MotionEvent mMotionEvent;
 
     public LOEvent(int type) {
         mType = type;
@@ -73,6 +78,13 @@ public class LOEvent implements Comparable<LOEvent> {
         mTile = tile;
     }
 
+    public LOEvent(int type, String touchType, MotionEvent motionEvent) {
+        mType = type;
+        mTypeString = "Touch";
+        mTouchType = touchType;
+        mMotionEvent = motionEvent;
+    }
+
     public String getTypeString() {
         if (mTypeString == null) {
             return "Event type: " + mType;
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
index 8091627..e894690 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java
@@ -3,6 +3,7 @@ package org.libreoffice;
 
 import android.os.Handler;
 import android.util.DisplayMetrics;
+import android.view.MotionEvent;
 
 
 public class LOKitShell {
@@ -13,21 +14,11 @@ public class LOKitShell {
         return metrics.density * 160;
     }
 
-    public static void sendEvent(LOEvent event) {
-        if (LibreOfficeMainActivity.mAppContext != null && LibreOfficeMainActivity.mAppContext.getLOKitThread() != null) {
-            LibreOfficeMainActivity.mAppContext.getLOKitThread().queueEvent(event);
-        }
-    }
-
     // Get a Handler for the main java thread
     public static Handler getMainHandler() {
         return LibreOfficeMainActivity.mAppContext.mMainHandler;
     }
 
-    public static void queueRedraw() {
-        LOKitShell.sendEvent(LOEventFactory.redraw());
-    }
-
     public static void showProgressSpinner() {
         getMainHandler().post(new Runnable() {
             @Override
@@ -55,7 +46,19 @@ public class LOKitShell {
         return metrics;
     }
 
+    // EVENTS
+
+    public static void sendEvent(LOEvent event) {
+        if (LibreOfficeMainActivity.mAppContext != null && LibreOfficeMainActivity.mAppContext.getLOKitThread() != null) {
+            LibreOfficeMainActivity.mAppContext.getLOKitThread().queueEvent(event);
+        }
+    }
+
     public static void sendThumbnailEvent(ThumbnailCreator.ThumbnailCreationTask task) {
-        LOKitShell.sendEvent(LOEventFactory.thumbnail(task));
+        LOKitShell.sendEvent(new LOEvent(LOEvent.THUMBNAIL, task));
+    }
+
+    public static void sentTouchEvent(String touchType, MotionEvent motionEvent) {
+        LOKitShell.sendEvent(new LOEvent(LOEvent.TOUCH, "SingleTap", motionEvent));
     }
 }
commit da39c5fd715fba173836a2098b68d647e867fba6
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jan 15 15:09:00 2015 +0900

    android: fennec import - double tap zoom in JavaPanZoomController
    
    Change-Id: I0fedb5bb353e4d6f9926a8c0f0b80a81b7257d0e

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java
index 40d1817..4ac49f7 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ZoomConstraints.java
@@ -10,28 +10,27 @@ import org.json.JSONObject;
 
 public final class ZoomConstraints {
     private final boolean mAllowZoom;
+    private final boolean mAllowDoubleTapZoom;
     private final float mDefaultZoom;
     private final float mMinZoom;
     private final float mMaxZoom;
 
     public ZoomConstraints(boolean allowZoom) {
         mAllowZoom = allowZoom;
+        mAllowDoubleTapZoom = allowZoom;
         mDefaultZoom = 0.0f;
         mMinZoom = 0.0f;
         mMaxZoom = 0.0f;
     }
 
-    ZoomConstraints(JSONObject message) throws JSONException {
-        mAllowZoom = message.getBoolean("allowZoom");
-        mDefaultZoom = (float)message.getDouble("defaultZoom");
-        mMinZoom = (float)message.getDouble("minZoom");
-        mMaxZoom = (float)message.getDouble("maxZoom");
-    }
-
     public final boolean getAllowZoom() {
         return mAllowZoom;
     }
 
+    public final boolean getAllowDoubleTapZoom() {
+        return mAllowDoubleTapZoom;
+    }
+
     public final float getDefaultZoom() {
         return mDefaultZoom;
     }
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
index 3b3d33e..ccf6280 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
@@ -87,6 +87,8 @@ public class JavaPanZoomController
     private long mLastEventTime;
     /* Current state the pan/zoom UI is in. */
     private PanZoomState mState;
+    /* Whether or not to wait for a double-tap before dispatching a single-tap */
+    private boolean mWaitForDoubleTap;
 
     public JavaPanZoomController(PanZoomTarget target) {
         mTarget = target;
@@ -865,6 +867,7 @@ public class JavaPanZoomController
         mTarget.setViewportMetrics(viewportMetrics);
     }
 
+    @Override
     public boolean getRedrawHint() {
         switch (mState) {
             case PINCHING:
@@ -881,18 +884,41 @@ public class JavaPanZoomController
     }
 
     @Override
+    public boolean onDown(MotionEvent motionEvent) {
+        mWaitForDoubleTap = mTarget.getZoomConstraints().getAllowDoubleTapZoom();
+        return false;
+    }
+
+    @Override
+    public void onShowPress(MotionEvent motionEvent) {
+        // If we get this, it will be followed either by a call to
+        // onSingleTapUp (if the user lifts their finger before the
+        // long-press timeout) or a call to onLongPress (if the user
+        // does not). In the former case, we want to make sure it is
+        // treated as a click. (Note that if this is called, we will
+        // not get a call to onDoubleTap).
+        mWaitForDoubleTap = false;
+    }
+
+    @Override
     public void onLongPress(MotionEvent motionEvent) {
     }
 
     @Override
     public boolean onSingleTapUp(MotionEvent motionEvent) {
-        // When zooming is enabled, wait to see if there's a double-tap.
+        // When double-tapping is allowed, we have to wait to see if this is
+        // going to be a double-tap.
+        if (!mWaitForDoubleTap) {
+        }
+        // return false because we still want to get the ACTION_UP event that triggers this
         return false;
     }
 
     @Override
     public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
-        // When zooming is disabled, we handle this in onSingleTapUp.
+        // In cases where we don't wait for double-tap, we handle this in onSingleTapUp.
+        if (mWaitForDoubleTap) {
+        }
         return true;
     }
 
@@ -938,8 +964,8 @@ public class JavaPanZoomController
 
         ImmutableViewportMetrics finalMetrics = getMetrics();
         finalMetrics = finalMetrics.setViewportOrigin(
-                zoomToRect.left * finalMetrics.zoomFactor,
-                zoomToRect.top * finalMetrics.zoomFactor);
+            zoomToRect.left * finalMetrics.zoomFactor,
+            zoomToRect.top * finalMetrics.zoomFactor);
         finalMetrics = finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
 
         // 2. now run getValidViewportMetrics on it, so that the target viewport is
@@ -951,16 +977,19 @@ public class JavaPanZoomController
     }
 
     /** This function must be called from the UI thread. */
+    @Override
     public void abortPanning() {
         checkMainThread();
         bounce();
     }
 
+    @Override
     public void setOverScrollMode(int overscrollMode) {
         mX.setOverScrollMode(overscrollMode);
         mY.setOverScrollMode(overscrollMode);
     }
 
+    @Override
     public int getOverScrollMode() {
         return mX.getOverScrollMode();
     }
commit 0f291b37ca5dd0b86fc2324756761a163727e355
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Jan 14 13:57:18 2015 +0900

    android: remove CheckerboardImage class as it is not needed
    
    Change-Id: I937eac9e613695490c8617aac85575f5e6fe290b

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/CheckerboardImage.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/CheckerboardImage.java
deleted file mode 100644
index 1343733..0000000
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/CheckerboardImage.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Color;
-
-import org.libreoffice.kit.DirectBufferAllocator;
-
-import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
-import java.util.Arrays;
-
-/** A Cairo image that displays a tinted checkerboard. */
-public class CheckerboardImage extends CairoImage {
-    // The width and height of the checkerboard tile.
-    private static final int SIZE = 16;
-    // The pixel format of the checkerboard tile.
-    private static final int FORMAT = CairoImage.FORMAT_RGB16_565;
-    // The color to mix in to tint the background color.
-    private static final int TINT_COLOR = Color.GRAY;
-    // The amount to mix in.
-    private static final float TINT_OPACITY = 0.4f;
-
-    private ByteBuffer mBuffer;
-    private int mMainColor;
-    private boolean mShowChecks;
-
-    /** Creates a new checkerboard image. */
-    public CheckerboardImage() {
-        int bpp = CairoUtils.bitsPerPixelForCairoFormat(FORMAT);
-        mBuffer = DirectBufferAllocator.allocate(SIZE * SIZE * bpp / 8);
-        update(true, Color.WHITE);
-    }
-
-    /** Returns the current color of the checkerboard. */
-    public int getColor() {
-        return mMainColor;
-    }
-
-    /** Returns whether or not we are currently showing checks on the checkerboard. */
-    public boolean getShowChecks() {
-        return mShowChecks;
-    }
-
-    /** Updates the checkerboard image. If showChecks is true, then create a
-        checkerboard image that is tinted to the color. Otherwise just return a flat
-        image of the color. */
-    public void update(boolean showChecks, int color) {
-        mMainColor = color;
-        mShowChecks = showChecks;
-
-        short mainColor16 = convertTo16Bit(mMainColor);
-
-        mBuffer.rewind();
-        ShortBuffer shortBuffer = mBuffer.asShortBuffer();
-
-        if (!mShowChecks) {
-            short color16 = convertTo16Bit(mMainColor);
-            short[] fillBuffer = new short[SIZE];
-            Arrays.fill(fillBuffer, color16);
-
-            for (int i = 0; i < SIZE; i++) {
-                shortBuffer.put(fillBuffer);
-            }
-
-            return;
-        }
-
-        short tintColor16 = convertTo16Bit(tint(mMainColor));
-
-        short[] mainPattern = new short[SIZE / 2], tintPattern = new short[SIZE / 2];
-        Arrays.fill(mainPattern, mainColor16);
-        Arrays.fill(tintPattern, tintColor16);
-
-        // The checkerboard pattern looks like this:
-        //
-        // +---+---+
-        // | N | T |  N = normal
-        // +---+---+  T = tinted
-        // | T | N |
-        // +---+---+
-
-        for (int i = 0; i < SIZE / 2; i++) {
-            shortBuffer.put(mainPattern);
-            shortBuffer.put(tintPattern);
-        }
-        for (int i = SIZE / 2; i < SIZE; i++) {
-            shortBuffer.put(tintPattern);
-            shortBuffer.put(mainPattern);
-        }
-    }
-
-    // Tints the given color appropriately and returns the tinted color.
-    private int tint(int color) {
-        float negTintOpacity = 1.0f - TINT_OPACITY;
-        float r = Color.red(color) * negTintOpacity + Color.red(TINT_COLOR) * TINT_OPACITY;
-        float g = Color.green(color) * negTintOpacity + Color.green(TINT_COLOR) * TINT_OPACITY;
-        float b = Color.blue(color) * negTintOpacity + Color.blue(TINT_COLOR) * TINT_OPACITY;
-        return Color.rgb(Math.round(r), Math.round(g), Math.round(b));
-    }
-
-    // Converts a 32-bit ARGB color to 16-bit R5G6B5, truncating values and discarding the alpha
-    // channel.
-    private short convertTo16Bit(int color) {
-        int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3;
-        int c = ((r << 11) | (g << 5) | b);
-        // Swap endianness.
-        return (short)((c >> 8) | ((c & 0xff) << 8));
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mBuffer != null) {
-                DirectBufferAllocator.free(mBuffer);
-                mBuffer = null;
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override
-    public ByteBuffer getBuffer() {
-        return mBuffer;
-    }
-
-    @Override
-    public void destroy() {
-
-    }
-
-    @Override
-    public IntSize getSize() {
-        return new IntSize(SIZE, SIZE);
-    }
-
-    @Override
-    public int getFormat() {
-        return FORMAT;
-    }
-}
-
commit c4cdb699e427c71617daff9ca780b0b13a9fc3e6
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 18:40:04 2015 +0100

    lokdocview: adapt comment to match reality
    
    Change-Id: I2d7ee76e132856483cdfa8f89641725c26762e37

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 91ebd76..5e6e790 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -159,7 +159,7 @@ void renderDocument( LOKDocView* pDocView )
             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.
+                                                    // Buffer and its size, depends on the position only.
                                                     pBuffer,
                                                     nTileWidthPixels, nTileHeightPixels,
                                                     &nRowStride,
commit 906945681773d9af3b46006e4f661993edc3e871
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 18:35:48 2015 +0100

    SwViewShell::PaintTile: paint a small red rectangle as well in debug mode
    
    Change-Id: I246965ac341ef0deeb30f1d3a0c518e67a074869

diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 8647409..ac49e5e 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1824,6 +1824,19 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
     // SwViewShell's output device tear down
     mpOut = pSaveOut;
     mbTiledRendering = bTiledRendering;
+
+    static bool bDebug = getenv("SW_DEBUG_TILEDRENDERING") != 0;
+    if (bDebug)
+    {
+        // Draw a small red rectangle in the top left corner so that it's easy to see where a new tile begins.
+        Rectangle aRect(0, 0, 5, 5);
+        aRect = rDevice.PixelToLogic(aRect);
+        rDevice.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
+        rDevice.SetFillColor(COL_LIGHTRED);
+        rDevice.SetLineColor();
+        rDevice.DrawRect(aRect);
+        rDevice.Pop();
+    }
 }
 
 #if !HAVE_FEATURE_DESKTOP
commit 58959bd1fc0b7ada7aa8386e698e2e5004a92cfb
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.
commit 1e3b09d398cd89a9905ecc91927fab32bf359500
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 14:37:20 2015 +0100

    lokdocview: clean up renderDocument()
    
    Change-Id: I7ee58b2c889da3ca01969617f7a382bf4135b7a1

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index d373235..c0262a2 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -100,19 +100,20 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_docview_new( LibreOfficeKit* pOffice )
     return GTK_WIDGET( pDocView );
 }
 
+// We know that VirtualDevises use a DPI of 96.
+static const int g_nDPI = 96;
+
+/// Converts from document coordinates to screen pixels.
+static float twipToPixel(float nInput)
+{
+    return nInput / 1440.0f * g_nDPI;
+}
+
 void renderDocument( LOKDocView* pDocView )
 {
-    long nWidth, nHeight;
-    int nRenderWidth, nRenderHeight;
+    long nDocumentWidthTwips, nDocumentHeightTwips, nBufferWidthPixels, nBufferHeightPixels;
     unsigned char* pBuffer;
     int nRowStride;
-    // TODO: we really should scale by screen DPI here -- 10 seems to be a vaguely
-    // correct factor for my screen at least.
-    const float fScaleFactor = 0.1;
-
-    // Various things blow up if we try to draw too large a tile,
-    // this size seems to be safe. (Very rare/unlikely that
-    const int nMaxWidth = 100000;
 
     g_assert( pDocView->pDocument );
 
@@ -121,37 +122,25 @@ void renderDocument( LOKDocView* pDocView )
         g_object_unref( G_OBJECT( pDocView->pPixBuf ) );
     }
 
-    pDocView->pDocument->pClass->getDocumentSize( pDocView->pDocument, &nWidth, &nHeight );
-
-    if ( nWidth * fScaleFactor > nMaxWidth )
-    {
-        nWidth = nMaxWidth;
-    }
-    if ( nHeight * fScaleFactor > nMaxWidth )
-    {
-        nHeight = nMaxWidth;
-    }
+    pDocView->pDocument->pClass->getDocumentSize(pDocView->pDocument, &nDocumentWidthTwips, &nDocumentHeightTwips);
 
     // Draw the whole document at once (for now)
 
-    nRenderWidth = nWidth * pDocView->fZoom * fScaleFactor;
-    nRenderHeight = nHeight * pDocView->fZoom * fScaleFactor;
+    nBufferWidthPixels = twipToPixel(nDocumentWidthTwips) * pDocView->fZoom;
+    nBufferHeightPixels = twipToPixel(nDocumentHeightTwips) * pDocView->fZoom;
 
     pDocView->pPixBuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
                                         TRUE, 8,
-                                        nRenderWidth, nRenderHeight);
+                                        nBufferWidthPixels, nBufferHeightPixels);
 
 
     pBuffer = gdk_pixbuf_get_pixels( pDocView->pPixBuf );
     pDocView->pDocument->pClass->paintTile( pDocView->pDocument,
                                             pBuffer,
-                                            nRenderWidth, nRenderHeight,
+                                            nBufferWidthPixels, nBufferHeightPixels,
                                             &nRowStride,
                                             0, 0, // origin
-                                            nWidth, nHeight );
-    // TODO: double check that the rowstride really matches what we expected,
-    // although presumably we'd already be crashing by now if things were
-    // wrong.
+                                            nDocumentWidthTwips, nDocumentHeightTwips );
     (void) nRowStride;
 
     gtk_image_set_from_pixbuf( GTK_IMAGE( pDocView->pCanvas ), pDocView->pPixBuf );
commit 57204a4816112a47f688ca7ca848b0ce1477c5d7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 13:31:27 2015 +0100

    sw: missing nullptr check
    
    As pointed out by JunitTest_sw_unoapi.
    
    Change-Id: Ia553dfb48215fab44f4899223c63ee454ff1c648

diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index 759b05c..9360a01 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -2026,7 +2026,7 @@ void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVi
 
             // center page if possible
             long nSizeDiff = 0;
-            if (nVisWidth > nCurrentRowWidth && !GetCurrShell()->isTiledRendering())
+            if (nVisWidth > nCurrentRowWidth && !(GetCurrShell() && GetCurrShell()->isTiledRendering()))
                 nSizeDiff = ( nVisWidth - nCurrentRowWidth ) / 2;
 
             // adjust positions of pages in current row
commit 99db6d8e376d594e2a4345d37637f9506d143fc9
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 14 10:28:40 2015 +0100

    SwRootFrm::CheckViewLayout: never center pages when doing tiled rendering
    
    The size of the root frame is usually the max of the page frame widths,
    except when the visual area is larger, in which case the root frame is
    the visual area width, and page frames are centered (when there is a
    single column).
    
    When doing tiled rendering, we are not interested in the gray area
    around the pages (not more than just having a gap between pages), so
    never do this centering. This has two benefits:
    
    1) When painting the tiles, we change the visual area already to always
    have the given tile visible, that would undo this centering anyway, but
    changing the size of the root frame causes a pointless
    mass-invalidation.
    
    2) When getting the size of the document, this way the width of the
    document (root frame) will independent from the visual area, i.e. it'll
    be always the same.
    
    Change-Id: Ib0d86bbe6c7b5a83646264a2f308624179ad6982

diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 574933c..89ebbc6 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -581,6 +581,10 @@ public:
     void registerLibreOfficeKitCallback(LibreOfficeKitCallback pCallback, void* pLibreOfficeKitData);
     /// Invokes the registered callback, if there are any.
     void libreOfficeKitCallback(int nType, const char* pPayload);
+    /// Set if we are doing tiled rendering.
+    void setTiledRendering(bool bTiledRendering);
+    /// Are we doing tiled rendering?
+    bool isTiledRendering();
 
     SwViewShell* GetNext()
         { return GetNextInRing(); }
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index 6ca0183..759b05c 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -2025,9 +2025,9 @@ void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVi
             }
 
             // center page if possible
-            const long nSizeDiff = nVisWidth > nCurrentRowWidth ?
-                                   ( nVisWidth - nCurrentRowWidth ) / 2 :
-                                   0;
+            long nSizeDiff = 0;
+            if (nVisWidth > nCurrentRowWidth && !GetCurrShell()->isTiledRendering())
+                nSizeDiff = ( nVisWidth - nCurrentRowWidth ) / 2;
 
             // adjust positions of pages in current row
             long nX = nSizeDiff;
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 332c30a..8647409 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -129,6 +129,16 @@ void SwViewShell::libreOfficeKitCallback(int nType, const char* pPayload)
         mpLibreOfficeKitCallback(nType, pPayload, mpLibreOfficeKitData);
 }
 
+void SwViewShell::setTiledRendering(bool bTiledRendering)
+{
+    mbTiledRendering = bTiledRendering;
+}
+
+bool SwViewShell::isTiledRendering()
+{
+    return mbTiledRendering;
+}
+
 static void
 lcl_PaintTransparentFormControls(SwViewShell & rShell, SwRect const& rRect)
 {
@@ -1764,6 +1774,7 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
     // them - mpBufferedOut, mpOut, mpWin, ..., and get rid of
     // mbTiledRendering)
     OutputDevice *pSaveOut = mpOut;
+    bool bTiledRendering = mbTiledRendering;
     mbTiledRendering = true;
     mpOut = &rDevice;
 
@@ -1812,7 +1823,7 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
 
     // SwViewShell's output device tear down
     mpOut = pSaveOut;
-    mbTiledRendering = false;
+    mbTiledRendering = bTiledRendering;
 }
 
 #if !HAVE_FEATURE_DESKTOP
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 4655298..e3d57dd 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3149,6 +3149,13 @@ Size SwXTextDocument::getDocumentSize()
 void SwXTextDocument::initializeForTiledRendering()
 {
     SolarMutexGuard aGuard;
+
+    // Call setTiledRendering() first, so that when we change the view layout,
+    // we already don't center the pages.
+    SwDoc* pDoc = pDocShell->GetDoc();
+    SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+    pViewShell->setTiledRendering(true);
+
     bool      bBookMode = false;
     sal_Int16 nColumns = 1;
 
commit f260218636430152be713a92d4dd08c3941cd6c4
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Jan 14 09:09:05 2015 +0900

    android: Inflate viewport even more to render more tiles offscreen
    
    Change-Id: I6a1f8bb8fd04e40ecd60eec87043e507ca6350e7

diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 1a67117..31c7a07 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -165,7 +165,8 @@ public abstract class ComposedTileLayer extends Layer {
                     }
                 }
                 if (!contains) {
-                    LOEvent event = LOEventFactory.tileRequest(this, new TileIdentifier((int) x, (int) y, zoom, tileSize), false);
+                    TileIdentifier tileId = new TileIdentifier((int) x, (int) y, zoom, tileSize);
+                    LOEvent event = LOEventFactory.tileRequest(this, tileId, true);
                     event.mPriority = getTilePriority();
                     LOKitShell.sendEvent(event);
                 }
@@ -212,6 +213,9 @@ public abstract class ComposedTileLayer extends Layer {
         return RectF.intersects(currentViewport, tileId.getRect()) || currentViewport.contains(tileId.getRect());
     }
 
+    /**
+     * Invalidate tiles which intersect the input rect
+     */
     public void invalidateTiles(RectF rect) {
         RectF zoomedRect = RectUtils.inverseScale(rect, currentZoom);
 
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
index 12ff723..38d6d80 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java
@@ -19,7 +19,7 @@ public class DynamicTileLayer extends ComposedTileLayer {
         return 0;
     }
 
-    protected IntSize getInflateFactor() {
-        return tileSize;
+    private IntSize getInflateFactor() {
+        return new IntSize(tileSize.width*2, tileSize.height*4);
     }
 }
commit 96240771442a104f3d201947fe34d7bec08de9c1
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 17:12:13 2015 +0100

    android: avoid setMessageCallback() for now
    
    This has to be only called when the user taps, not before. Don't do it
    at all till we figure out how to detect a tap.
    
    Change-Id: I184442d3f06fcbf56f0789bb85693dd7273daf28

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 8f4e56e..0e2db4b 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -69,7 +69,8 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
 
     public void postLoad() {
         mDocument.initializeForRendering();
-        mDocument.setMessageCallback(this);
+        // FIXME see gtktiledviewer, this has to be registered when we enter edit mode, not right after loading.
+        // mDocument.setMessageCallback(this);
 
         int parts = mDocument.getParts();
         Log.i(LOGTAG, "Document parts: " + parts);
commit fe3ab8481eaf50272f1aa3892ff5f74ffd47d461
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 16:47:23 2015 +0100

    gtktiledviewer: start in viewer mode, switch to edit mode by mouse click
    
    Change-Id: I0863ec8fb159a2e367951ba9e7d7310d250d8a1e

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 111381d..3fd0c4a 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -41,6 +41,8 @@ struct _LOKDocView
 
     LibreOfficeKit* pOffice;
     LibreOfficeKitDocument* pDocument;
+    /// View or edit mode.
+    gboolean m_bEdit;
 };
 
 struct _LOKDocViewClass
@@ -64,6 +66,9 @@ char*           lok_docview_get_part_name   (LOKDocView* pDocView,
                                              int nPart);
 void            lok_docview_set_partmode    (LOKDocView* pDocView,
                                              LibreOfficeKitPartMode ePartMode);
+/// Sets if the viewer is actually an editor or not.
+void            lok_docview_set_edit        (LOKDocView* pDocView,
+                                             gboolean bEdit);
 #ifdef __cplusplus
 }
 #endif
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index e1e9e4f..2be201f 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -131,8 +131,11 @@ void changeQuadView( GtkWidget* /*pButton*/, gpointer /* pItem */ )
 static void signalKey(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer /*pData*/)
 {
     LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView);
-
     int nCode = 0;
+
+    if (!pLOKDocView->m_bEdit)
+        return;
+
     switch (pEvent->keyval)
     {
     case GDK_BackSpace:
@@ -154,6 +157,14 @@ static void signalKey(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer /*pD
         pLOKDocView->pOffice->pClass->postKeyEvent(pLOKDocView->pOffice, LOK_KEYEVENT_KEYINPUT, nCode);
 }
 
+/// Receives a button press event.
+static void signalButton(GtkWidget* /*pWidget*/, GdkEvent* /*pEvent*/, gpointer /*pData*/)
+{
+    LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView);
+
+    lok_docview_set_edit(pLOKDocView, TRUE);
+}
+
 // GtkComboBox requires gtk 2.24 or later
 #if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2
 void populatePartSelector()
@@ -311,6 +322,7 @@ int main( int argc, char* argv[] )
     // Input handling.
     g_signal_connect(pWindow, "key-press-event", G_CALLBACK(signalKey), NULL);
     g_signal_connect(pWindow, "key-release-event", G_CALLBACK(signalKey), NULL);
+    g_signal_connect(pDocView, "button-press-event", G_CALLBACK(signalButton), NULL);
 
     gtk_container_add( GTK_CONTAINER(pVBox), pDocView );
 
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 2e4226c..d373235 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -71,6 +71,9 @@ static void lok_docview_init( LOKDocView* pDocView )
     gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView),
                                            pDocView->pEventBox );
 
+    // 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 );
 
@@ -84,6 +87,7 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->pDocument = 0;
 
     pDocView->fZoom = 1;
+    pDocView->m_bEdit = FALSE;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -212,7 +216,6 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c
     {
         pDocView->pDocument->pClass->initializeForRendering(pDocView->pDocument);
         renderDocument( pDocView );
-        pDocView->pDocument->pClass->registerCallback(pDocView->pDocument, &lok_docview_callback_worker, pDocView);
     }
 
     return TRUE;
@@ -261,4 +264,13 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_partmode( LOKDocView* pDocView,
     pDocView->pDocument->pClass->setPartMode( pDocView->pDocument, ePartMode );
     renderDocument( pDocView );
 }
+
+SAL_DLLPUBLIC_EXPORT void lok_docview_set_edit( LOKDocView* pDocView,
+                                                gboolean bEdit )
+{
+    if (!pDocView->m_bEdit && bEdit)
+        pDocView->pDocument->pClass->registerCallback(pDocView->pDocument, &lok_docview_callback_worker, pDocView);
+    pDocView->m_bEdit = bEdit;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f1a2759c29955040ac92c96bfa4e5621a78de8bb
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 12:48:58 2015 +0100

    android: if we don't have a document, then that can't be text
    
    Change-Id: I2b9e37aec2705ab723c11a0d1eb795aa5a63105e

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index fe389ef..8f4e56e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -254,7 +254,7 @@ public class LOKitTileProvider implements TileProvider, Document.MessageCallback
 
     @Override
     public boolean isTextDocument() {
-        return mDocument.getDocumentType() == Document.DOCTYPE_TEXT;
+        return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_TEXT;
     }
 
     @Override
commit 56dd27d9ed829ea0444b3b5932dcd0d431d6e251
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 12:34:22 2015 +0100

    sw: invalidate after keypresses when we have a callback
    
    Ideally we could always just invalidate and paint when the main loop
    says so, but currently without priorities that can take some time.
    
    So just do the invalidate-then-paint when we have a callback that is
    listening to invalidations.
    
    Change-Id: I6a835a0a149ae01a4ece3a319dffbe81cd5bd3eb

diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 9a5ff25..332c30a 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -393,7 +393,10 @@ void SwViewShell::ImplEndAction( const bool bIdleEnd )
 
                         if ( bPaintsFromSystem )
                             PaintDesktop( aRect );
-                        pCurrentLayout->Paint( aRect );
+                        if (!mpLibreOfficeKitCallback)
+                            pCurrentLayout->Paint( aRect );
+                        else
+                            pCurrentLayout->GetCurrShell()->InvalidateWindows(aRect.SVRect());
 
                         // #i75172# end DrawingLayer paint
                         DLPostPaint2(true);
commit 9adaaa36069cf2b3f2f00ca4eb431a08b501b8c8
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 12:02:00 2015 +0100

    gtktiledviewer: missing initializeForRendering()
    
    Without that, we can't be sure we'll get pages in a single column.
    
    Change-Id: I18725607251b74bb81254c149fcc7e451de9359e

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index cf3169c..2e4226c 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -210,6 +210,7 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c
     }
     else
     {
+        pDocView->pDocument->pClass->initializeForRendering(pDocView->pDocument);
         renderDocument( pDocView );
         pDocView->pDocument->pClass->registerCallback(pDocView->pDocument, &lok_docview_callback_worker, pDocView);
     }
commit 5c3c862c78798bd784bebb56dd9c99b5467333e5
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 13 12:00:07 2015 +0100

    Missing guard in SwXTextDocument::initializeForTiledRendering()
    
    Change-Id: Ic0b09b13612e92ec069cb72a951431939b979715

diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 4bba535..4655298 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3148,6 +3148,7 @@ Size SwXTextDocument::getDocumentSize()
 
 void SwXTextDocument::initializeForTiledRendering()
 {
+    SolarMutexGuard aGuard;
     bool      bBookMode = false;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list