Kaydet (Commit) 5ccb510e authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

LOAndroid3: (partially) render page with LOKitTileProvider

+ TileProvider & TileIterator interfaces
+ Clean-up obsolete mozilla stuff

Change-Id: Ief56f11bf7f8fd6da383ffc7be3461b765bf0157
üst 9948d956
......@@ -16,16 +16,10 @@ import java.nio.ByteBuffer;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
import org.libreoffice.kit.Document;
public class LOKitThread extends Thread {
private static final String LOGTAG = "GeckoThread";
private static final int TILE_SIZE = 256;
public Office mOffice;
public Document mDocument;
private TileProvider mTileProvider;
public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
private ViewportMetrics mViewportMetrics;
......@@ -33,55 +27,40 @@ public class LOKitThread extends Thread {
LOKitThread() {
}
private void openDocument() {
// enable debugging messages as the first thing
LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
String input = "/assets/test1.odt";
mDocument = mOffice.documentLoad(input);
}
private synchronized boolean draw() throws InterruptedException {
private boolean draw() throws InterruptedException {
final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
openDocument();
long height = mDocument.getDocumentHeight();
long width = mDocument.getDocumentWidth();
if (mTileProvider == null)
mTileProvider = new LOKitTileProvider(application.getLayerController());
Log.e(LOGTAG, "Document Size: " + width + " " + height);
int pageWidth = mTileProvider.getPageWidth();
int pageHeight = mTileProvider.getPageHeight();
int pageWidth = 1024;
int pageHeight = 1024;
String metadata = createJson(0, 0, pageWidth, pageHeight, pageWidth, pageHeight, 0, 0, 1.0);
mViewportMetrics = new ViewportMetrics();
String metadata = createJson(0, 0, 256, 256, pageWidth, pageHeight, 0, 0, 1.0);
boolean shouldContinue = application.getLayerClient().beginDrawing(pageWidth, pageHeight, TILE_SIZE, TILE_SIZE, metadata);
Rect bufferRect = application.getLayerClient().beginDrawing(256, 256, TILE_SIZE, TILE_SIZE, metadata);
/*if (bufferRect == null) {
Log.e(LOGTAG, "beginDrawing - false");
if (!shouldContinue) {
return false;
}*/
Log.e(LOGTAG, "Filling tiles..");
ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
Log.e(LOGTAG, "PaintTile..");
mDocument.paintTile(buffer, 256, 256, 1024, 1024, 4096, 4096);
}
Log.e(LOGTAG, "EndPaintTile..");
Log.i(LOGTAG, "Filling tiles..");
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
int x = 0;
int y = 0;
for (Bitmap bitmap : mTileProvider.getTileIterator()) {
application.getLayerClient().addTile(bitmap, x, y);
x += TILE_SIZE;
if (x > pageWidth) {
x = 0;
y += TILE_SIZE;
}
}
application.getLayerClient().addTile(bitmap, 0, 0);
Log.i(LOGTAG, "End Draw");
Log.e(LOGTAG, "EndDrawing..");
application.getLayerClient().endDrawing(0, 0, 256, 256);
application.getLayerClient().endDrawing(0, 0, pageWidth, pageHeight);
return true;
}
......@@ -143,22 +122,20 @@ public class LOKitThread extends Thread {
try {
boolean drawn = false;
while (true) {
if (!gEvents.isEmpty()) {
processEvent(gEvents.poll());
} else {
if (!drawn) {
drawn = draw();
}
Thread.sleep(2000L);
Thread.sleep(100L);
}
}
} catch (InterruptedException ex) {
}
}
private synchronized void processEvent(LOEvent event) throws InterruptedException {
private void processEvent(LOEvent event) throws InterruptedException {
switch (event.mType) {
case LOEvent.VIEWPORT:
mViewportMetrics = event.getViewport();
......
package org.libreoffice;
import android.graphics.Bitmap;
import android.util.Log;
import org.mozilla.gecko.gfx.LayerController;
import java.nio.ByteBuffer;
import java.util.Iterator;
import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
import org.libreoffice.kit.Document;
public class LOKitTileProvider implements TileProvider {
private final LayerController mLayerController;
public static int TILE_SIZE = 256;
public final Office mOffice;
public final Document mDocument;
public LOKitTileProvider(LayerController layerController) {
this.mLayerController = layerController;
LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
String input = "/assets/test1.odt";
mDocument = mOffice.documentLoad(input);
}
@Override
public int getPageWidth() {
return (int) (mDocument.getDocumentWidth() / 1440.0 * LOKitShell.getDpi());
}
@Override
public int getPageHeight() {
return (int) (mDocument.getDocumentHeight() / 1440.0 * LOKitShell.getDpi());
}
public TileIterator getTileIterator() {
return new LoKitTileIterator();
}
public class LoKitTileIterator implements TileIterator, Iterator<Bitmap> {
private final double mTileWidth;
private final double mTileHeight;
private boolean mShouldContinue = true;
private double mPositionWidth = 0;
private double mPositionHeight = 0;
private double mPageWidth;
private double mPageHeight;
public LoKitTileIterator() {
mTileWidth = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
mTileHeight = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
mPageWidth = mDocument.getDocumentWidth();
mPageHeight = mDocument.getDocumentHeight();
}
@Override
public boolean hasNext() {
return mShouldContinue;
}
@Override
public Bitmap next() {
ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) mPositionWidth, (int) mPositionHeight, (int) mTileWidth, (int) mTileHeight);
mPositionWidth += mTileWidth;
if (mPositionWidth > mPageWidth) {
mPositionHeight += mTileHeight;
mPositionWidth = 0;
}
if (mPositionHeight > mPageHeight || mPositionHeight > 20000) {
mShouldContinue = false;
}
bitmap.copyPixelsFromBuffer(buffer);
return bitmap;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Iterator<Bitmap> iterator() {
return this;
}
}
}
......@@ -11,8 +11,6 @@ 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;
......@@ -63,10 +61,12 @@ public class LibreOfficeMainActivity extends Activity {
mAppContext = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
setContentView(R.layout.activity_main);
// setup gecko layout
mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
......
package org.libreoffice;
import android.graphics.Bitmap;
import org.apache.http.MethodNotSupportedException;
import org.mozilla.gecko.gfx.LayerController;
import java.util.Iterator;
import java.util.List;
public class MockTileProvider implements TileProvider {
private final LayerController layerController;
public MockTileProvider(LayerController layerController) {
this.layerController = layerController;
}
@Override
public int getPageWidth() {
return 549;
}
@Override
public int getPageHeight() {
return 630;
}
public TileIterator getTileIterator() {
return new MockTileIterator(layerController);
}
public class MockTileIterator implements TileIterator, Iterator<Bitmap> {
private final LayerController layerController;
private int tileNumber = 1;
public MockTileIterator(LayerController layerController) {
this.layerController = layerController;
}
@Override
public boolean hasNext() {
return tileNumber <= 9;
}
@Override
public Bitmap next() {
String imageName = "d" + tileNumber;
tileNumber++;
Bitmap bitmap = layerController.getDrawable(imageName);
return bitmap;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Iterator<Bitmap> iterator() {
return this;
}
}
}
package org.libreoffice;
import android.graphics.Bitmap;
public interface TileIterator extends Iterable<Bitmap> {
}
package org.libreoffice;
import android.graphics.Bitmap;
import java.util.List;
public interface TileProvider {
int getPageWidth();
int getPageHeight();
TileIterator getTileIterator();
}
......@@ -41,7 +41,7 @@ package org.mozilla.gecko.gfx;
import org.libreoffice.LOKitShell;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerClient;
import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerRenderer;
import org.mozilla.gecko.gfx.MultiTileLayer;
......@@ -77,20 +77,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mFormat = CairoImage.FORMAT_ARGB32;
}
/*protected void finalize() throws Throwable {
try {
if (mBuffer != null)
LOKitShell.freeDirectBuffer(mBuffer);
mBuffer = null;
} finally {
super.finalize();
}
}*/
public void setLayerController(LayerController layerController) {
super.setLayerController(layerController);
layerController.setRoot(mTileLayer);
if (mGeckoViewport != null) {
layerController.setViewportMetrics(mGeckoViewport);
}
......@@ -104,7 +95,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
if(mTileLayer == null)
mTileLayer = new MultiTileLayer(TILE_SIZE);
getLayerController().setRoot(mTileLayer);
mLayerController.setRoot(mTileLayer);
// Force a resize event to be sent because the results of this
// are different depending on what tile system we're using
......@@ -114,22 +105,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
@Override
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 (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) {
Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
public boolean beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
boolean shouldContinue = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
if (bufferRect == null) {
return bufferRect;
if (!shouldContinue) {
return shouldContinue;
}
// If the window size has changed, reallocate the buffer to match.
......@@ -137,7 +117,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mBufferSize = new IntSize(width, height);
}
return bufferRect;
return shouldContinue;
}
@Override
......@@ -147,76 +127,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
}
/*private void copyPixelsFromMultiTileLayer(Bitmap target) {
Canvas c = new Canvas(target);
ByteBuffer tileBuffer = mBuffer.slice();
int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) {
for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) {
// Calculate tile size
IntSize tileSize = new IntSize(Math.min(mBufferSize.width - x, TILE_SIZE.width),
Math.min(mBufferSize.height - y, TILE_SIZE.height));
// Create a Bitmap from this tile
Bitmap tile = Bitmap.createBitmap(tileSize.width, tileSize.height,
CairoUtils.cairoFormatTobitmapConfig(mFormat));
tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer());
// Copy the tile to the master Bitmap and recycle it
c.drawBitmap(tile, x, y, null);
tile.recycle();
// Progress the buffer to the next tile
tileBuffer.position(tileSize.getArea() * bpp);
tileBuffer = tileBuffer.slice();
}
}
}*/
@Override
protected void tileLayerUpdated() {
/* No-op. */
}
@Override
public Bitmap getBitmap() {
if (mTileLayer == null)
return null;
// Begin a tile transaction, otherwise the buffer can be destroyed while
// we're reading from it.
/*beginTransaction(mTileLayer);
try {
if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0)
return null;
try {
Bitmap b = null;
if (mTileLayer instanceof MultiTileLayer) {
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");
}
return b;
} catch (OutOfMemoryError oom) {
Log.w(LOGTAG, "Unable to create bitmap", oom);
return null;
}
} finally {
endTransaction(mTileLayer);
}*/
return null;
}
@Override
public int getType() {
return LAYER_CLIENT_TYPE_SOFTWARE;
}
@Override
protected IntSize getBufferSize() {
return new IntSize(
......@@ -235,3 +145,4 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
}
}
}
/* -*- 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@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;
/**
* A layer client provides tiles and manages other information used by the layer controller.
*/
public abstract class LayerClient {
private LayerController mLayerController;
public abstract void geometryChanged();
public abstract void viewportSizeChanged();
protected abstract void render();
public LayerController getLayerController() {
return mLayerController;
}
public void setLayerController(LayerController layerController) {
mLayerController = layerController;
}
/**
* A utility function for calling Layer.beginTransaction with the
* appropriate LayerView.
*/
public void beginTransaction(Layer aLayer) {
if (mLayerController != null) {
LayerView view = mLayerController.getView();
if (view != null) {
aLayer.beginTransaction(view);
return;
}
}
aLayer.beginTransaction();
}
// Included for symmetry.
public void endTransaction(Layer aLayer) {
aLayer.endTransaction();
}
}
......@@ -88,7 +88,7 @@ public class LayerController {
private boolean mWaitForTouchListeners;
private PanZoomController mPanZoomController;
private OnTouchListener mOnTouchListener; /* The touch listener. */
private LayerClient mLayerClient; /* The layer client. */
private GeckoLayerClient mLayerClient; /* The layer client. */
/* The new color for the checkerboard. */
private int mCheckerboardColor;
private boolean mCheckerboardShouldShowChecks;
......@@ -111,11 +111,11 @@ public class LayerController {
mForceRedraw = true;
}
public LayerClient getLayerClient() {
public GeckoLayerClient getLayerClient() {
return mLayerClient;
}
public void setLayerClient(LayerClient layerClient) {
public void setLayerClient(GeckoLayerClient layerClient) {
mLayerClient = layerClient;
layerClient.setLayerController(this);
}
......
......@@ -88,7 +88,7 @@ abstract class Axis {
private float mTouchPos; /* Position of the most recent touch event on the current drag. */
private float mLastTouchPos; /* Position of the touch event before touchPos. */
private float mVelocity; /* Velocity in this direction; pixels per animation frame. */
public boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */
private float mDisplacement;
......@@ -147,7 +147,7 @@ abstract class Axis {
}
private Overscroll getOverscroll() {
boolean minus = (getOrigin() < 0.0f);
boolean minus = getOrigin() < 0.0f;
boolean plus = (getViewportEnd() > getPageLength());
if (minus && plus) {
return Overscroll.BOTH;
......@@ -164,10 +164,14 @@ abstract class Axis {
// overscrolled on this axis, returns 0.
private float getExcess() {
switch (getOverscroll()) {
case MINUS: return -getOrigin();
case PLUS: return getViewportEnd() - getPageLength();
case BOTH: return getViewportEnd() - getPageLength() - getOrigin();
default: return 0.0f;
case MINUS:
return -getOrigin();
case PLUS:
return getViewportEnd() - getPageLength();
case BOTH:
return getViewportEnd() - getPageLength() - getOrigin();
default:
return 0.0f;
}
}
......@@ -176,8 +180,7 @@ abstract class Axis {
* possible and this axis has not been scroll locked while panning. Otherwise, returns false.
*/
private boolean scrollable() {
return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE &&
!mScrollingDisabled;
return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE && !mScrollingDisabled;
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment