summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@suse.com>2012-06-05 17:05:56 +0300
committerTor Lillqvist <tlillqvist@suse.com>2012-06-05 17:17:41 +0300
commit8ae077379edcdbf7bf106121593361d2486aacb7 (patch)
tree207e4b9d516a56e2ebbf500cd80baca2d275894c /android
parent92f23297c93dc105e2ffd9ff09c0dafff1ee0fd3 (diff)
Use 32bpp bitmaps on Android (and iOS)
Modify DocumentLoader correspondingly. Take Android bug 32588 into account. Ideal would be to extend the XDevice stuff, or something, so that one could hand it a pre-allocated RGBA buffer into which the drawing/rendering would go. Then one could get rid of the silly convert-to-BMP phase, which prefixes the bitmap data with BMP and DIB headers (and thus, I guess, has to copy and allocate another copy). Will see. Change-Id: I4597cd933db8faa8105dc8f19638d712d5d2238a
Diffstat (limited to 'android')
-rw-r--r--android/Bootstrap/src/org/libreoffice/android/Bootstrap.java2
-rw-r--r--android/experimental/DocumentLoader/Makefile2
-rw-r--r--android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java195
3 files changed, 115 insertions, 84 deletions
diff --git a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
index 47366a22f46d..1f0c14ef5f98 100644
--- a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
+++ b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
@@ -116,6 +116,8 @@ public class Bootstrap extends NativeActivity
// documentation sucks.
public static native void twiddle_BGR_to_RGBA(byte[] source, int offset, int width, int height, ByteBuffer destination);
+ public static native void force_full_alpha(byte[] source, int offset, int size);
+
// This setup() method is called 1) in apps that use *this* class as their activity from onCreate(),
// and 2) should be called from other kinds of LO code using apps.
public static void setup(Activity activity)
diff --git a/android/experimental/DocumentLoader/Makefile b/android/experimental/DocumentLoader/Makefile
index 1e9cebcbe8be..8129948b2e76 100644
--- a/android/experimental/DocumentLoader/Makefile
+++ b/android/experimental/DocumentLoader/Makefile
@@ -262,8 +262,10 @@ uninstall:
$(ANDROID_SDK_HOME)/platform-tools/adb uninstall $(APP_PACKAGE)
run:
+# /data/local/tmp/sample-document.odt
adb shell am start -n org.libreoffice.android.examples/.DocumentLoader -e input /assets/test1.odt
+
clean: properties
$(ANT) clean
rm -rf assets libs $(SODEST) $(OBJLOCAL)
diff --git a/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java b/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
index 8ead7a96240d..4f027ecf7c1a 100644
--- a/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
+++ b/android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java
@@ -150,18 +150,21 @@ public class DocumentLoader
Log.i(TAG, " " + t.getTypeName());
}
- static void dumpBytes(String imageName, byte[] image)
+ static void dumpBytes(String name, byte[] bytes, int offset)
{
- if (image == null) {
- Log.i(TAG, imageName + " is null");
+ if (bytes == null) {
+ Log.i(TAG, name + " is null");
return;
}
- Log.i(TAG, imageName + " is " + image.length + " bytes");
+ Log.i(TAG, name + ":");
- for (int i = 0; i < Math.min(image.length, 160); i += 16) {
+ if (offset != 0)
+ Log.i(TAG, " (offset " + offset + ")");
+
+ for (int i = offset; i < Math.min(bytes.length, offset+160); i += 16) {
String s = "";
- for (int j = i; j < Math.min(image.length, i+16); j++)
- s = s + String.format(" %02x", image[j]);
+ for (int j = i; j < Math.min(bytes.length, i+16); j++)
+ s = s + String.format(" %02x", bytes[j]);
Log.i(TAG, s);
}
@@ -185,8 +188,8 @@ public class DocumentLoader
Bootstrap.dlopen("libswdlo.so");
Bootstrap.dlopen("libswlo.so");
- Log.i(TAG, "Sleeping NOW");
- Thread.sleep(20000);
+ // Log.i(TAG, "Sleeping NOW");
+ // Thread.sleep(20000);
XComponentContext xContext = null;
@@ -225,113 +228,137 @@ public class DocumentLoader
Log.i(TAG, "xCompLoader is" + (xCompLoader!=null ? " not" : "") + " null");
- // Load the wanted document(s)
- String[] inputs = input.split(":");
- for (int i = 0; i < inputs.length; i++) {
- PropertyValue loadProps[] = new PropertyValue[3];
- loadProps[0] = new PropertyValue();
- loadProps[0].Name = "Hidden";
- loadProps[0].Value = new Boolean(true);
- loadProps[1] = new PropertyValue();
- loadProps[1].Name = "ReadOnly";
- loadProps[1].Value = new Boolean(true);
- loadProps[2] = new PropertyValue();
- loadProps[2].Name = "Preview";
- loadProps[2].Value = new Boolean(true);
+ // Load the wanted document
- String sUrl = "file://" + inputs[i];
+ PropertyValue loadProps[] = new PropertyValue[3];
+ loadProps[0] = new PropertyValue();
+ loadProps[0].Name = "Hidden";
+ loadProps[0].Value = new Boolean(true);
+ loadProps[1] = new PropertyValue();
+ loadProps[1].Name = "ReadOnly";
+ loadProps[1].Value = new Boolean(true);
+ loadProps[2] = new PropertyValue();
+ loadProps[2].Name = "Preview";
+ loadProps[2].Value = new Boolean(true);
- Log.i(TAG, "Attempting to load " + sUrl);
+ String sUrl = "file://" + input;
- Object oDoc =
- xCompLoader.loadComponentFromURL
- (sUrl, "_blank", 0, loadProps);
+ Log.i(TAG, "Attempting to load " + sUrl);
- dumpUNOObject("oDoc", oDoc);
+ Object oDoc =
+ xCompLoader.loadComponentFromURL
+ (sUrl, "_blank", 0, loadProps);
- Object toolkit = xMCF.createInstanceWithContext
- ("com.sun.star.awt.Toolkit", xContext);
+ dumpUNOObject("oDoc", oDoc);
- dumpUNOObject("toolkit", toolkit);
+ Object toolkit = xMCF.createInstanceWithContext
+ ("com.sun.star.awt.Toolkit", xContext);
- XToolkit xToolkit = (XToolkit)
- UnoRuntime.queryInterface(XToolkit.class, toolkit);
+ dumpUNOObject("toolkit", toolkit);
- XDevice device = xToolkit.createScreenCompatibleDevice(1024, 1024);
+ XToolkit xToolkit = (XToolkit)
+ UnoRuntime.queryInterface(XToolkit.class, toolkit);
- dumpUNOObject("device", device);
+ XDevice device = xToolkit.createScreenCompatibleDevice(1024, 1024);
- // I guess the XRenderable thing might be what we want to use,
- // having the code pretend it is printing?
+ dumpUNOObject("device", device);
- XRenderable renderBabe = (XRenderable)
- UnoRuntime.queryInterface(XRenderable.class, oDoc);
+ XRenderable renderBabe = (XRenderable)
+ UnoRuntime.queryInterface(XRenderable.class, oDoc);
- PropertyValue renderProps[] =
- new PropertyValue[3];
- renderProps[0] = new PropertyValue();
- renderProps[0].Name = "IsPrinter";
- renderProps[0].Value = new Boolean(true);
- renderProps[1] = new PropertyValue();
- renderProps[1].Name = "RenderDevice";
- renderProps[1].Value = device;
- renderProps[2] = new PropertyValue();
- renderProps[2].Name = "View";
- renderProps[2].Value = new MyXController();
+ PropertyValue renderProps[] =
+ new PropertyValue[3];
+ renderProps[0] = new PropertyValue();
+ renderProps[0].Name = "IsPrinter";
+ renderProps[0].Value = new Boolean(true);
+ renderProps[1] = new PropertyValue();
+ renderProps[1].Name = "RenderDevice";
+ renderProps[1].Value = device;
+ renderProps[2] = new PropertyValue();
+ renderProps[2].Name = "View";
+ renderProps[2].Value = new MyXController();
- Log.i(TAG, "getRendererCount: " + renderBabe.getRendererCount(oDoc, renderProps));
+ Log.i(TAG, "getRendererCount: " + renderBabe.getRendererCount(oDoc, renderProps));
- renderBabe.render(0, oDoc, renderProps);
+ renderBabe.render(0, oDoc, renderProps);
- XBitmap bitmap = device.createBitmap(0, 0, 1024, 1024);
+ XBitmap bitmap = device.createBitmap(0, 0, 1024, 1024);
- byte[] image = bitmap.getDIB();
+ byte[] image = bitmap.getDIB();
- dumpBytes("image", image);
+ dumpBytes("image", image, 0);
- byte[] mask = bitmap.getMaskDIB();
+ if (image[0] != 'B' || image[1] != 'M') {
+ Log.wtf(TAG, "getDIB() didn't return a BMP file");
+ return;
+ }
- dumpBytes("mask", mask);
+ ByteBuffer imagebb = ByteBuffer.wrap(image);
+ imagebb.order(ByteOrder.LITTLE_ENDIAN);
- if (image[0] != 'B' || image[1] != 'M') {
- Log.e(TAG, "getDIB() didn't return a BMP file");
- return;
- }
+ if (imagebb.getInt(0x0e) != 40) {
+ Log.wtf(TAG, "getDIB() didn't return a DIB with BITMAPINFOHEADER");
+ return;
+ }
- ByteBuffer imagebb = ByteBuffer.wrap(image);
- imagebb.order(ByteOrder.LITTLE_ENDIAN);
+ if (imagebb.getShort(0x1c) != 32) {
+ Log.wtf(TAG, "getDIB() didn't return a 32 bpp DIB");
+ return;
+ }
- if (imagebb.getInt(0x0e) != 40) {
- Log.e(TAG, "getDIB() didn't return a DIB with BITMAPINFOHEADER");
- return;
- }
+ if (imagebb.getInt(0x1e) != 3) {
+ Log.wtf(TAG, "getDIB() didn't return a BI_BITFIELDS DIB");
+ return;
+ }
- if (imagebb.getShort(0x1c) != 24) {
- Log.e(TAG, "getDIB() didn't return a 24 bpp DIB");
- return;
- }
+ int offset = imagebb.getInt(0x0a);
+ int width = imagebb.getInt(0x12);
+ int height = imagebb.getInt(0x16);
+
+ Log.i(TAG, String.format("offset: %d (%x), width: %d, height: %d", offset, offset, width, height));
+
+ Bootstrap.force_full_alpha(image, offset, width * height * 4);
- if (imagebb.getInt(0x1e) != 0) {
- Log.e(TAG, "getDIB() didn't return a BI_RGB DIB");
- return;
+ Log.i(TAG, "after force_full_alpha:");
+ dumpBytes("image", image, 0);
+
+ for (int i = offset; i < offset + width * height * 4; i++) {
+ if (image[i] != -1) {
+ int o = offset + (((i-offset) - 4) / 4) * 4;
+ dumpBytes("First non-ones bytes", image, o);
+ o += 160;
+ dumpBytes("...", image, o);
+ o += 160;
+ dumpBytes("...", image, o);
+ o += 160;
+ dumpBytes("...", image, o);
+ break;
}
+ }
- int width = imagebb.getInt(0x12);
- int height = imagebb.getInt(0x16);
+ ImageView imageView = new GestureImageView(this);
+ imageView.setScaleY(-1);
- ByteBuffer argb = ByteBuffer.allocateDirect(width * height * 4);
+ Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ imagebb.position(offset);
- Bootstrap.twiddle_BGR_to_RGBA(image, imagebb.getInt(0x0a), width, height, argb);
+ // Thanks to Android bug 32588, the above is not enough to get the
+ // below copyPixelsFromBuffer() to start copying at offset, it
+ // will (as of Android 4.0.3) copy from position zero anyway. So
+ // instead have to shift (compact) the bloody buffer.
+ imagebb.compact();
- ImageView imageView = new GestureImageView(this);
+ // I don't understand what the compact() documentation says about
+ // the new position; so explicitly put it at zero, in case
+ // runnning on an Android where copyPixelsFromBuffer() *does* take
+ // the position into account.
+ imagebb.position(0);
- Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- bm.copyPixelsFromBuffer(argb);
+ bm.copyPixelsFromBuffer(imagebb);
- imageView.setImageBitmap(bm);
+ imageView.setImageBitmap(bm);
- setContentView(imageView);
- }
+ setContentView(imageView);
}
catch (Exception e) {
e.printStackTrace(System.err);