Fix android corner radius in cases when the radius is less than half the border width

This commit is contained in:
Panayot Cankov
2016-02-08 12:15:35 +02:00
parent 630daa03e9
commit 7e400edbae
2 changed files with 26 additions and 11 deletions

View File

@@ -45,6 +45,7 @@
<Button width="40" height="40" text="75" tap="applyTap" tag="margin: 20; background-color: lightgreen; background-image: url('~/pages/test2.png'); background-repeat:repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 9; border-width: 3; border-color: black;"/> <Button width="40" height="40" text="75" tap="applyTap" tag="margin: 20; background-color: lightgreen; background-image: url('~/pages/test2.png'); background-repeat:repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 9; border-width: 3; border-color: black;"/>
<Button width="40" height="40" text="76" tap="applyTap" tag="margin: 20; background-color: lightgreen; background-image: url('~/pages/test2.png'); background-repeat:no-repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 9; border-width: 3; border-color: black;"/> <Button width="40" height="40" text="76" tap="applyTap" tag="margin: 20; background-color: lightgreen; background-image: url('~/pages/test2.png'); background-repeat:no-repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 9; border-width: 3; border-color: black;"/>
<Button width="40" height="40" text="77" tap="applyTap" tag="margin: 20; background-color: #FF00FF00; background-image: url('~/pages/test2.png'); background-repeat:no-repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 20; border-width: 10; border-color: #66FF0000;"/> <Button width="40" height="40" text="77" tap="applyTap" tag="margin: 20; background-color: #FF00FF00; background-image: url('~/pages/test2.png'); background-repeat:no-repeat; background-position: -15% -15%; background-size: 50% 50%; border-radius: 20; border-width: 10; border-color: #66FF0000;"/>
<Button width="40" height="40" text="78" tap="applyTap" tag="margin: 20; background-color: #FF00FF00; background-image: url('~/pages/test2.png'); background-repeat:no-repeat; background-position: -15% -15%; background-size: 50% 50%; border-width: 10; border-color: #66FF0000;"/>
</WrapLayout> </WrapLayout>
</GridLayout> </GridLayout>
</Page> </Page>

View File

@@ -98,9 +98,10 @@ export module ad {
// 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.
let normalizedBorderAlpha = android.graphics.Color.alpha(this._borderColor) / 255; let normalizedBorderAlpha = android.graphics.Color.alpha(this._borderColor) / 255;
let backoffAntialias = Math.min(0.5, halfBorderWidth) * normalizedBorderAlpha; let backoffAntialias = Math.min(0.5, halfBorderWidth) * normalizedBorderAlpha;
let outerBoundsF = new android.graphics.RectF(bounds.left + backoffAntialias, bounds.top + backoffAntialias, bounds.right - backoffAntialias, bounds.bottom - backoffAntialias); let backgroundBoundsF = new android.graphics.RectF(bounds.left + backoffAntialias, bounds.top + backoffAntialias, bounds.right - backoffAntialias, bounds.bottom - backoffAntialias);
let outerRadius = Math.max(0, this._cornerRadius * this._density - backoffAntialias); let outerRadius = this._cornerRadius * this._density;
let backgroundRadius = Math.max(0, outerRadius - backoffAntialias);
// draw background // draw background
if (this.background.color && this.background.color.android) { if (this.background.color && this.background.color.android) {
@@ -109,7 +110,7 @@ export module ad {
backgroundColorPaint.setColor(this.background.color.android); backgroundColorPaint.setColor(this.background.color.android);
backgroundColorPaint.setAntiAlias(true); backgroundColorPaint.setAntiAlias(true);
canvas.drawRoundRect(outerBoundsF, outerRadius, outerRadius, backgroundColorPaint); canvas.drawRoundRect(backgroundBoundsF, outerRadius, outerRadius, backgroundColorPaint);
} }
// draw image // draw image
@@ -143,7 +144,7 @@ export module ad {
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.
let backgroundPath = new android.graphics.Path(); let backgroundPath = new android.graphics.Path();
backgroundPath.addRoundRect(outerBoundsF, outerRadius, outerRadius, android.graphics.Path.Direction.CCW); backgroundPath.addRoundRect(backgroundBoundsF, outerRadius, outerRadius, android.graphics.Path.Direction.CCW);
let backgroundNoRepeatPath = new android.graphics.Path(); let backgroundNoRepeatPath = new android.graphics.Path();
backgroundNoRepeatPath.addRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight, android.graphics.Path.Direction.CCW); backgroundNoRepeatPath.addRect(params.posX, params.posY, params.posX + imageWidth, params.posY + imageHeight, android.graphics.Path.Direction.CCW);
(<any>backgroundPath).op(backgroundNoRepeatPath, (<any>android).graphics.Path.Op.INTERSECT); (<any>backgroundPath).op(backgroundNoRepeatPath, (<any>android).graphics.Path.Op.INTERSECT);
@@ -152,23 +153,36 @@ export module ad {
// Clipping here will not be antialiased but at least it won't shine through the rounded corners. // Clipping here will not be antialiased 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);
canvas.drawRoundRect(outerBoundsF, outerRadius, outerRadius, backgroundImagePaint); canvas.drawRoundRect(backgroundBoundsF, outerRadius, outerRadius, backgroundImagePaint);
canvas.restore(); canvas.restore();
} }
} }
// draw border // draw border
if (borderWidth > 0 && this._borderColor) { if (borderWidth > 0 && this._borderColor) {
let middleRadius = Math.max(0, outerRadius - halfBorderWidth);
let middleBoundsF = new android.graphics.RectF(bounds.left + halfBorderWidth, bounds.top + halfBorderWidth, bounds.right - halfBorderWidth, bounds.bottom - halfBorderWidth); let middleBoundsF = new android.graphics.RectF(bounds.left + halfBorderWidth, bounds.top + halfBorderWidth, bounds.right - halfBorderWidth, bounds.bottom - halfBorderWidth);
let borderPaint = new android.graphics.Paint(); let borderPaint = new android.graphics.Paint();
borderPaint.setStyle(android.graphics.Paint.Style.STROKE);
borderPaint.setColor(this._borderColor); borderPaint.setColor(this._borderColor);
borderPaint.setAntiAlias(true); borderPaint.setAntiAlias(true);
borderPaint.setStrokeWidth(borderWidth);
if (outerRadius <= 0) {
borderPaint.setStyle(android.graphics.Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
canvas.drawRect(middleBoundsF, borderPaint);
} else if (outerRadius >= borderWidth) {
borderPaint.setStyle(android.graphics.Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
let middleRadius = Math.max(0, outerRadius - halfBorderWidth);
canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint); canvas.drawRoundRect(middleBoundsF, middleRadius, middleRadius, borderPaint);
} else {
let borderPath = new android.graphics.Path();
let borderOuterBoundsF = new android.graphics.RectF(bounds.left, bounds.top, bounds.right, bounds.bottom);
borderPath.addRoundRect(borderOuterBoundsF, outerRadius, outerRadius, android.graphics.Path.Direction.CCW);
let borderInnerBoundsF = new android.graphics.RectF(bounds.left + borderWidth, bounds.top + borderWidth, bounds.right - borderWidth, bounds.bottom - borderWidth);
borderPath.addRect(borderInnerBoundsF, android.graphics.Path.Direction.CW);
borderPaint.setStyle(android.graphics.Paint.Style.FILL);
canvas.drawPath(borderPath, borderPaint);
}
} }
} }
} }