virtual void onDraw(SkCanvas* canvas) { SkMatrix m; m.reset(); m.setRotate(33 * SK_Scalar1); m.postScale(3000 * SK_Scalar1, 3000 * SK_Scalar1); m.postTranslate(6000 * SK_Scalar1, -5000 * SK_Scalar1); canvas->concat(m); SkPaint paint; paint.setColor(SK_ColorRED); paint.setAntiAlias(true); bool success = m.invert(&m); SkASSERT(success); (void) success; // silence compiler :( SkPath path; SkPoint pt = {10 * SK_Scalar1, 10 * SK_Scalar1}; SkScalar small = 1 / (500 * SK_Scalar1); m.mapPoints(&pt, 1); path.addCircle(pt.fX, pt.fY, small); canvas->drawPath(path, paint); pt.set(30 * SK_Scalar1, 10 * SK_Scalar1); m.mapPoints(&pt, 1); SkRect rect = {pt.fX - small, pt.fY - small, pt.fX + small, pt.fY + small}; canvas->drawRect(rect, paint); SkBitmap bmp; bmp.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); bmp.allocPixels(); bmp.lockPixels(); uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels()); pixels[0] = SkPackARGB32(0xFF, 0xFF, 0x00, 0x00); pixels[1] = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00); pixels[2] = SkPackARGB32(0x80, 0x00, 0x00, 0x00); pixels[3] = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF); bmp.unlockPixels(); pt.set(30 * SK_Scalar1, 30 * SK_Scalar1); m.mapPoints(&pt, 1); SkShader* shader = SkShader::CreateBitmapShader( bmp, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix s; s.reset(); s.setScale(SK_Scalar1 / 1000, SK_Scalar1 / 1000); shader->setLocalMatrix(s); paint.setShader(shader)->unref(); paint.setAntiAlias(false); paint.setFilterLevel(SkPaint::kLow_FilterLevel); rect.setLTRB(pt.fX - small, pt.fY - small, pt.fX + small, pt.fY + small); canvas->drawRect(rect, paint); }
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; }
// found and fixed for android: not initializing rect for string's of length 0 static void regression_measureText(skiatest::Reporter* reporter) { SkPaint paint; paint.setTextSize(SkFloatToScalar(12.0f)); SkRect r; r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN); // test that the rect was reset paint.measureText("", 0, &r, SkFloatToScalar(1.0f)); REPORTER_ASSERT(reporter, r.isEmpty()); }
void GrDrawContext::drawPaint(GrRenderTarget* rt, const GrClip& clip, const GrPaint& origPaint, const SkMatrix& viewMatrix) { RETURN_IF_ABANDONED // set rect to be big enough to fill the space, but not super-huge, so we // don't overflow fixed-point implementations SkRect r; r.setLTRB(0, 0, SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); SkTCopyOnFirstWrite<GrPaint> paint(origPaint); // by definition this fills the entire clip, no need for AA if (paint->isAntiAlias()) { paint.writable()->setAntiAlias(false); } bool isPerspective = viewMatrix.hasPerspective(); // We attempt to map r by the inverse matrix and draw that. mapRect will // map the four corners and bound them with a new rect. This will not // produce a correct result for some perspective matrices. if (!isPerspective) { SkMatrix inverse; if (!viewMatrix.invert(&inverse)) { SkDebugf("Could not invert matrix\n"); return; } inverse.mapRect(&r); this->drawRect(rt, clip, *paint, viewMatrix, r); } else { SkMatrix localMatrix; if (!viewMatrix.invert(&localMatrix)) { SkDebugf("Could not invert matrix\n"); return; } AutoCheckFlush acf(fContext); if (!this->prepareToDraw(rt)) { return; } GrPipelineBuilder pipelineBuilder(*paint, rt, clip); fDrawTarget->drawBWRect(pipelineBuilder, paint->getColor(), SkMatrix::I(), r, NULL, &localMatrix); } }
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { SkASSERT(!antiAlias); SkASSERT(!stroke.isHairlineStyle()); GrDrawState* drawState = target->drawState(); SkASSERT(drawState->getStencil().isDisabled()); SkAutoTUnref<GrPath> p(fGpu->createPath(path)); SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(path.getFillType()); target->stencilPath(p, stroke, nonInvertedFill); // TODO: Use built in cover operation rather than a rect draw. This will require making our // fragment shaders be able to eat varyings generated by a matrix. // fill the path, zero out the stencil SkRect bounds = p->getBounds(); SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf; GrDrawState::AutoViewMatrixRestore avmr; if (nonInvertedFill == path.getFillType()) { GR_STATIC_CONST_SAME_STENCIL(kStencilPass, kZero_StencilOp, kZero_StencilOp, kNotEqual_StencilFunc, 0xffff, 0x0000, 0xffff); *drawState->stencil() = kStencilPass; } else { GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, kZero_StencilOp, kZero_StencilOp, // We know our rect will hit pixels outside the clip and the user bits will be 0 // outside the clip. So we can't just fill where the user bits are 0. We also need to // check that the clip bit is set. kEqualIfInClip_StencilFunc, 0xffff, 0x0000, 0xffff); SkMatrix vmi; bounds.setLTRB(0, 0, SkIntToScalar(drawState->getRenderTarget()->width()), SkIntToScalar(drawState->getRenderTarget()->height())); // mapRect through persp matrix may not be correct if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { vmi.mapRect(&bounds); // theoretically could set bloat = 0, instead leave it because of matrix inversion // precision. } else { avmr.setIdentity(drawState); bloat = 0; } *drawState->stencil() = kInvertedStencilPass; } bounds.outset(bloat, bloat); target->drawSimpleRect(bounds, NULL); target->drawState()->stencil()->setDisabled(); return true; }