Android:Region.Op 中的路径样式问题

发布于 2024-11-06 07:59:05 字数 4176 浏览 0 评论 0原文

我的基本目标是从 Android 1.6 中的预定区域(也是使用 Path 创建的)中减去 Path。

无论如何,是否可以让 Region.setPath 处理传递给它的路径,就像画布处理描边路径(这是我的用户所看到的)一样?

我知道样式用于在画布上绘画,但我需要行为来反映画布上绘制的内容,并且绘制的路径是描边的。

当向路径添加形状(path.addRect、path.addCircle)时,该行为有效,但在使用 lineTo、quadTo、cubeTo 时则无效。我唯一的其他选择是只组成一条由矩形或圆形组成的路径。

public class ComplexRegions extends Activity {

static Display display;

/** Code Sample for StackOverflow */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    display = getWindowManager().getDefaultDisplay();
    setContentView(new SampleView(this));             
}

private static class SampleView extends View {      
    Path orig_path, finger_path;
    Paint dirty_paint, fingerpaint, temp_paint;
    Region orig_region, clip, fingerregion, tempregion;
    Canvas c;
    int h, w;

    public float mX, mY, dx, dy;
    boolean b;

    public SampleView(Context context) {
        super(context);

        fingerregion = new Region();
        tempregion = new Region();
        orig_region = new Region();
        clip = new Region();
        orig_path = new Path();
        finger_path = new Path();

        dirty_paint = new Paint();
        dirty_paint.setStyle(Paint.Style.STROKE);
        dirty_paint.setColor(Color.BLUE);
        dirty_paint.setStrokeWidth(5);
        dirty_paint.setStrokeCap(Paint.Cap.ROUND);
        dirty_paint.setStrokeJoin(Paint.Join.ROUND);
        dirty_paint.setAntiAlias(false);

        fingerpaint = new Paint();
        fingerpaint.setColor(Color.GREEN);
        fingerpaint.setStrokeWidth(10);
        fingerpaint.setStyle(Paint.Style.STROKE);
        fingerpaint.setStrokeCap(Paint.Cap.ROUND);
        fingerpaint.setStrokeJoin(Paint.Join.ROUND);
        fingerpaint.setAntiAlias(false);

        temp_paint = new Paint();
        temp_paint.setColor(Color.RED);
        temp_paint.setStrokeWidth(1);
        temp_paint.setStyle(Paint.Style.STROKE);
        temp_paint.setStrokeCap(Paint.Cap.ROUND);
        temp_paint.setStrokeJoin(Paint.Join.ROUND);
        temp_paint.setAntiAlias(false);

        w = display.getWidth();
        h = display.getHeight();  
        clip.set(0, 0, w, h);

        orig_path.addRect(w*0.25f, h*0.55f, w*0.65f, h*0.65f, Path.Direction.CW);
        orig_region.setPath(orig_path, clip);           
    }

    @Override 
    protected void onDraw(Canvas c) {                       
        c.drawPath(orig_path, dirty_paint);
        c.drawPath(finger_path, fingerpaint);    
        //following line shows that finger_path is 
        //behaving as though fill and stroke is on
        //after being passed to the region class
        c.drawPath(tempregion.getBoundaryPath(), temp_paint);            
        invalidate();
    }

    //L T R B
    @Override 
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int)event.getX();
        int y = (int)event.getY();  

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
    }
        return true;         
}

    private void touch_start(float x, float y) {
        finger_path.moveTo(x, y);
        //finger_path.addCircle(x, y, 25, Path.Direction.CCW);
        //when addCircle is only Path method used on path the result is fine
    }

    private void touch_move(float x, float y){
        finger_path.lineTo(x, y);     
    }

    private void touch_up() {
        //*PROBLEM* Seems like setPath forces finger_path to default to fill and stroke
        fingerregion.setPath(finger_path, clip); 
        //set tempregion to the region resulting from this Op
        tempregion.op(orig_region, fingerregion, Region.Op.DIFFERENCE);
        //check if the resulting region is empty
        if(tempregion.isEmpty()){
            for(int i = 0;i<100;i++)
                Log.e("CR", "Region Completely Covered.");
        }
    }
}

}

