diff options
Diffstat (limited to 'tools/layoutlib/bridge')
25 files changed, 477 insertions, 279 deletions
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk index 80b4d59..0dbdd56 100644 --- a/tools/layoutlib/bridge/Android.mk +++ b/tools/layoutlib/bridge/Android.mk @@ -22,7 +22,6 @@ LOCAL_JAVACFLAGS := -source 6 -target 6 LOCAL_JAVA_LIBRARIES := \ - icu4j \ layoutlib_api-prebuilt \ tools-common-prebuilt diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml index 0baa5ab..d2b1259 100644 --- a/tools/layoutlib/bridge/bridge.iml +++ b/tools/layoutlib/bridge/bridge.iml @@ -24,15 +24,79 @@ </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="icu4j" level="project" /> - <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" /> - <orderEntry type="library" name="ninepatch-prebuilt" level="project" /> - <orderEntry type="library" name="tools-common-prebuilt" level="project" /> - <orderEntry type="library" name="framework.jar" level="project" /> - <orderEntry type="library" scope="TEST" name="kxml2-2.3.0" level="project" /> - <orderEntry type="library" scope="TEST" name="guava" level="project" /> + <orderEntry type="module-library"> + <library name="layoutlib_api-prebuilt"> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" /> + </SOURCES> + </library> + </orderEntry> + <orderEntry type="module-library"> + <library name="ninepatch-prebuilt"> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" /> + </SOURCES> + </library> + </orderEntry> + <orderEntry type="module-library"> + <library name="tools-common-prebuilt"> + <ANNOTATIONS> + <root url="file://$MODULE_DIR$/.." /> + </ANNOTATIONS> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" /> + </SOURCES> + </library> + </orderEntry> + <orderEntry type="module-library"> + <library name="framework.jar"> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$MODULE_DIR$/../../../core/java" /> + <root url="file://$MODULE_DIR$/../../../graphics/java" /> + <root url="file://$MODULE_DIR$/../../../../../libcore/luni/src/main/java" /> + </SOURCES> + </library> + </orderEntry> + <orderEntry type="module-library" scope="TEST"> + <library name="kxml2-2.3.0"> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" /> + </SOURCES> + </library> + </orderEntry> + <orderEntry type="module-library" scope="TEST"> + <library name="guava"> + <CLASSES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" /> + </SOURCES> + </library> + </orderEntry> <orderEntry type="module-library" scope="TEST"> - <library> + <library name="sdk-common"> <CLASSES> <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" /> </CLASSES> diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java index 7d4271b..572fdc9 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java @@ -758,6 +758,17 @@ public final class BridgeTypedArray extends TypedArray { return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false); } + @Override + public int getType(int index) { + if (!hasValue(index)) { + return TypedValue.TYPE_NULL; + } + ResourceValue value = mResourceData[index]; + ResourceType resourceType = value.getResourceType(); + return 0; + // TODO: fixme. + } + /** * Determines whether there is an attribute at <var>index</var>. * diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java index a4a3b7d..21f36ce 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java +++ b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java @@ -19,6 +19,12 @@ package android.graphics; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; +import android.graphics.Paint_Delegate.FontInfo; +import android.icu.lang.UScript; +import android.icu.lang.UScriptRun; +import android.icu.text.Bidi; +import android.icu.text.BidiRun; + import java.awt.Font; import java.awt.Graphics2D; import java.awt.Toolkit; @@ -29,13 +35,6 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import com.ibm.icu.lang.UScript; -import com.ibm.icu.lang.UScriptRun; -import com.ibm.icu.text.Bidi; -import com.ibm.icu.text.BidiRun; - -import android.graphics.Paint_Delegate.FontInfo; - /** * Render the text by breaking it into various scripts and using the right font for each script. * Can be used to measure the text without actually drawing it. diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java index e9b5d6e..af47aeb 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java @@ -23,7 +23,15 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.graphics.Shader.TileMode; +import java.awt.PaintContext; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.awt.image.ColorModel; +import java.awt.image.Raster; /** * Delegate implementing the native methods of android.graphics.BitmapShader @@ -67,9 +75,9 @@ public class BitmapShader_Delegate extends Shader_Delegate { // ---- native methods ---- @LayoutlibDelegate - /*package*/ static long nativeCreate(long native_bitmap, int shaderTileModeX, + /*package*/ static long nativeCreate(Bitmap androidBitmap, int shaderTileModeX, int shaderTileModeY) { - Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap); + Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap); if (bitmap == null) { return 0; } @@ -83,17 +91,17 @@ public class BitmapShader_Delegate extends Shader_Delegate { // ---- Private delegate/helper methods ---- - private BitmapShader_Delegate(java.awt.image.BufferedImage image, + private BitmapShader_Delegate(BufferedImage image, TileMode tileModeX, TileMode tileModeY) { mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY); } private class BitmapShaderPaint implements java.awt.Paint { - private final java.awt.image.BufferedImage mImage; + private final BufferedImage mImage; private final TileMode mTileModeX; private final TileMode mTileModeY; - BitmapShaderPaint(java.awt.image.BufferedImage image, + BitmapShaderPaint(BufferedImage image, TileMode tileModeX, TileMode tileModeY) { mImage = image; mTileModeX = tileModeX; @@ -101,29 +109,24 @@ public class BitmapShader_Delegate extends Shader_Delegate { } @Override - public java.awt.PaintContext createContext( - java.awt.image.ColorModel colorModel, - java.awt.Rectangle deviceBounds, - java.awt.geom.Rectangle2D userBounds, - java.awt.geom.AffineTransform xform, - java.awt.RenderingHints hints) { - - java.awt.geom.AffineTransform canvasMatrix; + public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds, + Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) { + AffineTransform canvasMatrix; try { canvasMatrix = xform.createInverse(); - } catch (java.awt.geom.NoninvertibleTransformException e) { + } catch (NoninvertibleTransformException e) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in BitmapShader", e, null /*data*/); - canvasMatrix = new java.awt.geom.AffineTransform(); + canvasMatrix = new AffineTransform(); } - java.awt.geom.AffineTransform localMatrix = getLocalMatrix(); + AffineTransform localMatrix = getLocalMatrix(); try { localMatrix = localMatrix.createInverse(); - } catch (java.awt.geom.NoninvertibleTransformException e) { + } catch (NoninvertibleTransformException e) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE, "Unable to inverse matrix in BitmapShader", e, null /*data*/); - localMatrix = new java.awt.geom.AffineTransform(); + localMatrix = new AffineTransform(); } if (!colorModel.isCompatibleRaster(mImage.getRaster())) { @@ -134,16 +137,16 @@ public class BitmapShader_Delegate extends Shader_Delegate { return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel); } - private class BitmapShaderContext implements java.awt.PaintContext { + private class BitmapShaderContext implements PaintContext { - private final java.awt.geom.AffineTransform mCanvasMatrix; - private final java.awt.geom.AffineTransform mLocalMatrix; - private final java.awt.image.ColorModel mColorModel; + private final AffineTransform mCanvasMatrix; + private final AffineTransform mLocalMatrix; + private final ColorModel mColorModel; public BitmapShaderContext( - java.awt.geom.AffineTransform canvasMatrix, - java.awt.geom.AffineTransform localMatrix, - java.awt.image.ColorModel colorModel) { + AffineTransform canvasMatrix, + AffineTransform localMatrix, + ColorModel colorModel) { mCanvasMatrix = canvasMatrix; mLocalMatrix = localMatrix; mColorModel = colorModel; @@ -154,13 +157,13 @@ public class BitmapShader_Delegate extends Shader_Delegate { } @Override - public java.awt.image.ColorModel getColorModel() { + public ColorModel getColorModel() { return mColorModel; } @Override - public java.awt.image.Raster getRaster(int x, int y, int w, int h) { - java.awt.image.BufferedImage image = new java.awt.image.BufferedImage( + public Raster getRaster(int x, int y, int w, int h) { + BufferedImage image = new BufferedImage( mColorModel, mColorModel.createCompatibleWritableRaster(w, h), mColorModel.isAlphaPremultiplied(), null); diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index 970b9d0..874bc9d 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -16,6 +16,7 @@ package android.graphics; +import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; @@ -82,6 +83,12 @@ public final class Bitmap_Delegate { return sManager.getDelegate(native_bitmap); } + @Nullable + public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) { + // refSkPixelRef is a hack to get the native pointer: see #nativeRefPixelRef() + return bitmap == null ? null : getDelegate(bitmap.refSkPixelRef()); + } + /** * Creates and returns a {@link Bitmap} initialized with the given file content. * @@ -180,18 +187,7 @@ public final class Bitmap_Delegate { return createBitmap(delegate, createFlags, density.getDpiValue()); } - public static int getBufferedImageType(int nativeBitmapConfig) { - switch (Config.nativeToConfig(nativeBitmapConfig)) { - case ALPHA_8: - return BufferedImage.TYPE_INT_ARGB; - case RGB_565: - return BufferedImage.TYPE_INT_ARGB; - case ARGB_4444: - return BufferedImage.TYPE_INT_ARGB; - case ARGB_8888: - return BufferedImage.TYPE_INT_ARGB; - } - + private static int getBufferedImageType() { return BufferedImage.TYPE_INT_ARGB; } @@ -218,10 +214,6 @@ public final class Bitmap_Delegate { return mHasAlpha && mConfig != Config.RGB_565; } - public boolean hasMipMap() { - // TODO: check if more checks are required as in hasAlpha. - return mHasMipMap; - } /** * Update the generationId. * @@ -236,7 +228,7 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width, int height, int nativeConfig, boolean isMutable) { - int imageType = getBufferedImageType(nativeConfig); + int imageType = getBufferedImageType(); // create the image BufferedImage image = new BufferedImage(width, height, imageType); @@ -264,7 +256,7 @@ public final class Bitmap_Delegate { int width = srcImage.getWidth(); int height = srcImage.getHeight(); - int imageType = getBufferedImageType(nativeConfig); + int imageType = getBufferedImageType(); // create the image BufferedImage image = new BufferedImage(width, height, imageType); @@ -353,22 +345,16 @@ public final class Bitmap_Delegate { /*package*/ static boolean nativeHasAlpha(long nativeBitmap) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); - if (delegate == null) { - return true; - } + return delegate == null || delegate.mHasAlpha; - return delegate.mHasAlpha; } @LayoutlibDelegate /*package*/ static boolean nativeHasMipMap(long nativeBitmap) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); - if (delegate == null) { - return true; - } + return delegate == null || delegate.mHasMipMap; - return delegate.mHasMipMap; } @LayoutlibDelegate @@ -489,11 +475,6 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static void nativePrepareToDraw(long nativeBitmap) { - // nothing to be done here. - } - - @LayoutlibDelegate /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); @@ -579,6 +560,14 @@ public final class Bitmap_Delegate { return Arrays.equals(argb1, argb2); } + // Only used by AssetAtlasService, which we don't care about. + @LayoutlibDelegate + /*package*/ static long nativeRefPixelRef(long nativeBitmap) { + // Hack: This is called by Bitmap.refSkPixelRef() and LayoutLib uses that method to get + // the native pointer from a Bitmap. So, we return nativeBitmap here. + return nativeBitmap; + } + // ---- Private delegate/helper methods ---- private Bitmap_Delegate(BufferedImage image, Config config) { diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java index e1091f0..47acc42 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java @@ -16,6 +16,7 @@ package android.graphics; +import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; @@ -114,7 +115,11 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static long initRaster(long nativeBitmapOrZero) { + /*package*/ static long initRaster(@Nullable Bitmap bitmap) { + long nativeBitmapOrZero = 0; + if (bitmap != null) { + nativeBitmapOrZero = bitmap.refSkPixelRef(); + } if (nativeBitmapOrZero > 0) { // get the Bitmap from the int Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero); @@ -132,8 +137,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ - static void native_setBitmap(long canvas, long bitmap, boolean copyState) { + /*package*/ static void native_setBitmap(long canvas, Bitmap bitmap) { Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas); Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap); if (canvasDelegate == null || bitmapDelegate==null) { @@ -427,8 +431,7 @@ public final class Canvas_Delegate { canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter); - if (canvasDelegate.mDrawFilter != null && - canvasDelegate.mDrawFilter.isSupported() == false) { + if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER, canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/); } @@ -444,7 +447,7 @@ public final class Canvas_Delegate { } Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds(); - if (rect != null && rect.isEmpty() == false) { + if (rect != null && !rect.isEmpty()) { bounds.left = rect.x; bounds.top = rect.y; bounds.right = rect.x + rect.width; @@ -720,7 +723,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap, + /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap, float left, float top, long nativePaintOrZero, int canvasDensity, @@ -742,7 +745,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap, + /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity) { @@ -783,7 +786,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, long nBitmap, + /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap, long nMatrix, long nPaint) { // get the delegate from the native int. Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas); @@ -795,7 +798,7 @@ public final class Canvas_Delegate { Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint); // get the delegate from the native int. - Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap); + Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap); if (bitmapDelegate == null) { return; } @@ -824,7 +827,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeDrawBitmapMesh(long nCanvas, long nBitmap, + /*package*/ static void nativeDrawBitmapMesh(long nCanvas, Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, long nPaint) { // FIXME @@ -1041,8 +1044,7 @@ public final class Canvas_Delegate { } /** - * Restores the {@link GcSnapshot} to <var>saveCount</var> - * @param saveCount the saveCount + * Restores the top {@link GcSnapshot} */ private void restore() { mSnapshot = mSnapshot.restore(); @@ -1105,7 +1107,7 @@ public final class Canvas_Delegate { // before drawing it. if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) { fixAlpha8Bitmap(image); - } else if (bitmap.hasAlpha() == false) { + } else if (!bitmap.hasAlpha()) { // hasAlpha is merely a rendering hint. There can in fact be alpha values // in the bitmap but it should be ignored at drawing time. // There is two ways to do this: @@ -1125,7 +1127,7 @@ public final class Canvas_Delegate { } // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB - if (forceSrcMode[0] == false) { + if (!forceSrcMode[0]) { image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF); } } diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java index e16dbda..e8d34d0 100644 --- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java @@ -90,7 +90,7 @@ public final class NinePatch_Delegate { if (oos != null) { try { oos.close(); - } catch (IOException e) { + } catch (IOException ignored) { } } } @@ -136,7 +136,7 @@ public final class NinePatch_Delegate { if (ois != null) { try { ois.close(); - } catch (IOException e) { + } catch (IOException ignored) { } } } @@ -150,15 +150,12 @@ public final class NinePatch_Delegate { @LayoutlibDelegate /*package*/ static boolean isNinePatchChunk(byte[] chunk) { NinePatchChunk chunkObject = getChunk(chunk); - if (chunkObject != null) { - return true; - } + return chunkObject != null; - return false; } @LayoutlibDelegate - /*package*/ static long validateNinePatchChunk(long bitmap, byte[] chunk) { + /*package*/ static long validateNinePatchChunk(byte[] chunk) { // the default JNI implementation only checks that the byte[] has the same // size as the C struct it represent. Since we cannot do the same check (serialization // will return different size depending on content), we do nothing. @@ -173,7 +170,7 @@ public final class NinePatch_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeDraw(long canvas_instance, RectF loc, long bitmap_instance, + /*package*/ static void nativeDraw(long canvas_instance, RectF loc, Bitmap bitmap_instance, long chunk, long paint_instance_or_null, int destDensity, int srcDensity) { draw(canvas_instance, (int) loc.left, (int) loc.top, (int) loc.right, (int) loc.bottom, @@ -182,7 +179,7 @@ public final class NinePatch_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeDraw(long canvas_instance, Rect loc, long bitmap_instance, + /*package*/ static void nativeDraw(long canvas_instance, Rect loc, Bitmap bitmap_instance, long chunk, long paint_instance_or_null, int destDensity, int srcDensity) { draw(canvas_instance, loc.left, loc.top, loc.right, loc.bottom, @@ -191,7 +188,7 @@ public final class NinePatch_Delegate { } @LayoutlibDelegate - /*package*/ static long nativeGetTransparentRegion(long bitmap, long chunk, Rect location) { + /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) { return 0; } @@ -199,7 +196,7 @@ public final class NinePatch_Delegate { private static void draw(long canvas_instance, final int left, final int top, final int right, final int bottom, - long bitmap_instance, long chunk, long paint_instance_or_null, + Bitmap bitmap_instance, long chunk, long paint_instance_or_null, final int destDensity, final int srcDensity) { // get the delegate from the native int. final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance); diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java index 0c8c0d6..a2e9a85 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java @@ -16,6 +16,8 @@ package android.graphics; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; @@ -83,6 +85,8 @@ public class Paint_Delegate { private float mTextScaleX; private float mTextSkewX; private int mHintingMode = Paint.HINTING_ON; + private int mHyphenEdit; + private float mLetterSpacing; // not used in actual text rendering. // Variant of the font. A paint's variant can only be compact or elegant. private FontVariant mFontVariant = FontVariant.COMPACT; @@ -100,6 +104,7 @@ public class Paint_Delegate { // ---- Public Helper methods ---- + @Nullable public static Paint_Delegate getDelegate(long native_paint) { return sManager.getDelegate(native_paint); } @@ -1088,18 +1093,107 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static float native_getLetterSpacing(long nativePaint) { - // TODO: throw a fidelity warning. - return 0; + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return 0; + } + return delegate.mLetterSpacing; } @LayoutlibDelegate /*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) { - // pass. + Bridge.getLog().fidelityWarning("textRendering", "Paint.setLetterSpacing() not supported.", + null, null); + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return; + } + delegate.mLetterSpacing = letterSpacing; } @LayoutlibDelegate /*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) { - // pass. + Bridge.getLog().fidelityWarning("textRendering", + "Paint.setFontFeatureSettings() not supported.", null, null); + } + + @LayoutlibDelegate + /*package*/ static int native_getHyphenEdit(long nativePaint) { + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return 0; + } + return delegate.mHyphenEdit; + } + + @LayoutlibDelegate + /*package*/ static void native_setHyphenEdit(long nativePaint, int hyphen) { + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return; + } + delegate.mHyphenEdit = hyphen; + } + + @LayoutlibDelegate + /*package*/ static boolean native_hasGlyph(long nativePaint, long nativeTypeface, int bidiFlags, + String string) { + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return false; + } + if (string.length() == 0) { + return false; + } + if (string.length() > 1) { + Bridge.getLog().fidelityWarning("textRendering", + "Paint.hasGlyph() is not supported for ligatures.", null, null); + return false; + } + assert nativeTypeface == delegate.mNativeTypeface; + Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface); + + char c = string.charAt(0); + for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) { + if (font.canDisplay(c)) { + return true; + } + } + return false; + } + + + @LayoutlibDelegate + /*package*/ static float native_getRunAdvance(long nativePaint, long nativeTypeface, + @NonNull char[] text, int start, int end, int contextStart, int contextEnd, + boolean isRtl, int offset) { + int count = end - start; + float[] advances = new float[count]; + native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count, + contextStart, contextEnd - contextStart, isRtl, advances, 0); + float sum = 0; + for (int i = 0; i < offset; i++) { + sum += advances[i]; + } + return sum; + } + + @LayoutlibDelegate + /*package*/ static int native_getOffsetForAdvance(long nativePaint, long nativeTypeface, + char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl, + float advance) { + int count = end - start; + float[] advances = new float[count]; + native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count, + contextStart, contextEnd - contextStart, isRtl, advances, 0); + float sum = 0; + int i; + for (i = 0; i < count && sum < advance; i++) { + sum += advances[i]; + } + float distanceToI = sum - advance; + float distanceToIMinus1 = advance - (sum - advances[i]); + return distanceToI > distanceToIMinus1 ? i : i - 1; } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java index 14e9960..0d491a0 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java @@ -81,14 +81,15 @@ public abstract class Shader_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) { + /*package*/ static long nativeSetLocalMatrix(long native_shader, long matrix_instance) { // get the delegate from the native int. Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader); if (shaderDelegate == null) { - return; + return native_shader; } shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance); + return native_shader; } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java index 6247dae..38171dc 100644 --- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java +++ b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java @@ -19,8 +19,8 @@ package android.text; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import com.ibm.icu.text.Bidi; +import android.icu.text.Bidi; /** * Delegate used to provide new implementation for the native methods of {@link AndroidBidi} diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java index c72efc2..b95cda6 100644 --- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java +++ b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java @@ -36,7 +36,7 @@ public class GreedyLineBreaker extends LineBreaker { } @Override - public void computeBreaks(LineBreaks lineBreaks) { + public void computeBreaks(@NonNull LineBreaks lineBreaks) { BreakInfo breakInfo = new BreakInfo(); int lineNum = 0; float width = 0, printedWidth = 0; diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java new file mode 100644 index 0000000..5a59597 --- /dev/null +++ b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.text; + +import com.android.layoutlib.bridge.impl.DelegateManager; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +import java.io.File; + +/** + * Delegate that overrides implementation for certain methods in {@link android.text.StaticLayout} + * <p/> + * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced + * by calls to methods of the same name in this delegate class. + */ +public class Hyphenator_Delegate { + + private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new + DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class); + + @LayoutlibDelegate + /*package*/ static File getSystemHyphenatorLocation() { + // FIXME + return null; + } + + /*package*/ static long loadHyphenator(String patternData) { + return sDelegateManager.addNewDelegate(new Hyphenator_Delegate()); + } +} diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java index 54445a4..edeef78 100644 --- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java +++ b/tools/layoutlib/bridge/src/android/text/LineBreaker.java @@ -39,6 +39,5 @@ public abstract class LineBreaker { mTabStops = tabStops; } - @NonNull public abstract void computeBreaks(@NonNull LineBreaks breakInfo); } diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java index 86d8da3..7971902 100644 --- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java +++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java @@ -8,15 +8,15 @@ import android.graphics.BidiRenderer; import android.graphics.Paint; import android.graphics.Paint_Delegate; import android.graphics.RectF; -import android.text.StaticLayout.LineBreaks; +import android.icu.text.BreakIterator; +import android.icu.util.ULocale; import android.text.Primitive.PrimitiveType; +import android.text.StaticLayout.LineBreaks; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.util.ULocale; import javax.swing.text.Segment; /** @@ -38,15 +38,55 @@ public class StaticLayout_Delegate { new DelegateManager<Builder>(Builder.class); @LayoutlibDelegate - /*package*/ static int nComputeLineBreaks(long nativeBuilder, - int length, float firstWidth, int firstWidthLineCount, float restWidth, - int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle, - int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength) { + /*package*/ static long nNewBuilder() { + return sBuilderManager.addNewDelegate(new Builder()); + } + + @LayoutlibDelegate + /*package*/ static void nFreeBuilder(long nativeBuilder) { + sBuilderManager.removeJavaReferenceFor(nativeBuilder); + } + + @LayoutlibDelegate + /*package*/ static void nFinishBuilder(long nativeBuilder) { + } + @LayoutlibDelegate + /*package*/ static long nLoadHyphenator(String patternData) { + return Hyphenator_Delegate.loadHyphenator(patternData); + } + + @LayoutlibDelegate + /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) { Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder != null) { + builder.mLocale = locale; + builder.mNativeHyphenator = nativeHyphenator; + } + } + + @LayoutlibDelegate + /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) { + // TODO. + } + + @LayoutlibDelegate + /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length, + float firstWidth, int firstWidthLineCount, float restWidth, + int[] variableTabStops, int defaultTabStop, int breakStrategy, + int hyphenationFrequency) { + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder == null) { + return; + } + + builder.mText = text; + builder.mWidths = new float[length]; + // compute all possible breakpoints. BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale)); it.setText(new Segment(builder.mText, 0, length)); + // average word length in english is 5. So, initialize the possible breaks with a guess. List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d)); int loc; @@ -54,17 +94,73 @@ public class StaticLayout_Delegate { while ((loc = it.next()) != BreakIterator.DONE) { breaks.add(loc); } - LineWidth lineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth); TabStops tabStopCalculator = new TabStops(variableTabStops, defaultTabStop); - List<Primitive> primitives = computePrimitives(builder.mText, builder.mWidths, length, breaks); - LineBreaker lineBreaker; - if (optimize) { - lineBreaker = new OptimizingLineBreaker(primitives, lineWidth, tabStopCalculator); - } else { - lineBreaker = new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator); + List<Primitive> primitives = + computePrimitives(builder.mText, builder.mWidths, length, breaks); + BreakStrategy strategy = BreakStrategy.getStrategy(breakStrategy); + switch (strategy) { + case GREEDY: + builder.mLineBreaker = + new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator); + break; + case HIGH_QUALITY: + // TODO + break; + case BALANCED: + builder.mLineBreaker = new OptimizingLineBreaker(primitives, lineWidth, + tabStopCalculator); + break; + } + } + + @LayoutlibDelegate + /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface, + int start, int end, boolean isRtl) { + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + + int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR; + return builder == null ? 0 : + measureText(nativePaint, builder.mText, start, end - start, builder.mWidths, + bidiFlags); + } + + @LayoutlibDelegate + /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) { + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder != null) { + System.arraycopy(widths, start, builder.mWidths, start, end - start); + } + } + + @LayoutlibDelegate + /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) { + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder == null) { + return; + } + builder.mWidths[start] = width; + Arrays.fill(builder.mWidths, start + 1, end, 0.0f); + } + + @LayoutlibDelegate + /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) { + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder != null) { + System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length); } - lineBreaker.computeBreaks(recycle); + } + + @LayoutlibDelegate + /*package*/ static int nComputeLineBreaks(long nativeBuilder, + LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths, + int[] recycleFlags, int recycleLength) { + + Builder builder = sBuilderManager.getDelegate(nativeBuilder); + if (builder == null) { + return 0; + } + builder.mLineBreaker.computeBreaks(recycle); return recycle.breaks.length; } @@ -109,63 +205,6 @@ public class StaticLayout_Delegate { return primitives; } - @LayoutlibDelegate - /*package*/ static long nNewBuilder() { - return sBuilderManager.addNewDelegate(new Builder()); - } - - @LayoutlibDelegate - /*package*/ static void nFinishBuilder(long nativeBuilder) { - } - - @LayoutlibDelegate - /*package*/ static void nFreeBuilder(long nativeBuilder) { - sBuilderManager.removeJavaReferenceFor(nativeBuilder); - } - - @LayoutlibDelegate - /*package*/ static void nSetLocale(long nativeBuilder, String locale) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - builder.mLocale = locale; - } - - @LayoutlibDelegate - /*package*/ static void nSetText(long nativeBuilder, char[] text, int length) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - builder.mText = text; - builder.mWidths = new float[length]; - } - - - @LayoutlibDelegate - /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface, - int start, int end, boolean isRtl) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - - int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR; - return measureText(nativePaint, builder.mText, start, end - start, builder.mWidths, bidiFlags); - } - - - @LayoutlibDelegate - /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - System.arraycopy(widths, start, builder.mWidths, start, end - start); - } - - @LayoutlibDelegate - /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - builder.mWidths[start] = width; - Arrays.fill(builder.mWidths, start + 1, end, 0.0f); - } - - @LayoutlibDelegate - /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) { - Builder builder = sBuilderManager.getDelegate(nativeBuilder); - System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length); - } - private static float measureText(long nativePaint, char []text, int index, int count, float[] widths, int bidiFlags) { Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint); @@ -174,12 +213,32 @@ public class StaticLayout_Delegate { return bounds.right - bounds.left; } + // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker. /** * Java representation of the native Builder class. */ - static class Builder { + private static class Builder { String mLocale; char[] mText; float[] mWidths; + LineBreaker mLineBreaker; + long mNativeHyphenator; + } + + private enum BreakStrategy { + GREEDY, HIGH_QUALITY, BALANCED; + + static BreakStrategy getStrategy(int strategy) { + switch (strategy) { + case 0: + return GREEDY; + case 1: + return HIGH_QUALITY; + case 2: + return BALANCED; + default: + throw new AssertionError("Unknown break strategy: " + strategy); + } + } } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index c6d60f8..af67a43 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -16,9 +16,6 @@ package com.android.layoutlib.bridge; -import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; -import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; - import com.android.annotations.NonNull; import com.android.ide.common.rendering.api.Capability; import com.android.ide.common.rendering.api.DrawableParams; @@ -36,13 +33,12 @@ import com.android.resources.ResourceType; import com.android.tools.layoutlib.create.MethodAdapter; import com.android.tools.layoutlib.create.OverrideMethod; import com.android.util.Pair; -import com.ibm.icu.util.ULocale; -import libcore.io.MemoryMappedFile_Delegate; import android.content.res.BridgeAssetManager; import android.graphics.Bitmap; import android.graphics.FontFamily_Delegate; import android.graphics.Typeface_Delegate; +import android.icu.util.ULocale; import android.os.Looper; import android.os.Looper_Accessor; import android.view.View; @@ -60,6 +56,11 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; +import libcore.io.MemoryMappedFile_Delegate; + +import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; +import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; + /** * Main entry point of the LayoutLib Bridge. * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java index ea5f1ea..e589d9e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java @@ -16,9 +16,9 @@ package com.android.layoutlib.bridge.android; -import java.util.Locale; +import android.icu.util.ULocale; -import com.ibm.icu.util.ULocale; +import java.util.Locale; /** * This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java index 261cc98..dbee9ea 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.impl; +import com.android.annotations.Nullable; import com.android.layoutlib.bridge.util.Debug; import com.android.layoutlib.bridge.util.SparseWeakArray; @@ -48,7 +49,7 @@ import java.util.List; * int -> Delegate class link. * * Native methods usually always have the int as parameters. The first thing the delegate method - * will do is call {@link #getDelegate(int)} to get the Java object matching the int. + * will do is call {@link #getDelegate(long)} to get the Java object matching the int. * * Typical native init methods are returning a new int back to the Java class, so * {@link #addNewDelegate(Object)} does the same. @@ -57,7 +58,7 @@ import java.util.List; * the Java object needs to count as a reference (even though it only holds an int), we use the * following mechanism: * - * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes + * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes * the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming * the delegate. * @@ -70,12 +71,13 @@ import java.util.List; * @param <T> the delegate class to manage */ public final class DelegateManager<T> { + @SuppressWarnings("FieldCanBeLocal") private final Class<T> mClass; private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>(); /** list used to store delegates when their main object holds a reference to them. * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed * @see #addNewDelegate(Object) - * @see #removeJavaReferenceFor(int) + * @see #removeJavaReferenceFor(long) */ private final List<T> mJavaReferences = new ArrayList<T>(); private int mDelegateCounter = 0; @@ -94,6 +96,7 @@ public final class DelegateManager<T> { * @param native_object the native int. * @return the delegate or null if not found. */ + @Nullable public T getDelegate(long native_object) { if (native_object > 0) { T delegate = mDelegates.get(native_object); diff --git a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java deleted file mode 100644 index d94c205..0000000 --- a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package libcore.icu; - -import java.text.FieldPosition; - -import com.android.ide.common.rendering.api.LayoutLog; -import com.android.layoutlib.bridge.Bridge; -import com.android.layoutlib.bridge.impl.DelegateManager; -import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import com.ibm.icu.text.DateIntervalFormat; -import com.ibm.icu.util.DateInterval; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; - -public class DateIntervalFormat_Delegate { - - // ---- delegate manager ---- - private static final DelegateManager<DateIntervalFormat_Delegate> sManager = - new DelegateManager<DateIntervalFormat_Delegate>(DateIntervalFormat_Delegate.class); - - // ---- delegate data ---- - private DateIntervalFormat mFormat; - - - // ---- native methods ---- - - @LayoutlibDelegate - /*package*/static String formatDateInterval(long address, long fromDate, long toDate) { - DateIntervalFormat_Delegate delegate = sManager.getDelegate((int)address); - if (delegate == null) { - Bridge.getLog().error(LayoutLog.TAG_BROKEN, - "Unable for find native DateIntervalFormat", null); - return null; - } - DateInterval interval = new DateInterval(fromDate, toDate); - StringBuffer sb = new StringBuffer(); - FieldPosition pos = new FieldPosition(0); - delegate.mFormat.format(interval, sb, pos); - return sb.toString(); - } - - @LayoutlibDelegate - /*package*/ static long createDateIntervalFormat(String skeleton, String localeName, - String tzName) { - TimeZone prevDefaultTz = TimeZone.getDefault(); - TimeZone.setDefault(TimeZone.getTimeZone(tzName)); - DateIntervalFormat_Delegate newDelegate = new DateIntervalFormat_Delegate(); - newDelegate.mFormat = - DateIntervalFormat.getInstance(skeleton, new ULocale(localeName)); - TimeZone.setDefault(prevDefaultTz); - return sManager.addNewDelegate(newDelegate); - } - - @LayoutlibDelegate - /*package*/ static void destroyDateIntervalFormat(long address) { - sManager.removeJavaReferenceFor((int)address); - } - -} diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java index b8b5fed..a6cbe56 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java @@ -17,9 +17,10 @@ package libcore.icu; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; -import com.ibm.icu.text.DateTimePatternGenerator; -import com.ibm.icu.util.Currency; -import com.ibm.icu.util.ULocale; + +import android.icu.text.DateTimePatternGenerator; +import android.icu.util.Currency; +import android.icu.util.ULocale; import java.util.Locale; @@ -252,4 +253,9 @@ public class ICU_Delegate { /*package*/ static String getDefaultLocale() { return ICU.getDefaultLocale(); } + + @LayoutlibDelegate + /*package*/ static String getTZDataVersion() { + return ICU.getTZDataVersion(); + } } diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk index 11390c3..5eef24a 100644 --- a/tools/layoutlib/bridge/tests/Android.mk +++ b/tools/layoutlib/bridge/tests/Android.mk @@ -26,7 +26,6 @@ LOCAL_MODULE_TAGS := optional LOCAL_JAVA_LIBRARIES := layoutlib \ kxml2-2.3.0 \ - icu4j \ layoutlib_api-prebuilt \ tools-common-prebuilt \ sdk-common \ diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png Binary files differindex c9b76be..cb72550 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java index 8b362ec..d8937f4 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java @@ -192,12 +192,12 @@ public class TestDelegates extends TestCase { StringBuilder sb = new StringBuilder(method.getName() + "("); for (int j = 0; j < parameters.length; j++) { Class<?> theClass = parameters[j]; - sb.append(theClass.getName()); int dimensions = 0; while (theClass.isArray()) { dimensions++; theClass = theClass.getComponentType(); } + sb.append(theClass.getName()); for (int i = 0; i < dimensions; i++) { sb.append("[]"); } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java index d87c99f..509f5eb 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java @@ -40,7 +40,7 @@ import static org.junit.Assert.assertEquals; public class BridgeXmlBlockParserTest { @BeforeClass - public void setUp() { + public static void setUp() { ParserFactory.setLayoutlibCallback(new LayoutlibTestCallback()); } @@ -128,7 +128,7 @@ public class BridgeXmlBlockParserTest { } @AfterClass - public void tearDown() { + public static void tearDown() { ParserFactory.setLayoutlibCallback(null); } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index bd467ef..91be0bd 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -17,6 +17,7 @@ package com.android.layoutlib.bridge.intensive; import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; @@ -364,13 +365,14 @@ public class Main { } @Override - public void fidelityWarning(String tag, String message, Throwable throwable, - Object data) { + public void fidelityWarning(@Nullable String tag, String message, + Throwable throwable, Object data) { + System.out.println("FidelityWarning " + tag + ": " + message); if (throwable != null) { throwable.printStackTrace(); } - failWithMsg(message); + failWithMsg(message == null ? "" : message); } @Override @@ -396,11 +398,11 @@ public class Main { if (sLogger == null) { sLogger = new ILogger() { @Override - public void error(Throwable t, String msgFormat, Object... args) { + public void error(Throwable t, @Nullable String msgFormat, Object... args) { if (t != null) { t.printStackTrace(); } - failWithMsg(msgFormat, args); + failWithMsg(msgFormat == null ? "" : msgFormat, args); } @Override |