// Same as OpaqueCompositeLayer, but the canvas has a rotation applied. This
// tests that the propert transform is applied to the copied layer.
TEST(TransparencyWin, RotateOpaqueCompositeLayer)
{
    OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), 1));

    // The background is white.
    Color white(0xFFFFFFFF);
    FloatRect fullRect(0, 0, 16, 16);
    src->context()->fillRect(fullRect, white);

    // Rotate the image by 90 degrees. This matrix is the same as
    // cw90.rotate(90); but avoids rounding errors. Rounding errors can cause
    // Skia to think that !rectStaysRect() and it will fall through to path
    // drawing mode, which in turn gives us antialiasing. We want no
    // antialiasing or other rounding problems since we're testing exact pixel
    // values.
    src->context()->save();
    AffineTransform cw90(0, 1, -1, 0, 0, 0);
    src->context()->concatCTM(cw90);

    // Make a transparency layer consisting of a horizontal line of 50% black.
    // Since the rotation is applied, this will actually be a vertical line
    // down the middle of the image.
    src->context()->beginTransparencyLayer(0.5);
    FloatRect blackRect(0, -9, 16, 2);
    Color black(0xFF000000);
    src->context()->fillRect(blackRect, black);

    // Now draw 50% red square.
    {
        // Create a transparency helper inset one pixel in the buffer. The
        // coordinates are before transforming into this space, and maps to
        // IntRect(1, 1, 14, 14).
        TransparencyWin helper;
        helper.init(src->context(),
                    TransparencyWin::OpaqueCompositeLayer,
                    TransparencyWin::Untransform,
                    IntRect(1, -15, 14, 14));

        // Fill with red.
        helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000));
        clearTopLayerAlphaChannel(helper.context());
        helper.composite();
    }

    // Finish the compositing.
    src->context()->endLayer();

    // Top corner should be the original background.
    EXPECT_EQ(white, getPixelAt(src->context(), 0, 0));

    // Check the stripe down the middle, first at the top...
    Color gray(0xFF808080);
    EXPECT_EQ(white, getPixelAt(src->context(), 6, 0));
    EXPECT_EQ(gray, getPixelAt(src->context(), 7, 0));
    EXPECT_EQ(gray, getPixelAt(src->context(), 8, 0));
    EXPECT_EQ(white, getPixelAt(src->context(), 9, 0));

    // ...now at the bottom.
    EXPECT_EQ(white, getPixelAt(src->context(), 6, 15));
    EXPECT_EQ(gray, getPixelAt(src->context(), 7, 15));
    EXPECT_EQ(gray, getPixelAt(src->context(), 8, 15));
    EXPECT_EQ(white, getPixelAt(src->context(), 9, 15));

    // Our red square should be 25% red over the top of those two.
    Color redwhite(0xFFdfbfbf);
    Color redgray(0xFF9f8080);
    EXPECT_EQ(white, getPixelAt(src->context(), 0, 1));
    EXPECT_EQ(redwhite, getPixelAt(src->context(), 1, 1));
    EXPECT_EQ(redwhite, getPixelAt(src->context(), 6, 1));
    EXPECT_EQ(redgray, getPixelAt(src->context(), 7, 1));
    EXPECT_EQ(redgray, getPixelAt(src->context(), 8, 1));
    EXPECT_EQ(redwhite, getPixelAt(src->context(), 9, 1));
    EXPECT_EQ(redwhite, getPixelAt(src->context(), 14, 1));
    EXPECT_EQ(white, getPixelAt(src->context(), 15, 1));

    // Complete the 50% transparent layer.
    src->context()->restore();
}
void CCardLabel::paintEvent(QPaintEvent *ev)
{
    QRectF titleRect(translatePoint(5, 2), translatePoint(155, 25));
    QRectF imgRect(translatePoint(5, 24), translatePoint(155, 144));
    QRectF blackRect(translatePoint(6, 24 + 40), translatePoint(156, 24 + 80));
    QRectF setRect(translatePoint(155 - 2 - 32, 144 + 8), translatePoint(155 - 2, 144 + 8 + 32));
    QRectF delayRect(translatePoint(155 - 40, 24), translatePoint(155,  24 + 40));
    QRectF attackRect(translatePoint(5 + 2, 215 - 20), translatePoint(5 + 2 + 20, 215));
    QRectF healthRect(translatePoint(155 - 2 - 20, 215 - 20), translatePoint(155 - 2, 215));
    QRectF ownedRect(translatePoint(155 - 60 - 2, 144 - 28), translatePoint(155 - 2, 144));
    QPointF upgradePos(translatePoint(50, 193));
    QPointF uniquePos(translatePoint(5 + 2, 144 - 28 - 2));
    QPointF skillPos(translatePoint(5 + 2, 144 + 8));

    // Update lock button geo before parent paint
    if (mLockButton)
    {
        mLockButton->setGeometry(QRect(imgRect.x() + 2, imgRect.y() + 2, 24, 24));
    }

    // Regular label painting (background image)
    QLabel::paintEvent(ev);

    if (mCard.isValid())
    {
        const CGlobalConfig &cfg = CGlobalConfig::getCfg();
        QPainter painter(this);

        // Paint upgrade symbol
        QString cardName = mCard.getName();
        if (mCard.getUpgradeLevel() != EUpgradeNotAvailable)
        {
            if (cardName.endsWith(QChar('*')))
            {
                cardName.replace("*", "");
            }
            switch(mCard.getUpgradeLevel())
            {
            case EUpgradeLevel1:
                painter.drawPixmap(upgradePos, QPixmap(cfg.getResourcePicturePath() + "UpgradeIcon1.png"));
                break;
            case EUpgradeLevel2:
                painter.drawPixmap(upgradePos, QPixmap(cfg.getResourcePicturePath() + "UpgradeIcon2.png"));
                break;
            default:
                break;
            }
        }

        // Paint title
        QPen inPen(Qt::white);
        painter.setPen(inPen);
        painter.drawText(titleRect.adjusted(titleRect.height() + 2, -1, 0, -1), Qt::AlignLeft | Qt::AlignVCenter, cardName);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
        if (!mTitleIcon.isNull())
        {
            painter.drawPixmap(titleRect.topLeft(), mTitleIcon.scaled(titleRect.height() + 1, titleRect.height() + 1, Qt::KeepAspectRatio, Qt::SmoothTransformation));
        }

        // Paint unique symbol
        if (mCard.isUnique())
        {
            painter.drawPixmap(uniquePos, QPixmap(":/img/unique.png"));
            //painter.drawText(dx + 2, dySkill - 15, 100, 12, Qt::AlignLeft | Qt::AlignVCenter, "Unique");
        }

        // Paint skill symbols
        const TSkillList &skills = mCard.getSkills();
        int curIdx = 0;
        for (TSkillList::const_iterator i = skills.begin(); i != skills.end(); ++i, ++curIdx)
        {
            const CSkill& curSkill = mCards.getSkillForId(i->getId());
            if (curSkill.isValid())
            {
                QPixmap skillPixmap;
                if (!skillPixmap.load(cfg.getResourcePicturePath() + curSkill.getPicture() + ".png"))
                {
                    skillPixmap.load(cfg.getCustomPicturePath() + curSkill.getPicture() + ".png");
                }
                painter.drawPixmap(skillPos, skillPixmap);
                skillPos += QPointF(16 + 2, 0);
                //painter.drawText(dx, 80 + i*10, 100, 10, Qt::AlignLeft | Qt::AlignVCenter, curSkill.makeSignature(skills.at(i)));
            }
        }

        // Paint set symbol
        if (mCard.getSet() != EUnknownSet)
        {
            QPixmap setPixmap;
            if (!setPixmap.load(cfg.getResourcePicturePath() + mCards.getPictureForCardSet(mCard.getSet())))
            {
                setPixmap.load(cfg.getCustomPicturePath() + mCards.getPictureForCardSet(mCard.getSet()));
            }
            painter.drawPixmap(setRect, setPixmap, QRectF(0, 0, 24, 24));
        }


        // Paint delay symbol
        if (mCard.getDelay() > -1)
        {
            painter.drawPixmap(delayRect, QPixmap(cfg.getResourcePicturePath() + "ClockIcon.png"), QRectF(0, 0, 32, 32));
            painter.drawText(delayRect, Qt::AlignCenter, QString("%1").arg(mCard.getDelay()));
        }

        // Paint attack symbol
        if (mCard.hasAttack())
        {
            painter.drawPixmap(attackRect, QPixmap(cfg.getResourcePicturePath() + "AttackIcon.png"), QRectF(0, 0, 20, 20));
            painter.drawText(attackRect.translated(attackRect.width() + 1, 0), Qt::AlignLeft | Qt::AlignVCenter, QString("%1").arg(mCard.getAttack()));
        }

        // Paint health symbol
        if (mCard.hasHealth())
        {
            painter.drawPixmap(healthRect, QPixmap(cfg.getResourcePicturePath() + "HealthIcon.png"), QRectF(0, 0, 20, 20));

            painter.drawText(healthRect.adjusted(-2 * healthRect.width() - 1, 0, -healthRect.width() - 1, 0), Qt::AlignRight | Qt::AlignVCenter, QString("%1").arg(mCard.getHealth()));
        }

        if (!mIsVirtual)
        {
            // Display owned status
            SCardStatus status = mCards.getCardStatus(mCard);
            {
                painter.setPen(Qt::green);
                QString ownageStr("x0");
                if (status.numOwned > 0)
                {
                    ownageStr = QString("x%1").arg(status.numOwned);
                }
                painter.drawText(ownedRect, Qt::AlignRight | Qt::AlignVCenter, ownageStr);
            }
            if (cfg.isCardShadingEnabled() && status.numOwned <= 0)
            {
                painter.setPen(Qt::NoPen);
                painter.setBrush(Qt::black);
                painter.setOpacity(0.6);
                painter.drawRoundedRect(rect(), 2.0, 2.0);
            }
            if (cfg.isBlackLabellingEnabled() && status.isBlack)
            {
                // Display black list status
                painter.setPen(Qt::white);
                painter.setOpacity(0.6);
                painter.fillRect(blackRect, QBrush(Qt::black));
                painter.setOpacity(1.0);
                painter.drawText(blackRect, Qt::AlignCenter, "Blacklisted");
            }
            else if (cfg.isWhiteLabellingEnabled() && status.isWhite)
            {
                // Display white list status
                painter.setPen(Qt::black);
                painter.setOpacity(0.6);
                painter.fillRect(blackRect, QBrush(Qt::white));
                painter.setOpacity(1.0);
                painter.drawText(blackRect, Qt::AlignCenter, "Whitelisted");
            }
        }
    }
}