Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / utils / SkGatherPixelRefsAndRects.h
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #ifndef SkGatherPixelRefsAndRects_DEFINED
9 #define SkGatherPixelRefsAndRects_DEFINED
10
11 #include "SkBitmap.h"
12 #include "SkDevice.h"
13 #include "SkDraw.h"
14 #include "SkPictureUtils.h"
15 #include "SkRasterClip.h"
16 #include "SkRefCnt.h"
17 #include "SkRRect.h"
18 #include "SkTypes.h"
19
20 // This GatherPixelRefs device passes all discovered pixel refs and their
21 // device bounds to the user provided SkPixelRefContainer-derived object
22 class SkGatherPixelRefsAndRectsDevice : public SkBaseDevice {
23 public:
24     SK_DECLARE_INST_COUNT(SkGatherPixelRefsAndRectsDevice)
25
26     SkGatherPixelRefsAndRectsDevice(int width, int height,
27                                     SkPictureUtils::SkPixelRefContainer* prCont) {
28         fSize.set(width, height);
29         fPRCont = prCont;
30         SkSafeRef(fPRCont);
31         fEmptyBitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
32     }
33
34     virtual ~SkGatherPixelRefsAndRectsDevice() {
35         SkSafeUnref(fPRCont);
36     }
37
38     virtual SkImageInfo imageInfo() const SK_OVERRIDE {
39         return fEmptyBitmap.info();
40     }
41
42 protected:
43     virtual void clear(SkColor color) SK_OVERRIDE {
44         NothingToDo();
45     }
46     virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE {
47         SkBitmap bm;
48
49         if (GetBitmapFromPaint(paint, &bm)) {
50             SkRect clipRect = SkRect::Make(draw.fRC->getBounds());
51             fPRCont->add(bm.pixelRef(), clipRect);
52         }
53     }
54     virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
55                             const SkPoint points[], const SkPaint& paint) SK_OVERRIDE {
56         SkBitmap bm;
57         if (!GetBitmapFromPaint(paint, &bm)) {
58             return;
59         }
60
61         if (0 == count) {
62             return;
63         }
64
65         SkPoint min = points[0];
66         SkPoint max = points[0];
67         for (size_t i = 1; i < count; ++i) {
68             const SkPoint& point = points[i];
69
70             min.set(SkMinScalar(min.x(), point.x()), SkMinScalar(min.y(), point.y()));
71             max.set(SkMaxScalar(max.x(), point.x()), SkMaxScalar(max.y(), point.y()));
72         }
73
74         SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x()+1, max.y()+1);
75
76         this->drawRect(draw, bounds, paint);
77     }
78     virtual void drawRect(const SkDraw& draw, const SkRect& rect,
79                           const SkPaint& paint) SK_OVERRIDE {
80         SkBitmap bm;
81         if (GetBitmapFromPaint(paint, &bm)) {
82             SkRect mappedRect;
83             draw.fMatrix->mapRect(&mappedRect, rect);
84             SkRect clipRect = SkRect::Make(draw.fRC->getBounds());
85             mappedRect.intersect(clipRect);
86             fPRCont->add(bm.pixelRef(), mappedRect);
87         }
88     }
89     virtual void drawOval(const SkDraw& draw, const SkRect& rect,
90                           const SkPaint& paint) SK_OVERRIDE {
91         this->drawRect(draw, rect, paint);
92     }
93     virtual void drawRRect(const SkDraw& draw, const SkRRect& rrect,
94                            const SkPaint& paint) SK_OVERRIDE {
95         this->drawRect(draw, rrect.rect(), paint);
96     }
97     virtual void drawPath(const SkDraw& draw, const SkPath& path,
98                           const SkPaint& paint, const SkMatrix* prePathMatrix,
99                           bool pathIsMutable) SK_OVERRIDE {
100         SkBitmap bm;
101         if (!GetBitmapFromPaint(paint, &bm)) {
102             return;
103         }
104
105         SkRect pathBounds = path.getBounds();
106         if (prePathMatrix) {
107             prePathMatrix->mapRect(&pathBounds);
108         }
109
110         this->drawRect(draw, pathBounds, paint);
111     }
112     virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
113                             const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {
114         SkMatrix totMatrix;
115         totMatrix.setConcat(*draw.fMatrix, matrix);
116
117         SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
118                                            SkIntToScalar(bitmap.height()));
119         SkRect mappedRect;
120         totMatrix.mapRect(&mappedRect, bitmapRect);
121         fPRCont->add(bitmap.pixelRef(), mappedRect);
122
123         SkBitmap paintBitmap;
124         if (GetBitmapFromPaint(paint, &paintBitmap)) {
125             fPRCont->add(paintBitmap.pixelRef(), mappedRect);
126         }
127     }
128     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
129                             int x, int y, const SkPaint& paint) SK_OVERRIDE {
130         // Sprites aren't affected by current matrix, so we can't reuse drawRect.
131         SkMatrix matrix;
132         matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
133
134         SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
135                                            SkIntToScalar(bitmap.height()));
136         SkRect mappedRect;
137         matrix.mapRect(&mappedRect, bitmapRect);
138         fPRCont->add(bitmap.pixelRef(), mappedRect);
139
140         SkBitmap paintBitmap;
141         if (GetBitmapFromPaint(paint, &paintBitmap)) {
142             fPRCont->add(paintBitmap.pixelRef(), mappedRect);
143         }
144     }
145     virtual void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
146                                 const SkRect* srcOrNull, const SkRect& dst,
147                                 const SkPaint& paint,
148                                 SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
149         SkRect bitmapRect = SkRect::MakeWH(SkIntToScalar(bitmap.width()),
150                                            SkIntToScalar(bitmap.height()));
151         SkMatrix matrix;
152         matrix.setRectToRect(bitmapRect, dst, SkMatrix::kFill_ScaleToFit);
153         this->drawBitmap(draw, bitmap, matrix, paint);
154     }
155     virtual void drawText(const SkDraw& draw, const void* text, size_t len,
156                           SkScalar x, SkScalar y,
157                           const SkPaint& paint) SK_OVERRIDE {
158         SkBitmap bitmap;
159         if (!GetBitmapFromPaint(paint, &bitmap)) {
160             return;
161         }
162
163         // Math is borrowed from SkBBoxRecord
164         SkRect bounds;
165         paint.measureText(text, len, &bounds);
166         SkPaint::FontMetrics metrics;
167         paint.getFontMetrics(&metrics);
168
169         if (paint.isVerticalText()) {
170             SkScalar h = bounds.fBottom - bounds.fTop;
171             if (paint.getTextAlign() == SkPaint::kCenter_Align) {
172                 bounds.fTop -= h / 2;
173                 bounds.fBottom -= h / 2;
174             }
175             bounds.fBottom += metrics.fBottom;
176             bounds.fTop += metrics.fTop;
177         } else {
178             SkScalar w = bounds.fRight - bounds.fLeft;
179             if (paint.getTextAlign() == SkPaint::kCenter_Align) {
180                 bounds.fLeft -= w / 2;
181                 bounds.fRight -= w / 2;
182             } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
183                 bounds.fLeft -= w;
184                 bounds.fRight -= w;
185             }
186             bounds.fTop = metrics.fTop;
187             bounds.fBottom = metrics.fBottom;
188         }
189
190         SkScalar pad = (metrics.fBottom - metrics.fTop) / 2;
191         bounds.fLeft -= pad;
192         bounds.fRight += pad;
193         bounds.offset(x, y);
194
195         this->drawRect(draw, bounds, paint);
196     }
197     virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
198                              const SkScalar pos[], SkScalar constY,
199                              int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE {
200         SkBitmap bitmap;
201         if (!GetBitmapFromPaint(paint, &bitmap)) {
202             return;
203         }
204
205         if (0 == len) {
206             return;
207         }
208
209         // Similar to SkDraw asserts.
210         SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2);
211
212         SkScalar y = scalarsPerPos == 1 ? constY : constY + pos[1];
213
214         SkPoint min, max;
215         min.set(pos[0], y);
216         max.set(pos[0], y);
217
218         for (size_t i = 1; i < len; ++i) {
219             SkScalar x = pos[i * scalarsPerPos];
220             SkScalar y = constY;
221             if (2 == scalarsPerPos) {
222                 y += pos[i * scalarsPerPos + 1];
223             }
224
225             min.set(SkMinScalar(x, min.x()), SkMinScalar(y, min.y()));
226             max.set(SkMaxScalar(x, max.x()), SkMaxScalar(y, max.y()));
227         }
228
229         SkRect bounds = SkRect::MakeLTRB(min.x(), min.y(), max.x(), max.y());
230
231         // Math is borrowed from SkBBoxRecord
232         SkPaint::FontMetrics metrics;
233         paint.getFontMetrics(&metrics);
234
235         bounds.fTop += metrics.fTop;
236         bounds.fBottom += metrics.fBottom;
237
238         SkScalar pad = (metrics.fTop - metrics.fBottom) / 2;
239         bounds.fLeft -= pad;
240         bounds.fRight += pad;
241
242         this->drawRect(draw, bounds, paint);
243     }
244     virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
245                                 const SkPath& path, const SkMatrix* matrix,
246                                 const SkPaint& paint) SK_OVERRIDE {
247         SkBitmap bitmap;
248         if (!GetBitmapFromPaint(paint, &bitmap)) {
249             return;
250         }
251
252         // Math is borrowed from SkBBoxRecord
253         SkRect bounds = path.getBounds();
254         SkPaint::FontMetrics metrics;
255         paint.getFontMetrics(&metrics);
256
257         SkScalar pad = metrics.fTop;
258         // TODO: inset?!
259         bounds.fLeft += pad;
260         bounds.fRight -= pad;
261         bounds.fTop += pad;
262         bounds.fBottom -= pad;
263
264         this->drawRect(draw, bounds, paint);
265     }
266     virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode, int vertexCount,
267                               const SkPoint verts[], const SkPoint texs[],
268                               const SkColor colors[], SkXfermode* xmode,
269                               const uint16_t indices[], int indexCount,
270                               const SkPaint& paint) SK_OVERRIDE {
271         this->drawPoints(draw, SkCanvas::kPolygon_PointMode, vertexCount, verts, paint);
272     }
273     virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
274                             const SkPaint&) SK_OVERRIDE {
275         NothingToDo();
276     }
277     // TODO: allow this call to return failure, or move to SkBitmapDevice only.
278     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
279         return fEmptyBitmap;
280     }
281     virtual void lockPixels() SK_OVERRIDE { NothingToDo(); }
282     virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); }
283     virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
284     virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
285     virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
286                              SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
287         return false;
288     }
289
290 private:
291     SkPictureUtils::SkPixelRefContainer* fPRCont;
292     SkISize                              fSize;
293
294     SkBitmap                             fEmptyBitmap; // legacy -- need to remove
295
296     static bool GetBitmapFromPaint(const SkPaint &paint, SkBitmap* bitmap) {
297         SkShader* shader = paint.getShader();
298         if (shader) {
299             if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) {
300                 return SkShader::kNone_BitmapType != shader->asABitmap(bitmap, NULL, NULL);
301             }
302         }
303         return false;
304     }
305
306     virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
307         NotSupported();
308     }
309
310     virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE {
311         // we expect to only get called via savelayer, in which case it is fine.
312         SkASSERT(kSaveLayer_Usage == usage);
313         return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice,
314                           (info.width(), info.height(), fPRCont));
315     }
316
317     static void NotSupported() {
318         SkDEBUGFAIL("this method should never be called");
319     }
320
321     static void NothingToDo() {}
322
323     typedef SkBaseDevice INHERITED;
324 };
325
326 #endif // SkGatherPixelRefsAndRects_DEFINED