My basic goal is to subtract a Path from a predetermined region (also created with a Path) in Android 1.6.

Is there anyway to get Region.setPath to treat the path passed to it the same way the canvas treats a stroked path (which is what my users are seeing)?

I understand that the Style is used for Painting to the canvas, but I need the behavior to reflect what is drawn on canvas and the path being drawn is Stroked.

The behavior works find when adding shapes to the path (path.addRect, path.addCircle), but not when using lineTo, quadTo, cubeTo. My only other option is to compose a path of nothing but rects or circles.

public class ComplexRegions extends Activity {

static Display display;

/** Code Sample for StackOverflow */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    display = getWindowManager().getDefaultDisplay();
    setContentView(new SampleView(this));             
}

private static class SampleView extends View {      
    Path orig_path, finger_path;
    Paint dirty_paint, fingerpaint, temp_paint;
    Region orig_region, clip, fingerregion, tempregion;
    Canvas c;
    int h, w;

    public float mX, mY, dx, dy;
    boolean b;

    public SampleView(Context context) {
        super(context);

        fingerregion = new Region();
        tempregion = new Region();
        orig_region = new Region();
        clip = new Region();
        orig_path = new Path();
        finger_path = new Path();

        dirty_paint = new Paint();
        dirty_paint.setStyle(Paint.Style.STROKE);
        dirty_paint.setColor(Color.BLUE);
        dirty_paint.setStrokeWidth(5);
        dirty_paint.setStrokeCap(Paint.Cap.ROUND);
        dirty_paint.setStrokeJoin(Paint.Join.ROUND);
        dirty_paint.setAntiAlias(false);

        fingerpaint = new Paint();
        fingerpaint.setColor(Color.GREEN);
        fingerpaint.setStrokeWidth(10);
        fingerpaint.setStyle(Paint.Style.STROKE);
        fingerpaint.setStrokeCap(Paint.Cap.ROUND);
        fingerpaint.setStrokeJoin(Paint.Join.ROUND);
        fingerpaint.setAntiAlias(false);

        temp_paint = new Paint();
        temp_paint.setColor(Color.RED);
        temp_paint.setStrokeWidth(1);
        temp_paint.setStyle(Paint.Style.STROKE);
        temp_paint.setStrokeCap(Paint.Cap.ROUND);
        temp_paint.setStrokeJoin(Paint.Join.ROUND);
        temp_paint.setAntiAlias(false);

        w = display.getWidth();
        h = display.getHeight();  
        clip.set(0, 0, w, h);

        orig_path.addRect(w*0.25f, h*0.55f, w*0.65f, h*0.65f, Path.Direction.CW);
        orig_region.setPath(orig_path, clip);           
    }

    @Override 
    protected void onDraw(Canvas c) {                       
        c.drawPath(orig_path, dirty_paint);
        c.drawPath(finger_path, fingerpaint);    
        //following line shows that finger_path is 
        //behaving as though fill and stroke is on
        //after being passed to the region class
        c.drawPath(tempregion.getBoundaryPath(), temp_paint);            
        invalidate();
    }

    //L T R B
    @Override 
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int)event.getX();
        int y = (int)event.getY();  

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
    }
        return true;         
}

    private void touch_start(float x, float y) {
        finger_path.moveTo(x, y);
        //finger_path.addCircle(x, y, 25, Path.Direction.CCW);
        //when addCircle is only Path method used on path the result is fine
    }

    private void touch_move(float x, float y){
        finger_path.lineTo(x, y);     
    }

    private void touch_up() {
        //*PROBLEM* Seems like setPath forces finger_path to default to fill and stroke
        fingerregion.setPath(finger_path, clip); 
        //set tempregion to the region resulting from this Op
        tempregion.op(orig_region, fingerregion, Region.Op.DIFFERENCE);
        //check if the resulting region is empty
        if(tempregion.isEmpty()){
            for(int i = 0;i<100;i++)
                Log.e("CR", "Region Completely Covered.");
        }
    }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文