13

I want to draw a shape as defined using Path with a stroke width of 5 where all of the stroke is inside the Path rather than half the stroke inside and half outside.

Thanks,

Carl

user2430147
  • 141
  • 1
  • 4
  • I don't understand the problem, could you be more specific? What do you mean be saying " all of the stroke is inside the Path rather than half the stroke inside and half outside"? – Marek May 29 '13 at 00:41
  • 2
    Suppose I draw a shape with a stroke that is 10 pixels wide in black and then draw over the shape with a stroke that is 5 pixels wide in red, then the red path will be half the width of the black path and it will be in the middle, as half the stroke will be inside the shape boundary and half will be outside. Instead what I want is the entire stroke to be inside the shape boundary. In the example above, this would mean that the red stroke would be at one side of the black stroke, the side closest to the shape boundary – user2430147 Jun 07 '13 at 14:40

3 Answers3

7

It seems it can not control the position of the stroke (i.e, inside, center or outside). For more info refer to: Android Paint stroke width positioning

My solution is offset the stroke width while drawing e.g.,

final RectF rectF = new RectF(halfStrokeWidth, halfStrokeWidth, width - halfStrokeWidth, height - halfStrokeWidth);
canvas.drawRoundRect(rectF, roundX, roundY, paint);
Community
  • 1
  • 1
chrisli
  • 1,161
  • 8
  • 12
2

You can use CornerPathEffect class for help! Taking drawing a roundrect shape as an example.

While drawing a background color with radius using canvas.drawRoundRect() method and the paint sets Style.FILL, you can get a round rect shape. And then drawing a round rect border on it with Style.STROKE and width of paint's setting using the same method, you can get a border.

The code:

mBackgroundRectF.set(0, 0, mWidth, mHeight);
canvas.drawRoundRect(mBackgroundRectF, mRadius, mRadius, mBackgroundPaint);
// edge ajustment because paint stroke style is center align
float edge = mBorderWidth / 2;
mBackgroundRectF.set(edge, edge, mWidth - edge, mHeight - edge);
canvas.drawRoundRect(mBackgroundRectF, mRadius, mRadius, mBorderPaint);

Now it looks like, it isn't the one i want which has some offset between background and border:

before

Let's try CornerPathEffect:

mBackgroundRectF.set(0, 0, mWidth, mHeight);
canvas.drawRoundRect(mBackgroundRectF, mRadius, mRadius, mBackgroundPaint);
// edge ajustment because paint stroke style is center align
float edge = mBorderWidth / 2;
mBackgroundRectF.set(edge, edge, mWidth - edge, mHeight - edge);
// use CornerPathEffect and then use drawRect() method
mBorderPaint.setPathEffect(new CornerPathEffect(mRadius / 2));
canvas.drawRect(mBackgroundRectF, mBorderPaint);

Now it looks correct:

after

YXP
  • 71
  • 8
2

Use Canvas#clipPath(Path, Op). But be aware that support for clipping to a path in a hardware accelerated canvas was removed in Android 3.0 and reintroduced in 4.3. There was apparently a workaround for 3.0-4.2, but I don't have a way to test it.

Community
  • 1
  • 1
Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82