I have a Canvas that comes from a Picture beginRecording() method.
I record things in the canvas and then call endRecording().
I would like to be able to record strokes that will not scale when the canvas is scaled afterwards.
I cannot see something like that in the Paint class. You can setStrokeWidth(float w), but:
- If w == 0 you have something like the functionality I want, but only with 1px
- If w != 0, canvas scaling means stroke scaling too.
Any ideas?

- 59,452
- 12
- 120
- 139

- 3,117
- 3
- 30
- 32
-
does anybody able to understand what was asked here? – Pratik Nov 14 '11 at 13:27
-
I've edited the question, I hope you understand me now. – mamuso Nov 14 '11 at 14:00
4 Answers
Extract the scale from the current transformation matrix and use the inverse of that to set your stroke width.

- 296,393
- 112
- 651
- 745
-
When I was using Picture for recording this was not possible, all was applied to the canvas and its content. See my new approach. Thanks! – mamuso Nov 15 '11 at 14:46
This is a silly answer:
Draw your strokes X number of times with w = 0 next to each other.

- 10,908
- 1
- 31
- 37
You will probably need to keep track of your width in a custom SVG object. As the object is scaled you can find the ratio between the new width and that of the initial size and multiply that to your initial stroke width. It doesn't have to be width, it could very much well be height or diagonal. It depends on how your object is scaling.
Or you could see if this already does what you want:

- 2,088
- 1
- 20
- 42
-
AFAIK svg-android doesn't provide this functionality. I've edited the question, cause I think you didn't understand due to my lack of precision. – mamuso Nov 14 '11 at 13:59
-
1Ah. Yes. The first solution that comes to mind would be to override Canvas' drawLine function, which would be easier than overriding all basic shape classes I guess. Alternatively you could try to draw a PathShape in place of the line, which should scale the way you want. – Andrew T. Nov 14 '11 at 14:20
-
Thanks, I will take a look at this. I'll tell you if it solves my problem so you can edit the answer and I check it as the right one. – mamuso Nov 14 '11 at 14:52
-
As the solution includes extending a class I will post the details. I've not tested it extensively but only in the context I needed it.
I wanted to get a Drawable from a list of actions like the way Picture.recording() works.
Fortunately a Path object can record the actions, and then we can paint them into a canvas.
Unfortunately painting it via canvas.drawPath() does not provide the no-scaling-stroke functionality.
So thanks to the hint given by @Andrew, I've extended Shape similarly to PathShape but with some different logic in onResize()
public class NonScalingStrokePathShape extends Shape{
private Path mPath;
private float mInitialWidth;
private float mInitialHeight;
private float mCurrentWidth;
private float mCurrentHeight;
public NonScalingStrokePathShape(Path pPath, float pInitialWidth, float pInitialHeight) {
mPath = pPath;
mInitialWidth = pInitialWidth;
mInitialHeight = pInitialHeight;
mCurrentWidth = mInitialWidth;
mCurrentHeight = mInitialHeight;
}
@Override
public void draw(Canvas canvas, Paint paint) {
canvas.drawPath(mPath,paint);
}
@Override
protected void onResize(float width, float height) {
Matrix matrix = new Matrix();
matrix.setScale(width / mCurrentWidth, height / mCurrentHeight);
mCurrentWidth = width;
mCurrentHeight = height;
mPath.transform(matrix);
}
@Override
public NonScalingStrokePathShape clone() throws CloneNotSupportedException {
NonScalingStrokePathShape shape = (NonScalingStrokePathShape) super.clone();
shape.mPath = new Path(mPath);
shape.mInitialHeight = mInitialHeight;
shape.mInitialWidth = mInitialWidth;
shape.mCurrentWidth = mInitialWidth;
shape.mCurrentHeight = mInitialHeight;
return shape;
}
}
This can be used in a ShapeDrawable, which is a Drawable that already takes bounds resizing into account by calling the Shape resize(float w, float h) method.

- 3,117
- 3
- 30
- 32