Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behavior for FillType.EVEN_ODD when adding a CornerPathEffect?

I was experimenting with Drawable here and found something I can't explain and hope someone can help me with.

Why does adding a CornerPathEffect to the Paint seems to “break” (?) the EVEN_ODD FillType?

To be more specific, I was testing this HexagonDrawable class as is. This is what I get:

Hard corners, outlined, expected behavior.

However, if I set a CornerPathEffect to the Paint, as shown below (constructor)...

public HexagonDrawable(int color) {
    paint.setColor(color);
    paint.setPathEffect(new CornerPathEffect(6)); // added
    hexagon.setFillType(Path.FillType.EVEN_ODD);
}

...this is what I get:

Rounded corners, outline effect disappears, unexpected behavior?

Rounded corners, yes, but no outlined appearance (odd/even/odd). Could someone please explain why?

like image 701
davidcesarino Avatar asked May 19 '15 04:05

davidcesarino


1 Answers

That HexagonDrawable class draws two different hexagons, stacked on top of each other. I don't know if you need it to be that way, but I think the best way to achieve the same result is to use a Paint with Stroke style.

To do so, you need to remove the second hexagon path and decrease the hexagon's size (so the view won't cut it):

public void computeHex(Rect bounds) {

    final int width = bounds.width();
    final int height = bounds.height();
    // We need to decrease the hexagon's size, so the view won't cut our stroke
    final int size = Math.min(width - (strokeWidth / 2), height - (strokeWidth / 2));
    final int centerX = bounds.left + (width / 2);
    final int centerY = bounds.top + (height / 2);

    hexagon.reset();
    hexagon.addPath(createHexagon(size, centerX, centerY));
    // Remove the second path
    // hexagon.addPath(createHexagon((int) (size * .8f), centerX, centerY));
} 

And add the Stroke effect to the paint:

private int strokeWidth;

public HexagonDrawable(int color, int strokeWidth) {        
    this.strokeWidth = strokeWidth;

    paint.setColor(color);

    // Add Stroke style and width
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(strokeWidth);

    // You can add these other attributes if you need to
    // paint.setDither(true);
    // paint.setStrokeJoin(Paint.Join.ROUND);
    // paint.setStrokeCap(Paint.Cap.ROUND);

    // Remove the fill type, you won't need anymore
    // hexagon.setFillType(Path.FillType.EVEN_ODD);

    // Finally add the Path Effect
    paint.setPathEffect(new CornerPathEffect(30.0f));
}

That should create a very similar effect to what you were looking for.

Hope it helps! ;)

Edit: I forgot to warn you that the Stroke width can't be greater than CornerPathEffect's radius, otherwise it'll get cut anyway.

like image 158
Renan Ferrari Avatar answered Nov 07 '22 06:11

Renan Ferrari