Project: skia Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Issue 943 [PDF] xfermode SrcIn and SrcOut don't really work
Starred by 5 users Project Member Reported by edisonn@google.com, Oct 21 2012 Back to list
Status: Accepted
Owner:
Cc:
Area: PDF
Priority: Medium
Type: Defect



Sign in to add a comment
See haimodes gm trimmed down to having two ovals, the one on top with SrcIn or SrcOut


/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkShader.h"

static const struct {
    SkXfermode::Mode  fMode;
    const char*         fLabel;
} gModes[] = {
    { SkXfermode::kClear_Mode,    "Clear"     },
    { SkXfermode::kSrc_Mode,      "Src"       },
    { SkXfermode::kDst_Mode,      "Dst"       },
    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
    { SkXfermode::kDstOver_Mode,  "DstOver"   },
    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
    { SkXfermode::kDstIn_Mode,    "DstIn"     },
    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
    { SkXfermode::kDstOut_Mode,   "DstOut"    },
    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
    { SkXfermode::kDstATop_Mode,  "DstATop"   },
    { SkXfermode::kXor_Mode,      "Xor"       },
};

const int gWidth = 64;
const int gHeight = 64;
const SkScalar W = SkIntToScalar(gWidth);
const SkScalar H = SkIntToScalar(gHeight);

#define foo 1

static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) {

    SkPaint paint;
    //paint.setAntiAlias(true);

    SkRect r = SkRect::MakeWH(W, H);
    r.inset(W/10, H/10);

    paint.setColor(SK_ColorBLUE);
    //paint.setAlpha(a0);
    canvas->drawOval(r, paint);

    paint.setColor(SK_ColorRED);
    //paint.setAlpha(a1);
    paint.setXfermode(mode);
    for (int angle = 0; angle < foo; ++angle) {
        SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / foo) * gWidth;
        SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / foo) * gHeight;
        paint.setStrokeWidth(SK_Scalar1 * angle * 2 / foo);
        //canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
        r.inset(W/10, H/10);
        canvas->drawOval(r, paint);
    }
    return H;
}

static SkShader* make_bg_shader() {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
    bm.allocPixels();
    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);

    SkShader* s = SkShader::CreateBitmapShader(bm,
                                               SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode);

    SkMatrix m;
    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
    s->setLocalMatrix(m);
    return s;
}

namespace skiagm {

    class HairModesGM : public GM {
        SkPaint fBGPaint;
    public:
        HairModesGM() {
            //fBGPaint.setShader(make_bg_shader())->unref();
        }

    protected:

        virtual SkString onShortName() {
            return SkString("hairmodes");
        }

        virtual SkISize onISize() { return make_isize(640, 480); }

        virtual void onDraw(SkCanvas* canvas) {
            const SkRect bounds = SkRect::MakeWH(W, H);
            static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };

            canvas->translate(SkIntToScalar(4), SkIntToScalar(4));

            for (int alpha = 0; alpha < 1/*4*/; ++alpha) {
            //    canvas->save();
            //    canvas->save();
                for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
                    if (i != 5) continue; // 5 is SrcIn, 7 is SrcOut
                    if (6 == i) {
                        canvas->restore();
                        canvas->translate(W * 5, 0);
                        canvas->save();
                    }
                    SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);

                    canvas->drawRect(bounds, fBGPaint);
                    //canvas->saveLayer(&bounds, NULL);
                    SkScalar dy = drawCell(canvas, mode,
                                           gAlphaValue[alpha & 1],
                                           gAlphaValue[alpha & 2]);
                    //canvas->restore();

                    canvas->translate(0, dy * 5 / 4);
                    SkSafeUnref(mode);
                }
           //     canvas->restore();
           //     canvas->restore();
                canvas->translate(W * 5 / 4, 0);
            }
        }

    private:
        typedef GM INHERITED;
    };

    //////////////////////////////////////////////////////////////////////////////

    static GM* MyFactory(void*) { return new HairModesGM; }
    static GMRegistry reg(MyFactory);


 
hairmodes_pdf.png
6.2 KB View Download
hairmodes_pdf.pdf
2.5 KB Download
hairmodes_8888.png
6.9 KB View Download
Project Member Comment 1 by vandebo@chromium.org, Oct 22 2012
I have a CL that improves the way xfer modes work that I've never gotten around to landing.  Before spending too much time debugging this, you might see if that CL fixes things: https://codereview.appspot.com/4631078/
Project Member Comment 2 by edisonn@google.com, Oct 25 2012
improvement result from https://codereview.appspot.com/4631078/
src_improve.zip
153 KB Download
Project Member Comment 3 by edisonn@google.com, Oct 24 2013
Labels: Area-PDF
Project Member Comment 4 by hcm@google.com, Jan 8 2014
Owner: bungeman@google.com
Project Member Comment 5 by hcm@google.com, Dec 7 2015
Labels: Hotlist-Fixit
Project Member Comment 6 by scro...@google.com, Dec 9 2015
Cc: bungeman@google.com
Owner: halcanary@google.com
Sign in to add a comment