mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Non-uniform borders
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -45,3 +45,4 @@ local.properties
|
|||||||
.DS_Store?
|
.DS_Store?
|
||||||
ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcuserdata/
|
ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcuserdata/
|
||||||
ios/TNSWidgets/TNSWidgets.xcodeproj/xcuserdata/
|
ios/TNSWidgets/TNSWidgets.xcodeproj/xcuserdata/
|
||||||
|
ios/TNSWidgets/DerivedData/
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import android.graphics.PointF;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -20,10 +22,24 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public class BorderDrawable extends ColorDrawable {
|
public class BorderDrawable extends ColorDrawable {
|
||||||
private float density;
|
private float density;
|
||||||
private float borderWidth;
|
|
||||||
private int borderColor;
|
private int borderTopColor;
|
||||||
private float borderRadius;
|
private int borderRightColor;
|
||||||
|
private int borderBottomColor;
|
||||||
|
private int borderLeftColor;
|
||||||
|
|
||||||
|
private float borderTopWidth;
|
||||||
|
private float borderRightWidth;
|
||||||
|
private float borderBottomWidth;
|
||||||
|
private float borderLeftWidth;
|
||||||
|
|
||||||
|
private float borderTopLeftRadius;
|
||||||
|
private float borderTopRightRadius;
|
||||||
|
private float borderBottomRightRadius;
|
||||||
|
private float borderBottomLeftRadius;
|
||||||
|
|
||||||
private String clipPath;
|
private String clipPath;
|
||||||
|
|
||||||
private int backgroundColor;
|
private int backgroundColor;
|
||||||
private Bitmap backgroundImage;
|
private Bitmap backgroundImage;
|
||||||
private String backgroundRepeat;
|
private String backgroundRepeat;
|
||||||
@@ -32,16 +48,80 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
private String backgroundSize;
|
private String backgroundSize;
|
||||||
private CSSValue[] backgroundSizeParsedCSSValues;
|
private CSSValue[] backgroundSizeParsedCSSValues;
|
||||||
|
|
||||||
public float getBorderWidth() {
|
public float getDensity() {
|
||||||
return borderWidth;
|
return density;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBorderColor() {
|
public int getBorderTopColor() {
|
||||||
return borderColor;
|
return borderTopColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getBorderRadius() {
|
public int getBorderRightColor() {
|
||||||
return borderRadius;
|
return borderRightColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBorderBottomColor() {
|
||||||
|
return borderBottomColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBorderLeftColor() {
|
||||||
|
return borderLeftColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUniformBorderColor() {
|
||||||
|
if (this.hasUniformBorderColor()){
|
||||||
|
return this.borderTopColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderTopWidth() {
|
||||||
|
return borderTopWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderRightWidth() {
|
||||||
|
return borderRightWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderBottomWidth() {
|
||||||
|
return borderBottomWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderLeftWidth() {
|
||||||
|
return borderLeftWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getUniformBorderWidth() {
|
||||||
|
if (this.hasUniformBorderWidth()){
|
||||||
|
return this.borderTopWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderTopLeftRadius() {
|
||||||
|
return borderTopLeftRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderTopRightRadius() {
|
||||||
|
return borderTopRightRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderBottomRightRadius() {
|
||||||
|
return borderBottomRightRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBorderBottomLeftRadius() {
|
||||||
|
return borderBottomLeftRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getUniformBorderRadius() {
|
||||||
|
if (this.hasUniformBorderRadius()){
|
||||||
|
return this.borderTopLeftRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClipPath() {
|
public String getClipPath() {
|
||||||
@@ -68,11 +148,36 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
return backgroundSize;
|
return backgroundSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasUniformBorderColor() {
|
||||||
|
return this.borderTopColor == this.borderRightColor &&
|
||||||
|
this.borderTopColor == this.borderBottomColor &&
|
||||||
|
this.borderTopColor == this.borderLeftColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasUniformBorderWidth() {
|
||||||
|
return this.borderTopWidth == this.borderRightWidth &&
|
||||||
|
this.borderTopWidth == this.borderBottomWidth &&
|
||||||
|
this.borderTopWidth == this.borderLeftWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasUniformBorderRadius() {
|
||||||
|
return this.borderTopLeftRadius == this.borderTopRightRadius &&
|
||||||
|
this.borderTopLeftRadius == this.borderBottomRightRadius &&
|
||||||
|
this.borderTopLeftRadius == this.borderBottomLeftRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasUniformBorder(){
|
||||||
|
return this.hasUniformBorderColor() &&
|
||||||
|
this.hasUniformBorderWidth() &&
|
||||||
|
this.hasUniformBorderRadius();
|
||||||
|
}
|
||||||
|
|
||||||
public BorderDrawable(float density){
|
public BorderDrawable(float density){
|
||||||
super();
|
super();
|
||||||
this.density = density;
|
this.density = density;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For backwards compatibility
|
||||||
public void refresh(float borderWidth,
|
public void refresh(float borderWidth,
|
||||||
int borderColor,
|
int borderColor,
|
||||||
float borderRadius,
|
float borderRadius,
|
||||||
@@ -84,10 +189,76 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
CSSValue[] backgroundPositionParsedCSSValues,
|
CSSValue[] backgroundPositionParsedCSSValues,
|
||||||
String backgroundSize,
|
String backgroundSize,
|
||||||
CSSValue[] backgroundSizeParsedCSSValues){
|
CSSValue[] backgroundSizeParsedCSSValues){
|
||||||
this.borderWidth = borderWidth;
|
this.refresh(
|
||||||
this.borderColor = borderColor;
|
borderColor,
|
||||||
this.borderRadius = borderRadius;
|
borderColor,
|
||||||
|
borderColor,
|
||||||
|
borderColor,
|
||||||
|
|
||||||
|
borderWidth,
|
||||||
|
borderWidth,
|
||||||
|
borderWidth,
|
||||||
|
borderWidth,
|
||||||
|
|
||||||
|
borderRadius,
|
||||||
|
borderRadius,
|
||||||
|
borderRadius,
|
||||||
|
borderRadius,
|
||||||
|
|
||||||
|
clipPath,
|
||||||
|
|
||||||
|
backgroundColor,
|
||||||
|
backgroundImage,
|
||||||
|
backgroundRepeat,
|
||||||
|
backgroundPosition,
|
||||||
|
backgroundPositionParsedCSSValues,
|
||||||
|
backgroundSize,
|
||||||
|
backgroundSizeParsedCSSValues
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(int borderTopColor,
|
||||||
|
int borderRightColor,
|
||||||
|
int borderBottomColor,
|
||||||
|
int borderLeftColor,
|
||||||
|
|
||||||
|
float borderTopWidth,
|
||||||
|
float borderRightWidth,
|
||||||
|
float borderBottomWidth,
|
||||||
|
float borderLeftWidth,
|
||||||
|
|
||||||
|
float borderTopLeftRadius,
|
||||||
|
float borderTopRightRadius,
|
||||||
|
float borderBottomRightRadius,
|
||||||
|
float borderBottomLeftRadius,
|
||||||
|
|
||||||
|
String clipPath,
|
||||||
|
|
||||||
|
int backgroundColor,
|
||||||
|
Bitmap backgroundImage,
|
||||||
|
String backgroundRepeat,
|
||||||
|
String backgroundPosition,
|
||||||
|
CSSValue[] backgroundPositionParsedCSSValues,
|
||||||
|
String backgroundSize,
|
||||||
|
CSSValue[] backgroundSizeParsedCSSValues){
|
||||||
|
|
||||||
|
this.borderTopColor = borderTopColor;
|
||||||
|
this.borderRightColor = borderRightColor;
|
||||||
|
this.borderBottomColor = borderBottomColor;
|
||||||
|
this.borderLeftColor = borderLeftColor;
|
||||||
|
|
||||||
|
this.borderTopWidth = borderTopWidth;
|
||||||
|
this.borderRightWidth = borderRightWidth;
|
||||||
|
this.borderBottomWidth = borderBottomWidth;
|
||||||
|
this.borderLeftWidth = borderLeftWidth;
|
||||||
|
|
||||||
|
this.borderTopLeftRadius = borderTopLeftRadius;
|
||||||
|
this.borderTopRightRadius = borderTopRightRadius;
|
||||||
|
this.borderBottomRightRadius = borderBottomRightRadius;
|
||||||
|
this.borderBottomLeftRadius = borderBottomLeftRadius;
|
||||||
|
|
||||||
this.clipPath = clipPath;
|
this.clipPath = clipPath;
|
||||||
|
|
||||||
this.backgroundColor = backgroundColor;
|
this.backgroundColor = backgroundColor;
|
||||||
this.backgroundImage = backgroundImage;
|
this.backgroundImage = backgroundImage;
|
||||||
this.backgroundRepeat = backgroundRepeat;
|
this.backgroundRepeat = backgroundRepeat;
|
||||||
@@ -95,22 +266,26 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
this.backgroundPositionParsedCSSValues = backgroundPositionParsedCSSValues;
|
this.backgroundPositionParsedCSSValues = backgroundPositionParsedCSSValues;
|
||||||
this.backgroundSize = backgroundSize;
|
this.backgroundSize = backgroundSize;
|
||||||
this.backgroundSizeParsedCSSValues = backgroundSizeParsedCSSValues;
|
this.backgroundSizeParsedCSSValues = backgroundSizeParsedCSSValues;
|
||||||
|
|
||||||
this.invalidateSelf();
|
this.invalidateSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
Rect bounds = this.getBounds();
|
Rect bounds = this.getBounds();
|
||||||
float borderWidth = this.borderWidth * this.density;
|
|
||||||
float halfBorderWidth = borderWidth / 2.0f;
|
|
||||||
|
|
||||||
// We will inset background colors and images so antialiasing will not color pixels outside the border.
|
float topBackoffAntialias = calculateBackoffAntialias(this.borderTopColor, this.borderTopWidth, this.density);
|
||||||
// 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 rightBackoffAntialias = calculateBackoffAntialias(this.borderRightColor, this.borderRightWidth, this.density);
|
||||||
float normalizedBorderAlpha = ((float)Color.alpha(this.borderColor)) / 255.0f;
|
float bottomBackoffAntialias = calculateBackoffAntialias(this.borderBottomColor, this.borderBottomWidth, this.density);
|
||||||
float backoffAntialias = Math.min(0.5f, halfBorderWidth) * normalizedBorderAlpha;
|
float leftBackoffAntialias = calculateBackoffAntialias(this.borderLeftColor, this.borderLeftWidth, this.density);
|
||||||
RectF backgroundBoundsF = new RectF(bounds.left + backoffAntialias, bounds.top + backoffAntialias, bounds.right - backoffAntialias, bounds.bottom - backoffAntialias);
|
|
||||||
|
|
||||||
float outerRadius = this.borderRadius * this.density;
|
RectF backgroundBoundsF = new RectF(
|
||||||
|
bounds.left + leftBackoffAntialias,
|
||||||
|
bounds.top + topBackoffAntialias,
|
||||||
|
bounds.right - rightBackoffAntialias,
|
||||||
|
bounds.bottom - bottomBackoffAntialias);
|
||||||
|
|
||||||
|
float outerRadius = this.getUniformBorderRadius() * this.density;
|
||||||
|
|
||||||
// draw background
|
// draw background
|
||||||
if (this.backgroundColor != 0) {
|
if (this.backgroundColor != 0) {
|
||||||
@@ -138,7 +313,7 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
params.sizeX = this.backgroundImage.getWidth();
|
params.sizeX = this.backgroundImage.getWidth();
|
||||||
params.sizeY = this.backgroundImage.getHeight();
|
params.sizeY = this.backgroundImage.getHeight();
|
||||||
}
|
}
|
||||||
transform.postTranslate(params.posX - backoffAntialias, params.posY - backoffAntialias);
|
transform.postTranslate(params.posX - leftBackoffAntialias, params.posY - topBackoffAntialias);
|
||||||
|
|
||||||
BitmapShader shader = new BitmapShader(this.backgroundImage, android.graphics.Shader.TileMode.REPEAT, android.graphics.Shader.TileMode.REPEAT);
|
BitmapShader shader = new BitmapShader(this.backgroundImage, android.graphics.Shader.TileMode.REPEAT, android.graphics.Shader.TileMode.REPEAT);
|
||||||
shader.setLocalMatrix(transform);
|
shader.setLocalMatrix(transform);
|
||||||
@@ -164,7 +339,8 @@ 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);
|
||||||
@@ -175,37 +351,142 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draw border
|
// draw border
|
||||||
if (borderWidth > 0 && this.borderColor != 0) {
|
if (this.hasUniformBorder()){
|
||||||
RectF middleBoundsF = new RectF(bounds.left + halfBorderWidth, bounds.top + halfBorderWidth, bounds.right - halfBorderWidth, bounds.bottom - halfBorderWidth);
|
float borderWidth = this.getUniformBorderWidth() * this.density;
|
||||||
Paint borderPaint = new Paint();
|
int borderColor = this.getUniformBorderColor();
|
||||||
borderPaint.setColor(this.borderColor);
|
|
||||||
borderPaint.setAntiAlias(true);
|
|
||||||
|
|
||||||
if (this.clipPath != null && !this.clipPath.isEmpty()) {
|
// iOS and browsers use black when no color is specified.
|
||||||
borderPaint.setStyle(Paint.Style.STROKE);
|
if (borderColor == Color.TRANSPARENT){
|
||||||
borderPaint.setStrokeWidth(borderWidth);
|
borderColor = Color.BLACK;
|
||||||
drawClipPath(this.clipPath, canvas, borderPaint, backgroundBoundsF, density);
|
}
|
||||||
} else {
|
if (borderWidth > 0) {
|
||||||
if (outerRadius <= 0) {
|
float halfBorderWidth = borderWidth / 2.0f;
|
||||||
|
RectF middleBoundsF = new RectF(bounds.left + halfBorderWidth, bounds.top + halfBorderWidth, bounds.right - halfBorderWidth, bounds.bottom - halfBorderWidth);
|
||||||
|
Paint borderPaint = new Paint();
|
||||||
|
borderPaint.setColor(borderColor);
|
||||||
|
borderPaint.setAntiAlias(true);
|
||||||
|
if (this.clipPath != null && !this.clipPath.isEmpty()) {
|
||||||
borderPaint.setStyle(Paint.Style.STROKE);
|
borderPaint.setStyle(Paint.Style.STROKE);
|
||||||
borderPaint.setStrokeWidth(borderWidth);
|
borderPaint.setStrokeWidth(borderWidth);
|
||||||
canvas.drawRect(middleBoundsF, borderPaint);
|
drawClipPath(this.clipPath, canvas, borderPaint, backgroundBoundsF, density);
|
||||||
} else if (outerRadius >= borderWidth) {
|
}
|
||||||
borderPaint.setStyle(Paint.Style.STROKE);
|
else {
|
||||||
borderPaint.setStrokeWidth(borderWidth);
|
if (outerRadius <= 0) {
|
||||||
float middleRadius = Math.max(0, outerRadius - halfBorderWidth);
|
borderPaint.setStyle(Paint.Style.STROKE);
|
||||||
canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint);
|
borderPaint.setStrokeWidth(borderWidth);
|
||||||
} else {
|
canvas.drawRect(middleBoundsF, borderPaint);
|
||||||
Path borderPath = new Path();
|
}
|
||||||
RectF borderOuterBoundsF = new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom);
|
else if (outerRadius >= borderWidth) {
|
||||||
borderPath.addRoundRect(borderOuterBoundsF, outerRadius, outerRadius, Path.Direction.CCW);
|
borderPaint.setStyle(Paint.Style.STROKE);
|
||||||
RectF borderInnerBoundsF = new RectF(bounds.left + borderWidth, bounds.top + borderWidth, bounds.right - borderWidth, bounds.bottom - borderWidth);
|
borderPaint.setStrokeWidth(borderWidth);
|
||||||
borderPath.addRect(borderInnerBoundsF, Path.Direction.CW);
|
float middleRadius = Math.max(0, outerRadius - halfBorderWidth);
|
||||||
borderPaint.setStyle(Paint.Style.FILL);
|
canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint);
|
||||||
canvas.drawPath(borderPath, borderPaint);
|
}
|
||||||
|
else {
|
||||||
|
Path borderPath = new Path();
|
||||||
|
RectF borderOuterBoundsF = new RectF(bounds.left, bounds.top, bounds.right, bounds.bottom);
|
||||||
|
borderPath.addRoundRect(borderOuterBoundsF, outerRadius, outerRadius, Path.Direction.CCW);
|
||||||
|
RectF borderInnerBoundsF = new RectF(bounds.left + borderWidth, bounds.top + borderWidth, bounds.right - borderWidth, bounds.bottom - borderWidth);
|
||||||
|
borderPath.addRect(borderInnerBoundsF, Path.Direction.CW);
|
||||||
|
borderPaint.setStyle(Paint.Style.FILL);
|
||||||
|
canvas.drawPath(borderPath, borderPaint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
float top = this.borderTopWidth * this.density;
|
||||||
|
float right = this.borderRightWidth * this.density;
|
||||||
|
float bottom = this.borderBottomWidth * this.density;
|
||||||
|
float left = this.borderLeftWidth * this.density;
|
||||||
|
|
||||||
|
//lto rto
|
||||||
|
// +---------------------+
|
||||||
|
// |lti rti|
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// |lbi rbi|
|
||||||
|
// +---------------------+
|
||||||
|
//lbo rbo
|
||||||
|
|
||||||
|
PointF lto = new PointF(0, 0); // left-top-outside
|
||||||
|
PointF lti = new PointF(left, top); // left-top-inside
|
||||||
|
|
||||||
|
PointF rto = new PointF(bounds.right, 0); // right-top-outside
|
||||||
|
PointF rti = new PointF(bounds.right - right, top); // right-top-outside
|
||||||
|
|
||||||
|
PointF rbo = new PointF(bounds.right, bounds.bottom); // right-bottom-outside
|
||||||
|
PointF rbi = new PointF(bounds.right - right, bounds.bottom - bottom); // right-bottom-inside
|
||||||
|
|
||||||
|
PointF lbo = new PointF(0, bounds.bottom); // left-bottom-outside
|
||||||
|
PointF lbi = new PointF(left, bounds.bottom - bottom); // left-bottom-inside
|
||||||
|
|
||||||
|
if (this.borderTopWidth > 0){
|
||||||
|
Paint topBorderPaint = new Paint();
|
||||||
|
topBorderPaint.setColor(this.borderTopColor);
|
||||||
|
topBorderPaint.setAntiAlias(true);
|
||||||
|
Path topBorderPath = new Path();
|
||||||
|
topBorderPath.setFillType(Path.FillType.EVEN_ODD);
|
||||||
|
topBorderPath.moveTo(lto.x, lto.y);
|
||||||
|
topBorderPath.lineTo(rto.x, rto.y);
|
||||||
|
topBorderPath.lineTo(rti.x, rti.y);
|
||||||
|
topBorderPath.lineTo(lti.x, lti.y);
|
||||||
|
topBorderPath.close();
|
||||||
|
canvas.drawPath(topBorderPath, topBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.borderRightWidth > 0){
|
||||||
|
Paint rightBorderPaint = new Paint();
|
||||||
|
rightBorderPaint.setColor(this.borderRightColor);
|
||||||
|
rightBorderPaint.setAntiAlias(true);
|
||||||
|
Path rightBorderPath = new Path();
|
||||||
|
rightBorderPath.setFillType(Path.FillType.EVEN_ODD);
|
||||||
|
rightBorderPath.moveTo(rto.x, rto.y);
|
||||||
|
rightBorderPath.lineTo(rbo.x, rbo.y);
|
||||||
|
rightBorderPath.lineTo(rbi.x, rbi.y);
|
||||||
|
rightBorderPath.lineTo(rti.x, rti.y);
|
||||||
|
rightBorderPath.close();
|
||||||
|
canvas.drawPath(rightBorderPath, rightBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.borderBottomWidth > 0){
|
||||||
|
Paint bottomBorderPaint = new Paint();
|
||||||
|
bottomBorderPaint.setColor(this.borderBottomColor);
|
||||||
|
bottomBorderPaint.setAntiAlias(true);
|
||||||
|
Path bottomBorderPath = new Path();
|
||||||
|
bottomBorderPath.setFillType(Path.FillType.EVEN_ODD);
|
||||||
|
bottomBorderPath.moveTo(rbo.x, rbo.y);
|
||||||
|
bottomBorderPath.lineTo(lbo.x, lbo.y);
|
||||||
|
bottomBorderPath.lineTo(lbi.x, lbi.y);
|
||||||
|
bottomBorderPath.lineTo(rbi.x, rbi.y);
|
||||||
|
bottomBorderPath.close();
|
||||||
|
canvas.drawPath(bottomBorderPath, bottomBorderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.borderLeftWidth > 0){
|
||||||
|
Paint leftBorderPaint = new Paint();
|
||||||
|
leftBorderPaint.setColor(this.borderLeftColor);
|
||||||
|
leftBorderPaint.setAntiAlias(true);
|
||||||
|
Path leftBorderPath = new Path();
|
||||||
|
leftBorderPath.setFillType(Path.FillType.EVEN_ODD);
|
||||||
|
leftBorderPath.moveTo(lbo.x, lbo.y);
|
||||||
|
leftBorderPath.lineTo(lto.x, lto.y);
|
||||||
|
leftBorderPath.lineTo(lti.x, lti.y);
|
||||||
|
leftBorderPath.lineTo(lbi.x, lbi.y);
|
||||||
|
leftBorderPath.close();
|
||||||
|
canvas.drawPath(leftBorderPath, leftBorderPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float calculateBackoffAntialias(int borderColor, float borderWidth, float density){
|
||||||
|
// 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.
|
||||||
|
float halfBorderWidth = borderWidth * density / 2.0f;
|
||||||
|
float normalizedBorderAlpha = ((float)Color.alpha(borderColor)) / 255.0f;
|
||||||
|
return Math.min(0.5f, halfBorderWidth) * normalizedBorderAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(19)
|
@TargetApi(19)
|
||||||
@@ -405,10 +686,10 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
float result;
|
float result;
|
||||||
source = source.trim();
|
source = source.trim();
|
||||||
|
|
||||||
if (source.indexOf("px") > -1) {
|
if (source.contains("px")) {
|
||||||
result = Float.parseFloat(source.replace("px", ""));
|
result = Float.parseFloat(source.replace("px", ""));
|
||||||
}
|
}
|
||||||
else if (source.indexOf("%") > -1 && total > 0) {
|
else if (source.contains("%") && total > 0) {
|
||||||
result = (Float.parseFloat(source.replace("%", "")) / 100) * (total / density);
|
result = (Float.parseFloat(source.replace("%", "")) / 100) * (total / density);
|
||||||
} else {
|
} else {
|
||||||
result = Float.parseFloat(source);
|
result = Float.parseFloat(source);
|
||||||
@@ -424,4 +705,4 @@ public class BorderDrawable extends ColorDrawable {
|
|||||||
private float sizeX;
|
private float sizeX;
|
||||||
private float sizeY;
|
private float sizeY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,15 +6,13 @@ package org.nativescript.widgets;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.*;
|
import android.graphics.*;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hhristov
|
* @author hhristov
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ImageView extends android.widget.ImageView {
|
public class ImageView extends android.widget.ImageView {
|
||||||
private float cornerRadius = 0;
|
|
||||||
private float borderWidth = 0;
|
|
||||||
|
|
||||||
private Path path = new Path();
|
private Path path = new Path();
|
||||||
private RectF rect = new RectF();
|
private RectF rect = new RectF();
|
||||||
|
|
||||||
@@ -26,28 +24,6 @@ public class ImageView extends android.widget.ImageView {
|
|||||||
this.setScaleType(ScaleType.FIT_CENTER);
|
this.setScaleType(ScaleType.FIT_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCornerRadius() {
|
|
||||||
return this.cornerRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCornerRadius(float radius) {
|
|
||||||
if (radius != this.cornerRadius) {
|
|
||||||
this.cornerRadius = radius;
|
|
||||||
this.invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBorderWidth() {
|
|
||||||
return this.borderWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBorderWidth(float radius) {
|
|
||||||
if (radius != this.borderWidth) {
|
|
||||||
this.borderWidth = radius;
|
|
||||||
this.invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
|
||||||
@@ -144,13 +120,17 @@ public class ImageView extends android.widget.ImageView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
|
BorderDrawable background = this.getBackground() instanceof BorderDrawable ? (BorderDrawable)this.getBackground() : null;
|
||||||
|
float uniformBorderWidth = background != null ? background.getUniformBorderWidth() * background.getDensity() : 0;
|
||||||
|
float uniformBorderRadius = background != null ? background.getUniformBorderRadius() * background.getDensity() : 0;
|
||||||
|
|
||||||
// floor the border width to avoid gaps between the border and the image
|
// floor the border width to avoid gaps between the border and the image
|
||||||
float roundedBorderWidth = (float) Math.floor(this.borderWidth);
|
float roundedBorderWidth = (float) Math.floor(uniformBorderWidth);
|
||||||
float innerRadius = Math.max(0, this.cornerRadius - roundedBorderWidth);
|
float innerRadius = Math.max(0, uniformBorderRadius - roundedBorderWidth);
|
||||||
|
|
||||||
// The border width is included in the padding so there is no need for
|
// The border width is included in the padding so there is no need for
|
||||||
// clip if there is no inner border radius.
|
// clip if there is no inner border radius.
|
||||||
if (innerRadius != 0) {
|
if (innerRadius > 0) {
|
||||||
this.rect.set(
|
this.rect.set(
|
||||||
roundedBorderWidth,
|
roundedBorderWidth,
|
||||||
roundedBorderWidth,
|
roundedBorderWidth,
|
||||||
|
|||||||
Reference in New Issue
Block a user