[Libreoffice-commits] core.git: 7 commits - android/Bootstrap android/experimental desktop/Library_sofficeapp.mk desktop/source sal/android solenv/bin

Tomaž Vajngerl tomaz.vajngerl at collabora.com
Tue Jul 1 00:09:37 PDT 2014


 android/Bootstrap/src/org/libreoffice/android/LibreOfficeKit.java                                     |  129 ----
 android/Bootstrap/src/org/libreoffice/kit/Document.java                                               |   57 ++
 android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java                                         |  102 +++
 android/Bootstrap/src/org/libreoffice/kit/Office.java                                                 |   34 +
 android/experimental/LOAndroid2/LOAndroid.iml                                                         |   12 
 android/experimental/LOAndroid2/LOAndroid2.iml                                                        |    7 
 android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java                    |  108 ++--
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java       |    4 
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoGLLayerClient.java       |  265 ----------
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java         |  174 ++----
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java |  146 +----
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java                    |    4 
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java           |   86 ---
 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java                  |   15 
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png                                 |binary
 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png                                 |binary
 android/experimental/LOAndroid2/build.gradle                                                          |    2 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java                 |   44 -
 desktop/Library_sofficeapp.mk                                                                         |    6 
 desktop/source/lib/lokandroid.cxx                                                                     |  124 ++++
 sal/android/libreofficekit-jni.c                                                                      |   45 -
 solenv/bin/native-code.py                                                                             |    9 
 29 files changed, 591 insertions(+), 782 deletions(-)

New commits:
commit b046b687f9caa71db29ce16e0d211d530648d141
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Mon Jun 30 23:34:15 2014 +0200

    lok bootstrap: nicer function names, clean-up
    
    + prevent lokandroid JNI functions to be removed from the library
    + basic use of lok Office / Document in LibreOfficeMainActivity
    
    Change-Id: I7bfe53738cf821b2270ab3e024cc506a7cff42f0

diff --git a/android/Bootstrap/src/org/libreoffice/android/LibreOfficeKit.java b/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java
similarity index 52%
rename from android/Bootstrap/src/org/libreoffice/android/LibreOfficeKit.java
rename to android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java
index 58d6c50..c76c0fd 100644
--- a/android/Bootstrap/src/org/libreoffice/android/LibreOfficeKit.java
+++ b/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java
@@ -7,7 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-package org.libreoffice.android;
+package org.libreoffice.kit;
 
 import android.app.Activity;
 import android.content.pm.ApplicationInfo;
