diff options
-rw-r--r-- | android/Bootstrap/src/org/libreoffice/android/Bootstrap.java | 2 | ||||
-rw-r--r-- | android/experimental/DocumentLoader/Makefile | 2 | ||||
-rw-r--r-- | android/experimental/DocumentLoader/src/org/libreoffice/android/examples/DocumentLoader.java | 195 | ||||
-rw-r--r-- | sal/android/lo-bootstrap.c | 23 | ||||
-rw-r--r-- | vcl/android/androidinst.cxx | 2 | ||||
-rw-r--r-- | vcl/headless/svpbmp.cxx | 1 | ||||
-rw-r--r-- | vcl/headless/svpframe.cxx | 5 | ||||
-rw-r--r-- | vcl/headless/svpvd.cxx | 6 |
8 files changed, 150 insertions, 86 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); diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c index fed7a4d5e271..b6e29baf13e3 100644 --- a/sal/android/lo-bootstrap.c +++ b/sal/android/lo-bootstrap.c @@ -1906,6 +1906,29 @@ Java_org_libreoffice_android_Bootstrap_twiddle_1BGR_1to_1RGBA(JNIEnv* env, } __attribute__ ((visibility("default"))) +void +Java_org_libreoffice_android_Bootstrap_force_1full_1alpha(JNIEnv* env, + jobject clazz, + jbyteArray array, + jint offset, + jint size) +{ + void *a = (*env)->GetPrimitiveArrayCritical(env, array, NULL); + jbyte *p = ((jbyte *) a) + offset; + + int i; + + (void) clazz; + + for (i = 0; i < size; i += 4) { + p[3] = 0xFF; + p += 4; + } + + (*env)->ReleasePrimitiveArrayCritical(env, array, a, 0); +} + +__attribute__ ((visibility("default"))) JavaVM * lo_get_javavm(void) { diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx index 7c0968cd780d..ac08ac5c3926 100644 --- a/vcl/android/androidinst.cxx +++ b/vcl/android/androidinst.cxx @@ -702,7 +702,7 @@ public: sal_uLong nSalFrameStyle, SystemParentData *pSysParent ) : SvpSalFrame( pInstance, pParent, nSalFrameStyle, - true, basebmp::Format::TWENTYFOUR_BIT_TC_MASK, + true, basebmp::Format::THIRTYTWO_BIT_TC_MASK, // FIXME: Or THIRTYTWO_BIT_TC_MASK_ARGB? pSysParent ) { enableDamageTracker(); diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx index d27b7654c56f..f1d8d49f6c66 100644 --- a/vcl/headless/svpbmp.cxx +++ b/vcl/headless/svpbmp.cxx @@ -59,6 +59,7 @@ bool SvpSalBitmap::Create( const Size& rSize, case 16: nFormat = Format::SIXTEEN_BIT_LSB_TC_MASK; break; #endif case 24: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break; + // FIXME: Should this for Android be THIRTYTWO_BIT_TC_MASK_ARGB? case 32: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break; } B2IVector aSize( rSize.Width(), rSize.Height() ); diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx index 63f4a49ac978..208313de99c3 100644 --- a/vcl/headless/svpframe.cxx +++ b/vcl/headless/svpframe.cxx @@ -92,8 +92,13 @@ SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance, m_aSystemChildData.nSize = sizeof( SystemChildData ); #if defined( UNX ) // FIXME: prolly redundant m_aSystemChildData.pSalFrame = this; +#if defined(ANDROID) || defined(IOS) + // We want 32-bit RGBA bitmaps + m_aSystemChildData.nDepth = 32; +#else m_aSystemChildData.nDepth = 24; #endif +#endif if( m_pParent ) m_pParent->m_aChildren.push_back( this ); diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx index 8b90d648d5d5..285eeafc9b15 100644 --- a/vcl/headless/svpvd.cxx +++ b/vcl/headless/svpvd.cxx @@ -80,9 +80,13 @@ sal_Bool SvpSalVirtualDevice::SetSize( long nNewDX, long nNewDY ) #else case 16: nFormat = Format::SIXTEEN_BIT_LSB_TC_MASK; break; #endif - case 0: case 24: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break; case 32: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break; +#if defined(ANDROID) || defined(IOS) + case 0: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break; +#else + case 0: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break; +#endif } m_aDevice = aDevPal.empty() ? createBitmapDevice( aDevSize, false, nFormat ) |