SkGatherPixelRefsAndRects.h revision f0a4013467dd5aab0b35ddc89f86ad9827ea49ad
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 2656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.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); 3156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fEmptyBitmap.setConfig(SkBitmap::kNo_Config, width, height); 3256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 3356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 3456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual ~SkGatherPixelRefsAndRectsDevice() { 3556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkSafeUnref(fPRCont); 3656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 3756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 3856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } 3956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 4056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual int width() const SK_OVERRIDE { return fSize.width(); } 4156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual int height() const SK_OVERRIDE { return fSize.height(); } 4256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool isOpaque() const SK_OVERRIDE { return false; } 4356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual SkBitmap::Config config() const SK_OVERRIDE { 4456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return SkBitmap::kNo_Config; 4556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 4656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void writePixels(const SkBitmap& bitmap, int x, int y, 4756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkCanvas::Config8888 config8888) SK_OVERRIDE { 4856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NotSupported(); 4956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } 5156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 5256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.comprotected: 5356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { 5456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 5556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void clear(SkColor color) SK_OVERRIDE { 5756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NothingToDo(); 5856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 5956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE { 6056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 6156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 6256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &bm)) { 6356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect clipRect = SkRect::Make(draw.fRC->getBounds()); 6456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bm.pixelRef(), clipRect); 6556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 6656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 6756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count, 6856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint points[], const SkPaint& paint) SK_OVERRIDE { 6956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 7056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bm)) { 7156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 7256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 7356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 7456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (0 == count) { 7556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 7656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 7756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 7856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint min = points[0]; 7956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint max = points[0]; 8056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com for (size_t i = 1; i < count; ++i) { 8156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint& point = points[i]; 8256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 8356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com min.set(SkMinScalar(min.x(), point.x()), SkMinScalar(min.y(), point.y())); 8456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com max.set(SkMaxScalar(max.x(), point.x()), SkMaxScalar(max.y(), point.y())); 8556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 8656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 8756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x()+1, max.y()+1); 8856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 8956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 9056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 9156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawRect(const SkDraw& draw, const SkRect& rect, 9256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 9356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 9456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &bm)) { 9556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 9656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com draw.fMatrix->mapRect(&mappedRect, rect); 9756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect clipRect = SkRect::Make(draw.fRC->getBounds()); 9856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com mappedRect.intersect(clipRect); 9956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bm.pixelRef(), mappedRect); 10056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 10156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 10256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawOval(const SkDraw& draw, const SkRect& rect, 10356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 10456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, rect, paint); 10556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 10656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect, 10756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 10856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, rrect.rect(), paint); 10956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 11056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPath(const SkDraw& draw, const SkPath& path, 11156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint, const SkMatrix* prePathMatrix, 11256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bool pathIsMutable) SK_OVERRIDE { 11356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bm; 11456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bm)) { 11556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 11656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 11756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 11856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect pathBounds = path.getBounds(); 11956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (NULL != prePathMatrix) { 12056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com prePathMatrix->mapRect(&pathBounds); 12156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 12256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 12356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, pathBounds, paint); 12456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 12556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, 12656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE { 12756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix totMatrix; 12856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com totMatrix.setConcat(*draw.fMatrix, matrix); 12956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 13056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 13156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 13256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 13356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com totMatrix.mapRect(&mappedRect, bitmapRect); 13456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bitmap.pixelRef(), mappedRect); 13556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 13656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap paintBitmap; 13756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &paintBitmap)) { 13856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(paintBitmap.pixelRef(), mappedRect); 13956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 14056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 14156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, 14256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int x, int y, const SkPaint& paint) SK_OVERRIDE { 14356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Sprites aren't affected by current matrix, so we can't reuse drawRect. 14456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix matrix; 14556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); 14656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 14756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 14856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 14956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect mappedRect; 15056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.mapRect(&mappedRect, bitmapRect); 15156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(bitmap.pixelRef(), mappedRect); 15256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 15356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap paintBitmap; 15456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (GetBitmapFromPaint(paint, &paintBitmap)) { 15556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com fPRCont->add(paintBitmap.pixelRef(), mappedRect); 15656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 15756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 15856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, 15956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkRect* srcOrNull, const SkRect& dst, 16056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint, 16156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE { 16256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()), 16356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkIntToScalar(bitmap.height())); 16456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkMatrix matrix; 16556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com matrix.setRectToRect(bitmapRect, dst, SkMatrix::kFill_ScaleToFit); 16656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawBitmap(draw, bitmap, matrix, paint); 16756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 16856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawText(const SkDraw& draw, const void* text, size_t len, 16956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar x, SkScalar y, 17056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 17156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 17256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 17356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 17456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 17556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 17656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 17756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds; 17856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.measureText(text, len, &bounds); 17956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 18056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 18156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 18256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.isVerticalText()) { 18356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar h = bounds.fBottom - bounds.fTop; 18456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 18556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop -= h / 2; 18656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom -= h / 2; 18756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 18856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom += metrics.fBottom; 18956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += metrics.fTop; 19056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } else { 19156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar w = bounds.fRight - bounds.fLeft; 19256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 19356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= w / 2; 19456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= w / 2; 19556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 19656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= w; 19756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= w; 19856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 19956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop = metrics.fTop; 20056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom = metrics.fBottom; 20156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 20256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 20356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; 20456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= pad; 20556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight += pad; 20656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.offset(x, y); 20756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 20856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 20956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 21056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawPosText(const SkDraw& draw, const void* text, size_t len, 21156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkScalar pos[], SkScalar constY, 21256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE { 21356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 21456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 21556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 21656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 21756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 21856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (0 == len) { 21956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 22056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 22156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 22256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Similar to SkDraw asserts. 22356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2); 22456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 225f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com SkScalar y = scalarsPerPos == 1 ? constY : constY + pos[1]; 226f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com 22756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPoint min, max; 228f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com min.set(pos[0], y); 229f0a4013467dd5aab0b35ddc89f86ad9827ea49adrobertphillips@google.com max.set(pos[0], y); 23056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 23156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com for (size_t i = 1; i < len; ++i) { 23256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar x = pos[i * scalarsPerPos]; 23356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar y = constY; 23456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (2 == scalarsPerPos) { 23556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com y += pos[i * scalarsPerPos + 1]; 23656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 23756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 23856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com min.set(SkMinScalar(x, min.x()), SkMinScalar(y, min.y())); 23956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com max.set(SkMaxScalar(x, max.x()), SkMaxScalar(y, max.y())); 24056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 24156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x(), max.y()); 24356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 24556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 24656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 24756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 24856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += metrics.fTop; 24956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom += metrics.fBottom; 25056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 25156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; 25256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft -= pad; 25356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight += pad; 25456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 25556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 25656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 25756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len, 25856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPath& path, const SkMatrix* matrix, 25956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 26056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap bitmap; 26156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (!GetBitmapFromPaint(paint, &bitmap)) { 26256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return; 26356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 26456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 26556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // Math is borrowed from SkBBoxRecord 26656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkRect bounds = path.getBounds(); 26756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPaint::FontMetrics metrics; 26856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com paint.getFontMetrics(&metrics); 26956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 27056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkScalar pad = metrics.fTop; 27156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // TODO: inset?! 27256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fLeft += pad; 27356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fRight -= pad; 27456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fTop += pad; 27556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bounds.fBottom -= pad; 27656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 27756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawRect(draw, bounds, paint); 27856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 27956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount, 28056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPoint verts[], const SkPoint texs[], 28156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkColor colors[], SkXfermode* xmode, 28256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const uint16_t indices[], int indexCount, 28356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint& paint) SK_OVERRIDE { 28456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com this->drawPoints(draw, SkCanvas::kPolygon_PointMode, vertexCount, verts, paint); 28556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 28656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 28756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com const SkPaint&) SK_OVERRIDE { 28856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NothingToDo(); 28956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 29056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // TODO: allow this call to return failure, or move to SkBitmapDevice only. 29156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { 29256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return fEmptyBitmap; 29356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 29456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool onReadPixels(const SkBitmap& bitmap, 29556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int x, int y, 29656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkCanvas::Config8888 config8888) SK_OVERRIDE { 29756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NotSupported(); 29856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 29956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 30056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void lockPixels() SK_OVERRIDE { NothingToDo(); } 30156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } 30256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE { return false; } 30356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE { return false; } 30456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&, 30556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { 30656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 30756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 30856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 30956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.comprivate: 31056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkPictureUtils::SkPixelRefContainer* fPRCont; 31156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkISize fSize; 31256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 31356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkBitmap fEmptyBitmap; // legacy -- need to remove 31456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 31556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static bool GetBitmapFromPaint(const SkPaint &paint, SkBitmap* bitmap) { 31656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkShader* shader = paint.getShader(); 31756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (NULL != shader) { 31856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) { 31956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return SkShader::kNone_BitmapType != shader->asABitmap(bitmap, NULL, NULL); 32056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return false; 32356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 32556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE { 32656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com NotSupported(); 32756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 32856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 32956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, 33056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com int width, int height, 33156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com bool isOpaque, 33256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com Usage usage) SK_OVERRIDE { 33356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com // we expect to only get called via savelayer, in which case it is fine. 33456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkASSERT(kSaveLayer_Usage == usage); 33556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice, (width, height, fPRCont)); 33656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 33756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 33856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com virtual void flush() SK_OVERRIDE {} 33956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 34056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static void NotSupported() { 34156bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com SkDEBUGFAIL("this method should never be called"); 34256bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com } 34356bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 34456bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com static void NothingToDo() {} 34556bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 34656bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com typedef SkBaseDevice INHERITED; 34756bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com}; 34856bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 34956bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com#endif // SkGatherPixelRefsAndRects_DEFINED 35056bf6e4bce26710b017b61ddadb13e277aab8a45robertphillips@google.com 351