LayoutLib: fix XmlUtils.convertValueToInt
It looks like the device implementation of Integer.parseInt
is able to handle converting hexa value > 80000000 while the
desktop VM cannot.
This patch provide a fix for this.
While implementing it and running the TestDegates test I realized
that some delegate methods for Region were mising, so this adds them
too.
Change-Id: Ifee1efd47c8c52adc2f4658ec4fc8bd55adb84b4
diff --git a/bridge/src/android/graphics/Region_Delegate.java b/bridge/src/android/graphics/Region_Delegate.java
index bc13b52..33c2aed 100644
--- a/bridge/src/android/graphics/Region_Delegate.java
+++ b/bridge/src/android/graphics/Region_Delegate.java
@@ -135,6 +135,123 @@
// ---- native methods ----
+ /*package*/ static boolean isEmpty(Region thisRegion) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return true;
+ }
+
+ return regionDelegate.mArea.isEmpty();
+ }
+
+ /*package*/ static boolean isRect(Region thisRegion) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return true;
+ }
+
+ return regionDelegate.mArea.isRectangular();
+ }
+
+ /*package*/ static boolean isComplex(Region thisRegion) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return true;
+ }
+
+ return regionDelegate.mArea.isSingular() == false;
+ }
+
+ /*package*/ static boolean contains(Region thisRegion, int x, int y) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return false;
+ }
+
+ return regionDelegate.mArea.contains(x, y);
+ }
+
+ /*package*/ static boolean quickContains(Region thisRegion,
+ int left, int top, int right, int bottom) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return false;
+ }
+
+ return regionDelegate.mArea.isRectangular() &&
+ regionDelegate.mArea.contains(left, top, right - left, bottom - top);
+ }
+
+ /*package*/ static boolean quickReject(Region thisRegion,
+ int left, int top, int right, int bottom) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return false;
+ }
+
+ return regionDelegate.mArea.isEmpty() ||
+ regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
+ }
+
+ /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return false;
+ }
+
+ Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
+ if (targetRegionDelegate == null) {
+ return false;
+ }
+
+ return regionDelegate.mArea.isEmpty() ||
+ regionDelegate.mArea.getBounds().intersects(
+ targetRegionDelegate.mArea.getBounds()) == false;
+
+ }
+
+ /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return;
+ }
+
+ Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
+ if (targetRegionDelegate == null) {
+ return;
+ }
+
+ if (regionDelegate.mArea.isEmpty()) {
+ targetRegionDelegate.mArea = new Area();
+ } else {
+ targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
+ AffineTransform mtx = new AffineTransform();
+ mtx.translate(dx, dy);
+ targetRegionDelegate.mArea.transform(mtx);
+ }
+ }
+
+ /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
+ Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+ if (regionDelegate == null) {
+ return;
+ }
+
+ Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
+ if (targetRegionDelegate == null) {
+ return;
+ }
+
+ if (regionDelegate.mArea.isEmpty()) {
+ targetRegionDelegate.mArea = new Area();
+ } else {
+ targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
+ AffineTransform mtx = new AffineTransform();
+ mtx.scale(scale, scale);
+ targetRegionDelegate.mArea.transform(mtx);
+ }
+ }
+
/*package*/ static int nativeConstructor() {
Region_Delegate newDelegate = new Region_Delegate();
return sManager.addDelegate(newDelegate);
diff --git a/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
new file mode 100644
index 0000000..84a90cd
--- /dev/null
+++ b/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 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 com.android.internal.util;
+
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
+ *
+ * Through the layoutlib_create tool, the original methods of XmlUtils have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class XmlUtils_Delegate {
+ /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
+ if (null == charSeq)
+ return defaultValue;
+
+ String nm = charSeq.toString();
+
+ // This code is copied from the original implementation. The issue is that
+ // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
+ // is > 80000000 but the Java VM cannot.
+
+ int value;
+ int sign = 1;
+ int index = 0;
+ int len = nm.length();
+ int base = 10;
+
+ if ('-' == nm.charAt(0)) {
+ sign = -1;
+ index++;
+ }
+
+ if ('0' == nm.charAt(index)) {
+ // Quick check for a zero by itself
+ if (index == (len - 1))
+ return 0;
+
+ char c = nm.charAt(index + 1);
+
+ if ('x' == c || 'X' == c) {
+ index += 2;
+ base = 16;
+ } else {
+ index++;
+ base = 8;
+ }
+ }
+ else if ('#' == nm.charAt(index))
+ {
+ index++;
+ base = 16;
+
+ return ((int)Long.parseLong(nm.substring(index), base)) * sign;
+ }
+
+ return Integer.parseInt(nm.substring(index), base) * sign;
+ }
+}