Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(778)

Unified Diff: src/utils/SkGatherPixelRefsAndRects.h

Issue 134473002: Pull in Chromium's version of GatherPixelRefs (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: cleaned up Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/utils/SkPictureUtils.h ('k') | src/utils/SkGatherPixelRefsAndRects.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkGatherPixelRefsAndRects.h
===================================================================
--- src/utils/SkGatherPixelRefsAndRects.h (revision 0)
+++ src/utils/SkGatherPixelRefsAndRects.h (revision 0)
@@ -0,0 +1,353 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkGatherPixelRefsAndRects_DEFINED
+#define SkGatherPixelRefsAndRects_DEFINED
+
+#include "SkBitmap.h"
+#include "SkDevice.h"
+#include "SkDraw.h"
+#include "SkPictureUtils.h"
+#include "SkRasterClip.h"
+#include "SkRefCnt.h"
+#include "SkRRect.h"
+#include "SkTypes.h"
+
+// This GatherPixelRefs device passes all discovered pixel refs and their
+// device bounds to the user provided SkPixelRefContainer-derived object
+class SkGatherPixelRefsAndRectsDevice : public SkBaseDevice {
+public:
+ SK_DECLARE_INST_COUNT(SkGatherPixelRefsAndRectsDevice)
+
+ SkGatherPixelRefsAndRectsDevice(int width, int height,
+ SkPictureUtils::SkPixelRefContainer* prCont) {
+ fSize.set(width, height);
+ fPRCont = prCont;
+ SkSafeRef(fPRCont);
+ fEmptyBitmap.setConfig(SkBitmap::kNo_Config, width, height);
+ }
+
+ virtual ~SkGatherPixelRefsAndRectsDevice() {
+ SkSafeUnref(fPRCont);
+ }
+
+ virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; }
+
+ virtual int width() const SK_OVERRIDE { return fSize.width(); }
+ virtual int height() const SK_OVERRIDE { return fSize.height(); }
+ virtual bool isOpaque() const SK_OVERRIDE { return false; }
+ virtual SkBitmap::Config config() const SK_OVERRIDE {
+ return SkBitmap::kNo_Config;
+ }
+ virtual void writePixels(const SkBitmap& bitmap, int x, int y,
+ SkCanvas::Config8888 config8888) SK_OVERRIDE {
+ NotSupported();
+ }
+ virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
+
+protected:
+ virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
+ return false;
+ }
+ virtual void clear(SkColor color) SK_OVERRIDE {
+ NothingToDo();
+ }
+ virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bm;
+
+ if (GetBitmapFromPaint(paint, &bm)) {
+ SkRect clipRect = SkRect::Make(draw.fRC->getBounds());
+ fPRCont->add(bm.pixelRef(), clipRect);
+ }
+ }
+ virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
+ const SkPoint points[], const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bm;
+ if (!GetBitmapFromPaint(paint, &bm)) {
+ return;
+ }
+
+ if (0 == count) {
+ return;
+ }
+
+ SkPoint min = points[0];
+ SkPoint max = points[0];
+ for (size_t i = 1; i < count; ++i) {
+ const SkPoint& point = points[i];
+
+ min.set(SkMinScalar(min.x(), point.x()), SkMinScalar(min.y(), point.y()));
+ max.set(SkMaxScalar(max.x(), point.x()), SkMaxScalar(max.y(), point.y()));
+ }
+
+ SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x()+1, max.y()+1);
+
+ this->drawRect(draw, bounds, paint);
+ }
+ virtual void drawRect(const SkDraw& draw, const SkRect& rect,
+ const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bm;
+ if (GetBitmapFromPaint(paint, &bm)) {
+ SkRect mappedRect;
+ draw.fMatrix->mapRect(&mappedRect, rect);
+ SkRect clipRect = SkRect::Make(draw.fRC->getBounds());
+ mappedRect.intersect(clipRect);
+ fPRCont->add(bm.pixelRef(), mappedRect);
+ }
+ }
+ virtual void drawOval(const SkDraw& draw, const SkRect& rect,
+ const SkPaint& paint) SK_OVERRIDE {
+ this->drawRect(draw, rect, paint);
+ }
+ virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect,
+ const SkPaint& paint) SK_OVERRIDE {
+ this->drawRect(draw, rrect.rect(), paint);
+ }
+ virtual void drawPath(const SkDraw& draw, const SkPath& path,
+ const SkPaint& paint, const SkMatrix* prePathMatrix,
+ bool pathIsMutable) SK_OVERRIDE {
+ SkBitmap bm;
+ if (!GetBitmapFromPaint(paint, &bm)) {
+ return;
+ }
+
+ SkRect pathBounds = path.getBounds();
+ if (NULL != prePathMatrix) {
+ prePathMatrix->mapRect(&pathBounds);
+ }
+
+ this->drawRect(draw, pathBounds, paint);
+ }
+ virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {
+ SkMatrix totMatrix;
+ totMatrix.setConcat(*draw.fMatrix, matrix);
+
+ SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
+ SkIntToScalar(bitmap.height()));
+ SkRect mappedRect;
+ totMatrix.mapRect(&mappedRect, bitmapRect);
+ fPRCont->add(bitmap.pixelRef(), mappedRect);
+
+ SkBitmap paintBitmap;
+ if (GetBitmapFromPaint(paint, &paintBitmap)) {
+ fPRCont->add(paintBitmap.pixelRef(), mappedRect);
+ }
+ }
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint) SK_OVERRIDE {
+ // Sprites aren't affected by current matrix, so we can't reuse drawRect.
+ SkMatrix matrix;
+ matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
+
+ SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
+ SkIntToScalar(bitmap.height()));
+ SkRect mappedRect;
+ matrix.mapRect(&mappedRect, bitmapRect);
+ fPRCont->add(bitmap.pixelRef(), mappedRect);
+
+ SkBitmap paintBitmap;
+ if (GetBitmapFromPaint(paint, &paintBitmap)) {
+ fPRCont->add(paintBitmap.pixelRef(), mappedRect);
+ }
+ }
+ virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+ const SkRect* srcOrNull, const SkRect& dst,
+ const SkPaint& paint,
+ SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
+ SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
+ SkIntToScalar(bitmap.height()));
+ SkMatrix matrix;
+ matrix.setRectToRect(bitmapRect, dst, SkMatrix::kFill_ScaleToFit);
+ this->drawBitmap(draw, bitmap, matrix, paint);
+ }
+ virtual void drawText(const SkDraw& draw, const void* text, size_t len,
+ SkScalar x, SkScalar y,
+ const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bitmap;
+ if (!GetBitmapFromPaint(paint, &bitmap)) {
+ return;
+ }
+
+ // Math is borrowed from SkBBoxRecord
+ SkRect bounds;
+ paint.measureText(text, len, &bounds);
+ SkPaint::FontMetrics metrics;
+ paint.getFontMetrics(&metrics);
+
+ if (paint.isVerticalText()) {
+ SkScalar h = bounds.fBottom - bounds.fTop;
+ if (paint.getTextAlign() == SkPaint::kCenter_Align) {
+ bounds.fTop -= h / 2;
+ bounds.fBottom -= h / 2;
+ }
+ bounds.fBottom += metrics.fBottom;
+ bounds.fTop += metrics.fTop;
+ } else {
+ SkScalar w = bounds.fRight - bounds.fLeft;
+ if (paint.getTextAlign() == SkPaint::kCenter_Align) {
+ bounds.fLeft -= w / 2;
+ bounds.fRight -= w / 2;
+ } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
+ bounds.fLeft -= w;
+ bounds.fRight -= w;
+ }
+ bounds.fTop = metrics.fTop;
+ bounds.fBottom = metrics.fBottom;
+ }
+
+ SkScalar pad = (metrics.fBottom - metrics.fTop) / 2;
+ bounds.fLeft -= pad;
+ bounds.fRight += pad;
+ bounds.offset(x, y);
+
+ this->drawRect(draw, bounds, paint);
+ }
+ virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bitmap;
+ if (!GetBitmapFromPaint(paint, &bitmap)) {
+ return;
+ }
+
+ if (0 == len) {
+ return;
+ }
+
+ // Similar to SkDraw asserts.
+ SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2);
+
+ SkPoint min, max;
+ if (1 == scalarsPerPos) {
+ min.set(pos[0], constY);
+ max.set(pos[0], constY);
+ } else if (2 == scalarsPerPos) {
+ min.set(pos[0], constY + pos[1]);
+ max.set(pos[0], constY + pos[1]);
+ }
+
+ for (size_t i = 1; i < len; ++i) {
+ SkScalar x = pos[i * scalarsPerPos];
+ SkScalar y = constY;
+ if (2 == scalarsPerPos) {
+ y += pos[i * scalarsPerPos + 1];
+ }
+
+ min.set(SkMinScalar(x, min.x()), SkMinScalar(y, min.y()));
+ max.set(SkMaxScalar(x, max.x()), SkMaxScalar(y, max.y()));
+ }
+
+ SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x(), max.y());
+
+ // Math is borrowed from SkBBoxRecord
+ SkPaint::FontMetrics metrics;
+ paint.getFontMetrics(&metrics);
+
+ bounds.fTop += metrics.fTop;
+ bounds.fBottom += metrics.fBottom;
+
+ SkScalar pad = (metrics.fTop - metrics.fBottom) / 2;
+ bounds.fLeft -= pad;
+ bounds.fRight += pad;
+
+ this->drawRect(draw, bounds, paint);
+ }
+ virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) SK_OVERRIDE {
+ SkBitmap bitmap;
+ if (!GetBitmapFromPaint(paint, &bitmap)) {
+ return;
+ }
+
+ // Math is borrowed from SkBBoxRecord
+ SkRect bounds = path.getBounds();
+ SkPaint::FontMetrics metrics;
+ paint.getFontMetrics(&metrics);
+
+ SkScalar pad = metrics.fTop;
+ // TODO: inset?!
+ bounds.fLeft += pad;
+ bounds.fRight -= pad;
+ bounds.fTop += pad;
+ bounds.fBottom -= pad;
+
+ this->drawRect(draw, bounds, paint);
+ }
+ virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount,
+ const SkPoint verts[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) SK_OVERRIDE {
+ this->drawPoints(draw, SkCanvas::kPolygon_PointMode, vertexCount, verts, paint);
+ }
+ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+ const SkPaint&) SK_OVERRIDE {
+ NothingToDo();
+ }
+ // TODO: allow this call to return failure, or move to SkBitmapDevice only.
+ virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
+ return fEmptyBitmap;
+ }
+ virtual bool onReadPixels(const SkBitmap& bitmap,
+ int x, int y,
+ SkCanvas::Config8888 config8888) SK_OVERRIDE {
+ NotSupported();
+ return false;
+ }
+ virtual void lockPixels() SK_OVERRIDE { NothingToDo(); }
+ virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); }
+ virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE { return false; }
+ virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE { return false; }
+ virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
+ SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
+ return false;
+ }
+
+private:
+ SkPictureUtils::SkPixelRefContainer* fPRCont;
+ SkISize fSize;
+
+ SkBitmap fEmptyBitmap; // legacy -- need to remove
+
+ static bool GetBitmapFromPaint(const SkPaint &paint, SkBitmap* bitmap) {
+ SkShader* shader = paint.getShader();
+ if (NULL != shader) {
+ if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) {
+ return SkShader::kNone_BitmapType != shader->asABitmap(bitmap, NULL, NULL);
+ }
+ }
+ return false;
+ }
+
+ virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
+ NotSupported();
+ }
+
+ virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage) SK_OVERRIDE {
+ // we expect to only get called via savelayer, in which case it is fine.
+ SkASSERT(kSaveLayer_Usage == usage);
+ return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice, (width, height, fPRCont));
+ }
+
+ virtual void flush() SK_OVERRIDE {}
+
+ static void NotSupported() {
+ SkDEBUGFAIL("this method should never be called");
+ }
+
+ static void NothingToDo() {}
+
+ typedef SkBaseDevice INHERITED;
+};
+
+#endif // SkGatherPixelRefsAndRects_DEFINED
+
Property changes on: src\utils\SkGatherPixelRefsAndRects.h
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « include/utils/SkPictureUtils.h ('k') | src/utils/SkGatherPixelRefsAndRects.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698