/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file.
*/
staticvoid bw_pt_hair_proc(const PtProcRec& rec, const SkPoint devPts[], int count, SkBlitter* blitter) { for (int i = 0; i < count; i++) { int x = SkScalarFloorToInt(devPts[i].fX); int y = SkScalarFloorToInt(devPts[i].fY); if (rec.fClip->contains(x, y)) {
blitter->blitH(x, y, 1);
}
}
}
staticvoid bw_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[], int count, SkBlitter* blitter) { for (int i = 0; i < count; i += 2) {
SkScan::HairLine(&devPts[i], 2, *rec.fRC, blitter);
}
}
// each of these costs 8-bytes of stack space, so don't make it too large // must be even for lines/polygon to work #define MAX_DEV_PTS 32
void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint,
SkDevice* device) const { // if we're in lines mode, force count to be even if (SkCanvas::kLines_PointMode == mode) {
count &= ~(size_t)1;
}
SkPoint devPts[MAX_DEV_PTS];
SkBlitter* bltr = blitter.get();
PtProcRec::Proc proc = rec.chooseProc(&bltr); // we have to back up subsequent passes if we're in polygon mode const size_t backup = (SkCanvas::kPolygon_PointMode == mode);
do { int n = SkToInt(count); if (n > MAX_DEV_PTS) {
n = MAX_DEV_PTS;
}
fCTM->mapPoints(devPts, pts, n); if (!SkIsFinite(&devPts[0].fX, n * 2)) { return;
}
proc(rec, devPts, n, bltr);
pts += n - backup;
SkASSERT(SkToInt(count) >= n);
count -= n; if (count > 0) {
count += backup;
}
} while (count != 0);
} else {
this->drawDevicePoints(mode, count, pts, paint, device);
}
}
staticbool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPixmap& pmap) { return clip.isBW() || clip.quickContains(SkIRect::MakeXYWH(x, y, pmap.width(), pmap.height()));
}
SkTCopyOnFirstWrite<SkPaint> paint(origPaint); if (origPaint.getStyle() != SkPaint::kFill_Style) {
paint.writable()->setStyle(SkPaint::kFill_Style);
}
SkMatrix matrix = *fCTM * prematrix;
if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) { return;
}
if (!SkColorTypeIsAlphaOnly(bitmap.colorType()) &&
SkTreatAsSprite(matrix, bitmap.dimensions(), sampling, paint->isAntiAlias())) { // // It is safe to call lock pixels now, since we know the matrix is // (more or less) identity. //
SkPixmap pmap; if (!bitmap.peekPixels(&pmap)) { return;
} int ix = SkScalarRoundToInt(matrix.getTranslateX()); int iy = SkScalarRoundToInt(matrix.getTranslateY()); if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
SkSTArenaAlloc<kSkBlitterContextSize> allocator; // blitter will be owned by the allocator.
SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, *paint, pmap, ix, iy, &allocator,
fRC->clipShader()); if (blitter) {
SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.height()),
*fRC, blitter); return;
} // if !blitter, then we fall-through to the slower case
}
}
// now make a temp draw on the stack, and use it //
SkDraw draw(*this);
draw.fCTM = &matrix;
// For a long time, the CPU backend treated A8 bitmaps as coverage, rather than alpha. This was // inconsistent with the GPU backend (skbug.com/9692). When this was fixed, it altered behavior // for some Android apps (b/231400686). Thus: keep the old behavior in the framework. #ifdefined(SK_SUPPORT_LEGACY_ALPHA_BITMAP_AS_COVERAGE) if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) {
draw.drawBitmapAsMask(bitmap, sampling, *paint); return;
} #endif
SkPixmap pmap; if (!bitmap.peekPixels(&pmap)) { return;
}
if (nullptr == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) { // blitter will be owned by the allocator.
SkSTArenaAlloc<kSkBlitterContextSize> allocator;
SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &allocator,
fRC->clipShader()); if (blitter) {
SkScan::FillIRect(bounds, *fRC, blitter); return;
}
}
SkMatrix matrix;
SkRect r;
// get a scalar version of our rect
r.set(bounds);
// create shader with offset
matrix.setTranslate(r.fLeft, r.fTop);
SkPaint paintWithShader = make_paint_with_image(paint, bitmap, SkSamplingOptions(), &matrix);
SkDraw draw(*this);
draw.fCTM = &SkMatrix::I(); // call ourself with a rect
draw.drawRect(r, paintWithShader);
}
// nothing to draw if (fRC->isEmpty()) { return;
}
if (SkTreatAsSprite(*fCTM, bitmap.dimensions(), sampling, paint.isAntiAlias()))
{ int ix = SkScalarRoundToInt(fCTM->getTranslateX()); int iy = SkScalarRoundToInt(fCTM->getTranslateY());
// set the mask's bounds to the transformed bitmap-bounds, // clipped to the actual device and further limited by the clip bounds
{
SkASSERT(fDst.bounds().contains(fRC->getBounds()));
SkIRect devBounds = fDst.bounds();
devBounds.intersect(fRC->getBounds().makeOutset(1, 1)); // need intersect(l, t, r, b) on irect if (!mask.bounds().intersect(devBounds)) { return;
}
}
mask.format() = SkMask::kA8_Format;
mask.rowBytes() = SkAlign4(mask.fBounds.width());
size_t size = mask.computeImageSize(); if (0 == size) { // the mask is too big to allocated, draw nothing return;
}
// allocate (and clear) our temp buffer to hold the transformed bitmap
AutoTMalloc<uint8_t> storage(size);
mask.image() = storage.get();
memset(mask.image(), 0, size);
// now draw our bitmap(src) into mask(dst), transformed by the matrix
{
SkBitmap device;
device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
mask.image(), mask.fRowBytes);
SkCanvas c(device); // need the unclipped top/left for the translate
c.translate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
c.concat(*fCTM);
// We can't call drawBitmap, or we'll infinitely recurse. Instead // we manually build a shader and draw that into our new mask
SkPaint tmpPaint;
tmpPaint.setAntiAlias(paint.isAntiAlias());
tmpPaint.setDither(paint.isDither());
SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap, sampling);
SkRect rr;
rr.setIWH(bitmap.width(), bitmap.height());
c.drawRect(rr, paintWithShader);
}
this->drawDevMask(mask, paint);
}
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.