static SkImage* make_image(GrContext* ctx, int w, int h, const SkIRect& ir) { const SkImageInfo info = SkImageInfo::MakeN32(w, h, kOpaque_SkAlphaType); SkAutoTUnref<SkSurface> surface(ctx ? SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info) : SkSurface::NewRaster(info)); SkCanvas* canvas = surface->getCanvas(); canvas->clear(SK_ColorWHITE); SkPaint paint; paint.setColor(SK_ColorBLACK); canvas->drawRect(SkRect::Make(ir), paint); return surface->newImageSnapshot(); }
// Only test this is in release mode. We deliberately crash in debug mode, since a valid caller // should never do this. static void test_bad_bitmap() { // This bitmap has a width and height but no pixels. As a result, attempting to record it will // fail. SkBitmap bm; bm.setInfo(SkImageInfo::MakeN32Premul(100, 100)); SkPictureRecorder recorder; SkCanvas* recordingCanvas = recorder.beginRecording(100, 100); recordingCanvas->drawBitmap(bm, 0, 0); SkAutoTUnref<SkPicture> picture(recorder.endRecording()); SkCanvas canvas; canvas.drawPicture(picture); }
static void test_abort(skiatest::Reporter* reporter) { SkDynamicMemoryWStream stream; auto doc = SkPDF::MakeDocument(&stream); SkCanvas* canvas = doc->beginPage(100, 100); canvas->drawColor(SK_ColorRED); doc->endPage(); doc->abort(); // Test that only the header is written, not the full document. REPORTER_ASSERT(reporter, stream.bytesWritten() < 256); }
void OsmAnd::MapRasterizer_P::rasterizePolylineIcons( const Context& context, SkCanvas& canvas, const SkPath& path, const MapStyleEvaluationResult& evalResult) { bool ok; QString pathIconName; ok = evalResult.getStringValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON, pathIconName); if (!ok || pathIconName.isEmpty()) return; float pathIconStep = 0.0f; ok = evalResult.getFloatValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON_STEP, pathIconStep); if (!ok || pathIconStep <= 0.0f) return; std::shared_ptr<const SkBitmap> pathIcon; ok = context.env->obtainMapIcon(pathIconName, pathIcon); if (!ok || !pathIcon) return; SkMatrix mIconTransform; mIconTransform.setIdentity(); mIconTransform.setTranslate(-0.5f * pathIcon->width(), -0.5f * pathIcon->height()); mIconTransform.postRotate(90.0f); SkPathMeasure pathMeasure(path, false); const auto length = pathMeasure.getLength(); auto iconOffset = 0.5f * pathIconStep; const auto iconInstancesCount = static_cast<int>((length - iconOffset) / pathIconStep) + 1; if (iconInstancesCount < 1) return; SkMatrix mIconInstanceTransform; for (auto iconInstanceIdx = 0; iconInstanceIdx < iconInstancesCount; iconInstanceIdx++, iconOffset += pathIconStep) { SkMatrix mPinPoint; ok = pathMeasure.getMatrix(iconOffset, &mPinPoint); if (!ok) break; mIconInstanceTransform.setConcat(mPinPoint, mIconTransform); canvas.save(); canvas.concat(mIconInstanceTransform); canvas.drawBitmap(*pathIcon, 0, 0, &_defaultPaint); canvas.restore(); } }
JNIEXPORT void JNICALL Java_com_example_HelloSkiaActivity_drawIntoBitmap(JNIEnv* env, jobject thiz, jobject dstBitmap, jlong elapsedTime) { // Grab the dst bitmap info and pixels AndroidBitmapInfo dstInfo; void* dstPixels; AndroidBitmap_getInfo(env, dstBitmap, &dstInfo); AndroidBitmap_lockPixels(env, dstBitmap, &dstPixels); SkImageInfo info = SkImageInfo::MakeN32Premul(dstInfo.width, dstInfo.height); // Create a surface from the given bitmap SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterDirect(info, dstPixels, dstInfo.stride)); SkCanvas* canvas = surface->getCanvas(); // Draw something "interesting" // Clear the canvas with a white color canvas->drawColor(SK_ColorWHITE); // Setup a SkPaint for drawing our text SkPaint paint; paint.setColor(SK_ColorBLACK); // This is a solid black color for our text paint.setTextSize(SkIntToScalar(30)); // Sets the text size to 30 pixels paint.setAntiAlias(true); // We turn on anti-aliasing so that the text to looks good. // Draw some text SkString text("Skia is Best!"); SkScalar fontHeight = paint.getFontSpacing(); canvas->drawText(text.c_str(), text.size(), // text's data and length 10, fontHeight, // X and Y coordinates to place the text paint); // SkPaint to tell how to draw the text // Adapt the SkPaint for drawing blue lines paint.setAntiAlias(false); // Turning off anti-aliasing speeds up the line drawing paint.setColor(0xFF0000FF); // This is a solid blue color for our lines paint.setStrokeWidth(SkIntToScalar(2)); // This makes the lines have a thickness of 2 pixels // Draw some interesting lines using trig functions for (int i = 0; i < 100; i++) { float x = (float)i / 99.0f; float offset = elapsedTime / 1000.0f; canvas->drawLine(sin(x * M_PI + offset) * 800.0f, 0, // first endpoint cos(x * M_PI + offset) * 800.0f, 800, // second endpoint paint); // SkPapint to tell how to draw the line } // Unlock the dst's pixels AndroidBitmap_unlockPixels(env, dstBitmap); }
static void fuzz_drawText(Fuzz* fuzz, sk_sp<SkTypeface> font) { SkPaint p; init_paint(fuzz, &p); sk_sp<SkSurface> surface; init_surface(fuzz, &surface); char text[kTxtLen]; init_string(fuzz, text, kTxtLen); SkScalar x, y; fuzz->next(&x, &y); // populate pts array SkPoint pts[kPtsLen]; for (uint8_t i = 0; i < kPtsLen; ++i) { pts[i].set(x, y); x += p.getTextSize(); } p.setTypeface(font); // set text related attributes bool b; fuzz->next(&b); p.setAutohinted(b); fuzz->next(&b); p.setDevKernText(b); fuzz->next(&b); p.setEmbeddedBitmapText(b); fuzz->next(&b); p.setFakeBoldText(b); fuzz->next(&b); p.setLCDRenderText(b); fuzz->next(&b); p.setLinearText(b); fuzz->next(&b); p.setSubpixelText(b); fuzz->next(&x); p.setTextScaleX(x); fuzz->next(&x); p.setTextSkewX(x); fuzz->next(&x); p.setTextSize(x); fuzz->next(&b); p.setVerticalText(b); SkCanvas* cnv = surface->getCanvas(); cnv->drawPosText(text, (kTxtLen-1), pts, p); fuzz->next(&x); fuzz->next(&y); cnv->drawText(text, (kTxtLen-1), x, y, p); }
void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options, ExceptionState& exceptionState) { if (options.id().isEmpty() && !options.control()) { exceptionState.throwDOMException(NotSupportedError, "Both id and control are null."); return; } if (options.control() && !canvas()->isSupportedInteractiveCanvasFallback(*options.control())) { exceptionState.throwDOMException(NotSupportedError, "The control is neither null nor a " "supported interactive canvas fallback " "element."); return; } Path hitRegionPath = options.hasPath() ? options.path()->path() : m_path; SkCanvas* c = drawingCanvas(); if (hitRegionPath.isEmpty() || !c || !state().isTransformInvertible() || !c->getClipDeviceBounds(0)) { exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels."); return; } hitRegionPath.transform(state().transform()); if (state().hasClip()) { hitRegionPath.intersectPath(state().getCurrentClipPath()); if (hitRegionPath.isEmpty()) exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels."); } if (!m_hitRegionManager) m_hitRegionManager = HitRegionManager::create(); // Remove previous region (with id or control) m_hitRegionManager->removeHitRegionById(options.id()); m_hitRegionManager->removeHitRegionByControl(options.control()); HitRegion* hitRegion = HitRegion::create(hitRegionPath, options); Element* element = hitRegion->control(); if (element && element->isDescendantOf(canvas())) updateElementAccessibility(hitRegion->path(), hitRegion->control()); m_hitRegionManager->addHitRegion(hitRegion); }
void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, const FloatPoint& point, int from, int to) const { if (!run.length()) return; SkCanvas* canvas = gc->platformContext()->canvas(); TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode(); bool fill = textMode & TextModeFill; bool stroke = (textMode & TextModeStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0; if (!fill && !stroke) return; SkPaint strokePaint, fillPaint; if (fill) { gc->platformContext()->setupPaintForFilling(&fillPaint); setupForTextPainting(&fillPaint, gc->fillColor().rgb()); } if (stroke) { gc->platformContext()->setupPaintForStroking(&strokePaint, 0, 0); setupForTextPainting(&strokePaint, gc->strokeColor().rgb()); } ComplexTextController controller(this, run, point.x(), point.y()); if (run.rtl()) controller.setupForRTL(); while (controller.nextScriptRun()) { // Check if there is any glyph found in the current script run. int fromGlyph, glyphLength; controller.glyphsForRange(from, to, fromGlyph, glyphLength); if (fromGlyph < 0 || glyphLength <= 0) continue; if (fill) { controller.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); adjustTextRenderMode(&fillPaint, gc->platformContext()); canvas->drawPosText(controller.glyphs() + fromGlyph, glyphLength << 1, controller.positions() + fromGlyph, fillPaint); } if (stroke) { controller.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); adjustTextRenderMode(&strokePaint, gc->platformContext()); canvas->drawPosText(controller.glyphs() + fromGlyph, glyphLength << 1, controller.positions() + fromGlyph, strokePaint); } } }
static SkImage* create_circle_texture(int size, SkColor color) { SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(size, size)); SkCanvas* canvas = surface->getCanvas(); canvas->clear(0xFF000000); SkPaint paint; paint.setColor(color); paint.setStrokeWidth(3); paint.setStyle(SkPaint::kStroke_Style); canvas->drawCircle(SkScalarHalf(size), SkScalarHalf(size), SkScalarHalf(size), paint); return surface->newImageSnapshot(); }
void anchor_handle_renderer::draw_anchor (SkCanvas &canvas, const SkRect &rect, SkPaint &paint) const { switch (m_node_type) { case handle_type::DIAMOND: { canvas.save (); canvas.translate (rect.centerX (), rect.centerY ()); canvas.rotate (45); SkRect moved_rect = rect; moved_rect.offset (-rect.centerX (), -rect.centerY ()); paint.setAntiAlias (true); canvas.drawRect (moved_rect, paint); canvas.restore (); break; } case handle_type::SQUARE: canvas.drawRect (rect, paint); break; case handle_type::CIRCLE: canvas.drawOval (rect, paint); break; case handle_type::DOUBLE_HEADED_ARROW: case handle_type::ROTATE_ARROW: SkPath path = qt2skia::path (*m_paths.at (m_node_type)); SkMatrix trans; trans.setIdentity (); trans.postRotate (m_rotation_angle, 32, 32); // TODO: change all these to use info from path_storage (bounding box and center (possibly should be made 0)) trans.postConcat (qt2skia::matrix (geom::rect2rect (QRectF (0, 0, 64, 64), qt2skia::rect (rect)))); path.transform (trans); paint.setAntiAlias (true); canvas.drawPath (path, paint); break; } }
void onDraw(SkCanvas* canvas) override { SkPaint blurPaint; SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(5.0f, 5.0f)); blurPaint.setImageFilter(blur); const SkScalar tile_size = SkIntToScalar(128); SkRect bounds; if (!canvas->getClipBounds(&bounds)) { bounds.setEmpty(); } int ts = SkScalarCeilToInt(tile_size); SkImageInfo info = SkImageInfo::MakeN32Premul(ts, ts); SkAutoTUnref<SkSurface> tileSurface(canvas->newSurface(info)); if (!tileSurface.get()) { tileSurface.reset(SkSurface::NewRaster(info)); } SkCanvas* tileCanvas = tileSurface->getCanvas(); for (SkScalar y = bounds.top(); y < bounds.bottom(); y += tile_size) { for (SkScalar x = bounds.left(); x < bounds.right(); x += tile_size) { tileCanvas->save(); tileCanvas->clear(0); tileCanvas->translate(-x, -y); SkRect rect = SkRect::MakeWH(WIDTH, HEIGHT); tileCanvas->saveLayer(&rect, &blurPaint); SkRRect rrect = SkRRect::MakeRectXY(rect.makeInset(20, 20), 25, 25); tileCanvas->clipRRect(rrect, SkRegion::kDifference_Op, true); SkPaint paint; tileCanvas->drawRect(rect, paint); tileCanvas->restore(); tileCanvas->restore(); canvas->drawImage(tileSurface->makeImageSnapshot().get(), x, y); } } }
// This exercises the problem discovered in crbug.com/570232. The return value from // SkBlurMask::BoxBlur wasn't being checked in SkBlurMaskFilter.cpp::GrRRectBlurEffect::Create DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SmallBoxBlurBug, reporter, ctxInfo) { SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128); auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info)); SkCanvas* canvas = surface->getCanvas(); SkRect r = SkRect::MakeXYWH(10, 10, 100, 100); SkRRect rr = SkRRect::MakeRectXY(r, 10, 10); SkPaint p; p.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 0.01f)); canvas->drawRRect(rr, p); }
/// M: added for HTML5-benchmark performance @{ PassRefPtr<Image> ImageBuffer::getContextImageRef() const { SkCanvas* canvas = imageBufferCanvas(this); if (!canvas) return 0; SkDevice* device = canvas->getDevice(); const SkBitmap& orig = device->accessBitmap(false); SkBitmapRef* ref = new SkBitmapRef(orig); RefPtr<Image> image = BitmapImage::create(ref, 0); ref->unref(); return image; }
sk_sp<SkSpecialImage> SkDropShadowImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx, SkIPoint* offset) const { SkIPoint inputOffset = SkIPoint::Make(0, 0); sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)); if (!input) { return nullptr; } const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(), input->width(), input->height()); SkIRect bounds; if (!this->applyCropRect(ctx, inputBounds, &bounds)) { return nullptr; } sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size())); if (!surf) { return nullptr; } SkCanvas* canvas = surf->getCanvas(); SkASSERT(canvas); canvas->clear(0x0); SkVector sigma = SkVector::Make(fSigmaX, fSigmaY); ctx.ctm().mapVectors(&sigma, 1); sigma.fX = SkMaxScalar(0, sigma.fX); sigma.fY = SkMaxScalar(0, sigma.fY); SkPaint paint; paint.setAntiAlias(true); paint.setImageFilter(SkBlurImageFilter::Make(sigma.fX, sigma.fY, nullptr)); paint.setColorFilter(SkColorFilter::MakeModeFilter(fColor, SkBlendMode::kSrcIn)); SkVector offsetVec = SkVector::Make(fDx, fDy); ctx.ctm().mapVectors(&offsetVec, 1); canvas->translate(SkIntToScalar(inputOffset.fX - bounds.fLeft), SkIntToScalar(inputOffset.fY - bounds.fTop)); input->draw(canvas, offsetVec.fX, offsetVec.fY, &paint); if (fShadowMode == kDrawShadowAndForeground_ShadowMode) { input->draw(canvas, 0, 0, nullptr); } offset->fX = bounds.fLeft; offset->fY = bounds.fTop; return surf->makeImageSnapshot(); }
void sk_canvas_draw_image_rect(sk_canvas_t* ccanvas, const sk_image_t* cimage, const sk_rect_t* csrcR, const sk_rect_t* cdstR, const sk_paint_t* cpaint) { SkCanvas* canvas = AsCanvas(ccanvas); const SkImage* image = AsImage(cimage); const SkRect& dst = AsRect(*cdstR); const SkPaint* paint = AsPaint(cpaint); if (csrcR) { canvas->drawImageRect(image, AsRect(*csrcR), dst, paint); } else { canvas->drawImageRect(image, dst, paint); } }
SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) { SkCanvas* canvas = this->INHERITED::setupCanvas(width, height); SkASSERT(fPicture); // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This // is mostly important for tiles on the right and bottom edges as they may go over this area and // the picture may have some commands that draw outside of this area and so should not actually // be written. // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set // by INHERITED::setupCanvas. SkRegion clipRegion; clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight()); canvas->clipRegion(clipRegion); return canvas; }
SkColor Request::getPixel(int x, int y) { SkCanvas* canvas = this->getCanvas(); canvas->flush(); SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas)); SkASSERT(bitmap); // Convert to format suitable for inspection sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bitmap); SkASSERT(encodedBitmap.get()); const uint8_t* start = encodedBitmap->bytes() + ((y * bitmap->width() + x) * 4); SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]); return result; }
void draw(SkCanvas* canvas) { SkPictureRecorder recorder; SkCanvas* pictureCanvas = recorder.beginRecording({0, 0, 256, 256}); SkPaint paint; pictureCanvas->drawRect(SkRect::MakeWH(200, 200), paint); paint.setColor(SK_ColorWHITE); pictureCanvas->drawRect(SkRect::MakeLTRB(20, 20, 180, 180), paint); sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); SkDynamicMemoryWStream writableStream; picture->serialize(&writableStream); std::unique_ptr<SkStreamAsset> readableStream = writableStream.detachAsStream(); sk_sp<SkPicture> copy = SkPicture::MakeFromStream(readableStream.get()); copy->playback(canvas); }
// Test out the layer replacement functionality with and w/o a BBH void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) { SkAutoTUnref<const SkPicture> pic; { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); SkPaint paint; canvas->saveLayer(nullptr, &paint); canvas->clear(SK_ColorRED); canvas->restore(); canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)), SkPaint()); pic.reset(recorder.endRecording()); } SkAutoTUnref<GrTexture> texture; SkPaint paint; GrLayerCache* layerCache = context->getLayerCache(); if (doReplace) { int key[1] = { 0 }; GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, SkIRect::MakeWH(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight), SkMatrix::I(), key, 1, &paint); GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidth; desc.fHeight = kHeight; desc.fSampleCnt = 0; texture.reset(context->textureProvider()->createTexture( desc, SkBudgeted::kNo, nullptr, 0)); layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); } SkRecord rerecord; SkRecorder canvas(&rerecord, kWidth, kHeight); GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/); int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); if (doReplace) { REPORTER_ASSERT(r, 0 == numLayers); } else { REPORTER_ASSERT(r, 1 == numLayers); } }
static void fuzz_drawPath(Fuzz* fuzz) { SkPaint p; init_paint(fuzz, &p); sk_sp<SkSurface> surface; init_surface(fuzz, &surface); // TODO(kjlubick): put the ability to fuzz a path in shared file, with // other common things (e.g. rects, lines) uint8_t i, j; fuzz->nextRange(&i, 0, 10); // set i to number of operations to perform SkPath path; SkScalar a, b, c, d, e, f; for (int k = 0; k < i; ++k) { fuzz->nextRange(&j, 0, 5); // set j to choose operation to perform switch (j) { case 0: fuzz->next(&a, &b); path.moveTo(a, b); break; case 1: fuzz->next(&a, &b); path.lineTo(a, b); break; case 2: fuzz->next(&a, &b, &c, &d); path.quadTo(a, b, c, d); break; case 3: fuzz->next(&a, &b, &c, &d, &e); path.conicTo(a, b, c, d, e); break; case 4: fuzz->next(&a, &b, &c, &d, &e, &f); path.cubicTo(a, b, c, d, e, f); break; case 5: fuzz->next(&a, &b, &c, &d, &e); path.arcTo(a, b, c, d, e); break; } } path.close(); SkCanvas* cnv = surface->getCanvas(); cnv->drawPath(path, p); bool bl; fuzz->next(&bl); cnv->clipPath(path, kIntersect_SkClipOp, bl); }
static void run_test(SkWStream* out, SkBlendMode mode, U8CPU alpha) { sk_sp<SkDocument> pdfDoc(SkDocument::MakePDF(out)); SkCanvas* c = pdfDoc->beginPage(612.0f, 792.0f); SkPaint black; SkPaint background; background.setColor(SK_ColorWHITE); background.setAlpha(alpha); background.setBlendMode(mode); c->drawRect(SkRect::MakeWH(612.0f, 792.0f), background); c->drawRect(SkRect::MakeXYWH(36.0f, 36.0f, 9.0f, 9.0f), black); c->drawRect(SkRect::MakeXYWH(72.0f, 72.0f, 468.0f, 648.0f), background); c->drawRect(SkRect::MakeXYWH(108.0f, 108.0f, 9.0f, 9.0f), black); pdfDoc->close(); }
void SkPictureImageFilter::drawPictureAtLocalResolution(SkSpecialImage* source, SkCanvas* canvas, const SkIRect& deviceBounds, const Context& ctx) const { SkMatrix inverseCtm; if (!ctx.ctm().invert(&inverseCtm)) { return; } SkRect localBounds = SkRect::Make(ctx.clipBounds()); inverseCtm.mapRect(&localBounds); if (!localBounds.intersect(fCropRect)) { return; } SkIRect localIBounds = localBounds.roundOut(); sk_sp<SkSpecialImage> localImg; { const SkImageInfo info = SkImageInfo::MakeN32(localIBounds.width(), localIBounds.height(), kPremul_SkAlphaType); sk_sp<SkSpecialSurface> localSurface(source->makeSurface(info)); if (!localSurface) { return; } SkCanvas* localCanvas = localSurface->getCanvas(); SkASSERT(localCanvas); localCanvas->translate(-SkIntToScalar(localIBounds.fLeft), -SkIntToScalar(localIBounds.fTop)); localCanvas->drawPicture(fPicture); localImg = localSurface->makeImageSnapshot(); SkASSERT(localImg); } { canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop)); canvas->concat(ctx.ctm()); SkPaint paint; paint.setFilterQuality(fFilterQuality); localImg->draw(canvas, SkIntToScalar(localIBounds.fLeft), SkIntToScalar(localIBounds.fTop), &paint); } }
static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp) { #if PLATFORM(CHROMIUM) TRACE_EVENT0("skia", "paintSkBitmap"); #endif SkPaint paint; paint.setXfermodeMode(compOp); paint.setAlpha(platformContext->getNormalizedAlpha()); paint.setLooper(platformContext->getDrawLooper()); // only antialias if we're rotated or skewed paint.setAntiAlias(hasNon90rotation(platformContext)); SkCanvas* canvas = platformContext->canvas(); ResamplingMode resampling; if (platformContext->isAccelerated()) resampling = RESAMPLE_LINEAR; else if (platformContext->printing()) resampling = RESAMPLE_NONE; else { // Take into account scale applied to the canvas when computing sampling mode (e.g. CSS scale or page scale). SkRect destRectTarget = destRect; if (!(canvas->getTotalMatrix().getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask))) canvas->getTotalMatrix().mapRect(&destRectTarget, destRect); resampling = computeResamplingMode(canvas->getTotalMatrix(), bitmap, srcRect.width(), srcRect.height(), SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height())); } if (resampling == RESAMPLE_NONE) { // FIXME: This is to not break tests (it results in the filter bitmap flag // being set to true). We need to decide if we respect RESAMPLE_NONE // being returned from computeResamplingMode. resampling = RESAMPLE_LINEAR; } resampling = limitResamplingMode(platformContext, resampling); paint.setFilterBitmap(resampling == RESAMPLE_LINEAR); if (resampling == RESAMPLE_AWESOME) drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect); else { // No resampling necessary, we can just draw the bitmap. We want to // filter it if we decided to do linear interpolation above, or if there // is something interesting going on with the matrix (like a rotation). // Note: for serialization, we will want to subset the bitmap first so // we don't send extra pixels. canvas->drawBitmapRect(bitmap.bitmap(), &srcRect, destRect, &paint); } platformContext->didDrawRect(destRect, paint, &bitmap.bitmap()); }
SkSpecialImage* SkOffsetImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx, SkIPoint* offset) const { SkIPoint srcOffset = SkIPoint::Make(0, 0); SkAutoTUnref<SkSpecialImage> input(this->filterInput(0, source, ctx, &srcOffset)); if (!input) { return nullptr; } SkVector vec; ctx.ctm().mapVectors(&vec, &fOffset, 1); if (!this->cropRectIsSet()) { offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX); offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY); return input.release(); } else { SkIRect bounds; SkIRect srcBounds = SkIRect::MakeWH(input->width(), input->height()); srcBounds.offset(srcOffset); if (!this->applyCropRect(ctx, srcBounds, &bounds)) { return nullptr; } SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), kPremul_SkAlphaType); sk_sp<SkSpecialSurface> surf(source->makeSurface(info)); if (!surf) { return nullptr; } SkCanvas* canvas = surf->getCanvas(); SkASSERT(canvas); // TODO: it seems like this clear shouldn't be necessary (see skbug.com/5075) canvas->clear(0x0); SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft), SkIntToScalar(srcOffset.fY - bounds.fTop)); input->draw(canvas, vec.x(), vec.y(), &paint); offset->fX = bounds.fLeft; offset->fY = bounds.fTop; return surf->makeImageSnapshot().release(); } }
void ClipRectToCanvas(const SkCanvas& canvas, const SkRect& srcRect, SkRect* destRect) { // Translate into the canvas' coordinate space. This is where the clipping // region applies. SkRect transformedSrc; canvas.getTotalMatrix().mapRect(&transformedSrc, srcRect); // Do the intersection. SkRect transformedDest; IntersectRectAndRegion(canvas.getTotalClip(), transformedSrc, &transformedDest); // Now transform it back into world space. SkMatrix inverseTransform; canvas.getTotalMatrix().invert(&inverseTransform); inverseTransform.mapRect(destRect, transformedDest); }
static void drawString(JNIEnv* env, jobject canvas, jstring text, jfloat x, jfloat y, jobject paint) { NPE_CHECK_RETURN_VOID(env, canvas); NPE_CHECK_RETURN_VOID(env, paint); NPE_CHECK_RETURN_VOID(env, text); size_t count = env->GetStringLength(text); if (0 == count) { return; } const jchar* text_ = env->GetStringChars(text, NULL); SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas); c->drawText(text_, count << 1, SkFloatToScalar(x), SkFloatToScalar(y), *GraphicsJNI::getNativePaint(env, paint)); env->ReleaseStringChars(text, text_); }
// http://crbug.com/472147 // RRect radii not properly scaled. static void test_crbug_472147_actual(skiatest::Reporter* reporter) { auto surface(SkSurface::MakeRasterN32Premul(1000, 1000)); SkCanvas* canvas = surface->getCanvas(); SkPaint p; SkRect r = SkRect::MakeLTRB(-246.0f, 33.0f, 848.0f, 33554464.0f); SkVector radii[4] = { { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554430.0f }, { 120.0f, 5.0f } }; SkRRect rr; rr.setRectRadii(r, radii); canvas->clipRRect(rr); SkRect r2 = SkRect::MakeLTRB(0, 33, 1102, 33554464); canvas->drawRect(r2, p); }
static void movie_draw(JNIEnv* env, jobject movie, jobject canvas, jfloat fx, jfloat fy, jobject jpaint) { NPE_CHECK_RETURN_VOID(env, movie); NPE_CHECK_RETURN_VOID(env, canvas); // its OK for paint to be null SkMovie* m = J2Movie(env, movie); SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas); SkScalar sx = SkFloatToScalar(fx); SkScalar sy = SkFloatToScalar(fy); const SkBitmap& b = m->bitmap(); const SkPaint* p = jpaint ? GraphicsJNI::getNativePaint(env, jpaint) : NULL; c->drawBitmap(b, sx, sy, p); }
static jboolean scrollRect(JNIEnv* env, jobject graphics2D, jobject canvas, jobject rect, int dx, int dy) { if (canvas == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return false; } SkIRect src, *srcPtr = NULL; if (NULL != rect) { GraphicsJNI::jrect_to_irect(env, rect, &src); srcPtr = &src; } SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas); const SkBitmap& bitmap = c->getDevice()->accessBitmap(true); return bitmap.scrollRect(srcPtr, dx, dy, NULL); }
// unused static void TestNWayCanvasStateConsistency( skiatest::Reporter* reporter, const TestData& d, CanvasTestStep* testStep, const SkCanvas& referenceCanvas) { SkBitmap indirectStore1; createBitmap(&indirectStore1, 0xFFFFFFFF); SkCanvas indirectCanvas1(indirectStore1); SkBitmap indirectStore2; createBitmap(&indirectStore2, 0xFFFFFFFF); SkCanvas indirectCanvas2(indirectStore2); SkISize canvasSize = referenceCanvas.getDeviceSize(); SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height()); nWayCanvas.addCanvas(&indirectCanvas1); nWayCanvas.addCanvas(&indirectCanvas2); testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat); testStep->draw(&nWayCanvas, d, reporter); // Verify that the SkNWayCanvas reports consitent state testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat); AssertCanvasStatesEqual(reporter, d, &nWayCanvas, &referenceCanvas, testStep); // Verify that the indirect canvases report consitent state testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat); AssertCanvasStatesEqual(reporter, d, &indirectCanvas1, &referenceCanvas, testStep); testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat); AssertCanvasStatesEqual(reporter, d, &indirectCanvas2, &referenceCanvas, testStep); }