156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com/* 256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com * Copyright 2014 Google Inc. 356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com * 456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com * found in the LICENSE file. 656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com */ 756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#ifndef SkGatherPixelRefsAndRects_DEFINED 956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#define SkGatherPixelRefsAndRects_DEFINED 1056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 1156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkBitmap.h" 1256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkDevice.h" 1356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkDraw.h" 1456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkPictureUtils.h" 1556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkRasterClip.h" 1656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkRefCnt.h" 1756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkRRect.h" 1856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#include "SkTypes.h" 1956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 2056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com// This GatherPixelRefs device passes all discovered pixel refs and their 2156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com// device bounds to the user provided SkPixelRefContainer-derived object 2256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.comclass SkGatherPixelRefsAndRectsDevice : public SkBaseDevice { 2356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.compublic: 2456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SK_DECLARE_INST_COUNT(SkGatherPixelRefsAndRectsDevice) 2556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 262e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com SkGatherPixelRefsAndRectsDevice(int width, int height, 2756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPictureUtils::SkPixelRefContainer* prCont) { 2856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fSize.set(width, height); 2956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont = prCont; 3056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkSafeRef(fPRCont); 31a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 3256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 3356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 3456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual ~SkGatherPixelRefsAndRectsDevice() { 3556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkSafeUnref(fPRCont); 3656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 3756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 3815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org virtual SkImageInfo imageInfo() const SK_OVERRIDE { 3915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return fEmptyBitmap.info(); 4015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org } 4115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 4256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } 4356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 4456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.comprotected: 4556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { 4656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 4756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 4856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void clear(SkColor color) SK_OVERRIDE { 4956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NothingToDo(); 5056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE { 5256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 5356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 5456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &bm)) { 5556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect clipRect = SkRect::Make(draw.fRC->getBounds()); 5656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bm.pixelRef(), clipRect); 5756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count, 6056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint points[], const SkPaint& paint) SK_OVERRIDE { 6156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 6256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bm)) { 6356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 6456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 6556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 6656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (0 == count) { 6756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 6856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 6956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 7056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint min = points[0]; 7156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint max = points[0]; 7256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com for (size_t i = 1; i < count; ++i) { 7356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint& point = points[i]; 7456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 7556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com min.set(SkMinScalar(min.x(), point.x()), SkMinScalar(min.y(), point.y())); 7656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com max.set(SkMaxScalar(max.x(), point.x()), SkMaxScalar(max.y(), point.y())); 7756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 7856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 7956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x()+1, max.y()+1); 8056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 8156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 8256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 8356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawRect(const SkDraw& draw, const SkRect& rect, 8456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 8556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 8656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &bm)) { 8756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 8856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com draw.fMatrix->mapRect(&mappedRect, rect); 8956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect clipRect = SkRect::Make(draw.fRC->getBounds()); 9056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com mappedRect.intersect(clipRect); 9156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bm.pixelRef(), mappedRect); 9256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 9356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 9456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawOval(const SkDraw& draw, const SkRect& rect, 9556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 9656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, rect, paint); 9756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 9856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect, 9956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 10056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, rrect.rect(), paint); 10156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 10256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPath(const SkDraw& draw, const SkPath& path, 10356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint, const SkMatrix* prePathMatrix, 10456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bool pathIsMutable) SK_OVERRIDE { 10556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 10656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bm)) { 10756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 10856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 10956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 11056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect pathBounds = path.getBounds(); 11156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (NULL != prePathMatrix) { 11256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com prePathMatrix->mapRect(&pathBounds); 1132e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com } 11456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 11556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, pathBounds, paint); 11656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 11756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, 11856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE { 11956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix totMatrix; 12056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com totMatrix.setConcat(*draw.fMatrix, matrix); 12156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 1222e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 12356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 12456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 12556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com totMatrix.mapRect(&mappedRect, bitmapRect); 12656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bitmap.pixelRef(), mappedRect); 12756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 12856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap paintBitmap; 12956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &paintBitmap)) { 13056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(paintBitmap.pixelRef(), mappedRect); 13156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 13256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 13356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, 13456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int x, int y, const SkPaint& paint) SK_OVERRIDE { 13556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Sprites aren't affected by current matrix, so we can't reuse drawRect. 13656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix matrix; 13756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 13856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 1392e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 14056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 14156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 14256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.mapRect(&mappedRect, bitmapRect); 14356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bitmap.pixelRef(), mappedRect); 14456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 14556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap paintBitmap; 14656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &paintBitmap)) { 14756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(paintBitmap.pixelRef(), mappedRect); 14856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 14956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 15056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, 15156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkRect* srcOrNull, const SkRect& dst, 15256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint, 15356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE { 1542e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 15556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 15656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix matrix; 15756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.setRectToRect(bitmapRect, dst, SkMatrix::kFill_ScaleToFit); 15856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawBitmap(draw, bitmap, matrix, paint); 15956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 16056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawText(const SkDraw& draw, const void* text, size_t len, 16156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar x, SkScalar y, 16256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 16356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 16456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 16556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 16656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 16756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 16856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 16956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds; 17056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.measureText(text, len, &bounds); 17156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 17256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 17356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 17456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.isVerticalText()) { 17556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar h = bounds.fBottom - bounds.fTop; 17656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 17756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop -= h / 2; 17856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom -= h / 2; 17956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 18056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom += metrics.fBottom; 18156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += metrics.fTop; 18256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } else { 18356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar w = bounds.fRight - bounds.fLeft; 18456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 18556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= w / 2; 18656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= w / 2; 18756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 18856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= w; 18956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= w; 19056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 19156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop = metrics.fTop; 19256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom = metrics.fBottom; 19356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 19456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 19556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; 19656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= pad; 19756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight += pad; 19856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.offset(x, y); 19956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 20056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 20156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 20256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPosText(const SkDraw& draw, const void* text, size_t len, 20356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkScalar pos[], SkScalar constY, 20456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE { 20556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 20656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 20756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 20856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 20956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 21056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (0 == len) { 21156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 21256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 21356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 21456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Similar to SkDraw asserts. 21556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2); 21656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 217f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com SkScalar y = scalarsPerPos == 1 ? constY : constY + pos[1]; 218f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com 21956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint min, max; 220f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com min.set(pos[0], y); 221f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com max.set(pos[0], y); 22256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 22356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com for (size_t i = 1; i < len; ++i) { 22456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar x = pos[i * scalarsPerPos]; 22556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar y = constY; 22656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (2 == scalarsPerPos) { 22756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com y += pos[i * scalarsPerPos + 1]; 22856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 22956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 23056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com min.set(SkMinScalar(x, min.x()), SkMinScalar(y, min.y())); 23156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com max.set(SkMaxScalar(x, max.x()), SkMaxScalar(y, max.y())); 23256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 23356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 23456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x(), max.y()); 23556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 23656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 23756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 23856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 23956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += metrics.fTop; 24156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom += metrics.fBottom; 24256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; 24456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= pad; 24556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight += pad; 24656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 24856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 24956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len, 25056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPath& path, const SkMatrix* matrix, 25156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 25256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 25356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 25456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 25556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 25656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 25756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 25856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = path.getBounds(); 25956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 26056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 26156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 26256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = metrics.fTop; 26356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // TODO: inset?! 26456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft += pad; 26556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= pad; 26656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += pad; 26756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom -= pad; 26856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 26956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 27056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 27156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount, 27256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint verts[], const SkPoint texs[], 27356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkColor colors[], SkXfermode* xmode, 27456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const uint16_t indices[], int indexCount, 27556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 2762e9a7157ee8ce47dae6e692162440c4f94a05574skia.committer@gmail.com this->drawPoints(draw, SkCanvas::kPolygon_PointMode, vertexCount, verts, paint); 27756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 27856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 27956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint&) SK_OVERRIDE { 28056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NothingToDo(); 28156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 28256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // TODO: allow this call to return failure, or move to SkBitmapDevice only. 28356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { 28456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return fEmptyBitmap; 28556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 28656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } 28756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } 288ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } 289ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } 2904cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, 29156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { 29256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 29356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 29456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 29556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.comprivate: 29656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPictureUtils::SkPixelRefContainer* fPRCont; 29756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkISize fSize; 29856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 29956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap fEmptyBitmap; // legacy -- need to remove 30056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 30156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static bool GetBitmapFromPaint(const SkPaint &paint, SkBitmap* bitmap) { 30256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkShader* shader = paint.getShader(); 30356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (NULL != shader) { 30456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) { 30556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return SkShader::kNone_BitmapType != shader->asABitmap(bitmap, NULL, NULL); 30656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 30756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 30856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 30956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 31056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 31156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE { 31256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NotSupported(); 31356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 31456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 31515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE { 31656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // we expect to only get called via savelayer, in which case it is fine. 31756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkASSERT(kSaveLayer_Usage == usage); 31815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice, 31915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org (info.width(), info.height(), fPRCont)); 32056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 32256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void flush() SK_OVERRIDE {} 32356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 32456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static void NotSupported() { 32556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkDEBUGFAIL("this method should never be called"); 32656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 32856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static void NothingToDo() {} 32956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 33056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com typedef SkBaseDevice INHERITED; 33156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com}; 33256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 33356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#endif // SkGatherPixelRefsAndRects_DEFINED 334