android/Bootstrap/Makefile.shared | 11 android/Bootstrap/src/org/libreoffice/kit/Document.java | 6 android/default-document/example.odt |binary android/experimental/LOAndroid3/res/layout/about.xml | 48 + android/experimental/LOAndroid3/res/layout/activity_main.xml | 21 android/experimental/LOAndroid3/res/menu/main.xml | 8 android/experimental/LOAndroid3/res/values/strings.xml | 14 android/experimental/LOAndroid3/src/java/org/libreoffice/DocumentPartView.java | 9 android/experimental/LOAndroid3/src/java/org/libreoffice/DocumentPartViewListAdpater.java | 6 android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java | 30 - android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java | 37 + android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java | 38 - android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java | 53 - android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java | 100 ++- android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java | 130 ++++ android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java | 13 android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java | 5 android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java | 32 + android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java | 202 +++++++ android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GLController.java | 28 - android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java | 44 - android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/Layer.java | 33 + android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java | 20 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java | 4 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java | 156 ++++- android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java | 273 ---------- android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SingleTileLayer.java | 104 ++- android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java | 43 + android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TileLayer.java | 7 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ViewTransform.java | 19 solenv/bin/native-code.py | 1 31 files changed, 922 insertions(+), 573 deletions(-)
New commits: commit 6d5c352cb098daac139cb9c32df3420321eaaf3b Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Oct 4 16:17:58 2014 +0200 android: Better detection of HW accel. (needed by TextureView) Change-Id: I32b091d13d9236cee654819e701c583041f869bb diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java index 0a993a7..ad5ad66 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java @@ -20,6 +20,7 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; +import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; @@ -27,6 +28,7 @@ import android.widget.FrameLayout; import org.libreoffice.LibreOfficeMainActivity; +import java.lang.reflect.Method; import java.nio.IntBuffer; /** @@ -61,21 +63,38 @@ public class LayerView extends FrameLayout { public static final int PAINT_BEFORE_FIRST = 1; public static final int PAINT_AFTER_FIRST = 2; + boolean shouldUseTextureView() { + // we can only use TextureView on ICS or higher + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + Log.i(LOGTAG, "Not using TextureView: not on ICS+"); + return false; + } + + try { + // and then we can only use it if we have a hardware accelerated window + Method m = View.class.getMethod("isHardwareAccelerated", new Class[0]); + return (Boolean) m.invoke(this); + } catch (Exception e) { + Log.i(LOGTAG, "Not using TextureView: caught exception checking for hw accel: " + e.toString()); + return false; + } + } + public LayerView(Context context, AttributeSet attrs) { super(context, attrs); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + if (shouldUseTextureView()) { + mTextureView = new TextureView(context); + mTextureView.setSurfaceTextureListener(new SurfaceTextureListener()); + + addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + } else { mSurfaceView = new SurfaceView(context); addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); SurfaceHolder holder = mSurfaceView.getHolder(); holder.addCallback(new SurfaceListener()); holder.setFormat(PixelFormat.RGB_565); - } else { - mTextureView = new TextureView(context); - mTextureView.setSurfaceTextureListener(new SurfaceTextureListener()); - - addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); } mGLController = new GLController(this); @@ -279,7 +298,7 @@ public class LayerView extends FrameLayout { } public Object getNativeWindow() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) + if (mSurfaceView != null) return mSurfaceView.getHolder(); return mTextureView.getSurfaceTexture(); commit dd8440a1c940e76626c23a40f62940aee5755e24 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Oct 4 16:09:26 2014 +0200 android: move getDrawable to LayerView (Fennec import) Change-Id: Idd15003939574963f836bfab1e0c5385957ab18b diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java index 583773b..eba732f 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java @@ -52,7 +52,7 @@ public class MockTileProvider implements TileProvider { tileNumber += 1; // 0 to 1 based numbering String imageName = "d" + tileNumber; - Bitmap bitmap = layerController.getDrawable(imageName); + Bitmap bitmap = layerController.getView().getDrawable(imageName); CairoImage image = new BufferedCairoImage(bitmap); @@ -61,7 +61,7 @@ public class MockTileProvider implements TileProvider { @Override public Bitmap thumbnail(int size) { - return layerController.getDrawable("dummy_page"); + return layerController.getView().getDrawable("dummy_page"); } @Override diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java index f35ee9d..c641c75 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java @@ -6,9 +6,6 @@ package org.mozilla.gecko.gfx; import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.PointF; import android.graphics.RectF; @@ -104,9 +101,6 @@ public class LayerController implements PanZoomTarget { return mViewportMetrics.getSize(); } - public Bitmap getBackgroundPattern() { return getDrawable("background"); } - public Bitmap getShadowPattern() { return getDrawable("shadow"); } - public PanZoomController getPanZoomController() { return mPanZoomController; } public GestureDetector.OnGestureListener getGestureListener() { return mPanZoomController; } public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() { @@ -114,14 +108,6 @@ public class LayerController implements PanZoomTarget { } public GestureDetector.OnDoubleTapListener getDoubleTapListener() { return mPanZoomController; } - public Bitmap getDrawable(String name) { - Resources resources = mContext.getResources(); - int resourceID = resources.getIdentifier(name, "drawable", mContext.getPackageName()); - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inScaled = false; - return BitmapFactory.decodeResource(mContext.getResources(), resourceID, options); - } - /** * The view calls this function to indicate that the viewport changed size. It must hold the * monitor while calling it. diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java index dcedaae..b4975da 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java @@ -160,12 +160,12 @@ public class LayerRenderer implements GLSurfaceView.Renderer { LayerController controller = view.getController(); - CairoImage backgroundImage = new BufferedCairoImage(controller.getBackgroundPattern()); + CairoImage backgroundImage = new BufferedCairoImage(view.getBackgroundPattern()); mBackgroundLayer = new SingleTileLayer(true, backgroundImage); mScreenshotLayer = ScreenshotLayer.create(); - CairoImage shadowImage = new BufferedCairoImage(controller.getShadowPattern()); + CairoImage shadowImage = new BufferedCairoImage(view.getShadowPattern()); mShadowLayer = new NinePatchTileLayer(shadowImage); mHorizScrollLayer = ScrollbarLayer.create(this, false); diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java index 505f933..0a993a7 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java @@ -7,7 +7,9 @@ package org.mozilla.gecko.gfx; import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.os.Build; @@ -235,6 +237,23 @@ public class LayerView extends FrameLayout { return mGLController; } + public Bitmap getDrawable(String name) { + Context context = getContext(); + Resources resources = context.getResources(); + int resourceID = resources.getIdentifier(name, "drawable", context.getPackageName()); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inScaled = false; + return BitmapFactory.decodeResource(context.getResources(), resourceID, options); + } + + Bitmap getBackgroundPattern() { + return getDrawable("background"); + } + + Bitmap getShadowPattern() { + return getDrawable("shadow"); + } + private void onSizeChanged(int width, int height) { mGLController.surfaceChanged(width, height); commit 488d19de01670c37b638e67bec99dc178d4792a5 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Oct 4 15:53:44 2014 +0200 android: use TextureView instead of SurfaceView for ICS+ devices Change-Id: I4c5585d5eac4faf46ad9bed2d3992fe87b3d9a03 diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GLController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GLController.java index 9bd7d2f..e296f47 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GLController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GLController.java @@ -5,8 +5,6 @@ package org.mozilla.gecko.gfx; -import android.view.SurfaceHolder; - import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGL11; import javax.microedition.khronos.egl.EGLConfig; @@ -119,8 +117,15 @@ public class GLController { return true; } + // This function is invoked by JNI + public synchronized void resumeCompositorIfValid() { + if (mSurfaceValid) { + mView.getListener().compositionResumeRequested(mWidth, mHeight); + } + } + // Wait until we are allowed to use EGL functions on the Surface backing - // this window. + // this window. This function is invoked by JNI public synchronized void waitForValidSurface() { while (!mSurfaceValid) { try { @@ -139,19 +144,16 @@ public class GLController { return mHeight; } - synchronized void surfaceCreated() { - mSurfaceValid = true; - notifyAll(); - } - synchronized void surfaceDestroyed() { mSurfaceValid = false; notifyAll(); } - synchronized void sizeChanged(int newWidth, int newHeight) { + synchronized void surfaceChanged(int newWidth, int newHeight) { mWidth = newWidth; mHeight = newHeight; + mSurfaceValid = true; + notifyAll(); } private void initEGL() { @@ -218,8 +220,8 @@ public class GLController { } private void createEGLSurface() { - SurfaceHolder surfaceHolder = mView.getHolder(); - mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); + Object window = mView.getNativeWindow(); + mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null); if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) { throw new GLControllerException("EGL window surface could not be created! " + getEGLError()); @@ -248,8 +250,8 @@ public class GLController { initEGL(); } - SurfaceHolder surfaceHolder = mView.getHolder(); - EGLSurface surface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); + Object window = mView.getNativeWindow(); + EGLSurface surface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null); if (surface == null || surface == EGL10.EGL_NO_SURFACE) { throw new GLControllerException("EGL window surface could not be created! " + getEGLError()); diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index cf4ba34..9b7dd39 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -227,23 +227,23 @@ public class GeckoLayerClient implements LayerView.Listener { } @Override - public void renderRequested() { + public void compositorCreated() { + } + @Override + public void renderRequested() { } @Override public void compositionPauseRequested() { - } @Override public void compositionResumeRequested(int width, int height) { - } @Override public void surfaceChanged(int width, int height) { - compositionResumeRequested(width, height); renderRequested(); } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java index 874d10a..505f933 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java @@ -9,14 +9,19 @@ package org.mozilla.gecko.gfx; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; +import android.graphics.SurfaceTexture; +import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.TextureView; +import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.widget.FrameLayout; import org.libreoffice.LibreOfficeMainActivity; @@ -30,7 +35,7 @@ import java.nio.IntBuffer; * * Note that LayerView is accessed by Robocop via reflection. */ -public class LayerView extends SurfaceView implements SurfaceHolder.Callback { +public class LayerView extends FrameLayout { private static String LOGTAG = "GeckoLayerView"; private LayerController mController; @@ -43,6 +48,9 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { /* Must be a PAINT_xxx constant */ private int mPaintState = PAINT_NONE; + private SurfaceView mSurfaceView; + private TextureView mTextureView; + private Listener mListener; /* Flags used to determine when to show the painted surface. The integer @@ -54,9 +62,19 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { public LayerView(Context context, AttributeSet attrs) { super(context, attrs); - SurfaceHolder holder = getHolder(); - holder.addCallback(this); - holder.setFormat(PixelFormat.RGB_565); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mSurfaceView = new SurfaceView(context); + addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + + SurfaceHolder holder = mSurfaceView.getHolder(); + holder.addCallback(new SurfaceListener()); + holder.setFormat(PixelFormat.RGB_565); + } else { + mTextureView = new TextureView(context); + mTextureView.setSurfaceTextureListener(new SurfaceTextureListener()); + + addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + } mGLController = new GLController(this); } @@ -217,10 +235,8 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { return mGLController; } - /** Implementation of SurfaceHolder.Callback */ - public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width, - int height) { - mGLController.sizeChanged(width, height); + private void onSizeChanged(int width, int height) { + mGLController.surfaceChanged(width, height); if (mGLThread != null) { mGLThread.surfaceChanged(width, height); @@ -231,16 +247,7 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { } } - /** Implementation of SurfaceHolder.Callback */ - public synchronized void surfaceCreated(SurfaceHolder holder) { - mGLController.surfaceCreated(); - if (mGLThread != null) { - mGLThread.surfaceCreated(); - } - } - - /** Implementation of SurfaceHolder.Callback */ - public synchronized void surfaceDestroyed(SurfaceHolder holder) { + private void onDestroyed() { mGLController.surfaceDestroyed(); if (mGLThread != null) { @@ -252,24 +259,73 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { } } + public Object getNativeWindow() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) + return mSurfaceView.getHolder(); + + return mTextureView.getSurfaceTexture(); + } + /** This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying signature. */ public static GLController registerCxxCompositor() { try { LayerView layerView = LibreOfficeMainActivity.mAppContext.getLayerController().getView(); + layerView.mListener.compositorCreated(); return layerView.getGLController(); } catch (Exception e) { - Log.e(LOGTAG, "### Exception! " + e); + Log.e(LOGTAG, "Error registering compositor!", e); return null; } } public interface Listener { + void compositorCreated(); void renderRequested(); void compositionPauseRequested(); void compositionResumeRequested(int width, int height); void surfaceChanged(int width, int height); } + private class SurfaceListener implements SurfaceHolder.Callback { + public void surfaceChanged(SurfaceHolder holder, int format, int width, + int height) { + onSizeChanged(width, height); + } + + public void surfaceCreated(SurfaceHolder holder) { + if (mGLThread != null) { + mGLThread.surfaceCreated(); + } + } + + public void surfaceDestroyed(SurfaceHolder holder) { + onDestroyed(); + } + } + + private class SurfaceTextureListener implements TextureView.SurfaceTextureListener { + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + // We don't do this for surfaceCreated above because it is always followed by a surfaceChanged, + // but that is not the case here. + if (mGLThread != null) { + mGLThread.surfaceCreated(); + } + onSizeChanged(width, height); + } + + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + onDestroyed(); + return true; // allow Android to call release() on the SurfaceTexture, we are done drawing to it + } + + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + onSizeChanged(width, height); + } + + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + } + } + private GLThread mGLThread; // Protected by this class's monitor. public synchronized void createGLThread() { commit 67be577f163831e460e19aee958bdcf7187b8a56 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Oct 4 15:51:02 2014 +0200 android: assure document close, introduce message box for errors Change-Id: I4d5607d5568ebf73a61067975c21e740020cc8f7 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java index c904942..bd1b27b 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java @@ -8,7 +8,6 @@ import org.libreoffice.kit.LibreOfficeKit; import org.libreoffice.kit.Office; import org.mozilla.gecko.gfx.BufferedCairoImage; import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.FloatSize; import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.gfx.LayerController; @@ -16,13 +15,14 @@ import java.nio.ByteBuffer; public class LOKitTileProvider implements TileProvider { private static final String LOGTAG = LOKitTileProvider.class.getSimpleName(); - public static int TILE_SIZE = 256; - public final Office mOffice; - public final Document mDocument; + private static int TILE_SIZE = 256; + private final Office mOffice; + private Document mDocument; private final LayerController mLayerController; private final float mTileWidth; private final float mTileHeight; private final String mInputFile; + private boolean mIsReady = false; private float mDPI; private float mWidthTwip; @@ -70,6 +70,8 @@ public class LOKitTileProvider implements TileProvider { LibreOfficeMainActivity.mAppContext.getDocumentPartViewListAdpater().notifyDataSetChanged(); } }); + + mIsReady = true; } } @@ -108,8 +110,15 @@ public class LOKitTileProvider implements TileProvider { mWidthTwip = mDocument.getDocumentWidth(); mHeightTwip = mDocument.getDocumentHeight(); - if (mWidthTwip == 0 && mHeightTwip == 0) { + if (mWidthTwip == 0 || mHeightTwip == 0) { Log.e(LOGTAG, "Document size zero - last error: " + mOffice.getError()); + LOKitShell.getMainHandler().post(new Runnable() { + @Override + public void run() { + LibreOfficeMainActivity.mAppContext.showAlertDialog("Document has no size!"); + } + }); + return false; } else { Log.i(LOGTAG, "Document size: " + mDocument.getDocumentWidth() + " x " + mDocument.getDocumentHeight()); } @@ -129,7 +138,7 @@ public class LOKitTileProvider implements TileProvider { @Override public boolean isReady() { - return mDocument != null; + return mIsReady; } @Override @@ -143,7 +152,7 @@ public class LOKitTileProvider implements TileProvider { float twipWidth = mTileWidth / zoom; float twipHeight = mTileHeight / zoom; long start = System.currentTimeMillis(); - Log.i(LOGTAG, "paintTile TOP @ " + start + "(" + tileSize.width + " " + tileSize.height + " " + (int)twipX + " " + (int)twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")"); + Log.i(LOGTAG, "paintTile TOP @ " + start + "(" + tileSize.width + " " + tileSize.height + " " + (int) twipX + " " + (int) twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")"); mDocument.paintTile(buffer, tileSize.width, tileSize.height, (int) twipX, (int) twipY, (int) twipWidth, (int) twipHeight); long stop = System.currentTimeMillis(); Log.i(LOGTAG, "paintTile TAIL @ " + stop + " - elapsed: " + (stop - start) + " "); @@ -173,6 +182,8 @@ public class LOKitTileProvider implements TileProvider { widthPixel = (int) (heightPixel * ratio); } + Log.w(LOGTAG, "Thumbnail size: " + getPageWidth() + " " + getPageHeight() + " " + widthPixel + " " + heightPixel); + ByteBuffer buffer = ByteBuffer.allocateDirect(widthPixel * heightPixel * 4); mDocument.paintTile(buffer, widthPixel, heightPixel, 0, 0, (int) mWidthTwip, (int) mHeightTwip); @@ -189,10 +200,17 @@ public class LOKitTileProvider implements TileProvider { Log.i(LOGTAG, "Document destroyed: " + mInputFile); if (mDocument != null) { mDocument.destroy(); + mDocument = null; } } @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + @Override public void changePart(int partIndex) { mDocument.setPart(partIndex); } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java index aa4f70c..c5ecccb 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -2,6 +2,7 @@ package org.libreoffice; import android.app.Activity; import android.app.AlertDialog; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -132,7 +133,7 @@ public class LibreOfficeMainActivity extends Activity { mLayerController = new LayerController(this); mLayerController.setZoomConstraints(new ZoomConstraints(true)); mLayerClient = new GeckoLayerClient(this); - LayerView layerView = (LayerView)findViewById(R.id.layer_view); + LayerView layerView = (LayerView) findViewById(R.id.layer_view); mLayerController.setView(layerView); mLayerController.setLayerClient(mLayerClient); @@ -147,10 +148,28 @@ public class LibreOfficeMainActivity extends Activity { @Override protected void onPause() { - Log.i(LOGTAG, "Pause.."); + Log.i(LOGTAG, "onPause.."); super.onPause(); } + @Override + protected void onStart() { + Log.i(LOGTAG, "onStart.."); + super.onStop(); + } + + @Override + protected void onStop() { + Log.i(LOGTAG, "onStop.."); + super.onStop(); + } + + @Override + protected void onDestroy() { + Log.i(LOGTAG, "onDestroy.."); + super.onDestroy(); + } + public LOKitThread getLOKitThread() { return sLOKitThread; } @@ -212,6 +231,22 @@ public class LibreOfficeMainActivity extends Activity { findViewById(R.id.loadingPanel).setVisibility(View.GONE); } + public void showAlertDialog(String s) { + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LibreOfficeMainActivity.this); + + alertDialogBuilder.setTitle("Error"); + alertDialogBuilder.setMessage(s); + alertDialogBuilder.setNeutralButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + finish(); + } + }); + + AlertDialog alertDialog = alertDialogBuilder.create(); + alertDialog.show(); + } + private class DocumentPartClickListener implements android.widget.AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java index 5de6a82..583773b 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java @@ -4,7 +4,6 @@ import android.graphics.Bitmap; import org.mozilla.gecko.gfx.BufferedCairoImage; import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.FloatSize; import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.gfx.LayerController; commit b43b980b1e44e3ad0b4c38d2d65cdb6dbfb77add Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Oct 4 15:47:44 2014 +0200 androdi: set TileProvider only when document is ready Change-Id: Iada0e4513cc00248f45c97bfecbc91590e80a437 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java index 398389b..528f419 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java @@ -74,10 +74,10 @@ public class LOKitThread extends Thread { } mTileProvider = TileProviderFactory.create(mController, filename); - mLayerClient.setTileProvider(mTileProvider); - boolean isReady = mTileProvider.isReady(); if (isReady) { + mLayerClient.setTileProvider(mTileProvider); + LOKitShell.showProgressSpinner(); refresh(); LOKitShell.hideProgressSpinner(); commit 450a4f46d9de0f2b2d7b4232e7fef380dacdfcd0 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Thu Oct 2 16:16:33 2014 +0200 android: TileIdentifier - contains tile position and zoom Change-Id: Ia82dc1f99eff5117fe16df2b61c1a7230b52e07a diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java index 407cdc1..01ab8be 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java @@ -97,10 +97,10 @@ public class DynamicTileLayer extends Layer { tile.beginTransaction(); Rect position = tile.getPosition(); - float positionX = tile.x / tile.zoom; - float positionY = tile.y / tile.zoom; - float tileSizeWidth = tileSize.width / tile.zoom; - float tileSizeHeight = tileSize.height / tile.zoom; + float positionX = tile.id.x / tile.id.zoom; + float positionY = tile.id.y / tile.id.zoom; + float tileSizeWidth = tileSize.width / tile.id.zoom; + float tileSizeHeight = tileSize.height / tile.id.zoom; position.set((int) positionX, (int) positionY, (int) (positionX + tileSizeWidth + 1), (int) (positionY + tileSizeHeight + 1)); tile.setPosition(position); @@ -157,7 +157,7 @@ public class DynamicTileLayer extends Layer { } boolean contains = false; for (SubTile tile : tiles) { - if (tile.x == x && tile.y == y && tile.zoom == viewportMetrics.zoomFactor) { + if (tile.id.x == x && tile.id.y == y && tile.id.zoom == viewportMetrics.zoomFactor) { contains = true; } } @@ -184,8 +184,8 @@ public class DynamicTileLayer extends Layer { private void markTiles(ImmutableViewportMetrics viewportMetrics) { for (SubTile tile : tiles) { - if (FloatUtils.fuzzyEquals(tile.zoom, viewportMetrics.zoomFactor)) { - RectF tileRect = new RectF(tile.x, tile.y, tile.x + tileSize.width, tile.y + tileSize.height); + if (FloatUtils.fuzzyEquals(tile.id.zoom, viewportMetrics.zoomFactor)) { + RectF tileRect = new RectF(tile.id.x, tile.id.y, tile.id.x + tileSize.width, tile.id.y + tileSize.height); if (!RectF.intersects(currentViewport, tileRect)) { tile.markForRemoval(); } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java index 27f11fc..7e60af1 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java @@ -6,42 +6,49 @@ package org.mozilla.gecko.gfx; public class SubTile extends SingleTileLayer { - public int x; - public int y; - public float zoom; - public boolean markedForRemoval = false; + public final TileIdentifier id; public SubTile(CairoImage mImage, int x, int y, float zoom) { super(mImage); - this.x = x; - this.y = y; - this.zoom = zoom; + id = new TileIdentifier(x, y, zoom); } public void markForRemoval() { markedForRemoval = true; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - SubTile subTile = (SubTile) o; - - if (x != subTile.x) return false; - if (y != subTile.y) return false; - if (Float.compare(subTile.zoom, zoom) != 0) return false; - - return true; - } - - @Override - public int hashCode() { - int result = x; - result = 31 * result + y; - result = 31 * result + (zoom != +0.0f ? Float.floatToIntBits(zoom) : 0); - return result; + public static class TileIdentifier { + public int x; + public int y; + public float zoom; + + public TileIdentifier(int x, int y, float zoom) { + this.x = x; + this.y = y; + this.zoom = zoom; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TileIdentifier that = (TileIdentifier) o; + + if (x != that.x) return false; + if (y != that.y) return false; + if (Float.compare(that.zoom, zoom) != 0) return false; + + return true; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + y; + result = 31 * result + (zoom != +0.0f ? Float.floatToIntBits(zoom) : 0); + return result; + } } } commit e910aa45d3d4fb92d2ac1e975f411785d5fc70ae Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Thu Oct 2 15:56:00 2014 +0200 android: construct LayerView in xml GUI definition (activity_main) Change-Id: I6cd3c8dff2ca36f3d64559b218d005d5a6da9066 diff --git a/android/experimental/LOAndroid3/res/layout/activity_main.xml b/android/experimental/LOAndroid3/res/layout/activity_main.xml index fd7d63b..1b1bb07 100644 --- a/android/experimental/LOAndroid3/res/layout/activity_main.xml +++ b/android/experimental/LOAndroid3/res/layout/activity_main.xml @@ -16,19 +16,25 @@ android:id="@+id/gecko_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:layout_weight="1"/> + android:layout_weight="1"> + + <org.mozilla.gecko.gfx.LayerView + android:id="@+id/layer_view" + android:layout_width="fill_parent" + android:layout_height="fill_parent"/> + </RelativeLayout> <RelativeLayout android:id="@+id/loadingPanel" android:layout_width="match_parent" android:layout_height="match_parent" - android:gravity="center" - android:background="#9333"> + android:background="#9333" + android:gravity="center"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:indeterminate="true" /> + android:indeterminate="true"/> </RelativeLayout> <View diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java index 8607ebf..aa4f70c 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -9,6 +9,7 @@ import android.os.Handler; import android.support.v4.widget.DrawerLayout; import android.util.DisplayMetrics; import android.util.Log; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -21,6 +22,7 @@ import android.widget.TextView; import org.mozilla.gecko.ZoomConstraints; import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.LayerController; +import org.mozilla.gecko.gfx.LayerView; import java.util.ArrayList; import java.util.List; @@ -96,6 +98,8 @@ public class LibreOfficeMainActivity extends Activity { mMainHandler = new Handler(); + LayoutInflater.from(this).setFactory(ViewFactory.getInstance()); + if (getIntent().getData() != null) { mInputFile = getIntent().getData().getEncodedPath(); } else { @@ -128,8 +132,9 @@ public class LibreOfficeMainActivity extends Activity { mLayerController = new LayerController(this); mLayerController.setZoomConstraints(new ZoomConstraints(true)); mLayerClient = new GeckoLayerClient(this); + LayerView layerView = (LayerView)findViewById(R.id.layer_view); + mLayerController.setView(layerView); mLayerController.setLayerClient(mLayerClient); - mGeckoLayout.addView(mLayerController.getView(), 0); LOKitShell.sendEvent(LOEventFactory.load(mInputFile)); } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java new file mode 100644 index 0000000..c26ad22 --- /dev/null +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/ViewFactory.java @@ -0,0 +1,32 @@ +package org.libreoffice; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; + +import org.mozilla.gecko.gfx.LayerView; + +public class ViewFactory implements LayoutInflater.Factory { + private static final String LOGTAG = ViewFactory.class.getSimpleName(); + private static final String LAYER_VIEW_ID = "org.mozilla.gecko.gfx.LayerView"; + private static final ViewFactory INSTANCE = new ViewFactory(); + + private ViewFactory() { + } + + public static LayoutInflater.Factory getInstance() { + return INSTANCE; + } + + @Override + public View onCreateView(String name, Context context, AttributeSet attrs) { + if (name.equals(LAYER_VIEW_ID)) { + Log.i(LOGTAG, "Creating custom Gecko view: " + name); + return new LayerView(context, attrs); + } + + return null; + } +} \ No newline at end of file diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java index 2e6a4a0..f35ee9d 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java @@ -69,11 +69,15 @@ public class LayerController implements PanZoomTarget { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); mViewportMetrics = new ImmutableViewportMetrics(displayMetrics); mPanZoomController = new PanZoomController(this); - mView = new LayerView(context, this); mCheckerboardShouldShowChecks = true; mZoomConstraints = new ZoomConstraints(false); } + public void setView(LayerView v) { + mView = v; + mView.connect(this); + } + public void setRoot(Layer layer) { mRootLayer = layer; } public void setLayerClient(GeckoLayerClient layerClient) { diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java index 38a09d8..874d10a 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java @@ -9,6 +9,7 @@ package org.mozilla.gecko.gfx; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; +import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; @@ -32,7 +33,6 @@ import java.nio.IntBuffer; public class LayerView extends SurfaceView implements SurfaceHolder.Callback { private static String LOGTAG = "GeckoLayerView"; - private Context mContext; private LayerController mController; private TouchEventHandler mTouchEventHandler; private GLController mGLController; @@ -51,18 +51,19 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { public static final int PAINT_BEFORE_FIRST = 1; public static final int PAINT_AFTER_FIRST = 2; - - public LayerView(Context context, LayerController controller) { - super(context); + public LayerView(Context context, AttributeSet attrs) { + super(context, attrs); SurfaceHolder holder = getHolder(); holder.addCallback(this); holder.setFormat(PixelFormat.RGB_565); mGLController = new GLController(this); - mContext = context; + } + + void connect(LayerController controller) { mController = controller; - mTouchEventHandler = new TouchEventHandler(context, this, mController); + mTouchEventHandler = new TouchEventHandler(getContext(), this, mController); mRenderer = new LayerRenderer(this); mInputConnectionHandler = null; @@ -208,6 +209,10 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { mListener = listener; } + Listener getListener() { + return mListener; + } + public GLController getGLController() { return mGLController; } @@ -267,10 +272,6 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { private GLThread mGLThread; // Protected by this class's monitor. - /** - * Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just - * like a GLSurfaceView. It is illegal to access the controller after this has been called. - */ public synchronized void createGLThread() { if (mGLThread != null) { throw new LayerViewException ("createGLThread() called with a GL thread already in place!"); @@ -282,10 +283,6 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback { notifyAll(); } - /** - * Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is - * fully shut down. - */ public synchronized Thread destroyGLThread() { // Wait for the GL thread to be started. Log.e(LOGTAG, "### Waiting for GL thread to be created..."); commit fc8e1ac501f021ac6f99f944fd5d38297bc7a00d Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Thu Oct 2 15:50:53 2014 +0200 android: use tile size and change the type to IntSize Change-Id: Id19c3517fc6fb59307c81a0c1c8868e0d0c777b4 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java index 4fdf84f..c904942 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java @@ -9,6 +9,7 @@ import org.libreoffice.kit.Office; import org.mozilla.gecko.gfx.BufferedCairoImage; import org.mozilla.gecko.gfx.CairoImage; import org.mozilla.gecko.gfx.FloatSize; +import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.gfx.LayerController; import java.nio.ByteBuffer; @@ -132,9 +133,9 @@ public class LOKitTileProvider implements TileProvider { } @Override - public CairoImage createTile(float x, float y, FloatSize tileSize, float zoom) { - ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4); - Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888); + public CairoImage createTile(float x, float y, IntSize tileSize, float zoom) { + ByteBuffer buffer = ByteBuffer.allocateDirect(tileSize.width * tileSize.height * 4); + Bitmap bitmap = Bitmap.createBitmap(tileSize.width, tileSize.height, Bitmap.Config.ARGB_8888); if (mDocument != null) { float twipX = pixelToTwip(x, mDPI) / zoom; @@ -142,8 +143,8 @@ public class LOKitTileProvider implements TileProvider { float twipWidth = mTileWidth / zoom; float twipHeight = mTileHeight / zoom; long start = System.currentTimeMillis(); - Log.i(LOGTAG, "paintTile TOP @ " + start + "(" + TILE_SIZE + " " + TILE_SIZE + " " + (int)twipX + " " + (int)twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")"); - mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) twipX, (int) twipY, (int) twipWidth, (int) twipHeight); + Log.i(LOGTAG, "paintTile TOP @ " + start + "(" + tileSize.width + " " + tileSize.height + " " + (int)twipX + " " + (int)twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")"); + mDocument.paintTile(buffer, tileSize.width, tileSize.height, (int) twipX, (int) twipY, (int) twipWidth, (int) twipHeight); long stop = System.currentTimeMillis(); Log.i(LOGTAG, "paintTile TAIL @ " + stop + " - elapsed: " + (stop - start) + " "); } else { diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java index 672973c..5de6a82 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java @@ -5,6 +5,7 @@ import android.graphics.Bitmap; import org.mozilla.gecko.gfx.BufferedCairoImage; import org.mozilla.gecko.gfx.CairoImage; import org.mozilla.gecko.gfx.FloatSize; +import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.gfx.LayerController; public class MockTileProvider implements TileProvider { @@ -45,7 +46,7 @@ public class MockTileProvider implements TileProvider { } @Override - public CairoImage createTile(float x, float y, FloatSize tileSize, float zoom) { + public CairoImage createTile(float x, float y, IntSize tileSize, float zoom) { int tiles = (int) (getPageWidth() / TILE_SIZE) + 1; int tileNumber = (int) ((y / TILE_SIZE) * tiles + (x / TILE_SIZE)); tileNumber %= 9; diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java index ada2360..12a47f6 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java @@ -4,7 +4,7 @@ package org.libreoffice; import android.graphics.Bitmap; import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.FloatSize; +import org.mozilla.gecko.gfx.IntSize; public interface TileProvider { int getPageWidth(); @@ -13,7 +13,7 @@ public interface TileProvider { boolean isReady(); - CairoImage createTile(float x, float y, FloatSize tileSize, float zoom); + CairoImage createTile(float x, float y, IntSize tileSize, float zoom); void changePart(int partIndex); diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java index 1ad8d38..407cdc1 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java @@ -17,14 +17,14 @@ public class DynamicTileLayer extends Layer { private final List<SubTile> tiles = new CopyOnWriteArrayList<SubTile>(); private TileProvider tileProvider; - private final FloatSize tileSize; + private final IntSize tileSize; private RectF currentViewport = new RectF(); public DynamicTileLayer() { - this.tileSize = new FloatSize(256, 256); + this.tileSize = new IntSize(256, 256); } - public DynamicTileLayer(FloatSize tileSize) { + public DynamicTileLayer(IntSize tileSize) { this.tileSize = tileSize; } @@ -108,7 +108,7 @@ public class DynamicTileLayer extends Layer { } } - private RectF roundToTileSize(RectF input, FloatSize tileSize) { + private RectF roundToTileSize(RectF input, IntSize tileSize) { float minX = ((int)(input.left / tileSize.width)) * tileSize.width; float minY = ((int)(input.top / tileSize.height)) * tileSize.height; float maxX = ((int)(input.right / tileSize.width) + 1) * tileSize.width; @@ -116,7 +116,7 @@ public class DynamicTileLayer extends Layer { return new RectF(minX, minY, maxX, maxY); } - private RectF inflate(RectF rect, FloatSize inflateSize) { + private RectF inflate(RectF rect, IntSize inflateSize) { RectF newRect = new RectF(rect); newRect.left -= inflateSize.width; newRect.left = newRect.left < 0.0f ? 0.0f : newRect.left; commit 1b81aeb2548d3492e0c50dfbfa61b3000cf9b6cb Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Thu Oct 2 15:24:41 2014 +0200 android: remove unused windowSizeChanged tracking Change-Id: I0d451d9fea83d70e69d07059e55a5e6067c45711 diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 23095ef..cf4ba34 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -42,7 +42,6 @@ import android.content.Context; import android.graphics.RectF; import android.util.DisplayMetrics; import android.util.Log; -import android.view.View; import org.libreoffice.LOEvent; import org.libreoffice.LOEventFactory; @@ -148,32 +147,24 @@ public class GeckoLayerClient implements LayerView.Listener { private void sendResizeEventIfNecessary(boolean force) { DisplayMetrics metrics = new DisplayMetrics(); LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - View view = mLayerController.getView(); IntSize newScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); - IntSize newWindowSize = new IntSize(view.getWidth(), view.getHeight()); // 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 = !mScreenSize.equals(newScreenSize); - boolean windowSizeChanged = !mWindowSize.equals(newWindowSize); - if (!force && !screenSizeChanged && !windowSizeChanged) { + if (!force && !screenSizeChanged) { return; } mScreenSize = newScreenSize; - mWindowSize = newWindowSize; if (screenSizeChanged) { Log.d(LOGTAG, "Screen-size changed to " + mScreenSize); } - if (windowSizeChanged) { - Log.d(LOGTAG, "Window-size changed to " + mWindowSize); - } - LOEvent event = LOEventFactory.sizeChanged(metrics.widthPixels, metrics.heightPixels); LOKitShell.sendEvent(event); } commit f33d88119830975e5de620470bee1804d6c98738 Author: Jan Holesovsky <ke...@collabora.com> Date: Wed Oct 1 23:38:09 2014 +0200 android: Better default document (when the app starts with no doc to load). Change-Id: Ie3cc30c29723133d5e320ad3848d13f06d133c78 diff --git a/android/Bootstrap/Makefile.shared b/android/Bootstrap/Makefile.shared index 5dd9f4a..7ec1419 100644 --- a/android/Bootstrap/Makefile.shared +++ b/android/Bootstrap/Makefile.shared @@ -130,7 +130,7 @@ copy-stuff: for F in program/services/services ure/share/misc/services; do \ sed -e 's!uri="vnd.sun.star.expand:$$LO_LIB_DIR/!uri="file://$$APP_DATA_DIR/lib/!g' <$(INSTDIR)/$$F.rdb >assets/$$F.rdb; \ done - cp $(SRC_ROOT)/odk/examples/java/DocumentHandling/test/test1.odt assets/example.odt + cp $(SRC_ROOT)/android/default-document/example.odt assets/example.odt cp $(SRC_ROOT)/readlicense_oo/license/LICENSE assets/license.txt cp $(SRC_ROOT)/readlicense_oo/license/NOTICE assets/notice.txt cp $(WORKDIR)/ComponentTarget/i18npool/util/i18npool.component assets/ComponentTarget/i18npool/util diff --git a/android/default-document/example.odt b/android/default-document/example.odt new file mode 100644 index 0000000..2da7ce6 Binary files /dev/null and b/android/default-document/example.odt differ commit 91569be0f9951fdfd8c928ba3e4f0956bc053577 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 23:37:14 2014 +0200 android: Log calls to createTile Change-Id: Ia0e92c24f771d47235fee7a9dbddc65631af9082 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java index 073876e..4fdf84f 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java @@ -141,7 +141,11 @@ public class LOKitTileProvider implements TileProvider { float twipY = pixelToTwip(y, mDPI) / zoom; float twipWidth = mTileWidth / zoom; float twipHeight = mTileHeight / zoom; + long start = System.currentTimeMillis(); + Log.i(LOGTAG, "paintTile TOP @ " + start + "(" + TILE_SIZE + " " + TILE_SIZE + " " + (int)twipX + " " + (int)twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")"); mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) twipX, (int) twipY, (int) twipWidth, (int) twipHeight); + long stop = System.currentTimeMillis(); + Log.i(LOGTAG, "paintTile TAIL @ " + stop + " - elapsed: " + (stop - start) + " "); } else { Log.e(LOGTAG, "Document is null!!"); } commit 34ea1ede6590399eb943d8f87c9ad473c6a71a68 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 23:08:27 2014 +0200 android: show progress spinner also when switching parts Change-Id: Ie21e71aa03eddef620d470e01daf6f1936a5d7c7 diff --git a/android/experimental/LOAndroid3/res/layout/activity_main.xml b/android/experimental/LOAndroid3/res/layout/activity_main.xml index 9ada4d3..fd7d63b 100644 --- a/android/experimental/LOAndroid3/res/layout/activity_main.xml +++ b/android/experimental/LOAndroid3/res/layout/activity_main.xml @@ -22,7 +22,8 @@ android:id="@+id/loadingPanel" android:layout_width="match_parent" android:layout_height="match_parent" - android:gravity="center" > + android:gravity="center" + android:background="#9333"> <ProgressBar android:layout_width="wrap_content" diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java index 332e0f8..7161f14 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java @@ -10,7 +10,7 @@ public class LOKitShell { public static float getDpi() { DisplayMetrics metrics = LibreOfficeMainActivity.mAppContext.getResources().getDisplayMetrics(); - return metrics.density * 160; + return metrics.density * 160; } public static void sendEvent(LOEvent event) { @@ -27,4 +27,22 @@ public class LOKitShell { public static void queueRedraw() { LOKitShell.sendEvent(LOEventFactory.redraw()); } + + public static void showProgressSpinner() { + getMainHandler().post(new Runnable() { + @Override + public void run() { + LibreOfficeMainActivity.mAppContext.showProgressSpinner(); + } + }); + } + + public static void hideProgressSpinner() { + getMainHandler().post(new Runnable() { + @Override + public void run() { + LibreOfficeMainActivity.mAppContext.hideProgressSpinner(); + } + }); + } } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java index 31b9eb5..398389b 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java @@ -55,8 +55,10 @@ public class LOKitThread extends Thread { } private void changePart(int partIndex) { + LOKitShell.showProgressSpinner(); mTileProvider.changePart(partIndex); refresh(); + LOKitShell.hideProgressSpinner(); } private boolean load(String filename) { @@ -76,14 +78,9 @@ public class LOKitThread extends Thread { boolean isReady = mTileProvider.isReady(); if (isReady) { + LOKitShell.showProgressSpinner(); refresh(); - LOKitShell.getMainHandler().post(new Runnable() { - @Override - public void run() { - LibreOfficeMainActivity.mAppContext.hideProgressBar(); - } - }); - + LOKitShell.hideProgressSpinner(); } return isReady; } diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java index 1fce7d4..8607ebf 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -199,11 +199,11 @@ public class LibreOfficeMainActivity extends Activity { } - public void showProgressBar() { + public void showProgressSpinner() { findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE); } - public void hideProgressBar() { + public void hideProgressSpinner() { findViewById(R.id.loadingPanel).setVisibility(View.GONE); } commit d885cf403c805eb6d4d23b9491feecbcecdcb43d Author: Jan Holesovsky <ke...@collabora.com> Date: Wed Oct 1 22:48:38 2014 +0200 android: Fix typo. Change-Id: I22f7bbcc5bc5f58c30a5915c876736f664a42a61 diff --git a/android/experimental/LOAndroid3/res/values/strings.xml b/android/experimental/LOAndroid3/res/values/strings.xml index d04f92e..f913e5e 100644 --- a/android/experimental/LOAndroid3/res/values/strings.xml +++ b/android/experimental/LOAndroid3/res/values/strings.xml @@ -4,8 +4,8 @@ <string name="app_name">LibreOffice Viewer</string> <string name="app_about_name"><b>LibreOffice Viewer \'Beta\'</b></string> - <string name="app_description">LibreOffice Viewer is an document viewer based on LibreOffice</string> - <string name="app_credits">http://www.libreoffice.com</string> + <string name="app_description">LibreOffice Viewer is a document viewer based on LibreOffice</string> + <string name="app_credits">http://www.libreoffice.org</string> <string name="browser_app_name">LibreOffice Browser</string> <string name="menu_search">Search</string> commit 623007c0fab937d6874487870e44bfac513244de Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 19:56:01 2014 +0200 android: about dialog description, app names - viewer & browser Change-Id: I4f759b6a004ca8f12974f3d0daa9f1d78c015f2a diff --git a/android/experimental/LOAndroid3/res/layout/about.xml b/android/experimental/LOAndroid3/res/layout/about.xml index f1222dc..ec014a0 100644 --- a/android/experimental/LOAndroid3/res/layout/about.xml +++ b/android/experimental/LOAndroid3/res/layout/about.xml @@ -12,17 +12,18 @@ android:layout_height="wrap_content" android:text="@string/app_description" android:textColor="@android:color/secondary_text_light" - android:textSize="16sp"/> + android:textSize="18sp"/> <TextView android:id="@+id/about_credits" android:layout_width="match_parent" android:layout_height="wrap_content" android:autoLink="web" + android:paddingBottom="20dip" android:paddingTop="20dip" android:text="@string/app_credits" android:textColor="@android:color/secondary_text_light" - android:textSize="16dip"/> + android:textSize="18dip"/> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" @@ -33,15 +34,15 @@ android:id="@+id/about_license_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="License" - /> + android:layout_marginRight="12dp" + android:text="License"/> <Button android:id="@+id/about_notice_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Notice" - /> + android:layout_marginRight="12dp" + android:text="Notice"/> </LinearLayout> </LinearLayout> \ No newline at end of file diff --git a/android/experimental/LOAndroid3/res/values/strings.xml b/android/experimental/LOAndroid3/res/values/strings.xml index 74dee00..d04f92e 100644 --- a/android/experimental/LOAndroid3/res/values/strings.xml +++ b/android/experimental/LOAndroid3/res/values/strings.xml @@ -1,11 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="app_name">LibreOffice</string> - <string name="app_description">Description</string> - <string name="app_credits">Credits</string> + <string name="app_name">LibreOffice Viewer</string> - <string name="browser_app_name">LibreOfficeUI</string> + <string name="app_about_name"><b>LibreOffice Viewer \'Beta\'</b></string> + <string name="app_description">LibreOffice Viewer is an document viewer based on LibreOffice</string> + <string name="app_credits">http://www.libreoffice.com</string> + + <string name="browser_app_name">LibreOffice Browser</string> <string name="menu_search">Search</string> <string name="list_view">List</string> <string name="grid_view">Grid</string> commit 3e31057f5a8336d84d1b321cfb1db6b008035148 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 19:54:08 2014 +0200 android: clicking "Parts" in preferences opens the side drawer Change-Id: I3cfd0a31409f6a798c933dae4a47b75e93601f6b diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java index a37438e..1fce7d4 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -63,9 +63,13 @@ public class LibreOfficeMainActivity extends Activity { @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); - if (id == R.id.action_about) { - showAbout(); - return true; + switch (id) { + case R.id.action_about: + showAbout(); + return true; + case R.id.action_parts: + mDrawerLayout.openDrawer(mDrawerList); + return true; } return super.onOptionsItemSelected(item); } commit 32fe0017ee87d21eb4bf16efa42ab0328bb159e4 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 17:46:03 2014 +0200 android: fix redrawing everyting on part change (via sidebar) Change-Id: If7aeeca3da65f44dfe1f9a5bc347baf4e3cadd82 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java index 54478bf..31b9eb5 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java @@ -46,10 +46,11 @@ public class LOKitThread extends Thread { mApplication.getLayerController().getView().changeCheckerboardBitmap(bitmap, mTileProvider.getPageWidth(), mTileProvider.getPageHeight()); } - mLayerClient.clearAllTiles(); - + mLayerClient.clearAndResetlayers(); + draw(); RectF rect = new RectF(0, 0, mTileProvider.getPageWidth(), mTileProvider.getPageHeight()); mController.setPageRect(rect, rect); + mController.setViewportMetrics(mController.getViewportMetrics()); mController.setForceRedraw(); } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java index c6c7d7938..1ad8d38 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java @@ -195,7 +195,7 @@ public class DynamicTileLayer extends Layer { } } - public void clearAllTiles() { + public void clearAndReset() { tiles.clear(); currentViewport = new RectF(); } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 5905d4a..23095ef 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -264,8 +264,8 @@ public class GeckoLayerClient implements LayerView.Listener { mRootLayer.reevaluateTiles(mLayerController.getViewportMetrics()); } - public void clearAllTiles() { - mRootLayer.clearAllTiles(); + public void clearAndResetlayers() { + mRootLayer.clearAndReset(); } private class AdjustRunnable implements Runnable { commit 20ca5ea8ab6d652fc70aa29038685845f6e3881b Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 17:41:02 2014 +0200 android: null safeguards and cleanup unneeded calls Change-Id: I0ffcfb0fbaa03e5035bec9dd1ffed21f85972470 diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java index 859a3d8..332e0f8 100644 --- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java +++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitShell.java @@ -3,7 +3,6 @@ package org.libreoffice; import android.os.Handler; import android.util.DisplayMetrics; -import android.util.Log; public class LOKitShell { @@ -20,10 +19,6 @@ public class LOKitShell { } } - public static void viewSizeChanged() { - Log.i(LOGTAG, "viewSizeChanged"); - } - // Get a Handler for the main java thread public static Handler getMainHandler() { return LibreOfficeMainActivity.mAppContext.mMainHandler; diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java index 03da4bf..c6c7d7938 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java @@ -131,6 +131,10 @@ public class DynamicTileLayer extends Layer { } public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics) { + if (tileProvider == null) { + return; + } + RectF newCurrentViewPort = inflate(roundToTileSize(viewportMetrics.getViewport(), tileSize), tileSize); if (!currentViewport.equals(newCurrentViewPort)) { @@ -193,5 +197,6 @@ public class DynamicTileLayer extends Layer { public void clearAllTiles() { tiles.clear(); + currentViewport = new RectF(); } } diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 9ae462b..5905d4a 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -71,7 +71,6 @@ public class GeckoLayerClient implements LayerView.Listener { private ImmutableViewportMetrics mNewGeckoViewport; private Context mContext; private boolean mPendingViewportAdjust; - private boolean mViewportSizeChanged; public GeckoLayerClient(Context context) { mContext = context; @@ -147,8 +146,6 @@ public class GeckoLayerClient implements LayerView.Listener { /* Informs Gecko that the screen size has changed. */ private void sendResizeEventIfNecessary(boolean force) { - Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force); - DisplayMetrics metrics = new DisplayMetrics(); LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); View view = mLayerController.getView(); @@ -183,7 +180,6 @@ public class GeckoLayerClient implements LayerView.Listener { public void viewportSizeChanged() { sendResizeEventIfNecessary(true); - LOKitShell.viewSizeChanged(); } void adjustViewport(DisplayPortMetrics displayPort) { @@ -204,10 +200,6 @@ public class GeckoLayerClient implements LayerView.Listener { } LOKitShell.sendEvent(LOEventFactory.viewport(clampedMetrics)); - if (mViewportSizeChanged) { - mViewportSizeChanged = false; - LOKitShell.viewSizeChanged(); - } } /** This function is invoked by Gecko via JNI; be careful when modifying signature. commit 52228bbd790bb5fb3958fa2ef84a4171f0ad199c Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 13:53:42 2014 +0200 android: image in TileLayer can be null Change-Id: I4a910eb60f6fe81f97933d1b9e57bac6af4547c9 diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TileLayer.java index 1ee1f1a..28ac487 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TileLayer.java @@ -28,7 +28,7 @@ public abstract class TileLayer extends Layer { private PaintMode mPaintMode; public TileLayer(CairoImage image, PaintMode paintMode) { - super(image.getSize()); + super(image == null ? null : image.getSize()); mPaintMode = paintMode; mImage = image; commit 0d3e2ee5cdb685e68ec4a16f2218967f75a2dab5 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 13:53:11 2014 +0200 android: SubTile - equals and hash Change-Id: I6e8cf220d108cefdf16f9b4553e2d2ecd7a5338c diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java index 5ab4f0d..27f11fc 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java @@ -22,4 +22,26 @@ public class SubTile extends SingleTileLayer { public void markForRemoval() { markedForRemoval = true; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SubTile subTile = (SubTile) o; + + if (x != subTile.x) return false; + if (y != subTile.y) return false; + if (Float.compare(subTile.zoom, zoom) != 0) return false; + + return true; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + y; + result = 31 * result + (zoom != +0.0f ? Float.floatToIntBits(zoom) : 0); + return result; + } } commit a55068030ebc354caf8d8282a5ff00db3ced8665 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 13:52:07 2014 +0200 android: SingleTileLayer - less var. trashing (Fennec update) Change-Id: I8c32f6a43cad6dd3790a3e7dd0b990516a35ebca diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SingleTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SingleTileLayer.java index cc1988f..0bc2716 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SingleTileLayer.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SingleTileLayer.java @@ -23,14 +23,40 @@ public class SingleTileLayer extends TileLayer { private Rect mMask; - public SingleTileLayer(CairoImage image) { this(false, image); } + // To avoid excessive GC, declare some objects here that would otherwise + // be created and destroyed frequently during draw(). + private final RectF mBounds; + private final RectF mTextureBounds; + private final RectF mViewport; + private final Rect mIntBounds; + private final Rect mSubRect; + private final RectF mSubRectF; + private final Region mMaskedBounds; + private final Rect mCropRect; + private final RectF mObjRectF; + private final float[] mCoords; + + public SingleTileLayer(CairoImage image) { + this(false, image); + } public SingleTileLayer(boolean repeat, CairoImage image) { - super(image, repeat ? PaintMode.REPEAT : PaintMode.NORMAL); + this(image, repeat ? TileLayer.PaintMode.REPEAT : TileLayer.PaintMode.NORMAL); } public SingleTileLayer(CairoImage image, TileLayer.PaintMode paintMode) { super(image, paintMode); + + mBounds = new RectF(); + mTextureBounds = new RectF(); + mViewport = new RectF(); + mIntBounds = new Rect(); + mSubRect = new Rect(); + mSubRectF = new RectF(); + mMaskedBounds = new Region(); + mCropRect = new Rect(); + mObjRectF = new RectF(); + mCoords = new float[20]; } /** @@ -47,83 +73,69 @@ public class SingleTileLayer extends TileLayer { if (!initialized()) return; - RectF bounds; - RectF textureBounds; - RectF viewport = context.viewport; + mViewport.set(context.viewport); if (repeats()) { // If we're repeating, we want to adjust the texture bounds so that // the texture repeats the correct number of times when drawn at // the size of the viewport. - bounds = getBounds(context); - textureBounds = new RectF(0.0f, 0.0f, bounds.width(), bounds.height()); - bounds = new RectF(0.0f, 0.0f, viewport.width(), viewport.height()); + mBounds.set(getBounds(context)); + mTextureBounds.set(0.0f, 0.0f, mBounds.width(), mBounds.height()); + mBounds.set(0.0f, 0.0f, mViewport.width(), mViewport.height()); } else if (stretches()) { // If we're stretching, we just want the bounds and texture bounds // to fit to the page. - bounds = new RectF(context.pageRect); - textureBounds = bounds; + mBounds.set(context.pageRect); + mTextureBounds.set(mBounds); } else { - bounds = getBounds(context); - textureBounds = bounds; + mBounds.set(getBounds(context)); + mTextureBounds.set(mBounds); } - Rect intBounds = new Rect(); - bounds.roundOut(intBounds); - Region maskedBounds = new Region(intBounds); + mBounds.roundOut(mIntBounds); + mMaskedBounds.set(mIntBounds); if (mMask != null) { - maskedBounds.op(mMask, Region.Op.DIFFERENCE); - if (maskedBounds.isEmpty()) + mMaskedBounds.op(mMask, Region.Op.DIFFERENCE); + if (mMaskedBounds.isEmpty()) return; } // XXX Possible optimisation here, form this array so we can draw it in // a single call. - RegionIterator i = new RegionIterator(maskedBounds); - for (Rect subRect = new Rect(); i.next(subRect);) { + RegionIterator i = new RegionIterator(mMaskedBounds); + while (i.next(mSubRect)) { // Compensate for rounding errors at the edge of the tile caused by // the roundOut above - RectF subRectF = new RectF(Math.max(bounds.left, (float)subRect.left), - Math.max(bounds.top, (float)subRect.top), - Math.min(bounds.right, (float)subRect.right), - Math.min(bounds.bottom, (float)subRect.bottom)); + mSubRectF.set(Math.max(mBounds.left, (float)mSubRect.left), + Math.max(mBounds.top, (float)mSubRect.top), + Math.min(mBounds.right, (float)mSubRect.right), + Math.min(mBounds.bottom, (float)mSubRect.bottom)); // This is the left/top/right/bottom of the rect, relative to the // bottom-left of the layer, to use for texture coordinates. - int[] cropRect = new int[] { Math.round(subRectF.left - bounds.left), - Math.round(bounds.bottom - subRectF.top), - Math.round(subRectF.right - bounds.left), - Math.round(bounds.bottom - subRectF.bottom) }; - - float left = subRectF.left - viewport.left; - float top = viewport.bottom - subRectF.bottom; - float right = left + subRectF.width(); - float bottom = top + subRectF.height(); - - float[] coords = { - //x, y, z, texture_x, texture_y - left/viewport.width(), bottom/viewport.height(), 0, - cropRect[0]/textureBounds.width(), cropRect[1]/textureBounds.height(), - - left/viewport.width(), top/viewport.height(), 0, - cropRect[0]/textureBounds.width(), cropRect[3]/textureBounds.height(), + mCropRect.set(Math.round(mSubRectF.left - mBounds.left), + Math.round(mBounds.bottom - mSubRectF.top), + Math.round(mSubRectF.right - mBounds.left), + Math.round(mBounds.bottom - mSubRectF.bottom)); - right/viewport.width(), bottom/viewport.height(), 0, - cropRect[2]/textureBounds.width(), cropRect[1]/textureBounds.height(), + mObjRectF.set(mSubRectF.left - mViewport.left, + mViewport.bottom - mSubRectF.bottom, + mSubRectF.right - mViewport.left, + mViewport.bottom - mSubRectF.top); - right/viewport.width(), top/viewport.height(), 0, - cropRect[2]/textureBounds.width(), cropRect[3]/textureBounds.height() - }; + fillRectCoordBuffer(mCoords, mObjRectF, mViewport.width(), mViewport.height(), + mCropRect, mTextureBounds.width(), mTextureBounds.height()); FloatBuffer coordBuffer = context.coordBuffer; int positionHandle = context.positionHandle; int textureHandle = context.textureHandle; + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID()); // Make sure we are at position zero in the buffer coordBuffer.position(0); - coordBuffer.put(coords); + coordBuffer.put(mCoords); // Unbind any the current array buffer so we can use client side buffers GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); commit 7afb0e2491ac47021412529e3330f3924991d234 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Wed Oct 1 13:51:00 2014 +0200 android: replace MultiTileLayer with new & simpler DynamicTileLayer Change-Id: Idec2246975a65f8ce664642a4ef49415e20ca187 diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java new file mode 100644 index 0000000..03da4bf --- /dev/null +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/DynamicTileLayer.java @@ -0,0 +1,197 @@ +package org.mozilla.gecko.gfx; + +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Region; +import android.util.Log; + +import org.libreoffice.TileProvider; +import org.mozilla.gecko.util.FloatUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class DynamicTileLayer extends Layer { + private static final String LOGTAG = DynamicTileLayer.class.getSimpleName(); + + private final List<SubTile> tiles = new CopyOnWriteArrayList<SubTile>(); + private TileProvider tileProvider; + private final FloatSize tileSize; + private RectF currentViewport = new RectF(); + + public DynamicTileLayer() { + this.tileSize = new FloatSize(256, 256); + } + + public DynamicTileLayer(FloatSize tileSize) { + this.tileSize = tileSize; + } + + public void setTileProvider(TileProvider tileProvider) { + this.tileProvider = tileProvider; + } + + public void invalidate() { + for (SubTile layer : tiles) { + layer.invalidate(); + } + } + + @Override + public void beginTransaction() { + super.beginTransaction(); + for (SubTile tile : tiles) { + tile.beginTransaction(); + } + } + + @Override + public void endTransaction() { + for (SubTile tile : tiles) { + tile.endTransaction(); + } + super.endTransaction(); + } + + @Override + public void draw(RenderContext context) { + for (SubTile tile : tiles) { + if (RectF.intersects(tile.getBounds(context), context.viewport)) { + tile.draw(context); + } + } + } + + @Override + protected void performUpdates(RenderContext context) { + super.performUpdates(context); + + refreshTileMetrics(); + + for (SubTile tile : tiles) { + tile.performUpdates(context); + } + } + + @Override + public Region getValidRegion(RenderContext context) { + Region validRegion = new Region(); + for (SubTile tile : tiles) { + validRegion.op(tile.getValidRegion(context), Region.Op.UNION); + } + + return validRegion; + } + + @Override + public void setResolution(float newResolution) { + super.setResolution(newResolution); + for (SubTile tile : tiles) { + tile.setResolution(newResolution); + } + } + + private void refreshTileMetrics() { + for (SubTile tile : tiles) { + tile.beginTransaction(); + + Rect position = tile.getPosition(); + float positionX = tile.x / tile.zoom; + float positionY = tile.y / tile.zoom; + float tileSizeWidth = tileSize.width / tile.zoom; + float tileSizeHeight = tileSize.height / tile.zoom; + position.set((int) positionX, (int) positionY, (int) (positionX + tileSizeWidth + 1), (int) (positionY + tileSizeHeight + 1)); + tile.setPosition(position); + + tile.endTransaction(); + } + } + + private RectF roundToTileSize(RectF input, FloatSize tileSize) { + float minX = ((int)(input.left / tileSize.width)) * tileSize.width; + float minY = ((int)(input.top / tileSize.height)) * tileSize.height; + float maxX = ((int)(input.right / tileSize.width) + 1) * tileSize.width; + float maxY = ((int)(input.bottom / tileSize.height) + 1) * tileSize.height; + return new RectF(minX, minY, maxX, maxY); + } + + private RectF inflate(RectF rect, FloatSize inflateSize) { + RectF newRect = new RectF(rect); + newRect.left -= inflateSize.width; + newRect.left = newRect.left < 0.0f ? 0.0f : newRect.left; + + newRect.top -= inflateSize.height; + newRect.top = newRect.top < 0.0f ? 0.0f : newRect.top; + + newRect.right += inflateSize.width; + newRect.bottom += inflateSize.height; + + return newRect; + } + + public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics) { + RectF newCurrentViewPort = inflate(roundToTileSize(viewportMetrics.getViewport(), tileSize), tileSize); + + if (!currentViewport.equals(newCurrentViewPort)) { + Log.i(LOGTAG, "reevaluateTiles " + currentViewport + " " + newCurrentViewPort); + currentViewport = newCurrentViewPort; + clearMarkedTiles(); + addNewTiles(viewportMetrics); + markTiles(viewportMetrics); + } + } + + private void addNewTiles(ImmutableViewportMetrics viewportMetrics) { + for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) { + if (y > viewportMetrics.getPageHeight()) { + continue; + } + for (float x = currentViewport.left; x < currentViewport.right; x += tileSize.width) { + if (x > viewportMetrics.getPageWidth()) { + continue; + } + boolean contains = false; + for (SubTile tile : tiles) { + if (tile.x == x && tile.y == y && tile.zoom == viewportMetrics.zoomFactor) { + contains = true; + } + } + if (!contains) { + CairoImage image = tileProvider.createTile(x, y, tileSize, viewportMetrics.zoomFactor); + SubTile tile = new SubTile(image, (int) x, (int) y, viewportMetrics.zoomFactor); + tile.beginTransaction(); + tiles.add(tile); + } + } + } + } + + private void clearMarkedTiles() { + List<SubTile> tilesToRemove = new ArrayList<SubTile>(); + for (SubTile tile : tiles) { + if (tile.markedForRemoval) { + tile.destroy(); + tilesToRemove.add(tile); + } + } + tiles.removeAll(tilesToRemove); + } + + private void markTiles(ImmutableViewportMetrics viewportMetrics) { + for (SubTile tile : tiles) { + if (FloatUtils.fuzzyEquals(tile.zoom, viewportMetrics.zoomFactor)) { + RectF tileRect = new RectF(tile.x, tile.y, tile.x + tileSize.width, tile.y + tileSize.height); + if (!RectF.intersects(currentViewport, tileRect)) { + tile.markForRemoval(); + } + } else { + tile.markForRemoval(); + } + } + } + + public void clearAllTiles() { + tiles.clear(); + } +} diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 9c3a893..9ae462b 100644 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -62,7 +62,7 @@ public class GeckoLayerClient implements LayerView.Listener { private boolean mRecordDrawTimes; private DrawTimingQueue mDrawTimingQueue; - private MultiTileLayer mRootLayer; + private DynamicTileLayer mRootLayer; /* The viewport that Gecko is currently displaying. */ private ImmutableViewportMetrics mGeckoViewport; @@ -88,7 +88,7 @@ public class GeckoLayerClient implements LayerView.Listener { mLayerController = layerController; - mRootLayer = new MultiTileLayer(); + mRootLayer = new DynamicTileLayer(); view.setListener(this); layerController.setRoot(mRootLayer); diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java deleted file mode 100644 index 7d1306e..0000000 --- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java +++ /dev/null @@ -1,273 +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) 2011-2012 -* the Initial Developer. All Rights Reserved. -* -* Contributor(s): -* Chris Lord <chrislord....@gmail.com> -* Arkady Blyakher <rka...@mit.edu> -* -* 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.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; - -import org.libreoffice.TileProvider; -import org.mozilla.gecko.util.FloatUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -public class MultiTileLayer extends Layer { - private static final String LOGTAG = "MultiTileLayer"; - - private static int TILE_SIZE = 256; - private final List<SubTile> mTiles = new CopyOnWriteArrayList<SubTile>(); - private TileProvider tileProvider; - private RectF currentViewPort = new RectF(); - - public void invalidate() { - for (SubTile layer : mTiles) { - layer.invalidate(); - } - } - - private void validateTiles() { - // Set tile origins and resolution - Point origin = new Point(); - refreshTileMetrics(origin, getResolution(), false); - } - - @Override - protected void performUpdates(RenderContext context) { - super.performUpdates(context); - - validateTiles(); - - // Iterate over the tiles and decide which ones we'll be drawing - int dirtyTiles = 0; - boolean screenUpdateDone = false; - SubTile firstDirtyTile = null; - for (SubTile layer : mTiles) { - // First do a non-texture update to make sure coordinates are - // up-to-date. - layer.performUpdates(context); - - RectF layerBounds = layer.getBounds(context); - - if (!RectF.intersects(layerBounds, context.viewport)) { - if (firstDirtyTile == null) { - firstDirtyTile = layer; - } - dirtyTiles++; - } else { - // This tile intersects with the screen and is dirty, - // update it immediately. - screenUpdateDone = true; - layer.performUpdates(context); - } - } - - // Now if no tiles that intersect with the screen were updated, update - // a single tile that doesn't (if there are any). This has the effect - // of spreading out non-critical texture upload over time, and smoothing - // upload-related hitches. - if (!screenUpdateDone && firstDirtyTile != null) { - firstDirtyTile.performUpdates(context); - dirtyTiles--; - } - - } - - private void refreshTileMetrics(Point origin, float resolution, boolean inTransaction) { - for (SubTile layer : mTiles) { - if (!inTransaction) { - layer.beginTransaction(); - } - - if (origin != null) { - Rect position = layer.getPosition(); - float positionX = origin.x + (layer.x / layer.zoom); - float positionY = origin.y + (layer.y / layer.zoom); - float tileSize = TILE_SIZE / layer.zoom; - position.set((int) positionX, (int) positionY, (int) (positionX + tileSize + 1), (int) (positionY + tileSize + 1)); - layer.setPosition(position); - } - if (resolution >= 0.0f) { - layer.setResolution(resolution); - } - - if (!inTransaction) { - layer.endTransaction(); - } - } - } - - @Override - public void setResolution(float newResolution) { - super.setResolution(newResolution); - refreshTileMetrics(null, newResolution, true); - } - - @Override - public void beginTransaction() { - super.beginTransaction(); - - for (SubTile layer : mTiles) { - layer.beginTransaction(); - } - } - - @Override - public void endTransaction() { - for (SubTile layer : mTiles) { - layer.endTransaction(); - } - super.endTransaction(); - } - - private RectF roundToTileSize(RectF input, int tileSize) { - float minX = (Math.round(input.left) / tileSize) * tileSize; - float minY = (Math.round(input.top) / tileSize) * tileSize; - float maxX = ((Math.round(input.right) / tileSize) + 1) * tileSize; - float maxY = ((Math.round(input.bottom) / tileSize) + 1) * tileSize; - return new RectF(minX, minY, maxX, maxY); - } - - private RectF inflate(RectF rect, float inflateSize) { - RectF newRect = new RectF(rect); - newRect.left -= inflateSize; - newRect.left = newRect.left < 0.0f ? 0.0f : newRect.left; - - newRect.top -= inflateSize; - newRect.top = newRect.top < 0.0f ? 0.0f : newRect.top; - - newRect.right += inflateSize; - newRect.bottom += inflateSize; - - return newRect; - } - - @Override - public void draw(RenderContext context) { - for (SubTile layer : mTiles) { - // Avoid work, only draw tiles that intersect with the viewport - RectF layerBounds = layer.getBounds(context); - - if (RectF.intersects(layerBounds, context.viewport)) { - layer.draw(context); - } - } - } - - @Override - public Region getValidRegion(RenderContext context) { - Region validRegion = new Region(); - for (SubTile tile : mTiles) { - validRegion.op(tile.getValidRegion(context), Region.Op.UNION); - } - - return validRegion; - } - - public void setTileProvider(TileProvider tileProvider) { - this.tileProvider = tileProvider; - } - - public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics) { - RectF newCurrentViewPort = inflate(roundToTileSize(viewportMetrics.getViewport(), TILE_SIZE), TILE_SIZE); - - if (currentViewPort != newCurrentViewPort) { - currentViewPort = newCurrentViewPort; - clearMarkedTiles(); - addNewTiles(viewportMetrics); - markTiles(viewportMetrics); - } - } - - private void clearMarkedTiles() { - List<SubTile> tilesToRemove = new ArrayList<SubTile>(); - for(SubTile tile : mTiles) { - if (tile.markedForRemoval) { - tile.destroy(); - tilesToRemove.add(tile); - } - } - mTiles.removeAll(tilesToRemove); - } - - private void addNewTiles(ImmutableViewportMetrics viewportMetrics) { - for (float y = currentViewPort.top; y < currentViewPort.bottom; y += TILE_SIZE) { - if (y > viewportMetrics.getPageHeight()) { - continue; - } - for (float x = currentViewPort.left; x < currentViewPort.right; x += TILE_SIZE) { - if (x > viewportMetrics.getPageWidth()) { - continue; - } - boolean contains = false; - for (SubTile tile : mTiles) { - if (tile.x == x && tile.y == y && tile.zoom == viewportMetrics.zoomFactor) { - contains = true; - } ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits