示例#1
0
static SkShader* make_shader() {
    int a = 0x99;
    int b = 0xBB;
    SkPoint pts[] = { { 0, 0 }, { W, H } };
    SkColor colors[] = { SkColorSetRGB(a, a, a), SkColorSetRGB(b, b, b) };
    return SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
}
示例#2
0
int tool_main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage("Creates a simple .skp file for testing.");
    SkCommandLineFlags::Parse(argc, argv);

    // Validate flags.
    if ((FLAGS_blue < 0) || (FLAGS_blue > 255)) {
        SkDebugf("--blue must be within range [0,255]\n");
        exit(-1);
    }
    if ((FLAGS_green < 0) || (FLAGS_green > 255)) {
        SkDebugf("--green must be within range [0,255]\n");
        exit(-1);
    }
    if (FLAGS_height <= 0) {
        SkDebugf("--height must be >0\n");
        exit(-1);
    }
    if ((FLAGS_red < 0) || (FLAGS_red > 255)) {
        SkDebugf("--red must be within range [0,255]\n");
        exit(-1);
    }
    if (FLAGS_width <= 0) {
        SkDebugf("--width must be >0\n");
        exit(-1);
    }
    if (FLAGS_writePath.isEmpty()) {
        SkDebugf("--writePath must be nonempty\n");
        exit(-1);
    }

    SkColor color = SkColorSetRGB(FLAGS_red, FLAGS_green, FLAGS_blue);
    skpmaker(FLAGS_width, FLAGS_height, FLAGS_border, color, FLAGS_writePath[0]);
    return 0;
}
void
_DC::SetTextColor(COLORREF crText){
	if( !context_ ) return;
	if (_canvas)
		_skPaintText.setColor(SkColorSetRGB(_GetRValue(crText), _GetGValue(crText), _GetBValue(crText)));
	::SetTextColor(context_, crText);
	}
示例#4
0
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint rectPaint;
        rectPaint.setStyle(SkPaint::kStroke_Style);
        rectPaint.setStrokeWidth(-1);

        SkPaint fillPaint;
        fillPaint.setColor(SkColorSetRGB(0xA0,0xDD,0xA0));

        for (int i = 0; i < kRows; ++i) {
            for (int j = 0; j < kCols; ++j) {
                canvas->save();

                canvas->translate(kPadX * SK_Scalar1 + (fWidth + kPadX * SK_Scalar1)*j,
                                  kPadY * SK_Scalar1 + (fHeight + kPadY * SK_Scalar1)*i);

                // draw the original shapes first so we can see the
                // antialiasing on the clipped draw
                for (int k = 0; k < 5; ++k) {
                    rectPaint.setColor(fRectColors[k]);
                    switch (fClip) {
                        case kRect_Clip:
                            canvas->drawRect(fRects[k], rectPaint);
                            break;
                        case kRRect_Clip:
                            canvas->drawRRect(fRRects[k], rectPaint);
                            break;
                        case kPath_Clip:
                            canvas->drawPath(fPaths[k], rectPaint);
                            break;
                    }
                }

                for (int k = 0; k < 5; ++k) {
                    switch (fClip) {
                        case kRect_Clip:
                            canvas->clipRect(fRects[k],
                                             fOps[j*kRows+i][k],
                                             fAntiAlias);
                            break;
                        case kRRect_Clip:
                            canvas->clipRRect(fRRects[k],
                                              fOps[j*kRows+i][k],
                                              fAntiAlias);
                            break;
                        case kPath_Clip:
                            canvas->clipPath(fPaths[k],
                                             fOps[j*kRows+i][k],
                                             fAntiAlias);
                            break;
                    }
                }
                canvas->drawRect(SkRect::MakeWH(fWidth, fHeight), fillPaint);
                canvas->restore();
            }
        }
    }
示例#5
0
static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,
                                 SkColorTable*) {
    SkASSERT(width > 0);
    const SkPMColor* s = (const SkPMColor*)src;
    do {
        SkPMColor c = SkPixel4444ToPixel32(*s++);
        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
                               SkGetPackedB32(c));
    } while (--width != 0);
}
示例#6
0
static void ToColor_S565(SkColor dst[], const void* src, int width,
                         SkColorTable*) {
    SkASSERT(width > 0);
    const uint16_t* s = (const uint16_t*)src;
    do {
        uint16_t c = *s++;
        *dst++ =  SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c),
                                SkPacked16ToB32(c));
    } while (--width != 0);
}
    LightingView() {
        SkString diffusePath = GetResourcePath("brickwork-texture.jpg");
        SkImageDecoder::DecodeFile(diffusePath.c_str(), &fDiffuseBitmap);
        SkString normalPath = GetResourcePath("brickwork_normal-map.jpg");
        SkImageDecoder::DecodeFile(normalPath.c_str(), &fNormalBitmap);

        fLightAngle = 0.0f;
        fColorFactor = 0;

        LightingShader::Light light;
        light.fColor = SkColorSetRGB(0xff, 0xff, 0xff);
        light.fDirection.fX = SkScalarSin(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f);
        light.fDirection.fY = SkScalarCos(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f);
        light.fDirection.fZ = SkScalarCos(SK_ScalarPI*0.25f);

        SkColor ambient = SkColorSetRGB(0x1f, 0x1f, 0x1f);

        fShader.reset(SkNEW_ARGS(LightingShader, (fDiffuseBitmap, fNormalBitmap, light, ambient)));
    }
示例#8
0
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
                               SkColorTable* ctable) {
    SkASSERT(width > 0);
    const uint8_t* s = (const uint8_t*)src;
    const SkPMColor* colors = ctable->lockColors();
    do {
        SkPMColor c = colors[*s++];
        *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
                               SkGetPackedB32(c));
    } while (--width != 0);
    ctable->unlockColors(false);
}
示例#9
0
static void draw(SkCanvas* canvas, SkRect& target, int x, int y) {
    SkPaint borderPaint;
    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
    borderPaint.setAntiAlias(true);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
    backgroundPaint.setAntiAlias(true);
    SkPaint foregroundPaint;
    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
    foregroundPaint.setAntiAlias(true);

    canvas->save();
    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
    canvas->drawRect(target, borderPaint);
    target.inset(SkIntToScalar(2), SkIntToScalar(2));
    canvas->drawRect(target, backgroundPaint);
    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
    canvas->drawRect(target, foregroundPaint);
    canvas->restore();
}
示例#10
0
static void create_gradient(SkBitmap* bm) {
    SkASSERT(1 == bm->width());
    const int height = bm->height();

    float deltaB = 255.0f / height;
    float blue = 255.0f;

    SkAutoLockPixels lock(*bm);
    for (int y = 0; y < height; y++) {
        *bm->getAddr32(0, y) = SkColorSetRGB(0, 0, (U8CPU) blue);
        blue -= deltaB;
    }
}
示例#11
0
void Font::drawComplexText(GraphicsContext* graphicsContext,
                           const TextRun& run,
                           const FloatPoint& point,
                           int from,
                           int to) const
{
    PlatformGraphicsContext* context = graphicsContext->platformContext();
    UniscribeHelperTextRun state(run, *this);

    SkColor color = graphicsContext->platformContext()->effectiveFillColor();
    unsigned char alpha = SkColorGetA(color);
    // Skip 100% transparent text; no need to draw anything.
    if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
        return;

#if USE(SKIA_TEXT)
    HDC hdc = 0;
#else
    TransparencyAwareUniscribePainter painter(graphicsContext, this, run, from, to, point);

    HDC hdc = painter.hdc();
    if (windowsCanHandleTextDrawing(graphicsContext) && !hdc)
        return;

    // TODO(maruel): http://b/700464 SetTextColor doesn't support transparency.
    // Enforce non-transparent color.
    color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
    if (hdc) {
        SetTextColor(hdc, skia::SkColorToCOLORREF(color));
        SetBkMode(hdc, TRANSPARENT);
    }

    // If there is a non-blur shadow and both the fill color and shadow color 
    // are opaque, handle without skia. 
    FloatSize shadowOffset;
    float shadowBlur;
    Color shadowColor;
    ColorSpace shadowColorSpace;
    if (graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace) && windowsCanHandleDrawTextShadow(graphicsContext)) {
        COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
        COLORREF savedTextColor = GetTextColor(hdc);
        SetTextColor(hdc, textColor);
        state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowOffset.width(),
                   static_cast<int>(point.y() - fontMetrics().ascent()) + shadowOffset.height(), from, to);
        SetTextColor(hdc, savedTextColor); 
    }
#endif
    // Uniscribe counts the coordinates from the upper left, while WebKit uses
    // the baseline, so we have to subtract off the ascent.
    state.draw(graphicsContext, hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), from, to);
}
示例#12
0
static void draw_rotated_image(SkCanvas* canvas, const SkImage* image) {
    sk_tool_utils::draw_checkerboard(canvas, SkColorSetRGB(156, 154, 156),
                                     SK_ColorWHITE, 12);
    if (!image) {
        return;
    }
    SkRect rect = SkRect::MakeLTRB(-68.0f, -68.0f, 68.0f, 68.0f);
    SkPaint paint;
    paint.setColor(SkColorSetRGB(49, 48, 49));
    SkScalar scale = SkTMin(128.0f / image->width(),
                            128.0f / image->height());
    SkScalar point[2] = {-0.5f * image->width(), -0.5f * image->height()};
    for (int j = 0; j < 4; ++j) {
        for (int i = 0; i < 4; ++i) {
            SkAutoCanvasRestore autoCanvasRestore(canvas, true);
            canvas->translate(96.0f + 192.0f * i, 96.0f + 192.0f * j);
            canvas->rotate(18.0f * (i + 4 * j));
            canvas->drawRect(rect, paint);
            canvas->scale(scale, scale);
            canvas->drawImage(image, point[0], point[1]);
        }
    }
}
示例#13
0
void DemoLabel::CreateDemoView(view::View* container)
{
    link_ = new view::Link(L"Click me!");
    link_->set_listener(this);
    link_custom_ = new view::Link(L"Click me!");
    link_custom_->set_listener(this);
    link_custom_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
        ui::ResourceBundle::BoldFont));
    link_custom_->SetNormalColor(SK_ColorMAGENTA);
    link_custom_->SetHighlightedColor(SK_ColorGREEN);
    link_disable_ = new view::Link(L"Click me! Oops, I'm disabled!");
    link_disable_->SetEnabled(false);
    link_disable_->set_listener(this);
    link_disable_custom_ = new view::Link(L"Click me! Oops, I'm disabled!");
    link_disable_custom_->SetEnabled(false);
    link_disable_custom_->SetDisabledColor(SK_ColorGRAY);
    link_disable_custom_->set_listener(this);

    separator_ = new view::Separator();

    label_ = new view::Label(L"I'm a Label!");
    label_->SetColor(SkColorSetRGB(142, 233, 233));
    label_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
        ui::ResourceBundle::LargeFont));
    label_align_left_ = new view::Label(L"I'm a Label!");
    label_align_left_->SetHorizontalAlignment(view::Label::ALIGN_LEFT);
    label_align_right_ = new view::Label(L"I'm a Label!");
    label_align_right_->SetHorizontalAlignment(view::Label::ALIGN_RIGHT);
    label_multi_line_ = new view::Label(L"I'm a Label! \nTihs's the second line.");
    label_multi_line_->SetMultiLine(true);
    label_multi_line_->SizeToFit(label_multi_line_->width());
    label_multi_line_->SetTooltipText(L"¶àÐбêÇ©");

    container->SetLayoutManager(new view::BoxLayout(
        view::BoxLayout::kVertical, 5, 5, 5));
    container->AddChildView(link_);
    container->AddChildView(link_custom_);
    container->AddChildView(link_disable_);
    container->AddChildView(link_disable_custom_);

    container->AddChildView(separator_);

    container->AddChildView(label_);
    container->AddChildView(label_align_left_);
    container->AddChildView(label_align_right_);
    container->AddChildView(label_multi_line_);
}
bool SkSVGAttributeParser::parseRGBColorToken(SkColor* c) {
    return this->parseParenthesized("rgb", [this](SkColor* c) -> bool {
        int32_t r, g, b;
        if (this->parseColorComponentToken(&r) &&
            this->parseSepToken() &&
            this->parseColorComponentToken(&g) &&
            this->parseSepToken() &&
            this->parseColorComponentToken(&b)) {

            *c = SkColorSetRGB(static_cast<uint8_t>(r),
                               static_cast<uint8_t>(g),
                               static_cast<uint8_t>(b));
            return true;
        }
        return false;
    }, c);
}
示例#15
0
bool SkGradientShaderBase::onAsLuminanceColor(SkColor* lum) const {
    // we just compute an average color.
    // possibly we could weight this based on the proportional width for each color
    //   assuming they are not evenly distributed in the fPos array.
    int r = 0;
    int g = 0;
    int b = 0;
    const int n = fColorCount;
    for (int i = 0; i < n; ++i) {
        SkColor c = fOrigColors[i];
        r += SkColorGetR(c);
        g += SkColorGetG(c);
        b += SkColorGetB(c);
    }
    *lum = SkColorSetRGB(rounded_divide(r, n), rounded_divide(g, n), rounded_divide(b, n));
    return true;
}
int
_DC::FillSolidRect(RECTDef* pRect, COLORREF crFillColor){
	if( !context_ ) return 0;

	int nRet = 0;
	if (_canvas) {
		SkPaint paint;
		paint.setColor(SkColorSetRGB(_GetRValue(crFillColor), _GetGValue(crFillColor), _GetBValue(crFillColor)));
		
		SkRect rect;
		// Invert rect cords for windows memory bitmap.
		if (this->image_) {
			int height = _canvas->imageInfo().fHeight;
			rect.setLTRB(SkIntToScalar(pRect->left),
				SkIntToScalar(height - pRect->top),
				SkIntToScalar(pRect->right),
				SkIntToScalar(height - pRect->bottom));
		}
		else {
			rect.setLTRB(SkIntToScalar(pRect->left),
				SkIntToScalar(pRect->top),
				SkIntToScalar(pRect->right),
				SkIntToScalar(pRect->bottom));
		}
		_canvas->drawRect(rect, paint);
		
		/*
		SkImageInfo imageInfo;
		imageInfo.fAlphaType = SkAlphaType::kOpaque_SkAlphaType;
		imageInfo.fColorType = SkColorType::kN32_SkColorType;
		imageInfo.fHeight = 5;
		imageInfo.fWidth = 5;

		SkBitmap bm;
		bm.setInfo(imageInfo);

		_canvas->readPixels(&bm, 0, 0);*/
		}
	else {
		HBRUSH	hBrush = CreateSolidBrush(crFillColor);
		nRet = ::FillRect(context_, pRect, hBrush);
		::DeleteObject(hBrush);
		}
	return nRet;
	}
示例#17
0
SkColor GrTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) {
    SkColor canonicalColor = SkPaintPriv::ComputeLuminanceColor(paint);
    if (lcd) {
        // This is the correct computation, but there are tons of cases where LCD can be overridden.
        // For now we just regenerate if any run in a textblob has LCD.
        // TODO figure out where all of these overrides are and see if we can incorporate that logic
        // at a higher level *OR* use sRGB
        SkASSERT(false);
        //canonicalColor = SkMaskGamma::CanonicalColor(canonicalColor);
    } else {
        // A8, though can have mixed BMP text but it shouldn't matter because BMP text won't have
        // gamma corrected masks anyways, nor color
        U8CPU lum = SkComputeLuminance(SkColorGetR(canonicalColor),
                                       SkColorGetG(canonicalColor),
                                       SkColorGetB(canonicalColor));
        // reduce to our finite number of bits
        canonicalColor = SkMaskGamma::CanonicalColor(SkColorSetRGB(lum, lum, lum));
    }
    return canonicalColor;
}
示例#18
0
#include "SkShader.h"

#include "ui_gfx/canvas_skia.h"

#include "view/widget/widget.h"
#include "view/widget/native_widget_win.h"

#include "native_view_photobooth.h"

static const int kTransparentAlpha = 200;
static const int kOpaqueAlpha = 255;
static const int kDragFrameBorderSize = 2;
static const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize;
static const float kScalingFactor = 0.5;
static const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162);

////////////////////////////////////////////////////////////////////////////////
// DraggedTabView, public:

DraggedTabView::DraggedTabView(const std::vector<view::View*>& renderers,
                               const std::vector<gfx::Rect>& renderer_bounds,
                               const gfx::Point& mouse_tab_offset,
                               const gfx::Size& contents_size,
                               NativeViewPhotobooth* photobooth)
    : renderers_(renderers),
      renderer_bounds_(renderer_bounds),
      show_contents_on_drag_(true),
      mouse_tab_offset_(mouse_tab_offset),
      photobooth_(photobooth),
      contents_size_(contents_size)
示例#19
0
PassOwnPtr<DragImage> DragImage::create(const KURL& url, const String& inLabel, const FontDescription& systemFont, float deviceScaleFactor)
{
    const Font labelFont = deriveDragLabelFont(kDragLinkLabelFontSize, FontWeightBold, systemFont);
    const Font urlFont = deriveDragLabelFont(kDragLinkUrlFontSize, FontWeightNormal, systemFont);
    FontCachePurgePreventer fontCachePurgePreventer;

    bool drawURLString = true;
    bool clipURLString = false;
    bool clipLabelString = false;

    String urlString = url.string();
    String label = inLabel.stripWhiteSpace();
    if (label.isEmpty()) {
        drawURLString = false;
        label = urlString;
    }

    // First step is drawing the link drag image width.
    TextRun labelRun(label.impl());
    TextRun urlRun(urlString.impl());
    IntSize labelSize(labelFont.width(labelRun), labelFont.fontMetrics().ascent() + labelFont.fontMetrics().descent());

    if (labelSize.width() > kMaxDragLabelStringWidth) {
        labelSize.setWidth(kMaxDragLabelStringWidth);
        clipLabelString = true;
    }

    IntSize urlStringSize;
    IntSize imageSize(labelSize.width() + kDragLabelBorderX * 2, labelSize.height() + kDragLabelBorderY * 2);

    if (drawURLString) {
        urlStringSize.setWidth(urlFont.width(urlRun));
        urlStringSize.setHeight(urlFont.fontMetrics().ascent() + urlFont.fontMetrics().descent());
        imageSize.setHeight(imageSize.height() + urlStringSize.height());
        if (urlStringSize.width() > kMaxDragLabelStringWidth) {
            imageSize.setWidth(kMaxDragLabelWidth);
            clipURLString = true;
        } else
            imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + kDragLabelBorderX * 2);
    }

    // We now know how big the image needs to be, so we create and
    // fill the background
    IntSize scaledImageSize = imageSize;
    scaledImageSize.scale(deviceScaleFactor);
    OwnPtr<ImageBuffer> buffer(ImageBuffer::create(scaledImageSize));
    if (!buffer)
        return nullptr;

    buffer->canvas()->scale(deviceScaleFactor, deviceScaleFactor);

    const float DragLabelRadius = 5;

    IntRect rect(IntPoint(), imageSize);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(140, 140, 140));
    SkRRect rrect;
    rrect.setRectXY(SkRect::MakeWH(imageSize.width(), imageSize.height()), DragLabelRadius, DragLabelRadius);
    buffer->canvas()->drawRRect(rrect, backgroundPaint);

    // Draw the text
    SkPaint textPaint;
    if (drawURLString) {
        if (clipURLString)
            urlString = StringTruncator::centerTruncate(urlString, imageSize.width() - (kDragLabelBorderX * 2.0f), urlFont);
        IntPoint textPos(kDragLabelBorderX, imageSize.height() - (kLabelBorderYOffset + urlFont.fontMetrics().descent()));
        TextRun textRun(urlString);
        urlFont.drawText(buffer->canvas(), TextRunPaintInfo(textRun), textPos, deviceScaleFactor, textPaint);
    }

    if (clipLabelString)
        label = StringTruncator::rightTruncate(label, imageSize.width() - (kDragLabelBorderX * 2.0f), labelFont);

    bool hasStrongDirectionality;
    TextRun textRun = textRunWithDirectionality(label, &hasStrongDirectionality);
    IntPoint textPos(kDragLabelBorderX, kDragLabelBorderY + labelFont.fontDescription().computedPixelSize());
    if (hasStrongDirectionality && textRun.direction() == RTL) {
        float textWidth = labelFont.width(textRun);
        int availableWidth = imageSize.width() - kDragLabelBorderX * 2;
        textPos.setX(availableWidth - ceilf(textWidth));
    }
    labelFont.drawBidiText(buffer->canvas(), TextRunPaintInfo(textRun), FloatPoint(textPos), Font::DoNotPaintIfFontNotReady, deviceScaleFactor, textPaint);

    RefPtr<Image> image = buffer->newImageSnapshot();
    return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
}
示例#20
0
bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test,
                                   const BitmapsToCreate& bitmapsToCreate,
                                   Result* result) const {
    double startTime = get_seconds();

    // Ensure the images are comparable
    if (baseline->width() != test->width() || baseline->height() != test->height() ||
        baseline->width() <= 0 || baseline->height() <= 0 ||
        baseline->colorType() != test->colorType()) {
        SkASSERT(baseline->width() == test->width());
        SkASSERT(baseline->height() == test->height());
        SkASSERT(baseline->width() > 0);
        SkASSERT(baseline->height() > 0);
        SkASSERT(baseline->colorType() == test->colorType());
        return false;
    }

    int width = baseline->width();
    int height = baseline->height();
    int maxRedDiff = 0;
    int maxGreenDiff = 0;
    int maxBlueDiff = 0;

    // Prepare any bitmaps we will be filling in
    if (bitmapsToCreate.alphaMask) {
        result->poiAlphaMask.allocPixels(SkImageInfo::MakeA8(width, height));
        result->poiAlphaMask.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
    }
    if (bitmapsToCreate.rgbDiff) {
        result->rgbDiffBitmap.allocPixels(SkImageInfo::Make(width, height, baseline->colorType(),
                                                            kPremul_SkAlphaType));
        result->rgbDiffBitmap.eraseARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
    }
    if (bitmapsToCreate.whiteDiff) {
        result->whiteDiffBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
        result->whiteDiffBitmap.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
    }

    // Prepare the pixels for comparison
    result->poiCount = 0;
    baseline->lockPixels();
    test->lockPixels();
    for (int y = 0; y < height; y++) {
        // Grab a row from each image for easy comparison
        // TODO(epoger): The code below already assumes 4 bytes per pixel, so I think
        // we could just call getAddr32() to save a little time.
        // OR, if we want to play it safe, call ComputeBytesPerPixel instead
        // of assuming 4 bytes per pixel.
        uint32_t* baselineRow = static_cast<uint32_t *>(baseline->getAddr(0, y));
        uint32_t* testRow = static_cast<uint32_t *>(test->getAddr(0, y));
        for (int x = 0; x < width; x++) {
            // Compare one pixel at a time so each differing pixel can be noted
            // TODO(epoger): This loop looks like a good place to work on performance,
            // but we should run the code through a profiler to be sure.
            uint32_t baselinePixel = baselineRow[x];
            uint32_t testPixel = testRow[x];
            if (baselinePixel != testPixel) {
                result->poiCount++;

                int redDiff = SkTAbs(static_cast<int>(SkColorGetR(baselinePixel) -
                                                      SkColorGetR(testPixel)));
                if (redDiff > maxRedDiff) {maxRedDiff = redDiff;}
                int greenDiff = SkTAbs(static_cast<int>(SkColorGetG(baselinePixel) -
                                                        SkColorGetG(testPixel)));
                if (greenDiff > maxGreenDiff) {maxGreenDiff = greenDiff;}
                int blueDiff = SkTAbs(static_cast<int>(SkColorGetB(baselinePixel) -
                                                       SkColorGetB(testPixel)));
                if (blueDiff > maxBlueDiff) {maxBlueDiff = blueDiff;}

                if (bitmapsToCreate.alphaMask) {
                    *result->poiAlphaMask.getAddr8(x,y) = SK_AlphaTRANSPARENT;
                }
                if (bitmapsToCreate.rgbDiff) {
                    *result->rgbDiffBitmap.getAddr32(x,y) =
                        SkColorSetRGB(redDiff, greenDiff, blueDiff);
                }
                if (bitmapsToCreate.whiteDiff) {
                    *result->whiteDiffBitmap.getAddr32(x,y) = SK_ColorWHITE;
                }
            }
        }
    }
    test->unlockPixels();
    baseline->unlockPixels();

    result->maxRedDiff = maxRedDiff;
    result->maxGreenDiff = maxGreenDiff;
    result->maxBlueDiff = maxBlueDiff;

    if (bitmapsToCreate.alphaMask) {
        result->poiAlphaMask.unlockPixels();
    }
    if (bitmapsToCreate.rgbDiff) {
        result->rgbDiffBitmap.unlockPixels();
    }
    if (bitmapsToCreate.whiteDiff) {
        result->whiteDiffBitmap.unlockPixels();
    }

    // Calculates the percentage of identical pixels
    result->result = 1.0 - ((double)result->poiCount / (width * height));
    result->timeElapsed = get_seconds() - startTime;

    return true;
}
示例#21
0
void CCTiledLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData)
{
    const IntRect& contentRect = visibleContentRect();

    if (!m_tiler || m_tiler->hasEmptyBounds() || contentRect.isEmpty())
        return;

    CCSharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQuadState());
    appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData);

    int left, top, right, bottom;
    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);

    if (hasDebugBorders()) {
        for (int j = top; j <= bottom; ++j) {
            for (int i = left; i <= right; ++i) {
                DrawableTile* tile = tileAt(i, j);
                IntRect tileRect = m_tiler->tileBounds(i, j);
                SkColor borderColor;

                if (m_skipsDraw || !tile || !tile->resourceId())
                    borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderMissingTileColorRed, debugTileBorderMissingTileColorGreen, debugTileBorderMissingTileColorBlue);
                else
                    borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderColorRed, debugTileBorderColorGreen, debugTileBorderColorBlue);
                quadSink.append(CCDebugBorderDrawQuad::create(sharedQuadState, tileRect, borderColor, debugTileBorderWidth).PassAs<CCDrawQuad>(), appendQuadsData);
            }
        }
    }

    if (m_skipsDraw)
        return;

    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            DrawableTile* tile = tileAt(i, j);
            IntRect tileRect = m_tiler->tileBounds(i, j);
            IntRect displayRect = tileRect;
            tileRect.intersect(contentRect);

            // Skip empty tiles.
            if (tileRect.isEmpty())
                continue;

            if (!tile || !tile->resourceId()) {
                if (drawCheckerboardForMissingTiles()) {
                    SkColor defaultColor = SkColorSetRGB(defaultCheckerboardColorRed, defaultCheckerboardColorGreen, defaultCheckerboardColorBlue);
                    SkColor evictedColor = SkColorSetRGB(debugTileEvictedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue);
                    SkColor invalidatedColor = SkColorSetRGB(debugTileInvalidatedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue);

                    SkColor checkerColor;
                    if (hasDebugBorders())
                        checkerColor = tile ? invalidatedColor : evictedColor;
                    else
                        checkerColor = defaultColor;

                    appendQuadsData.hadMissingTiles |= quadSink.append(CCCheckerboardDrawQuad::create(sharedQuadState, tileRect, checkerColor).PassAs<CCDrawQuad>(), appendQuadsData);
                } else
                    appendQuadsData.hadMissingTiles |= quadSink.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()).PassAs<CCDrawQuad>(), appendQuadsData);
                continue;
            }

            IntRect tileOpaqueRect = tile->opaqueRect();
            tileOpaqueRect.intersect(contentRect);

            // Keep track of how the top left has moved, so the texture can be
            // offset the same amount.
            IntSize displayOffset = tileRect.minXMinYCorner() - displayRect.minXMinYCorner();
            IntPoint textureOffset = m_tiler->textureOffset(i, j) + displayOffset;
            float tileWidth = static_cast<float>(m_tiler->tileSize().width());
            float tileHeight = static_cast<float>(m_tiler->tileSize().height());
            IntSize textureSize(tileWidth, tileHeight);

            bool clipped = false;
            FloatQuad visibleContentInTargetQuad = CCMathUtil::mapQuad(drawTransform(), FloatQuad(visibleContentRect()), clipped);
            bool isAxisAlignedInTarget = !clipped && visibleContentInTargetQuad.isRectilinear();
            bool useAA = m_tiler->hasBorderTexels() && !isAxisAlignedInTarget;

            bool leftEdgeAA = !i && useAA;
            bool topEdgeAA = !j && useAA;
            bool rightEdgeAA = i == m_tiler->numTilesX() - 1 && useAA;
            bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA;

            const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST;
            quadSink.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tileOpaqueRect, tile->resourceId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA).PassAs<CCDrawQuad>(), appendQuadsData);
        }
    }
}
示例#22
0
void SkPixelXorXfermode::flatten(SkWriteBuffer& wb) const {
    wb.writeColor(SkColorSetRGB(SkGetPackedR32(fOpColor),
                                SkGetPackedG32(fOpColor),
                                SkGetPackedB32(fOpColor)));
}
示例#23
0
namespace WebTestRunner {

static const SkColor edgeColor     = SK_ColorBLACK;
static const SkColor readOnlyColor = SkColorSetRGB(0xe9, 0xc2, 0xa6);
static const SkColor bgColors[]    = {
    SkColorSetRGB(0xc9, 0xc9, 0xc9), // Disabled
    SkColorSetRGB(0x43, 0xf9, 0xff), // Hover (Win's "Hot")
    SkColorSetRGB(0x89, 0xc4, 0xff), // Normal
    SkColorSetRGB(0xa9, 0xff, 0x12), // Pressed
    SkColorSetRGB(0x00, 0xf3, 0xac), // Focused
    SkColorSetRGB(0xf3, 0xe0, 0xd0), // Readonly
};


blink::WebSize WebTestThemeEngineMock::getSize(WebThemeEngine::Part part)
{
    // FIXME: We use this constant to indicate we are being asked for the size of
    // a part that we don't expect to be asked about. We return a garbage value
    // rather than just asserting because this code doesn't have access to either
    // WTF or base to raise an assertion or do any logging :(.
    const blink::WebSize invalidPartSize = blink::WebSize(100, 100);

    switch (part) {
    case WebThemeEngine::PartScrollbarLeftArrow:
        return blink::WebSize(17, 15);
    case WebThemeEngine::PartScrollbarRightArrow:
        return invalidPartSize;
    case WebThemeEngine::PartScrollbarUpArrow:
        return blink::WebSize(15, 17);
    case WebThemeEngine::PartScrollbarDownArrow:
        return invalidPartSize;
    case WebThemeEngine::PartScrollbarHorizontalThumb:
        return blink::WebSize(15, 15);
    case WebThemeEngine::PartScrollbarVerticalThumb:
        return blink::WebSize(15, 15);
    case WebThemeEngine::PartScrollbarHorizontalTrack:
        return blink::WebSize(0, 15);
    case WebThemeEngine::PartScrollbarVerticalTrack:
        return blink::WebSize(15, 0);
    case WebThemeEngine::PartCheckbox:
    case WebThemeEngine::PartRadio:
        return blink::WebSize(13, 13);
    case WebThemeEngine::PartSliderThumb:
        return blink::WebSize(11, 21);
    case WebThemeEngine::PartInnerSpinButton:
        return blink::WebSize(15, 8);
    default:
        return invalidPartSize;
    }
}

static SkIRect webRectToSkIRect(const WebRect& webRect)
{
    SkIRect irect;
    irect.set(webRect.x, webRect.y,
        webRect.x + webRect.width - 1, webRect.y + webRect.height - 1);
    return irect;
}

static SkIRect validate(const SkIRect& rect, WebThemeEngine::Part part)
{
    switch (part) {
    case WebThemeEngine::PartCheckbox:
    case WebThemeEngine::PartRadio: {
        SkIRect retval = rect;

        // The maximum width and height is 13.
        // Center the square in the passed rectangle.
        const int maxControlSize = 13;
        int controlSize = std::min(rect.width(), rect.height());
        controlSize = std::min(controlSize, maxControlSize);

        retval.fLeft   = rect.fLeft + (rect.width() / 2) - (controlSize / 2);
        retval.fRight  = retval.fLeft + controlSize - 1;
        retval.fTop    = rect.fTop + (rect.height() / 2) - (controlSize / 2);
        retval.fBottom = retval.fTop + controlSize - 1;

        return retval;
    }
    default:
        return rect;
    }
}


void box(SkCanvas *canvas, const SkIRect& rect, SkColor fillColor)
{
    SkPaint paint;

    paint.setStyle(SkPaint::kFill_Style);
    paint.setColor(fillColor);
    canvas->drawIRect(rect, paint);

    paint.setColor(edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawIRect(rect, paint);
}

void line(SkCanvas *canvas, int x0, int y0, int x1, int y1, SkColor color)
{
    SkPaint paint;
    paint.setColor(color);
    canvas->drawLine(SkIntToScalar(x0), SkIntToScalar(y0),
        SkIntToScalar(x1), SkIntToScalar(y1), paint);
}

void triangle(SkCanvas *canvas,
    int x0, int y0,
    int x1, int y1,
    int x2, int y2,
    SkColor color)
{
    SkPath path;
    SkPaint paint;

    paint.setColor(color);
    paint.setStyle(SkPaint::kFill_Style);
    path.incReserve(4);
    path.moveTo(SkIntToScalar(x0), SkIntToScalar(y0));
    path.lineTo(SkIntToScalar(x1), SkIntToScalar(y1));
    path.lineTo(SkIntToScalar(x2), SkIntToScalar(y2));
    path.close();
    canvas->drawPath(path, paint);

    paint.setColor(edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawPath(path, paint);
}

void roundRect(SkCanvas *canvas, SkIRect irect, SkColor color)
{
    SkRect rect;
    SkScalar radius = SkIntToScalar(5);
    SkPaint paint;

    rect.set(irect);
    paint.setColor(color);
    paint.setStyle(SkPaint::kFill_Style);
    canvas->drawRoundRect(rect, radius, radius, paint);

    paint.setColor(edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawRoundRect(rect, radius, radius, paint);
}

void oval(SkCanvas* canvas, SkIRect irect, SkColor color)
{
    SkRect rect;
    SkPaint paint;

    rect.set(irect);
    paint.setColor(color);
    paint.setStyle(SkPaint::kFill_Style);
    canvas->drawOval(rect, paint);

    paint.setColor(edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawOval(rect, paint);
}

void circle(SkCanvas *canvas, SkIRect irect, SkScalar radius, SkColor color)
{
    int left = irect.fLeft;
    int width = irect.width();
    int height = irect.height();
    int top = irect.fTop;

    SkScalar cy = SkIntToScalar(top  + height / 2);
    SkScalar cx = SkIntToScalar(left + width / 2);
    SkPaint paint;

    paint.setColor(color);
    paint.setStyle(SkPaint::kFill_Style);
    canvas->drawCircle(cx, cy, radius, paint);

    paint.setColor(edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawCircle(cx, cy, radius, paint);
}

void nestedBoxes(SkCanvas *canvas,
    SkIRect irect,
    int indentLeft,
    int indentTop,
    int indentRight,
    int indentBottom,
    SkColor outerColor,
    SkColor innerColor)
{
    SkIRect lirect;
    box(canvas, irect, outerColor);
    lirect.set(irect.fLeft + indentLeft,
        irect.fTop + indentTop,
        irect.fRight - indentRight,
        irect.fBottom - indentBottom);
    box(canvas, lirect, innerColor);
}

void markState(SkCanvas *canvas, SkIRect irect, WebThemeEngine::State state)
{
    int left = irect.fLeft;
    int right = irect.fRight;
    int top = irect.fTop;
    int bottom = irect.fBottom;

    // The length of a triangle side for the corner marks.
    const int triangleSize = 5;

    switch (state) {
    case WebThemeEngine::StateDisabled:
    case WebThemeEngine::StateNormal:
        // Don't visually mark these states (color is enough).
        break;

    case WebThemeEngine::StateReadonly: {
        // The horizontal lines in a read only control are spaced by this amount.
        const int readOnlyLineOffset = 5;

        // Drawing lines across the control.
        for (int i = top + readOnlyLineOffset; i < bottom; i += readOnlyLineOffset)
            line(canvas, left + 1, i, right - 1, i, readOnlyColor);
        break;
    }
    case WebThemeEngine::StateHover:
        // Draw a triangle in the upper left corner of the control. (Win's "hot")
        triangle(canvas,
            left,                 top,
            left + triangleSize,  top,
            left,                 top + triangleSize,
            edgeColor);
        break;

    case WebThemeEngine::StateFocused:
        // Draw a triangle in the bottom right corner of the control.
        triangle(canvas,
            right,                bottom,
            right - triangleSize, bottom,
            right,                bottom - triangleSize,
            edgeColor);
        break;

    case WebThemeEngine::StatePressed:
        // Draw a triangle in the bottom left corner of the control.
        triangle(canvas,
            left,                 bottom,
            left,                 bottom - triangleSize,
            left + triangleSize,  bottom,
            edgeColor);
        break;

    default:
        // FIXME: Should we do something here to indicate that we got an invalid state?
        // Unfortunately, we can't assert because we don't have access to WTF or base.
        break;
    }
}

void WebTestThemeEngineMock::paint(
    blink::WebCanvas* canvas,
    WebThemeEngine::Part part,
    WebThemeEngine::State state,
    const blink::WebRect& rect,
    const WebThemeEngine::ExtraParams* extraParams)
{
    SkIRect irect = webRectToSkIRect(rect);
    SkPaint paint;

    // Indent amounts for the check in a checkbox or radio button.
    const int checkIndent = 3;

    // Indent amounts for short and long sides of the scrollbar notches.
    const int notchLongOffset = 1;
    const int notchShortOffset = 4;
    const int noOffset = 0;

    // Indent amounts for the short and long sides of a scroll thumb box.
    const int thumbLongIndent = 0;
    const int thumbShortIndent = 2;

    // Indents for the crosshatch on a scroll grip.
    const int gripLongIndent = 3;
    const int gripShortIndent = 5;

    // Indents for the the slider track.
    const int sliderIndent = 2;

    int halfHeight = irect.height() / 2;
    int halfWidth = irect.width() / 2;
    int quarterHeight = irect.height() / 4;
    int quarterWidth = irect.width() / 4;
    int left = irect.fLeft;
    int right = irect.fRight;
    int top = irect.fTop;
    int bottom = irect.fBottom;

    switch (part) {
    case WebThemeEngine::PartScrollbarDownArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarLeftArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            right - quarterWidth, top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + quarterWidth, top    + halfHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarRightArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + halfHeight,
            left  + quarterWidth, bottom - quarterHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarUpArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarHorizontalThumb: {
        // Draw a narrower box on top of the outside box.
        nestedBoxes(canvas, irect, thumbLongIndent, thumbShortIndent,
            thumbLongIndent, thumbShortIndent,
            bgColors[state], bgColors[state]);
        // Draw a horizontal crosshatch for the grip.
        int longOffset = halfWidth - gripLongIndent;
        line(canvas,
            left  + gripLongIndent, top    + halfHeight,
            right - gripLongIndent, top    + halfHeight,
            edgeColor);
        line(canvas,
            left  + longOffset,     top    + gripShortIndent,
            left  + longOffset,     bottom - gripShortIndent,
            edgeColor);
        line(canvas,
            right - longOffset,     top    + gripShortIndent,
            right - longOffset,     bottom - gripShortIndent,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalThumb: {
        // Draw a shorter box on top of the outside box.
        nestedBoxes(canvas, irect, thumbShortIndent, thumbLongIndent,
            thumbShortIndent, thumbLongIndent,
            bgColors[state], bgColors[state]);
        // Draw a vertical crosshatch for the grip.
        int longOffset = halfHeight - gripLongIndent;
        line(canvas,
            left  + halfWidth,       top    + gripLongIndent,
            left  + halfWidth,       bottom - gripLongIndent,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, top    + longOffset,
            right - gripShortIndent, top    + longOffset,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, bottom - longOffset,
            right - gripShortIndent, bottom - longOffset,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarHorizontalTrack: {
        int longOffset = halfHeight - notchLongOffset;
        int shortOffset = irect.width() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch on left
            nestedBoxes(canvas, irect, noOffset, longOffset, shortOffset,
                longOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch on right
            nestedBoxes(canvas, irect, shortOffset, longOffset, noOffset,
                longOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalTrack: {
        int longOffset = halfWidth - notchLongOffset;
        int shortOffset = irect.height() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch at top
            nestedBoxes(canvas, irect, longOffset, noOffset, longOffset,
                shortOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch at bottom
            nestedBoxes(canvas, irect, longOffset, shortOffset, longOffset,
                noOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartCheckbox:
        if (extraParams->button.indeterminate) {
            nestedBoxes(canvas, irect,
                checkIndent, halfHeight,
                checkIndent, halfHeight,
                bgColors[state], edgeColor);
        } else if (extraParams->button.checked) {
            irect = validate(irect, part);
            nestedBoxes(canvas, irect,
                checkIndent, checkIndent,
                checkIndent, checkIndent,
                bgColors[state], edgeColor);
        } else {
            irect = validate(irect, part);
            box(canvas, irect, bgColors[state]);
        }
        break;

    case WebThemeEngine::PartRadio:
        irect = validate(irect, part);
        halfHeight = irect.height() / 2;
        if (extraParams->button.checked) {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
            circle(canvas, irect, SkIntToScalar(halfHeight - checkIndent), edgeColor);
        } else {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
        }
        break;

    case WebThemeEngine::PartButton:
        roundRect(canvas, irect, bgColors[state]);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartTextField:
        paint.setColor(extraParams->textField.backgroundColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawIRect(irect, paint);

        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartMenuList:
        if (extraParams->menuList.fillContentArea) {
            box(canvas, irect, extraParams->menuList.backgroundColor);
        } else {
            SkPaint paint;
            paint.setColor(edgeColor);
            paint.setStyle(SkPaint::kStroke_Style);
            canvas->drawIRect(irect, paint);
        }

        // clip the drop-down arrow to be inside the select box
        if (extraParams->menuList.arrowX - 4 > irect.fLeft)
            irect.fLeft = extraParams->menuList.arrowX - 4;
        if (extraParams->menuList.arrowX + 12 < irect.fRight)
            irect.fRight = extraParams->menuList.arrowX + 12;

        irect.fTop = extraParams->menuList.arrowY - (extraParams->menuList.arrowHeight) / 2;
        irect.fBottom = extraParams->menuList.arrowY + (extraParams->menuList.arrowHeight - 1) / 2;
        halfWidth = irect.width() / 2;
        quarterWidth = irect.width() / 4;

        if (state == WebThemeEngine::StateFocused) // FIXME: draw differenty?
            state = WebThemeEngine::StateNormal;
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            irect.fLeft  + quarterWidth, irect.fTop,
            irect.fRight - quarterWidth, irect.fTop,
            irect.fLeft  + halfWidth,    irect.fBottom,
            edgeColor);

        break;

    case WebThemeEngine::PartSliderTrack: {
        SkIRect lirect =  irect;

        // Draw a narrow rect for the track plus box hatches on the ends.
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        if (extraParams->slider.vertical) {
            lirect.inset(halfWidth - sliderIndent, noOffset);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, right, top, edgeColor);
            line(canvas, left, bottom, right, bottom, edgeColor);
        } else {
            lirect.inset(noOffset, halfHeight - sliderIndent);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, left, bottom, edgeColor);
            line(canvas, right, top, right, bottom, edgeColor);
        }
        break;
    }

    case WebThemeEngine::PartSliderThumb:
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        oval(canvas, irect, bgColors[state]);
        break;

    case WebThemeEngine::PartInnerSpinButton: {
        // stack half-height up and down arrows on top of each other
        SkIRect lirect;
        int halfHeight = rect.height / 2;
        if (extraParams->innerSpin.readOnly)
            state = blink::WebThemeEngine::StateDisabled;

        lirect.set(rect.x, rect.y, rect.x + rect.width - 1, rect.y + halfHeight - 1);
        box(canvas, lirect, bgColors[state]);
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            edgeColor);

        lirect.set(rect.x, rect.y + halfHeight, rect.x + rect.width - 1,
            rect.y + 2 * halfHeight - 1);
        top = lirect.fTop;
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        box(canvas, lirect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }
    case WebThemeEngine::PartProgressBar: {
        paint.setColor(bgColors[state]);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        // Emulate clipping
        SkIRect tofill = irect;
        if (extraParams->progressBar.determinate) {
            tofill.set(extraParams->progressBar.valueRectX,
                extraParams->progressBar.valueRectY,
                extraParams->progressBar.valueRectX +
                extraParams->progressBar.valueRectWidth - 1,
                extraParams->progressBar.valueRectY +
                extraParams->progressBar.valueRectHeight);
        }

        tofill.intersect(irect, tofill);
        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(tofill, paint);

        markState(canvas, irect, state);
        break;
    }
    default:
        // FIXME: Should we do something here to indicate that we got an invalid part?
        // Unfortunately, we can't assert because we don't have access to WTF or base.
        break;
    }
}

} // namespace WebTestRunner
void NativeTabbedPaneWin::CreateNativeControl()
{
    // Create the tab control.
    //
    // Note that we don't follow the common convention for NativeControl
    // subclasses and we don't pass the value returned from
    // NativeControl::GetAdditionalExStyle() as the dwExStyle parameter. Here is
    // why: on RTL locales, if we pass NativeControl::GetAdditionalExStyle() when
    // we basically tell Windows to create our HWND with the WS_EX_LAYOUTRTL. If
    // we do that, then the HWND we create for |content_window_| below will
    // inherit the WS_EX_LAYOUTRTL property and this will result in the contents
    // being flipped, which is not what we want (because we handle mirroring in
    // views without the use of Windows' support for mirroring). Therefore,
    // we initially create our HWND without WS_EX_LAYOUTRTL and we explicitly set
    // this property our child is created. This way, on RTL locales, our tabs
    // will be nicely rendered from right to left (by virtue of Windows doing the
    // right thing with the TabbedPane HWND) and each tab contents will use an
    // RTL layout correctly (by virtue of the mirroring infrastructure in views
    // doing the right thing with each View we put in the tab).
    DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CLIPCHILDREN;
    HWND tab_control = ::CreateWindowEx(0,
                                        WC_TABCONTROL,
                                        L"",
                                        style,
                                        0, 0, width(), height(),
                                        GetWidget()->GetNativeView(), NULL, NULL,
                                        NULL);
    ui::CheckWindowCreated(tab_control);

    HFONT font = ui::ResourceBundle::GetSharedInstance().
                 GetFont(ui::ResourceBundle::BaseFont).GetNativeFont();
    SendMessage(tab_control, WM_SETFONT, reinterpret_cast<WPARAM>(font), FALSE);

    // Create the view container which is a child of the TabControl.
    content_window_ = new Widget;
    Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
    params.parent = tab_control;
    content_window_->Init(params);

    // Explicitly setting the WS_EX_LAYOUTRTL property for the HWND (see above
    // for why we waited until |content_window_| is created before we set this
    // property for the tabbed pane's HWND).
    if(base::i18n::IsRTL())
    {
        ui::HWNDSetRTLLayout(tab_control);
    }

    View* root_view = content_window_->GetRootView();
    tab_layout_manager_ = new TabLayout();
    root_view->SetLayoutManager(tab_layout_manager_);
    DWORD sys_color = ::GetSysColor(COLOR_3DHILIGHT);
    SkColor color = SkColorSetRGB(GetRValue(sys_color), GetGValue(sys_color),
                                  GetBValue(sys_color));
    root_view->set_background(Background::CreateSolidBackground(color));

    content_window_->SetFocusTraversableParentView(this);

    NativeControlCreated(tab_control);

    // Add tabs that are already added if any.
    if(!tab_views_.empty())
    {
        InitializeTabs();
        if(selected_index_ >= 0)
        {
            DoSelectTabAt(selected_index_, false);
        }
    }

    ResizeContents();
}
bool RenderThemeChromiumSkia::paintMediaSliderTrack(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
#if ENABLE(VIDEO)
    HTMLMediaElement* mediaElement = mediaElementParent(object->node());
    if (!mediaElement)
        return false;

    SkCanvas* canvas = paintInfo.context->platformContext()->canvas();
    SkRect backgroundRect;
    backgroundRect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());

    SkPaint paint;
    paint.setAntiAlias(true);

    // Draw the border of the time bar. The border only has one single color,
    // width and radius. So use the property of the left border.
    SkColor borderColor = object->style()->borderLeftColor().rgb();
    int borderWidth = object->style()->borderLeftWidth();
    IntSize borderRadius = object->style()->borderTopLeftRadius();
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(borderWidth);
    paint.setColor(borderColor);
    canvas->drawRoundRect(backgroundRect, borderRadius.width(), borderRadius.height(), paint);

    // Draw the background of the time bar.
    SkColor backgroundColor = object->style()->backgroundColor().rgb();
    paint.setStyle(SkPaint::kFill_Style);
    paint.setColor(backgroundColor);
    canvas->drawRoundRect(backgroundRect, borderRadius.width(), borderRadius.height(), paint);

    if (backgroundRect.width() >= 3 && backgroundRect.height() >= 3)
    {
        // Draw the buffered ranges.
        // FIXME: Draw multiple ranges if there are multiple buffered ranges.
        SkRect bufferedRect;
        bufferedRect.set(backgroundRect.fLeft + 2, backgroundRect.fTop + 2,
                         backgroundRect.fRight - 1, backgroundRect.fBottom - 1);
        int width = static_cast<int>(bufferedRect.width() * mediaElement->percentLoaded());
        bufferedRect.fRight = bufferedRect.fLeft + width;

        SkPoint points[2] = { { 0, bufferedRect.fTop }, { 0, bufferedRect.fBottom } };
        SkColor startColor = object->style()->color().rgb();
        SkColor endColor = SkColorSetRGB(SkColorGetR(startColor) / 2,
                                         SkColorGetG(startColor) / 2,
                                         SkColorGetB(startColor) / 2);
        SkColor colors[2] = { startColor, endColor };
        SkShader* gradient = SkGradientShader::CreateLinear(points, colors, 0,
                                                            sizeof(points) / sizeof(points[0]),
                                                            SkShader::kMirror_TileMode, 0);

        paint.reset();
        paint.setShader(gradient);
        paint.setAntiAlias(true);
        // Check for round rect with zero width or height, otherwise Skia will assert
        if (bufferedRect.width() > 0 && bufferedRect.height() > 0)
            canvas->drawRoundRect(bufferedRect, borderRadius.width(), borderRadius.height(), paint);
        gradient->unref();
    }
    return true;
#else
    UNUSED_PARAM(object);
    UNUSED_PARAM(paintInfo);
    UNUSED_PARAM(rect);
    return false;
#endif
}