Merge pull request #85 from NativeScript/clip-path-density

Use density for clip-path calculations
This commit is contained in:
Alexander Vakrilov
2017-02-21 14:18:28 +02:00
committed by GitHub

View File

@@ -70,7 +70,7 @@ public class BorderDrawable extends ColorDrawable {
} }
public int getUniformBorderColor() { public int getUniformBorderColor() {
if (this.hasUniformBorderColor()){ if (this.hasUniformBorderColor()) {
return this.borderTopColor; return this.borderTopColor;
} }
@@ -94,7 +94,7 @@ public class BorderDrawable extends ColorDrawable {
} }
public float getUniformBorderWidth() { public float getUniformBorderWidth() {
if (this.hasUniformBorderWidth()){ if (this.hasUniformBorderWidth()) {
return this.borderTopWidth; return this.borderTopWidth;
} }
@@ -118,7 +118,7 @@ public class BorderDrawable extends ColorDrawable {
} }
public float getUniformBorderRadius() { public float getUniformBorderRadius() {
if (this.hasUniformBorderRadius()){ if (this.hasUniformBorderRadius()) {
return this.borderTopLeftRadius; return this.borderTopLeftRadius;
} }
@@ -150,37 +150,37 @@ public class BorderDrawable extends ColorDrawable {
} }
public boolean hasUniformBorderColor() { public boolean hasUniformBorderColor() {
return this.borderTopColor == this.borderRightColor && return this.borderTopColor == this.borderRightColor &&
this.borderTopColor == this.borderBottomColor && this.borderTopColor == this.borderBottomColor &&
this.borderTopColor == this.borderLeftColor; this.borderTopColor == this.borderLeftColor;
} }
public boolean hasUniformBorderWidth() { public boolean hasUniformBorderWidth() {
return this.borderTopWidth == this.borderRightWidth && return this.borderTopWidth == this.borderRightWidth &&
this.borderTopWidth == this.borderBottomWidth && this.borderTopWidth == this.borderBottomWidth &&
this.borderTopWidth == this.borderLeftWidth; this.borderTopWidth == this.borderLeftWidth;
} }
public boolean hasUniformBorderRadius() { public boolean hasUniformBorderRadius() {
return this.borderTopLeftRadius == this.borderTopRightRadius && return this.borderTopLeftRadius == this.borderTopRightRadius &&
this.borderTopLeftRadius == this.borderBottomRightRadius && this.borderTopLeftRadius == this.borderBottomRightRadius &&
this.borderTopLeftRadius == this.borderBottomLeftRadius; this.borderTopLeftRadius == this.borderBottomLeftRadius;
} }
public boolean hasUniformBorder(){ public boolean hasUniformBorder() {
return this.hasUniformBorderColor() && return this.hasUniformBorderColor() &&
this.hasUniformBorderWidth() && this.hasUniformBorderWidth() &&
this.hasUniformBorderRadius(); this.hasUniformBorderRadius();
} }
public BorderDrawable(float density){ public BorderDrawable(float density) {
super(); super();
this.density = 1f; this.density = density;
} }
public BorderDrawable(float density, String id){ public BorderDrawable(float density, String id) {
super(); super();
this.density = 1f; this.density = density;
this.id = id; this.id = id;
} }
@@ -195,7 +195,7 @@ public class BorderDrawable extends ColorDrawable {
String backgroundPosition, String backgroundPosition,
CSSValue[] backgroundPositionParsedCSSValues, CSSValue[] backgroundPositionParsedCSSValues,
String backgroundSize, String backgroundSize,
CSSValue[] backgroundSizeParsedCSSValues){ CSSValue[] backgroundSizeParsedCSSValues) {
this.refresh( this.refresh(
borderColor, borderColor,
borderColor, borderColor,
@@ -247,7 +247,7 @@ public class BorderDrawable extends ColorDrawable {
String backgroundPosition, String backgroundPosition,
CSSValue[] backgroundPositionParsedCSSValues, CSSValue[] backgroundPositionParsedCSSValues,
String backgroundSize, String backgroundSize,
CSSValue[] backgroundSizeParsedCSSValues){ CSSValue[] backgroundSizeParsedCSSValues) {
this.borderTopColor = borderTopColor; this.borderTopColor = borderTopColor;
this.borderRightColor = borderRightColor; this.borderRightColor = borderRightColor;
@@ -285,10 +285,10 @@ public class BorderDrawable extends ColorDrawable {
return; return;
} }
float topBackoffAntialias = calculateBackoffAntialias(this.borderTopColor, this.borderTopWidth, this.density); float topBackoffAntialias = calculateBackoffAntialias(this.borderTopColor, this.borderTopWidth);
float rightBackoffAntialias = calculateBackoffAntialias(this.borderRightColor, this.borderRightWidth, this.density); float rightBackoffAntialias = calculateBackoffAntialias(this.borderRightColor, this.borderRightWidth);
float bottomBackoffAntialias = calculateBackoffAntialias(this.borderBottomColor, this.borderBottomWidth, this.density); float bottomBackoffAntialias = calculateBackoffAntialias(this.borderBottomColor, this.borderBottomWidth);
float leftBackoffAntialias = calculateBackoffAntialias(this.borderLeftColor, this.borderLeftWidth, this.density); float leftBackoffAntialias = calculateBackoffAntialias(this.borderLeftColor, this.borderLeftWidth);
RectF backgroundBoundsF = new RectF( RectF backgroundBoundsF = new RectF(
bounds.left + leftBackoffAntialias, bounds.left + leftBackoffAntialias,
@@ -296,7 +296,7 @@ public class BorderDrawable extends ColorDrawable {
bounds.right - rightBackoffAntialias, bounds.right - rightBackoffAntialias,
bounds.bottom - bottomBackoffAntialias); bounds.bottom - bottomBackoffAntialias);
float outerRadius = this.getUniformBorderRadius() * this.density; float outerRadius = this.getUniformBorderRadius();
// draw background // draw background
if (this.backgroundColor != 0) { if (this.backgroundColor != 0) {
@@ -306,14 +306,13 @@ public class BorderDrawable extends ColorDrawable {
backgroundColorPaint.setAntiAlias(true); backgroundColorPaint.setAntiAlias(true);
if (this.clipPath != null && !this.clipPath.isEmpty()) { if (this.clipPath != null && !this.clipPath.isEmpty()) {
drawClipPath(this.clipPath, canvas, backgroundColorPaint, backgroundBoundsF, density); drawClipPath(this.clipPath, canvas, backgroundColorPaint, backgroundBoundsF, this.density);
} } else {
else {
canvas.drawRoundRect(backgroundBoundsF, outerRadius, outerRadius, backgroundColorPaint); canvas.drawRoundRect(backgroundBoundsF, outerRadius, outerRadius, backgroundColorPaint);
} }
} }
if (this.backgroundImage != null){ if (this.backgroundImage != null) {
BackgroundDrawParams params = this.getDrawParams(bounds.width(), bounds.height()); BackgroundDrawParams params = this.getDrawParams(bounds.width(), bounds.height());
Matrix transform = new Matrix(); Matrix transform = new Matrix();
if (params.sizeX > 0 && params.sizeY > 0) { if (params.sizeX > 0 && params.sizeY > 0) {
@@ -338,9 +337,8 @@ public class BorderDrawable extends ColorDrawable {
params.posY = params.repeatY ? 0 : params.posY; params.posY = params.repeatY ? 0 : params.posY;
if (this.clipPath != null && !this.clipPath.isEmpty()) { if (this.clipPath != null && !this.clipPath.isEmpty()) {
drawClipPath(this.clipPath, canvas, backgroundImagePaint, backgroundBoundsF, density); drawClipPath(this.clipPath, canvas, backgroundImagePaint, backgroundBoundsF, this.density);
} } else {
else {
boolean supportsPathOp = android.os.Build.VERSION.SDK_INT >= 19; boolean supportsPathOp = android.os.Build.VERSION.SDK_INT >= 19;
if (supportsPathOp) { if (supportsPathOp) {
// Path.Op can be used in API level 19+ to achieve the perfect geometry. // Path.Op can be used in API level 19+ to achieve the perfect geometry.
@@ -350,8 +348,7 @@ public class BorderDrawable extends ColorDrawable {
backgroundNoRepeatPath.addRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight, Path.Direction.CCW); backgroundNoRepeatPath.addRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight, Path.Direction.CCW);
intersect(backgroundPath, backgroundNoRepeatPath); intersect(backgroundPath, backgroundNoRepeatPath);
canvas.drawPath(backgroundPath, backgroundImagePaint); canvas.drawPath(backgroundPath, backgroundImagePaint);
} } else {
else {
// Clipping here will not be anti-aliased but at least it won't shine through the rounded corners. // Clipping here will not be anti-aliased but at least it won't shine through the rounded corners.
canvas.save(); canvas.save();
canvas.clipRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight); canvas.clipRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight);
@@ -362,8 +359,8 @@ public class BorderDrawable extends ColorDrawable {
} }
// draw border // draw border
if (this.hasUniformBorder()){ if (this.hasUniformBorder()) {
float borderWidth = this.getUniformBorderWidth() * this.density; float borderWidth = this.getUniformBorderWidth();
int borderColor = this.getUniformBorderColor(); int borderColor = this.getUniformBorderColor();
// iOS and browsers use black when no color is specified. // iOS and browsers use black when no color is specified.
@@ -376,21 +373,18 @@ public class BorderDrawable extends ColorDrawable {
if (this.clipPath != null && !this.clipPath.isEmpty()) { if (this.clipPath != null && !this.clipPath.isEmpty()) {
borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth); borderPaint.setStrokeWidth(borderWidth);
drawClipPath(this.clipPath, canvas, borderPaint, backgroundBoundsF, density); drawClipPath(this.clipPath, canvas, borderPaint, backgroundBoundsF, this.density);
} } else {
else {
if (outerRadius <= 0) { if (outerRadius <= 0) {
borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth); borderPaint.setStrokeWidth(borderWidth);
canvas.drawRect(middleBoundsF, borderPaint); canvas.drawRect(middleBoundsF, borderPaint);
} } else if (outerRadius >= borderWidth) {
else if (outerRadius >= borderWidth) {
borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth); borderPaint.setStrokeWidth(borderWidth);
float middleRadius = Math.max(0, outerRadius - halfBorderWidth); float middleRadius = Math.max(0, outerRadius - halfBorderWidth);
canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint); canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint);
} } else {
else {
Path borderPath = new Path(); Path borderPath = new Path();
RectF borderOuterBoundsF = new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom); RectF borderOuterBoundsF = new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom);
borderPath.addRoundRect(borderOuterBoundsF, outerRadius, outerRadius, Path.Direction.CCW); borderPath.addRoundRect(borderOuterBoundsF, outerRadius, outerRadius, Path.Direction.CCW);
@@ -401,12 +395,11 @@ public class BorderDrawable extends ColorDrawable {
} }
} }
} }
} } else {
else { float top = this.borderTopWidth;
float top = this.borderTopWidth * this.density; float right = this.borderRightWidth;
float right = this.borderRightWidth * this.density; float bottom = this.borderBottomWidth;
float bottom = this.borderBottomWidth * this.density; float left = this.borderLeftWidth;
float left = this.borderLeftWidth * this.density;
//lto rto //lto rto
// +---------------------+ // +---------------------+
@@ -431,7 +424,7 @@ public class BorderDrawable extends ColorDrawable {
PointF lbo = new PointF(0, bounds.bottom); // left-bottom-outside PointF lbo = new PointF(0, bounds.bottom); // left-bottom-outside
PointF lbi = new PointF(left, bounds.bottom - bottom); // left-bottom-inside PointF lbi = new PointF(left, bounds.bottom - bottom); // left-bottom-inside
if (this.borderTopWidth > 0){ if (this.borderTopWidth > 0) {
Paint topBorderPaint = new Paint(); Paint topBorderPaint = new Paint();
topBorderPaint.setColor(this.borderTopColor); topBorderPaint.setColor(this.borderTopColor);
topBorderPaint.setAntiAlias(true); topBorderPaint.setAntiAlias(true);
@@ -445,7 +438,7 @@ public class BorderDrawable extends ColorDrawable {
canvas.drawPath(topBorderPath, topBorderPaint); canvas.drawPath(topBorderPath, topBorderPaint);
} }
if (this.borderRightWidth > 0){ if (this.borderRightWidth > 0) {
Paint rightBorderPaint = new Paint(); Paint rightBorderPaint = new Paint();
rightBorderPaint.setColor(this.borderRightColor); rightBorderPaint.setColor(this.borderRightColor);
rightBorderPaint.setAntiAlias(true); rightBorderPaint.setAntiAlias(true);
@@ -459,7 +452,7 @@ public class BorderDrawable extends ColorDrawable {
canvas.drawPath(rightBorderPath, rightBorderPaint); canvas.drawPath(rightBorderPath, rightBorderPaint);
} }
if (this.borderBottomWidth > 0){ if (this.borderBottomWidth > 0) {
Paint bottomBorderPaint = new Paint(); Paint bottomBorderPaint = new Paint();
bottomBorderPaint.setColor(this.borderBottomColor); bottomBorderPaint.setColor(this.borderBottomColor);
bottomBorderPaint.setAntiAlias(true); bottomBorderPaint.setAntiAlias(true);
@@ -473,7 +466,7 @@ public class BorderDrawable extends ColorDrawable {
canvas.drawPath(bottomBorderPath, bottomBorderPaint); canvas.drawPath(bottomBorderPath, bottomBorderPaint);
} }
if (this.borderLeftWidth > 0){ if (this.borderLeftWidth > 0) {
Paint leftBorderPaint = new Paint(); Paint leftBorderPaint = new Paint();
leftBorderPaint.setColor(this.borderLeftColor); leftBorderPaint.setColor(this.borderLeftColor);
leftBorderPaint.setAntiAlias(true); leftBorderPaint.setAntiAlias(true);
@@ -489,21 +482,22 @@ public class BorderDrawable extends ColorDrawable {
} }
} }
private static float calculateBackoffAntialias(int borderColor, float borderWidth, float density){ private static float calculateBackoffAntialias(int borderColor, float borderWidth) {
// We will inset background colors and images so antialiasing will not color pixels outside the border. // We will inset background colors and images so antialiasing will not color pixels outside the border.
// If the border is transparent we will backoff less, and we will not backoff more than half a pixel or half the border width. // If the border is transparent we will backoff less, and we will not backoff more than half a pixel or half the border width.
float halfBorderWidth = borderWidth * density / 2.0f; float halfBorderWidth = borderWidth / 2.0f;
float normalizedBorderAlpha = ((float)Color.alpha(borderColor)) / 255.0f; float normalizedBorderAlpha = ((float) Color.alpha(borderColor)) / 255.0f;
return Math.min(0.5f, halfBorderWidth) * normalizedBorderAlpha; return Math.min(0.5f, halfBorderWidth) * normalizedBorderAlpha;
} }
@TargetApi(19) @TargetApi(19)
private static void intersect(Path path1, Path path2){ private static void intersect(Path path1, Path path2) {
path1.op(path2, Path.Op.INTERSECT); path1.op(path2, Path.Op.INTERSECT);
} }
private static Pattern spaceAndComma = Pattern.compile("[\\s,]+"); private static Pattern spaceAndComma = Pattern.compile("[\\s,]+");
private static Pattern space = Pattern.compile("\\s+"); private static Pattern space = Pattern.compile("\\s+");
private static void drawClipPath(String clipPath, Canvas canvas, Paint paint, RectF bounds, float density) { private static void drawClipPath(String clipPath, Canvas canvas, Paint paint, RectF bounds, float density) {
// Sample string is polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%); // Sample string is polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
String functionName = clipPath.substring(0, clipPath.indexOf("(")); String functionName = clipPath.substring(0, clipPath.indexOf("("));
@@ -514,7 +508,7 @@ public class BorderDrawable extends ColorDrawable {
float right; float right;
float bottom; float bottom;
float left; float left;
switch (functionName){ switch (functionName) {
case "rect": case "rect":
arr = spaceAndComma.split(value); arr = spaceAndComma.split(value);
@@ -522,7 +516,7 @@ public class BorderDrawable extends ColorDrawable {
right = cssValueToDevicePixels(arr[1], bounds.right, density); right = cssValueToDevicePixels(arr[1], bounds.right, density);
bottom = cssValueToDevicePixels(arr[2], bounds.bottom, density); bottom = cssValueToDevicePixels(arr[2], bounds.bottom, density);
left = cssValueToDevicePixels(arr[3], bounds.right, density); left = cssValueToDevicePixels(arr[3], bounds.right, density);
canvas.drawRect(left, top, right, bottom, paint); canvas.drawRect(left, top, right, bottom, paint);
break; break;
case "inset": case "inset":
@@ -533,17 +527,14 @@ public class BorderDrawable extends ColorDrawable {
String leftString = "0"; String leftString = "0";
if (arr.length == 1) { if (arr.length == 1) {
topString = rightString = bottomString = leftString = arr[0]; topString = rightString = bottomString = leftString = arr[0];
} } else if (arr.length == 2) {
else if (arr.length == 2) {
topString = bottomString = arr[0]; topString = bottomString = arr[0];
rightString = leftString = arr[1]; rightString = leftString = arr[1];
} } else if (arr.length == 3) {
else if (arr.length == 3) {
topString = arr[0]; topString = arr[0];
rightString = leftString = arr[1]; rightString = leftString = arr[1];
bottomString = arr[2]; bottomString = arr[2];
} } else if (arr.length == 4) {
else if (arr.length == 4) {
topString = arr[0]; topString = arr[0];
rightString = arr[1]; rightString = arr[1];
bottomString = arr[2]; bottomString = arr[2];
@@ -591,7 +582,7 @@ public class BorderDrawable extends ColorDrawable {
path.lineTo(point.x, point.y); path.lineTo(point.x, point.y);
} }
if (firstPoint != null){ if (firstPoint != null) {
path.lineTo(firstPoint.x, firstPoint.y); path.lineTo(firstPoint.x, firstPoint.y);
} }
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
@@ -634,8 +625,7 @@ public class BorderDrawable extends ColorDrawable {
res.sizeX = imageWidth; res.sizeX = imageWidth;
res.sizeY = imageHeight; res.sizeY = imageHeight;
} } else if ("number".equals(vx.getType()) && "number".equals(vy.getType()) &&
else if ("number".equals(vx.getType()) && "number".equals(vy.getType()) &&
(("px".equals(vx.getUnit()) && "px".equals(vy.getUnit())) || ((vx.getUnit() == null || vx.getUnit().isEmpty()) && (vy.getUnit() == null || vy.getUnit().isEmpty())))) { (("px".equals(vx.getUnit()) && "px".equals(vy.getUnit())) || ((vx.getUnit() == null || vx.getUnit().isEmpty()) && (vy.getUnit() == null || vy.getUnit().isEmpty())))) {
imageWidth = vx.getValue(); imageWidth = vx.getValue();
imageHeight = vy.getValue(); imageHeight = vy.getValue();
@@ -643,14 +633,12 @@ public class BorderDrawable extends ColorDrawable {
res.sizeX = imageWidth; res.sizeX = imageWidth;
res.sizeY = imageHeight; res.sizeY = imageHeight;
} }
} } else if (this.backgroundSizeParsedCSSValues.length == 1 && "ident".equals(this.backgroundSizeParsedCSSValues[0].getType())) {
else if (this.backgroundSizeParsedCSSValues.length == 1 && "ident".equals(this.backgroundSizeParsedCSSValues[0].getType())) {
float scale = 0; float scale = 0;
if ("cover".equals(this.backgroundSizeParsedCSSValues[0].getString())) { if ("cover".equals(this.backgroundSizeParsedCSSValues[0].getString())) {
scale = Math.max(width / imageWidth, height / imageHeight); scale = Math.max(width / imageWidth, height / imageHeight);
} } else if ("contain".equals(this.backgroundSizeParsedCSSValues[0].getString())) {
else if ("contain".equals(this.backgroundSizeParsedCSSValues[0].getString())) {
scale = Math.min(width / imageWidth, height / imageHeight); scale = Math.min(width / imageWidth, height / imageHeight);
} }
@@ -676,24 +664,20 @@ public class BorderDrawable extends ColorDrawable {
if ("%".equals(vx.getUnit()) && "%".equals(vy.getUnit())) { if ("%".equals(vx.getUnit()) && "%".equals(vy.getUnit())) {
res.posX = spaceX * vx.getValue() / 100; res.posX = spaceX * vx.getValue() / 100;
res.posY = spaceY * vy.getValue() / 100; res.posY = spaceY * vy.getValue() / 100;
} } else if ("number".equals(vx.getType()) && "number".equals(vy.getType()) &&
else if ("number".equals(vx.getType()) && "number".equals(vy.getType()) &&
(("px".equals(vx.getUnit()) && "px".equals(vy.getUnit())) || ((vx.getUnit() == null || vx.getUnit().isEmpty()) && (vy.getUnit() == null || vy.getUnit().isEmpty())))) { (("px".equals(vx.getUnit()) && "px".equals(vy.getUnit())) || ((vx.getUnit() == null || vx.getUnit().isEmpty()) && (vy.getUnit() == null || vy.getUnit().isEmpty())))) {
res.posX = vx.getValue(); res.posX = vx.getValue();
res.posY = vy.getValue(); res.posY = vy.getValue();
} } else if ("ident".equals(vx.getType()) && "ident".equals(vy.getType())) {
else if ("ident".equals(vx.getType()) && "ident".equals(vy.getType())) {
if ("center".equals(vx.getString().toLowerCase(Locale.ENGLISH))) { if ("center".equals(vx.getString().toLowerCase(Locale.ENGLISH))) {
res.posX = spaceX / 2; res.posX = spaceX / 2;
} } else if ("right".equals(vx.getString().toLowerCase(Locale.ENGLISH))) {
else if ("right".equals(vx.getString().toLowerCase(Locale.ENGLISH))) {
res.posX = spaceX; res.posX = spaceX;
} }
if ("center".equals(vy.getString().toLowerCase(Locale.ENGLISH))) { if ("center".equals(vy.getString().toLowerCase(Locale.ENGLISH))) {
res.posY = spaceY / 2; res.posY = spaceY / 2;
} } else if ("bottom".equals(vy.getString().toLowerCase(Locale.ENGLISH))) {
else if ("bottom".equals(vy.getString().toLowerCase(Locale.ENGLISH))) {
res.posY = spaceY; res.posY = spaceY;
} }
} }
@@ -715,13 +699,11 @@ public class BorderDrawable extends ColorDrawable {
// If you only one keyword is specified, the other value is "center" // If you only one keyword is specified, the other value is "center"
if ("left".equals(val) || "right".equals(val)) { if ("left".equals(val) || "right".equals(val)) {
result = new CSSValue[] {values[0], center}; result = new CSSValue[]{values[0], center};
} } else if ("top".equals(val) || "bottom".equals(val)) {
else if ("top".equals(val) || "bottom".equals(val)) { result = new CSSValue[]{center, values[0]};
result = new CSSValue[] {center, values[0]}; } else if ("center".equals(val)) {
} result = new CSSValue[]{center, center};
else if ("center".equals(val)) {
result = new CSSValue[] {center, center};
} }
} }
@@ -729,48 +711,43 @@ public class BorderDrawable extends ColorDrawable {
} }
private static float cssValueToDevicePixels(String source, float total, float density) { private static float cssValueToDevicePixels(String source, float total, float density) {
float result;
source = source.trim(); source = source.trim();
if (source.contains("%")) {
if (source.contains("px")) { return Float.parseFloat(source.replace("%", "")) * total / 100;
result = Float.parseFloat(source.replace("px", "")); } else if (source.contains("px")) {
} return Float.parseFloat(source.replace("px", "")) * density;
else if (source.contains("%")) {
result = (Float.parseFloat(source.replace("%", "")) / 100) * (total / density);
} else { } else {
result = Float.parseFloat(source); return Float.parseFloat(source) * density;
} }
return result * density;
} }
public String toDebugString() { public String toDebugString() {
return return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + "; " +
getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + "; " +
"id: " + this.id + "; " + "id: " + this.id + "; " +
"borderTopColor: " + this.borderTopColor + "; " + "borderTopColor: " + this.borderTopColor + "; " +
"borderRightColor: " + this.borderRightColor + "; " + "borderRightColor: " + this.borderRightColor + "; " +
"borderBottomColor: " + this.borderBottomColor + "; " + "borderBottomColor: " + this.borderBottomColor + "; " +
"borderLeftColor: " + this.borderLeftColor + "; " + "borderLeftColor: " + this.borderLeftColor + "; " +
"borderTopWidth: " + this.borderTopWidth + "; " + "borderTopWidth: " + this.borderTopWidth + "; " +
"borderRightWidth: " + this.borderRightWidth + "; " + "borderRightWidth: " + this.borderRightWidth + "; " +
"borderBottomWidth: " + this.borderBottomWidth + "; " + "borderBottomWidth: " + this.borderBottomWidth + "; " +
"borderLeftWidth: " + this.borderLeftWidth + "; " + "borderLeftWidth: " + this.borderLeftWidth + "; " +
"borderTopLeftRadius: " + this.borderTopLeftRadius + "; " + "borderTopLeftRadius: " + this.borderTopLeftRadius + "; " +
"borderTopRightRadius: " + this.borderTopRightRadius + "; " + "borderTopRightRadius: " + this.borderTopRightRadius + "; " +
"borderBottomRightRadius: " + this.borderBottomRightRadius + "; " + "borderBottomRightRadius: " + this.borderBottomRightRadius + "; " +
"borderBottomLeftRadius: " + this.borderBottomLeftRadius + "; " + "borderBottomLeftRadius: " + this.borderBottomLeftRadius + "; " +
"clipPath: " + this.clipPath + "; " + "clipPath: " + this.clipPath + "; " +
"backgroundColor: " + this.backgroundColor + "; " + "backgroundColor: " + this.backgroundColor + "; " +
"backgroundImage: " + this.backgroundImage + "; " + "backgroundImage: " + this.backgroundImage + "; " +
"backgroundRepeat: " + this.backgroundRepeat + "; " + "backgroundRepeat: " + this.backgroundRepeat + "; " +
"backgroundPosition: " + this.backgroundPosition + "; " + "backgroundPosition: " + this.backgroundPosition + "; " +
"backgroundSize: " + this.backgroundSize + "; " "backgroundSize: " + this.backgroundSize + "; "
; ;
} }
private class BackgroundDrawParams { private class BackgroundDrawParams {