@@ -21,6 +21,8 @@ import java.util.Arrays;
 // final because subclassing would be meaningless.
 public final class LibreOfficeKit
 {
+    private long handle;
+
     // private constructor because instantiating would be meaningless
     private LibreOfficeKit()
     {
@@ -33,88 +35,59 @@ public final class LibreOfficeKit
     // System.loadLibrary() and Android's JNI works only to such libraries, it
     // seems.
 
-    private static native boolean init(String dataDir,
-                                       String cacheDir,
-                                       String apkFile);
+    private static native boolean initializeNative(String dataDir, String cacheDir, String apkFile);
 
-/*
-    // Wrapper for getpid()
-    public static native int getpid();
+    public static native long getLibreOfficeKitHandle();
 
-    // Wrapper for system()
-    public static native void system(String cmdline);
-*/
     // Wrapper for putenv()
     public static native void putenv(String string);
-/*
-    // A wrapper for InitVCL() in libvcl (svmain.cxx), called indirectly
-    // through the lo-bootstrap library
-    public static native void initVCL();
-
-    // A wrapper for osl_setCommandArgs(). Before calling
-    // osl_setCommandArgs(), argv[0] is prefixed with the parent directory of
-    // where the lo-bootstrap library is.
-    public static native void setCommandArgs(String[] argv);
-*/
+
     // A method that starts a thread to redirect stdout and stderr writes to
     // the Android logging mechanism, or stops the redirection.
-    public static native void redirect_stdio(boolean state);
-/*
-    // The DIB returned by css.awt.XBitmap.getDIB is in BGR_888 form, at least
-    // for Writer documents. We need it in Android's Bitmap.Config.ARGB_888
-    // format, which actually is RGBA_888, whee... At least in Android 4.0.3,
-    // at least on my device. No idea if it is always like that or not, the
-    // documentation sucks.
-    public static native void twiddle_BGR_to_RGBA(byte[] source, int offset, int width, int height, ByteBuffer destination);
-
-    public static native void force_full_alpha_array(byte[] array, int offset, int length);
-
-    public static native void force_full_alpha_bb(ByteBuffer buffer, int offset, int length);
-
-    public static native long new_byte_buffer_wrapper(ByteBuffer bbuffer);
+    public static native void redirectStdio(boolean state);
 
-    public static native void delete_byte_buffer_wrapper(long bbw);
-*/
-
-    static boolean init_done = false;
+    static boolean initializeDone = false;
 
     // This init() method should be called from the upper Java level of
     // LO-based apps.
     public static synchronized void init(Activity activity)
     {
-        if (init_done)
+        if (initializeDone)
             return;
 
         String dataDir = null;
 
-        ApplicationInfo ai = activity.getApplicationInfo();
-        dataDir = ai.dataDir;
+        ApplicationInfo applicationInfo = activity.getApplicationInfo();
+        dataDir = applicationInfo.dataDir;
         Log.i(TAG, String.format("Initializing LibreOfficeKit, dataDir=%s\n", dataDir));
 
-        redirect_stdio(true);
+        redirectStdio(true);
+
+        String cacheDir = activity.getApplication().getCacheDir().getAbsolutePath();
+        String apkFile = activity.getApplication().getPackageResourcePath();
 
-        if (!init(dataDir,
-                  activity.getApplication().getCacheDir().getAbsolutePath(),
-                  activity.getApplication().getPackageResourcePath()))
+        if (!initializeNative(dataDir, cacheDir, apkFile)) {
             return;
+        }
 
         // If we notice that a fonts.conf file was extracted, automatically
         // set the FONTCONFIG_FILE env var.
-        InputStream i;
+        InputStream inputStream = null;
         try {
-            i = activity.getAssets().open("unpack/etc/fonts/fonts.conf");
-        }
-        catch (java.io.IOException e) {
-            i = null;
+            inputStream = activity.getAssets().open("unpack/etc/fonts/fonts.conf");
+        } catch (java.io.IOException exception) {
         }
+
         putenv("OOO_DISABLE_RECOVERY=1");
-        if (i != null)
+
+        if (inputStream != null) {
             putenv("FONTCONFIG_FILE=" + dataDir + "/etc/fonts/fonts.conf");
+        }
 
         // TMPDIR is used by osl_getTempDirURL()
         putenv("TMPDIR=" + activity.getCacheDir().getAbsolutePath());
 
-        init_done = true;
+        initializeDone = true;
     }
 
     // Now with static loading we always have all native code in one native
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index a4ae79c..2345aea 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -11,12 +11,16 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
+import android.os.Environment;
+import java.io.File;
 
 import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
 import org.mozilla.gecko.gfx.LayerController;
 import org.mozilla.gecko.gfx.LayerView;
 
-import org.libreoffice.android.LibreOfficeKit;
+import org.libreoffice.kit.LibreOfficeKit;
+import org.libreoffice.kit.Office;
+import org.libreoffice.kit.Document;
 
 import com.sun.star.frame.XComponentLoader;
 import com.sun.star.lang.XMultiComponentFactory;
@@ -76,48 +80,30 @@ public class LibreOfficeMainActivity extends Activity {
         try {
             // enable debugging messages as the first thing
             LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl");
-
             LibreOfficeKit.init(this);
 
-            setContentView(R.layout.activity_main);
-
-            Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
-
-            /*
-            String input = "/assets/test1.odt";
-
-            String[] argv = { "lo-document-loader", input };
-
-            LibreOfficeKit.setCommandArgs(argv);
-
-            Bootstrap.initVCL();
+            Log.w(LOGTAG, "LOK Handle:" + handle);
+            Office office = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
 
-            context = com.sun.star.comp.helper.Bootstrap.defaultBootstrap_InitialComponentContext();
+            File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+            String input = file.getPath() + "/test.odt";
+            Document document = office.documentLoad(input);
+            if (document == null) {
+                Log.w(LOGTAG, "LOK Document error:" + office.getErrorNative());
+            }
 
-            Log.i(LOGTAG, "context is" + (context!=null ? " not" : "") + " null");
-
-            mcf = context.getServiceManager();
-
-            Log.i(LOGTAG, "mcf is" + (mcf!=null ? " not" : "") + " null");
-
-            Object desktop = mcf.createInstanceWithContext("com.sun.star.frame.Desktop", context);
-            Log.i(LOGTAG, "desktop is" + (desktop!=null ? " not" : "") + " null");
-
-            componentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktop);
-            Log.i(LOGTAG, "componentLoader is" + (componentLoader!=null ? " not" : "") + " null");
-            */
         } catch (Exception e) {
             e.printStackTrace(System.err);
-            //finish();
+            finish();
         }
 
         setContentView(R.layout.activity_main);
+        Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
 
         // setup gecko layout
         mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
         mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
 
-
         if (mLayerController == null) {
             mLayerController = new LayerController(this);
 
diff --git a/sal/android/libreofficekit-jni.c b/sal/android/libreofficekit-jni.c
index 3dcf773..4c9f20b 100644
--- a/sal/android/libreofficekit-jni.c
+++ b/sal/android/libreofficekit-jni.c
@@ -30,47 +30,40 @@
 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "LibreOfficeKit", __VA_ARGS__))
 
 /* These are valid / used in all apps. */
-extern const char *data_dir;
-extern const char *cache_dir;
-extern void *apk_file;
+extern const char* data_dir;
+extern const char* cache_dir;
+extern void* apk_file;
 extern int apk_file_size;
 
 extern void Java_org_libreoffice_android_Bootstrap_putenv(JNIEnv* env, jobject clazz, jstring string);
 extern void Java_org_libreoffice_android_Bootstrap_redirect_1stdio(JNIEnv* env, jobject clazz, jboolean state);
 
-extern LibreOfficeKit *libreofficekit_hook(const char* install_path);
+extern LibreOfficeKit* libreofficekit_hook(const char* install_path);
 
-static LibreOfficeKit* pOffice;
+static LibreOfficeKit* gpOffice;
 
 /// Call the same method from Bootstrap.
 __attribute__ ((visibility("default")))
 void
-Java_org_libreoffice_android_LibreOfficeKit_putenv(JNIEnv* env,
-                                              jobject clazz,
-                                              jstring string)
+Java_org_libreoffice_kit_LibreOfficeKit_putenv
+    (JNIEnv* env, jobject clazz, jstring string)
 {
     Java_org_libreoffice_android_Bootstrap_putenv(env, clazz, string);
 }
 
 /// Call the same method from Bootstrap.
 __attribute__ ((visibility("default")))
-void
-Java_org_libreoffice_android_LibreOfficeKit_redirect_1stdio(JNIEnv* env,
-                                                            jobject clazz,
-                                                            jboolean state)
+void Java_org_libreoffice_kit_LibreOfficeKit_redirectStdio
+    (JNIEnv* env, jobject clazz, jboolean state)
 {
     Java_org_libreoffice_android_Bootstrap_redirect_1stdio(env, clazz, state);
 }
 
 /// Initialize the LibreOfficeKit.
 __attribute__ ((visibility("default")))
-jboolean
-Java_org_libreoffice_android_LibreOfficeKit_init__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2
-    (JNIEnv* env,
-     jobject clazz,
-     jstring dataDir,
-     jstring cacheDir,
-     jstring apkFile)
+jboolean Java_org_libreoffice_kit_LibreOfficeKit_initializeNative
+    (JNIEnv* env, jobject clazz,
+     jstring dataDir, jstring cacheDir, jstring apkFile)
 {
     struct stat st;
     int fd;
@@ -131,8 +124,8 @@ Java_org_libreoffice_android_LibreOfficeKit_init__Ljava_lang_String_2Ljava_lang_
     extract_files(UNPACK_TREE_GZ, UNPACK_TREE_GZ, 1);
 
     // Initialize LibreOfficeKit
-    pOffice = libreofficekit_hook(data_dir);
-    if (!pOffice)
+    gpOffice = libreofficekit_hook(data_dir);
+    if (!gpOffice)
     {
         LOGE("libreofficekit_hook returned null");
         return JNI_FALSE;
@@ -143,4 +136,14 @@ Java_org_libreoffice_android_LibreOfficeKit_init__Ljava_lang_String_2Ljava_lang_
     return JNI_TRUE;
 }
 
+__attribute__ ((visibility("default")))
+jlong Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle
+    (JNIEnv* env, jobject clazz)
+{
+    (void) env;
+    (void) clazz;
+
+    return (jlong) (intptr_t) gpOffice;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 0de8ed3..4b3b87b 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -230,8 +230,13 @@ if options.java:
     extern void Java_org_libreoffice_android_AppSupport_renderVCL();
     p = (void *) Java_org_libreoffice_android_AppSupport_renderVCL;
 
-    extern void Java_org_libreoffice_android_LibreOfficeKit_init__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2();
-    p = (void *) Java_org_libreoffice_android_LibreOfficeKit_init__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2;""")
+    extern void Java_org_libreoffice_kit_LibreOfficeKit_initializeNative();
+    p = (void *) Java_org_libreoffice_kit_LibreOfficeKit_initializeNative;
+
+    extern void Java_org_libreoffice_kit_Office_initialize();
+    p = (void *) Java_org_libreoffice_kit_Office_initialize;
+
+    """)
 
 print ("""
     return map;
commit ca61fdcac919f799b5273c24932adc0cbd8300e2
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Mon Jun 30 23:30:03 2014 +0200

    libreofficekit JNI for Android
    
    Change-Id: Ia905c20fb4ee9b126d65fd3c8e3c1f54649abe1a

diff --git a/android/Bootstrap/src/org/libreoffice/kit/Document.java b/android/Bootstrap/src/org/libreoffice/kit/Document.java
new file mode 100644
index 0000000..2670b9e
--- /dev/null
+++ b/android/Bootstrap/src/org/libreoffice/kit/Document.java
@@ -0,0 +1,57 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.libreoffice.kit;
+
+import java.nio.ByteBuffer;
+
+public class Document {
+
+    private final long handle;
+
+    private native void setPartNative(long handle, int part);
+    private native int getNumberOfPartsNative(long handle);
+    private native int getDocumentTypeNative(long handle);
+    private native void paintTileNative(long handle, ByteBuffer buffer, int canvasWidth, int canvasHeight, int tilePositionX, int tilePositionY, int tileWidth, int tileHeight);
+    private native long getDocumentHeightNative(long handle);
+    private native long getDocumentWidthNative(long handle);
+
+    public Document(long handle) {
+        this.handle = handle;
+    }
+
+    public boolean saveAs(String url) {
+        return false;
+    }
+
+    public int getDocumentType() {
+        return getDocumentTypeNative(handle);
+    }
+
+    public int getNumberOfParts() {
+        return getNumberOfPartsNative(handle);
+    }
+
+    public void setPart(int part) {
+        setPartNative(handle, part);
+    }
+
+    void paintTile(ByteBuffer buffer, int canvasWidth, int canvasHeight, int tilePositionX, int tilePositionY, int tileWidth, int tileHeight) {
+        paintTileNative(handle, buffer, canvasWidth, canvasHeight, tilePositionX, tilePositionY, tileWidth, tileHeight);
+    }
+
+    public long getDocumentWidth() {
+        return getDocumentWidthNative(handle);
+    }
+
+    public long getDocumentHeight() {
+        return getDocumentHeightNative(handle);
+    }
+
+}
diff --git a/android/Bootstrap/src/org/libreoffice/kit/Office.java b/android/Bootstrap/src/org/libreoffice/kit/Office.java
new file mode 100644
index 0000000..abd98c7
--- /dev/null
+++ b/android/Bootstrap/src/org/libreoffice/kit/Office.java
@@ -0,0 +1,34 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.libreoffice.kit;
+
+import android.util.Log;
+
+public class Office {
+
+    private long handle;
+
+    public Office(long handle) {
+        this.handle = handle;
+    }
+
+    public native String getErrorNative();
+
+    private native long documentLoadNative(String url);
+
+    public Document documentLoad(String url) {
+        long handle = documentLoadNative(url);
+        Document document = null;
+        if (handle > 0) {
+            document = new Document(handle);
+        }
+        return document;
+    }
+}
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index 867e398..d81420f 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -100,6 +100,12 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
 	desktop/source/lib/init \
 ))
 
+ifeq ($(OS),ANDROID)
+$(eval $(call gb_Library_add_exception_objects,sofficeapp,\
+	desktop/source/lib/lokandroid \
+))
+endif
+
 ifeq ($(ENABLE_TELEPATHY),TRUE)
 $(eval $(call gb_Library_use_libraries,sofficeapp,tubes))
 endif
diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx
new file mode 100644
index 0000000..5b05591
--- /dev/null
+++ b/desktop/source/lib/lokandroid.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <jni.h>
+
+#include <sal/types.h>
+
+#include <android/log.h>
+
+#include <osl/detail/android-bootstrap.h>
+
+#define LOK_USE_UNSTABLE_API
+
+#include <LibreOfficeKit/LibreOfficeKit.h>
+
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "LibreOfficeKit", __VA_ARGS__))
+
+/* LibreOfficeKit */
+
+jfieldID getHandleField(JNIEnv* pEnv, jobject aObject)
+{
+    jclass clazz = pEnv->GetObjectClass(aObject);
+    return pEnv->GetFieldID(clazz, "handle", "J");
+}
+
+template <typename T>
+T* getHandle(JNIEnv* pEnv, jobject aObject)
+{
+    jlong aHandle = pEnv->GetLongField(aObject, getHandleField(pEnv, aObject));
+    return reinterpret_cast<T*>(aHandle);
+}
+
+template <typename T>
+void setHandle(JNIEnv* pEnv, jobject aObject, T* aType)
+{
+    jlong aHandle = reinterpret_cast<jlong>(aType);
+    pEnv->SetLongField(aObject, getHandleField(pEnv, aObject), aHandle);
+}
+
+extern "C" SAL_JNI_EXPORT jstring JNICALL Java_org_libreoffice_kit_Office_getErrorNative(JNIEnv* pEnv, jobject aObject)
+{
+    LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject);
+    char* pError = pLibreOfficeKit->pClass->getError(pLibreOfficeKit);
+    return pEnv->NewStringUTF(pError);
+}
+
+extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_initialize(JNIEnv* pEnv, jobject aObject, jlong aLokHandle)
+{
+    pEnv->SetLongField(aObject, getHandleField(pEnv, aObject), aLokHandle);
+}
+
+extern "C" SAL_JNI_EXPORT jlong JNICALL Java_org_libreoffice_kit_Office_documentLoadNative(JNIEnv* pEnv, jobject aObject, jstring documentPath)
+{
+    const char* aCloneDocumentPath;
+
+    const char* aCharDocumentPath = pEnv->GetStringUTFChars(documentPath, NULL);
+    aCloneDocumentPath = strdup(aCharDocumentPath);
+    pEnv->ReleaseStringUTFChars(documentPath, aCharDocumentPath);
+
+    LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject);
+    LOGI("D( %s ): %d", aCloneDocumentPath, (int) pLibreOfficeKit);
+
+    LibreOfficeKitDocument* pDocument = pLibreOfficeKit->pClass->documentLoad(pLibreOfficeKit, aCloneDocumentPath);
+    return (jlong) (intptr_t) pDocument;
+}
+
+/* Document */
+extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_setPartNative
+    (JNIEnv* pEnv, jobject aObject, jint aPart)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    pDocument->pClass->setPart(pDocument, aPart);
+}
+
+extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Document_getNumberOfPartsNative
+    (JNIEnv* pEnv, jobject aObject)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    return (jint) pDocument->pClass->getNumberOfParts(pDocument);
+}
+
+extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Document_getDocumentTypeNative
+    (JNIEnv* pEnv, jobject aObject)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    return (jint) pDocument->pClass->getDocumentType(pDocument);
+}
+
+extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_paintTileNative
+    (JNIEnv* pEnv, jobject aObject, jobject /*aByteBuffer*/,
+    jint nCanvasWidth, jint nCanvasHeight, jint nTilePosX, jint nTilePosY,
+    jint nTileWidth, jint nTileHeight)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    return pDocument->pClass->paintTile(pDocument, NULL, nCanvasWidth, nCanvasHeight, NULL, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+}
+
+extern "C" SAL_JNI_EXPORT jlong JNICALL Java_org_libreoffice_kit_Document_getDocumentHeightNative
+    (JNIEnv* pEnv, jobject aObject)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    long nWidth;
+    long nHeight;
+    pDocument->pClass->getDocumentSize(pDocument, &nWidth, &nHeight);
+    return nHeight;
+}
+
+extern "C" SAL_JNI_EXPORT jlong JNICALL Java_org_libreoffice_kit_Document_getDocumentWidthNative
+    (JNIEnv* pEnv, jobject aObject)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    long nWidth;
+    long nHeight;
+    pDocument->pClass->getDocumentSize(pDocument, &nWidth, &nHeight);
+    return nWidth;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3799a6f3a8b08585cd29a52de89ce0a76c99cef4
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Mon Jun 30 09:02:22 2014 +0200

    LODroid: Make SubTile hold the buffer for a tile
    
    Previously there was only one buffer which contained all the
    tiles currently visible. This is inflexible - we need to control
    each tile individually. This commit introduces SubTile object,
    which is the holder of the buffer for each individual tile.
    
    Change-Id: I511f13dc7fad7c3c04f3d7f23b3abc97a3cc2268

diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
index 6274e4b..f486ad8 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
@@ -40,19 +40,23 @@ public class LOKitThread extends Thread {
         }
 
         Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata);
-        if (bufferRect == null)
+        if (bufferRect == null) {
             return false;
+        }
+        int x = 0;
+        int y = 0;
 
-        ByteBuffer buffer = application.getLayerClient().lockBuffer();
         for (Integer i = 1; i <= 9; i++) {
             String imageName = "d" + i;
             Bitmap bitmap = application.getLayerClient().getLayerController().getDrawable(imageName);
-            bitmap.copyPixelsToBuffer(buffer.asIntBuffer());
-            buffer.position(buffer.position() + bitmap.getByteCount());
+            application.getLayerClient().addTile(bitmap, x, y);
+            x += TILE_SIZE;
+            if (x > originalBitmap.getWidth()) {
+                x = 0;
+                y += TILE_SIZE;
+            }
         }
-        buffer.position(0);
 
-        application.getLayerClient().unlockBuffer();
         application.getLayerClient().endDrawing(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight());
 
         application.runOnUiThread(new Runnable() {
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index a491f07..134c406 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -72,7 +72,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
     private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
     private static Pattern sColorPattern;
     protected IntSize mScreenSize;
-    protected IntSize mBufferSize;
     protected Layer mTileLayer;
     /* The viewport that Gecko is currently displaying. */
     protected ViewportMetrics mGeckoViewport;
@@ -94,7 +93,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
 
     public GeckoLayerClient(Context context) {
         mScreenSize = new IntSize(0, 0);
-        mBufferSize = new IntSize(0, 0);
     }
 
     // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
@@ -340,7 +338,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
     private void adjustViewport() {
         ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics());
 
-        PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(mBufferSize);
+        PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(getBufferSize());
         viewportMetrics.setViewportOffset(viewportOffset);
         viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
 
@@ -359,7 +357,8 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
             mUpdateViewportOnEndDraw = true;
 
             // Redraw everything.
-            Rect rect = new Rect(0, 0, mBufferSize.width, mBufferSize.height);
+            IntSize bufferSize = getBufferSize();
+            Rect rect = new Rect(0, 0, bufferSize.width, bufferSize.height);
             LOKitShell.sendEvent(LOEvent.draw(rect));
         } else if ("Viewport:UpdateLater".equals(event)) {
             Log.e(LOGTAG, "### Java side Viewport:UpdateLater()!");
@@ -373,14 +372,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         render();
     }
 
-    public int getWidth() {
-        return mBufferSize.width;
-    }
-
-    public int getHeight() {
-        return mBufferSize.height;
-    }
-
     public ViewportMetrics getGeckoViewportMetrics() {
         if (mGeckoViewport != null)
             return new ViewportMetrics(mGeckoViewport);
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
index ee99d16..9269f96 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
@@ -68,28 +68,18 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
 
     private int mFormat;
     private IntSize mViewportSize;
-    private ByteBuffer mBuffer;
-
-    private CairoImage mCairoImage;
-
+    private IntSize mBufferSize;
     private static final IntSize TILE_SIZE = new IntSize(256, 256);
 
     public GeckoSoftwareLayerClient(Context context) {
         super(context);
-
+        mBufferSize = new IntSize(0,0);
         mFormat = CairoImage.FORMAT_ARGB32;
 
-        mCairoImage = new CairoImage() {
-            @Override
-            public ByteBuffer getBuffer() { return mBuffer; }
-            @Override
-            public IntSize getSize() { return mBufferSize; }
-            @Override
-            public int getFormat() { return mFormat; }
-        };
+
     }
 
-    protected void finalize() throws Throwable {
+    /*protected void finalize() throws Throwable {
         try {
             if (mBuffer != null)
                 LOKitShell.freeDirectBuffer(mBuffer);
@@ -97,7 +87,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
         } finally {
             super.finalize();
         }
-    }
+    }*/
 
     public void setLayerController(LayerController layerController) {
         super.setLayerController(layerController);
@@ -116,7 +106,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
             return false;
 
         Log.i(LOGTAG, "Creating MultiTileLayer");
-        mTileLayer = new MultiTileLayer(mCairoImage, TILE_SIZE);
+        mTileLayer = new MultiTileLayer(TILE_SIZE);
 
         getLayerController().setRoot(mTileLayer);
 
@@ -149,21 +139,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
         // If the window size has changed, reallocate the buffer to match.
         if (mBufferSize.width != width || mBufferSize.height != height) {
             mBufferSize = new IntSize(width, height);
-
-            // Reallocate the buffer if necessary
-            if (mTileLayer instanceof MultiTileLayer) {
-                int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
-                int size = mBufferSize.getArea() * bpp;
-                if (mBuffer == null || mBuffer.capacity() != size) {
-                    // Free the old buffer
-                    if (mBuffer != null) {
-                        LOKitShell.freeDirectBuffer(mBuffer);
-                        mBuffer = null;
-                    }
-
-                    mBuffer = LOKitShell.allocateDirectBuffer(size);
-                }
-            }
         }
 
         return bufferRect;
@@ -176,7 +151,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
         }
     }
 
-    private void copyPixelsFromMultiTileLayer(Bitmap target) {
+    /*private void copyPixelsFromMultiTileLayer(Bitmap target) {
         Canvas c = new Canvas(target);
         ByteBuffer tileBuffer = mBuffer.slice();
         int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
@@ -201,7 +176,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
                 tileBuffer = tileBuffer.slice();
             }
         }
-    }
+    }*/
 
     @Override
     protected void tileLayerUpdated() {
@@ -215,7 +190,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
 
         // Begin a tile transaction, otherwise the buffer can be destroyed while
         // we're reading from it.
-        beginTransaction(mTileLayer);
+        /*beginTransaction(mTileLayer);
         try {
             if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0)
                 return null;
@@ -223,8 +198,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
                 Bitmap b = null;
 
                 if (mTileLayer instanceof MultiTileLayer) {
-                    b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,
-                            CairoUtils.cairoFormatTobitmapConfig(mFormat));
+                    b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,CairoUtils.cairoFormatTobitmapConfig(mFormat));
                     copyPixelsFromMultiTileLayer(b);
                 } else {
                     Log.w(LOGTAG, "getBitmap() called on a layer (" + mTileLayer + ") we don't know how to get a bitmap from");
@@ -237,20 +211,9 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
             }
         } finally {
             endTransaction(mTileLayer);
-        }
-    }
-
-    /** Returns the back buffer. This function is for Gecko to use. */
-    public ByteBuffer lockBuffer() {
-        return mBuffer;
-    }
+        }*/
 
-    /**
-     * Gecko calls this function to signal that it is done with the back buffer. After this call,
-     * it is forbidden for Gecko to touch the buffer.
-     */
-    public void unlockBuffer() {
-        /* no-op */
+        return null;
     }
 
     @Override
@@ -269,5 +232,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
     protected IntSize getTileSize() {
         return TILE_SIZE;
     }
+
+    public void addTile(Bitmap bitmap, int x, int y) {
+        if (mTileLayer instanceof MultiTileLayer) {
+            ((MultiTileLayer)mTileLayer).addTile(bitmap, x, y);
+        }
+    }
 }
 
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
index 2dd3316..4078653 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
@@ -121,8 +121,8 @@ public abstract class Layer {
      * This function may block, so you should never call this on the main UI thread.
      */
     public void beginTransaction(LayerView aView) {
-        if (mTransactionLock.isHeldByCurrentThread())
-            throw new RuntimeException("Nested transactions are not supported");
+        //if (mTransactionLock.isHeldByCurrentThread())
+        //    throw new RuntimeException("Nested transactions are not supported");
         mTransactionLock.lock();
         mView = aView;
         mInTransaction = true;
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java
index 3514b42..a958a54 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java
@@ -38,11 +38,16 @@
 
 package org.mozilla.gecko.gfx;
 
+import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
+import android.util.Log;
 
+import org.libreoffice.LOKitShell;
+
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
@@ -54,18 +59,15 @@ import java.util.ArrayList;
 public class MultiTileLayer extends Layer {
     private static final String LOGTAG = "GeckoMultiTileLayer";
 
-    private final CairoImage mImage;
     private final ArrayList<SubTile> mTiles;
     private IntSize mTileSize;
-    private IntSize mBufferSize;
+    private IntSize mSize;
 
-    public MultiTileLayer(CairoImage image, IntSize tileSize) {
+    public MultiTileLayer(IntSize tileSize) {
         super();
-
-        mImage = image;
         mTileSize = tileSize;
-        mBufferSize = new IntSize(0, 0);
         mTiles = new ArrayList<SubTile>();
+        mSize = new IntSize(0,0);
     }
 
     public void invalidate(Rect dirtyRect) {
@@ -90,67 +92,20 @@ public class MultiTileLayer extends Layer {
         }
     }
 
+    public void setSize(IntSize size) {
+        mSize = size;
+    }
+
     @Override
     public IntSize getSize() {
-        return mImage.getSize();
+        return mSize;
     }
 
     private void validateTiles() {
-        IntSize size = getSize();
-
-        if (size.equals(mBufferSize)) {
-            return;
-        }
-
-        // Regenerate tiles
-        mTiles.clear();
-        int offset = 0;
-        final int format = mImage.getFormat();
-        final ByteBuffer buffer = mImage.getBuffer().slice();
-        final int bpp = CairoUtils.bitsPerPixelForCairoFormat(format) / 8;
-        for (int y = 0; y < size.height; y += mTileSize.height) {
-            for (int x = 0; x < size.width; x += mTileSize.width) {
-                // Create a CairoImage implementation that returns a
-                // tile from the parent CairoImage. It's assumed that
-                // the tiles are stored in series.
-                final IntSize layerSize =
-                        new IntSize(Math.min(mTileSize.width, size.width - x),
-                                Math.min(mTileSize.height, size.height - y));
-                final int tileOffset = offset;
-
-                CairoImage subImage = new CairoImage() {
-                    @Override
-                    public ByteBuffer getBuffer() {
-                        // Create a ByteBuffer that shares the data of the original
-                        // buffer, but is positioned and limited so that only the
-                        // tile data is accessible.
-                        buffer.position(tileOffset);
-                        ByteBuffer tileBuffer = buffer.slice();
-                        tileBuffer.limit(layerSize.getArea() * bpp);
-
-                        return tileBuffer;
-                    }
-
-                    @Override
-                    public IntSize getSize() {
-                        return layerSize;
-                    }
-
-                    @Override
-                    public int getFormat() {
-                        return format;
-                    }
-                };
-
-                mTiles.add(new SubTile(subImage, x, y));
-                offset += layerSize.getArea() * bpp;
-            }
-        }
+        Log.i(LOGTAG, "validateTiles()");
 
         // Set tile origins and resolution
         refreshTileMetrics(getOrigin(), getResolution(), false);
-
-        mBufferSize = size;
     }
 
     @Override
@@ -286,15 +241,10 @@ public class MultiTileLayer extends Layer {
         return validRegion;
     }
 
-    class SubTile extends SingleTileLayer {
-        public int x;
-        public int y;
-
-        public SubTile(CairoImage mImage, int mX, int mY) {
-            super(mImage);
-            x = mX;
-            y = mY;
-        }
+    public void addTile(Bitmap bitmap, int x, int y) {
+        SubTile tile = new SubTile(new BufferedCairoImage(bitmap), x,y);
+        tile.beginTransaction();
+        mTiles.add(tile);
     }
 }
 
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java
new file mode 100644
index 0000000..0c40c3c
--- /dev/null
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java
@@ -0,0 +1,15 @@
+package org.mozilla.gecko.gfx;
+
+/**
+* Created by quikee on 29.6.2014.
+*/
+public class SubTile extends SingleTileLayer {
+    public int x;
+    public int y;
+
+    public SubTile(CairoImage mImage, int mX, int mY) {
+        super(mImage);
+        x = mX;
+        y = mY;
+    }
+}
commit 7164161de92340809155e1ec4b218d101b7f2d9c
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Sun Jun 29 22:12:06 2014 +0200

    LODroid: remove hasDirectTexture for now
    
    Change-Id: Iaf4ce2df890c0f61c9466a8ea1ec35731d3eed44

diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
index 4027d61..6274e4b 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
@@ -39,7 +39,7 @@ public class LOKitThread extends Thread {
             metadata = createJson(mViewportMetrics);
         }
 
-        Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata, false);
+        Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata);
         if (bufferRect == null)
             return false;
 
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
index b6c3977..2ffe113 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
@@ -71,7 +71,7 @@ public class BufferedCairoImage extends CairoImage {
         mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
         mNeedToFreeBuffer = true;
         // XXX Why is this * 4? Shouldn't it depend on mFormat?
-        mBuffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(mSize.getArea() * 4);
+        mBuffer = LOKitShell.allocateDirectBuffer(mSize.getArea() * 4);
 
         bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
     }
@@ -79,7 +79,7 @@ public class BufferedCairoImage extends CairoImage {
     protected void finalize() throws Throwable {
         try {
             if (mNeedToFreeBuffer && mBuffer != null)
-                /*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer);
+                LOKitShell.freeDirectBuffer(mBuffer);
             mNeedToFreeBuffer = false;
             mBuffer = null;
         } finally {
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoGLLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoGLLayerClient.java
deleted file mode 100644
index 9e4f376..0000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoGLLayerClient.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Patrick Walton <pcwalton at mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.View;
-
-import org.libreoffice.LOEvent;
-import org.libreoffice.LOKitShell;
-
-public class GeckoGLLayerClient extends GeckoLayerClient
-        implements FlexibleGLSurfaceView.Listener, VirtualLayer.Listener {
-    private static final String LOGTAG = "GeckoGLLayerClient";
-
-    private LayerRenderer mLayerRenderer;
-    private boolean mLayerRendererInitialized;
-
-    public GeckoGLLayerClient(Context context) {
-        super(context);
-    }
-
-    @Override
-    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight,
-                             String metadata, boolean hasDirectTexture) {
-        Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight,
-                metadata, hasDirectTexture);
-        if (bufferRect == null) {
-            return null;
-        }
-
-        // Be sure to adjust the buffer size; if it's not at least as large as the viewport size,
-        // ViewportMetrics.getOptimumViewportOffset() gets awfully confused and severe display
-        // corruption results!
-        if (mBufferSize.width != width || mBufferSize.height != height) {
-            mBufferSize = new IntSize(width, height);
-        }
-
-        return bufferRect;
-    }
-
-    @Override
-    protected boolean handleDirectTextureChange(boolean hasDirectTexture) {
-        Log.e(LOGTAG, "### handleDirectTextureChange");
-        if (mTileLayer != null) {
-            return false;
-        }
-
-        Log.e(LOGTAG, "### Creating virtual layer");
-        VirtualLayer virtualLayer = new VirtualLayer();
-        virtualLayer.setListener(this);
-        virtualLayer.setSize(getBufferSize());
-        getLayerController().setRoot(virtualLayer);
-        mTileLayer = virtualLayer;
-
-        sendResizeEventIfNecessary(true);
-        return true;
-    }
-
-    @Override
-    public void setLayerController(LayerController layerController) {
-        super.setLayerController(layerController);
-
-        LayerView view = layerController.getView();
-        view.setListener(this);
-
-        mLayerRenderer = new LayerRenderer(view);
-    }
-
-    @Override
-    protected boolean shouldDrawProceed(int tileWidth, int tileHeight) {
-        Log.e(LOGTAG, "### shouldDrawProceed");
-        // Always draw.
-        return true;
-    }
-
-    @Override
-    protected void updateLayerAfterDraw(Rect updatedRect) {
-        Log.e(LOGTAG, "### updateLayerAfterDraw");
-        // Nothing to do.
-    }
-
-    @Override
-    protected IntSize getBufferSize() {
-        View view = (View) getLayerController().getView();
-        IntSize size = new IntSize(view.getWidth(), view.getHeight());
-        Log.e(LOGTAG, "### getBufferSize " + size);
-        return size;
-    }
-
-    @Override
-    protected IntSize getTileSize() {
-        Log.e(LOGTAG, "### getTileSize " + getBufferSize());
-        return getBufferSize();
-    }
-
-    @Override
-    protected void tileLayerUpdated() {
-        // Set the new origin and resolution instantly.
-        mTileLayer.performUpdates(null);
-    }
-
-    @Override
-    public Bitmap getBitmap() {
-        Log.e(LOGTAG, "### getBitmap");
-        IntSize size = getBufferSize();
-        try {
-            return Bitmap.createBitmap(size.width, size.height, Bitmap.Config.RGB_565);
-        } catch (OutOfMemoryError oom) {
-            Log.e(LOGTAG, "Unable to create bitmap", oom);
-            return null;
-        }
-    }
-
-    @Override
-    public int getType() {
-        Log.e(LOGTAG, "### getType");
-        return LAYER_CLIENT_TYPE_GL;
-    }
-
-    public void dimensionsChanged(Point newOrigin, float newResolution) {
-        Log.e(LOGTAG, "### dimensionsChanged " + newOrigin + " " + newResolution);
-    }
-
-    /* Informs Gecko that the screen size has changed. */
-    @Override
-    protected void sendResizeEventIfNecessary(boolean force) {
-        Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force);
-
-        IntSize newSize = getBufferSize();
-        if (!force && mScreenSize != null && mScreenSize.equals(newSize)) {
-            return;
-        }
-
-        mScreenSize = newSize;
-
-        Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize);
-        //GeckoEvent event = GeckoEvent.createSizeChangedEvent(mScreenSize.width, mScreenSize.height,
-        //        mScreenSize.width, mScreenSize.height,
-        //        mScreenSize.width, mScreenSize.height);
-        //GeckoAppShell.sendEventToGecko(event);
-        LOEvent event = LOEvent.sizeChanged(mScreenSize.width, mScreenSize.height,
-                                            mScreenSize.width, mScreenSize.height,
-                                            mScreenSize.width, mScreenSize.height);
-        LOKitShell.sendEvent(event);
-
-    }
-
-    /**
-     * For Gecko to use.
-     */
-    public ViewTransform getViewTransform() {
-        Log.e(LOGTAG, "### getViewTransform()");
-
-        // NB: We don't begin a transaction here because this can be called in a synchronous
-        // manner between beginDrawing() and endDrawing(), and that will cause a deadlock.
-
-        LayerController layerController = getLayerController();
-        synchronized (layerController) {
-            ViewportMetrics viewportMetrics = layerController.getViewportMetrics();
-            PointF viewportOrigin = viewportMetrics.getOrigin();
-            Point tileOrigin = mTileLayer.getOrigin();
-            float scrollX = viewportOrigin.x;
-            float scrollY = viewportOrigin.y;
-            float zoomFactor = viewportMetrics.getZoomFactor();
-            Log.e(LOGTAG, "### Viewport metrics = " + viewportMetrics + " tile reso = " +
-                    mTileLayer.getResolution());
-            return new ViewTransform(scrollX, scrollY, zoomFactor);
-        }
-    }
-
-    public void renderRequested() {
-        Log.e(LOGTAG, "### Render requested, scheduling composite");
-        LOKitShell.scheduleComposite();
-    }
-
-    public void compositionPauseRequested() {
-        Log.e(LOGTAG, "### Scheduling PauseComposition");
-        LOKitShell.schedulePauseComposition();
-    }
-
-    public void compositionResumeRequested() {
-        Log.e(LOGTAG, "### Scheduling ResumeComposition");
-        LOKitShell.scheduleResumeComposition();
-    }
-
-    public void surfaceChanged(int width, int height) {
-        compositionPauseRequested();
-        LayerController layerController = getLayerController();
-        layerController.setViewportSize(new FloatSize(width, height));
-        compositionResumeRequested();
-        renderRequested();
-    }
-
-    /**
-     * For Gecko to use.
-     */
-    public LayerRenderer.Frame createFrame() {
-        // Create the shaders and textures if necessary.
-        if (!mLayerRendererInitialized) {
-            mLayerRenderer.createProgram();
-            mLayerRendererInitialized = true;
-        }
-
-        // Build the contexts and create the frame.
-        Layer.RenderContext pageContext = mLayerRenderer.createPageContext();
-        Layer.RenderContext screenContext = mLayerRenderer.createScreenContext();
-        return mLayerRenderer.createFrame(pageContext, screenContext);
-    }
-
-    /**
-     * For Gecko to use.
-     */
-    public void activateProgram() {
-        mLayerRenderer.activateProgram();
-    }
-
-    /**
-     * For Gecko to use.
-     */
-    public void deactivateProgram() {
-        mLayerRenderer.deactivateProgram();
-    }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 7c7579e..a491f07 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -38,17 +38,6 @@
 
 package org.mozilla.gecko.gfx;
 
-import org.libreoffice.LOEvent;
-import org.libreoffice.LOKitShell;
-import org.libreoffice.LibreOfficeMainActivity;
-import org.mozilla.gecko.util.FloatUtils;
-//import org.mozilla.gecko.GeckoApp;
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.GeckoEventListener;
-import org.json.JSONException;
-import org.json.JSONObject;
-
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -59,13 +48,26 @@ import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.libreoffice.LOEvent;
+import org.libreoffice.LOKitShell;
+import org.libreoffice.LibreOfficeMainActivity;
+import org.mozilla.gecko.GeckoEventListener;
+import org.mozilla.gecko.util.FloatUtils;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+//import org.mozilla.gecko.GeckoApp;
+//import org.mozilla.gecko.GeckoAppShell;
+//import org.mozilla.gecko.GeckoEvent;
+
 public abstract class GeckoLayerClient extends LayerClient implements GeckoEventListener {
     public static final int LAYER_CLIENT_TYPE_NONE = 0;
     public static final int LAYER_CLIENT_TYPE_SOFTWARE = 1;
     public static final int LAYER_CLIENT_TYPE_GL = 2;
+
     private static final String LOGTAG = "GeckoLayerClient";
     private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
     private static Pattern sColorPattern;
@@ -79,6 +81,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
     private long mLastViewportChangeTime;
     private boolean mPendingViewportAdjust;
     private boolean mViewportSizeChanged;
+
     // mUpdateViewportOnEndDraw is used to indicate that we received a
     // viewport update notification while drawing. therefore, when the
     // draw finishes, we need to update the entire viewport rather than
@@ -112,7 +115,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         return Color.rgb(r, g, b);
     }
 
-    protected abstract boolean handleDirectTextureChange(boolean hasDirectTexture);
+    protected abstract boolean setupLayer();
 
     protected abstract boolean shouldDrawProceed(int tileWidth, int tileHeight);
 
@@ -140,19 +143,15 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
             layerController.setViewportMetrics(mGeckoViewport);
         }
 
-        //GeckoAppShell.registerGeckoEventListener("Viewport:UpdateAndDraw", this);
-        //GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
-
         sendResizeEventIfNecessary();
     }
 
-    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata, boolean hasDirectTexture) {
+    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
 
-        Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight + " " + hasDirectTexture);
+        Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight);
 
-        // If we've changed surface types, cancel this draw
-        if (handleDirectTextureChange(hasDirectTexture)) {
-            Log.e(LOGTAG, "### Cancelling draw due to direct texture change");
+        if (setupLayer()) {
+            Log.e(LOGTAG, "### Cancelling due to layer setup");
             return null;
         }
 
@@ -180,7 +179,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
             return null;
         }
 
-
         // Make sure we don't spend time painting areas we aren't interested in.
         // Only do this if the Gecko viewport isn't going to override our viewport.
         Rect bufferRect = new Rect(0, 0, width, height);
@@ -263,15 +261,14 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         mTileLayer.setResolution(mGeckoViewport.getZoomFactor());
 
         this.tileLayerUpdated();
-        Log.e(LOGTAG, "### updateViewport onlyUpdatePageSize=" + onlyUpdatePageSize +
-                " getTileViewport " + mGeckoViewport);
+        Log.e(LOGTAG, "### updateViewport onlyUpdatePageSize=" + onlyUpdatePageSize + " getTileViewport " + mGeckoViewport);
 
         if (onlyUpdatePageSize) {
             // Don't adjust page size when zooming unless zoom levels are
             // approximately equal.
-            if (FloatUtils.fuzzyEquals(controller.getZoomFactor(),
-                    mGeckoViewport.getZoomFactor()))
+            if (FloatUtils.fuzzyEquals(controller.getZoomFactor(), mGeckoViewport.getZoomFactor())) {
                 controller.setPageSize(mGeckoViewport.getPageSize());
+            }
         } else {
             controller.setViewportMetrics(mGeckoViewport);
             controller.abortPanZoomAnimation();
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
index 07b68ce..ee99d16 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
@@ -74,9 +74,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
 
     private static final IntSize TILE_SIZE = new IntSize(256, 256);
 
-    // Whether or not the last paint we got used direct texturing
-    private boolean mHasDirectTexture;
-
     public GeckoSoftwareLayerClient(Context context) {
         super(context);
 
@@ -110,28 +107,16 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
             layerController.setViewportMetrics(mGeckoViewport);
         }
 
-        //GeckoAppShell.registerGeckoEventListener("Viewport:UpdateAndDraw", this);
-        //GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
-        //GeckoAppShell.registerGeckoEventListener("Checkerboard:Toggle", this);
-
-        // XXX: Review pcwalton. This signature changed on m-c, should force = false here?
         sendResizeEventIfNecessary(false);
     }
 
     @Override
-    protected boolean handleDirectTextureChange(boolean hasDirectTexture) {
-        if (mTileLayer != null && hasDirectTexture == mHasDirectTexture)
+    protected boolean setupLayer() {
+        if (mTileLayer != null)
             return false;
 
-        mHasDirectTexture = hasDirectTexture;
-
-        if (mHasDirectTexture) {
-            Log.i(LOGTAG, "Creating WidgetTileLayer");
-            mTileLayer = new WidgetTileLayer(mCairoImage);
-        } else {
-            Log.i(LOGTAG, "Creating MultiTileLayer");
-            mTileLayer = new MultiTileLayer(mCairoImage, TILE_SIZE);
-        }
+        Log.i(LOGTAG, "Creating MultiTileLayer");
+        mTileLayer = new MultiTileLayer(mCairoImage, TILE_SIZE);
 
         getLayerController().setRoot(mTileLayer);
 
@@ -146,26 +131,16 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
     protected boolean shouldDrawProceed(int tileWidth, int tileHeight) {
         // Make sure the tile-size matches. If it doesn't, we could crash trying
         // to access invalid memory.
-        if (mHasDirectTexture) {
-            if (tileWidth != 0 || tileHeight != 0) {
-                Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" +
-                        tileHeight);
-                return false;
-            }
-        } else {
-            if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) {
-                Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" +
-                        tileHeight);
-                return false;
-            }
+        if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) {
+            Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" + tileHeight);
+            return false;
         }
-
         return true;
     }
 
     @Override
-    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata, boolean hasDirectTexture) {
-        Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata, hasDirectTexture);
+    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
+        Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
 
         if (bufferRect == null) {
             return bufferRect;
@@ -196,11 +171,9 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
 
     @Override
     protected void updateLayerAfterDraw(Rect updatedRect) {
-        if (!(mTileLayer instanceof MultiTileLayer)) {
-            return;
+        if (mTileLayer instanceof MultiTileLayer) {
+            ((MultiTileLayer)mTileLayer).invalidate(updatedRect);
         }
-
-        ((MultiTileLayer)mTileLayer).invalidate(updatedRect);
     }
 
     private void copyPixelsFromMultiTileLayer(Bitmap target) {
@@ -287,35 +260,14 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
 
     @Override
     protected IntSize getBufferSize() {
-        // Round up depending on layer implementation to remove texture wastage
-        if (!mHasDirectTexture) {
-            // Round to the next multiple of the tile size
-            return new IntSize(((mScreenSize.width + LayerController.MIN_BUFFER.width - 1) /
-                    TILE_SIZE.width + 1) * TILE_SIZE.width,
-                    ((mScreenSize.height + LayerController.MIN_BUFFER.height - 1) /
-                            TILE_SIZE.height + 1) * TILE_SIZE.height);
-        }
-
-        int maxSize = getLayerController().getView().getMaxTextureSize();
-
-        // XXX Integrate gralloc/tiling work to circumvent this
-        if (mScreenSize.width > maxSize || mScreenSize.height > maxSize) {
-            throw new RuntimeException("Screen size of " + mScreenSize +
-                    " larger than maximum texture size of " + maxSize);
-        }
-
-        // Round to next power of two until we have NPOT texture support, respecting maximum
-        // texture size
-        return new IntSize(Math.min(maxSize, IntSize.nextPowerOfTwo(mScreenSize.width +
-                LayerController.MIN_BUFFER.width)),
-                Math.min(maxSize, IntSize.nextPowerOfTwo(mScreenSize.height +
-                        LayerController.MIN_BUFFER.height)));
+        return new IntSize(
+            ((mScreenSize.width + LayerController.MIN_BUFFER.width - 1) / TILE_SIZE.width + 1) * TILE_SIZE.width,
+            ((mScreenSize.height + LayerController.MIN_BUFFER.height - 1) / TILE_SIZE.height + 1) * TILE_SIZE.height);
     }
 
     @Override
     protected IntSize getTileSize() {
-        // Round up depending on layer implementation to remove texture wastage
-        return !mHasDirectTexture ? TILE_SIZE : new IntSize(0, 0);
+        return TILE_SIZE;
     }
 }
 
commit 2820ecb7184f04f6e29b178a7d857888828d5e04
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Sun Jun 29 21:54:00 2014 +0200

    LODroid: Use tile images in LOAndroid2
    
    Change-Id: Ic274d19467b8d0915ae438a0651f19da14392697

diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
index ea3472b..4027d61 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
@@ -17,6 +17,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 
 public class LOKitThread extends Thread {
     private static final String LOGTAG = "GeckoThread";
+    private static final int TILE_SIZE = 256;
+
 
     public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
     private ViewportMetrics mViewportMetrics;
@@ -28,59 +30,75 @@ public class LOKitThread extends Thread {
     private boolean draw() throws InterruptedException {
         final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
 
-        Bitmap bitmap = application.getLayerClient().getLayerController().getDrawable("docu");
-        //bitmap = convert(bitmap, Bitmap.Config.ARGB_8888);
+        Bitmap originalBitmap = application.getLayerClient().getLayerController().getDrawable("dummy_page");
+
+        String metadata;
+        if (mViewportMetrics == null) {
+            metadata = createJson(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), originalBitmap.getWidth(), originalBitmap.getHeight(), 0, 0, 1.0);
+        } else {
+            metadata = createJson(mViewportMetrics);
+        }
 
-        StringWriter stringWriter = new StringWriter();
+        Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata, false);
+        if (bufferRect == null)
+            return false;
+
+        ByteBuffer buffer = application.getLayerClient().lockBuffer();
+        for (Integer i = 1; i <= 9; i++) {
+            String imageName = "d" + i;
+            Bitmap bitmap = application.getLayerClient().getLayerController().getDrawable(imageName);
+            bitmap.copyPixelsToBuffer(buffer.asIntBuffer());
+            buffer.position(buffer.position() + bitmap.getByteCount());
+        }
+        buffer.position(0);
+
+        application.getLayerClient().unlockBuffer();
+        application.getLayerClient().endDrawing(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight());
+
+        application.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                application.getLayerClient().handleMessage("Viewport:UpdateLater", null);
+            }
+        });
+
+        return true;
+    }
 
+    private String createJson(ViewportMetrics viewportMetrics) {
+        return createJson(
+                (int) viewportMetrics.getOrigin().x,
+                (int) viewportMetrics.getOrigin().y,
+                (int) viewportMetrics.getSize().width,
+                (int) viewportMetrics.getSize().height,
+                (int) viewportMetrics.getPageSize().width,
+                (int) viewportMetrics.getPageSize().height,
+                (int) viewportMetrics.getViewportOffset().x,
+                (int) viewportMetrics.getViewportOffset().y,
+                viewportMetrics.getZoomFactor());
+    }
+
+    private String createJson(int x, int y, int width, int height, int pageWidth, int pageHeight, int offsetX, int offsetY, double zoom) {
         try {
+            StringWriter stringWriter = new StringWriter();
             JsonWriter writer = new JsonWriter(stringWriter);
             writer.beginObject();
-            if (mViewportMetrics == null) {
-                writer.name("x").value(0);
-                writer.name("y").value(0);
-                writer.name("width").value(bitmap.getWidth());
-                writer.name("height").value(bitmap.getHeight());
-                writer.name("pageWidth").value(bitmap.getWidth());
-                writer.name("pageHeight").value(bitmap.getHeight());
-                writer.name("offsetX").value(0);
-                writer.name("offsetY").value(0);
-                writer.name("zoom").value(0.5);
-            } else {
-                writer.name("x").value(mViewportMetrics.getOrigin().x);
-                writer.name("y").value(mViewportMetrics.getOrigin().y);
-                writer.name("width").value(mViewportMetrics.getSize().width);
-                writer.name("height").value(mViewportMetrics.getSize().height);
-                writer.name("pageWidth").value(mViewportMetrics.getPageSize().width);
-                writer.name("pageHeight").value(mViewportMetrics.getPageSize().height);
-                writer.name("offsetX").value(mViewportMetrics.getViewportOffset().x);
-                writer.name("offsetY").value(mViewportMetrics.getViewportOffset().y);
-                writer.name("zoom").value(mViewportMetrics.getZoomFactor());
-            }
+            writer.name("x").value(x);
+            writer.name("y").value(y);
+            writer.name("width").value(width);
+            writer.name("height").value(height);
+            writer.name("pageWidth").value(pageWidth);
+            writer.name("pageHeight").value(pageHeight);
+            writer.name("offsetX").value(offsetX);
+            writer.name("offsetY").value(offsetY);
+            writer.name("zoom").value(zoom);
             writer.name("backgroundColor").value("rgb(255,255,255)");
             writer.endObject();
             writer.close();
+            return stringWriter.toString();
         } catch (IOException ex) {
         }
-
-        Rect bufferRect = application.getLayerClient().beginDrawing(bitmap.getWidth(), bitmap.getHeight(), 256, 256, stringWriter.toString(), false);
-
-        if (bufferRect == null) {
-            return false;
-        }
-            ByteBuffer buffer = application.getLayerClient().lockBuffer();
-            bitmap.copyPixelsToBuffer(buffer.asIntBuffer());
-            application.getLayerClient().unlockBuffer();
-
-            application.getLayerClient().endDrawing(0, 0, bitmap.getWidth(), bitmap.getHeight());
-
-            application.runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    application.getLayerClient().handleMessage("Viewport:UpdateLater", null);
-                }
-            });
-        return true;
+        return null;
     }
 
     private short convertTo16Bit(int color) {
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png
new file mode 100644
index 0000000..72713b5
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png
new file mode 100644
index 0000000..4a10703
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png
new file mode 100644
index 0000000..2150c89
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png
new file mode 100644
index 0000000..8a12a76
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png
new file mode 100644
index 0000000..5a72e17
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png
new file mode 100644
index 0000000..3abb776
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png
new file mode 100644
index 0000000..9e46db7
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png
new file mode 100644
index 0000000..c6091ae
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png
new file mode 100644
index 0000000..978606d
Binary files /dev/null and b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png differ
commit 2c3d341f81b72c8bb7567508d95d8c4121712767
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Sun Jun 29 20:19:37 2014 +0200

    LODroid: Don't ignore size change event, clean-up GeckoLayerClient
    
    Change-Id: I615a762334434068681ecb1cc7ae6890319bd7ec

diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 09349b4..7c7579e 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -48,6 +48,7 @@ import org.mozilla.gecko.util.FloatUtils;
 import org.mozilla.gecko.GeckoEventListener;
 import org.json.JSONException;
 import org.json.JSONObject;
+
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -57,61 +58,79 @@ import android.graphics.RectF;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 public abstract class GeckoLayerClient extends LayerClient implements GeckoEventListener {
-    private static final String LOGTAG = "GeckoLayerClient";
-
     public static final int LAYER_CLIENT_TYPE_NONE = 0;
     public static final int LAYER_CLIENT_TYPE_SOFTWARE = 1;
     public static final int LAYER_CLIENT_TYPE_GL = 2;
-
+    private static final String LOGTAG = "GeckoLayerClient";
+    private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
+    private static Pattern sColorPattern;
     protected IntSize mScreenSize;
     protected IntSize mBufferSize;
-
     protected Layer mTileLayer;
-
     /* The viewport that Gecko is currently displaying. */
     protected ViewportMetrics mGeckoViewport;
-
     /* The viewport that Gecko will display when drawing is finished */
     protected ViewportMetrics mNewGeckoViewport;
-
-    private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
     private long mLastViewportChangeTime;
     private boolean mPendingViewportAdjust;
     private boolean mViewportSizeChanged;
-
     // mUpdateViewportOnEndDraw is used to indicate that we received a
     // viewport update notification while drawing. therefore, when the
     // draw finishes, we need to update the entire viewport rather than
     // just the page size. this boolean should always be accessed from
     // inside a transaction, so no synchronization is needed.
     private boolean mUpdateViewportOnEndDraw;
-
     private String mLastCheckerboardColor;
-
-    private static Pattern sColorPattern;
-
     /* Used by robocop for testing purposes */
     private DrawListener mDrawListener;
 
+    public GeckoLayerClient(Context context) {
+        mScreenSize = new IntSize(0, 0);
+        mBufferSize = new IntSize(0, 0);
+    }
+
+    // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
+    // cannot be parsed, returns white.
+    private static int parseColorFromGecko(String string) {
+        if (sColorPattern == null) {
+            sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
+        }
+
+        Matcher matcher = sColorPattern.matcher(string);
+        if (!matcher.matches()) {
+            return Color.WHITE;
+        }
+
+        int r = Integer.parseInt(matcher.group(1));
+        int g = Integer.parseInt(matcher.group(2));
+        int b = Integer.parseInt(matcher.group(3));
+        return Color.rgb(r, g, b);
+    }
+
     protected abstract boolean handleDirectTextureChange(boolean hasDirectTexture);
+
     protected abstract boolean shouldDrawProceed(int tileWidth, int tileHeight);
+
     protected abstract void updateLayerAfterDraw(Rect updatedRect);
+
     protected abstract IntSize getBufferSize();
+
     protected abstract IntSize getTileSize();
+
     protected abstract void tileLayerUpdated();
+
     public abstract Bitmap getBitmap();
-    public abstract int getType();
 
-    public GeckoLayerClient(Context context) {
-        mScreenSize = new IntSize(0, 0);
-        mBufferSize = new IntSize(0, 0);
-    }
+    public abstract int getType();
 
-    /** Attaches the root layer to the layer controller so that Gecko appears. */
+    /**
+     * Attaches the root layer to the layer controller so that Gecko appears.
+     */
     @Override
     public void setLayerController(LayerController layerController) {
         super.setLayerController(layerController);
@@ -127,10 +146,9 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         sendResizeEventIfNecessary();
     }
 
-    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight,
-                             String metadata, boolean hasDirectTexture) {
-        Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " +
-                tileHeight + " " + hasDirectTexture);
+    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata, boolean hasDirectTexture) {
+
+        Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight + " " + hasDirectTexture);
 
         // If we've changed surface types, cancel this draw
         if (handleDirectTextureChange(hasDirectTexture)) {
@@ -187,6 +205,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
 
 
             // Take the intersection of the two as the area we're interested in rendering.
+
             if (!bufferRect.intersect(currentRect)) {
                 // If there's no intersection, we have no need to render anything,
                 // but make sure to update the viewport size.
@@ -264,15 +283,14 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force);
 
         DisplayMetrics metrics = new DisplayMetrics();
-        /*GeckoApp*/LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+        LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
 
         // Return immediately if the screen size hasn't changed or the viewport
         // size is zero (which indicates that the rendering surface hasn't been
         // allocated yet).
-        boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width ||
-                metrics.heightPixels != mScreenSize.height);
-        boolean viewportSizeValid = (getLayerController() != null &&
-                getLayerController().getViewportSize().isPositive());
+        boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width || metrics.heightPixels != mScreenSize.height);
+        boolean viewportSizeValid = (getLayerController() != null && getLayerController().getViewportSize().isPositive());
+
         if (!(force || (screenSizeChanged && viewportSizeValid))) {
             return;
         }
@@ -281,31 +299,11 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         IntSize bufferSize = getBufferSize(), tileSize = getTileSize();
 
         Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize);
-        //GeckoEvent event = GeckoEvent.createSizeChangedEvent(bufferSize.width, bufferSize.height,
-        //        metrics.widthPixels, metrics.heightPixels,
-        //        tileSize.width, tileSize.height);
-        //GeckoAppShell.sendEventToGecko(event);
-        LOEvent event = LOEvent.sizeChanged(bufferSize.width, bufferSize.height,
-                                            metrics.widthPixels, metrics.heightPixels,
-                                            tileSize.width, tileSize.height);
-    }
 
-    // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
-    // cannot be parsed, returns white.
-    private static int parseColorFromGecko(String string) {
-        if (sColorPattern == null) {
-            sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
-        }
-
-        Matcher matcher = sColorPattern.matcher(string);
-        if (!matcher.matches()) {
-            return Color.WHITE;
-        }
-
-        int r = Integer.parseInt(matcher.group(1));
-        int g = Integer.parseInt(matcher.group(2));
-        int b = Integer.parseInt(matcher.group(3));
-        return Color.rgb(r, g, b);
+        LOEvent event = LOEvent.sizeChanged(bufferSize.width, bufferSize.height,
+                metrics.widthPixels, metrics.heightPixels,
+                tileSize.width, tileSize.height);
+        LOKitShell.sendEvent(event);
     }
 
     @Override
@@ -328,7 +326,8 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
                             mPendingViewportAdjust = false;
                             adjustViewport();
                         }
-                    }, MIN_VIEWPORT_CHANGE_DELAY - timeDelta);
+                    }, MIN_VIEWPORT_CHANGE_DELAY - timeDelta
+            );
             mPendingViewportAdjust = true;
             return;
         }
@@ -342,18 +341,15 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
     }
 
     private void adjustViewport() {
-        ViewportMetrics viewportMetrics =
-                new ViewportMetrics(getLayerController().getViewportMetrics());
+        ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics());
 
         PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(mBufferSize);
         viewportMetrics.setViewportOffset(viewportOffset);
         viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
 
-        //GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(viewportMetrics));
         LOKitShell.sendEvent(LOEvent.viewport(viewportMetrics));
         if (mViewportSizeChanged) {
             mViewportSizeChanged = false;
-            //GeckoAppShell.viewSizeChanged();
             LOKitShell.viewSizeChanged();
         }
 
@@ -367,7 +363,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
 
             // Redraw everything.
             Rect rect = new Rect(0, 0, mBufferSize.width, mBufferSize.height);
-            //GeckoAppShell.sendEventToGecko(GeckoEvent.createDrawEvent(rect));
             LOKitShell.sendEvent(LOEvent.draw(rect));
         } else if ("Viewport:UpdateLater".equals(event)) {
             Log.e(LOGTAG, "### Java side Viewport:UpdateLater()!");
@@ -377,7 +372,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
 
     @Override
     public void geometryChanged() {
-        /* Let Gecko know if the screensize has changed */
         sendResizeEventIfNecessary();
         render();
     }
@@ -391,7 +385,6 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
     }
 
     public ViewportMetrics getGeckoViewportMetrics() {
-        // Return a copy, as we modify this inside the Gecko thread
         if (mGeckoViewport != null)
             return new ViewportMetrics(mGeckoViewport);
         return null;
@@ -401,14 +394,17 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
         sendResizeEventIfNecessary(false);
     }
 
-    /** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */
+    /**
+     * Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop.
+     */
     public void setDrawListener(DrawListener listener) {
         mDrawListener = listener;
     }
 
-    /** Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop. */
+    /**
+     * Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop.
+     */
     public interface DrawListener {
         public void drawFinished(int x, int y, int width, int height);
     }
-}
-
+}
\ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
index fa1d5ad..07b68ce 100644
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
+++ b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
@@ -164,10 +164,9 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
     }
 
     @Override
-    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight,
-                             String metadata, boolean hasDirectTexture) {
-        Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight,
-                metadata, hasDirectTexture);
+    public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata, boolean hasDirectTexture) {
+        Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata, hasDirectTexture);
+
         if (bufferRect == null) {
             return bufferRect;
         }
commit 0d55277947fbc2f92fb9fe40dcfa804dc619c37a
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date:   Sun Jun 29 20:15:50 2014 +0200

    LODroid: cleanup
    
    Change-Id: I3c2b156c6ed5c6a27ac845481150150812eef1ec

diff --git a/android/experimental/LOAndroid2/LOAndroid.iml b/android/experimental/LOAndroid2/LOAndroid.iml
deleted file mode 100644
index cd51bb4..0000000
--- a/android/experimental/LOAndroid2/LOAndroid.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.7" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
-
diff --git a/android/experimental/LOAndroid2/LOAndroid2.iml b/android/experimental/LOAndroid2/LOAndroid2.iml
index edb62a6..0bb6048 100644
--- a/android/experimental/LOAndroid2/LOAndroid2.iml
+++ b/android/experimental/LOAndroid2/LOAndroid2.iml
@@ -1,5 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
   <component name="NewModuleRootManager" inherit-compiler-output="true">
     <exclude-output />
     <content url="file://$MODULE_DIR$">
diff --git a/android/experimental/LOAndroid2/build.gradle b/android/experimental/LOAndroid2/build.gradle
index 4c8f6d8..e33f142 100644
--- a/android/experimental/LOAndroid2/build.gradle
+++ b/android/experimental/LOAndroid2/build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.11.+'
+        classpath 'com.android.tools.build:gradle:0.12.+'
     }
 }
 


More information about the Libreoffice-commits mailing list