Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkDevice.cpp
1 /*
2  * Copyright 2011 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 #include "SkDevice.h"
9 #include "SkDeviceProperties.h"
10 #include "SkDraw.h"
11 #include "SkMetaData.h"
12 #include "SkPatchUtils.h"
13 #include "SkShader.h"
14 #include "SkTextBlob.h"
15
16 SkBaseDevice::SkBaseDevice()
17     : fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType)))
18 #ifdef SK_DEBUG
19     , fAttachedToCanvas(false)
20 #endif
21 {
22     fOrigin.setZero();
23     fMetaData = NULL;
24 }
25
26 SkBaseDevice::~SkBaseDevice() {
27     SkDELETE(fLeakyProperties);
28     SkDELETE(fMetaData);
29 }
30
31 SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) {
32     return this->onCreateDevice(info, kGeneral_Usage);
33 }
34
35 SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) {
36     return this->onCreateDevice(info, kSaveLayer_Usage);
37 }
38
39 SkBaseDevice* SkBaseDevice::createCompatibleDeviceForImageFilter(const SkImageInfo& info) {
40     return this->onCreateDevice(info, kImageFilter_Usage);
41 }
42
43 SkMetaData& SkBaseDevice::getMetaData() {
44     // metadata users are rare, so we lazily allocate it. If that changes we
45     // can decide to just make it a field in the device (rather than a ptr)
46     if (NULL == fMetaData) {
47         fMetaData = new SkMetaData;
48     }
49     return *fMetaData;
50 }
51
52 SkImageInfo SkBaseDevice::imageInfo() const {
53     return SkImageInfo::MakeUnknown();
54 }
55
56 const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
57     const SkBitmap& bitmap = this->onAccessBitmap();
58     if (changePixels) {
59         bitmap.notifyPixelsChanged();
60     }
61     return bitmap;
62 }
63
64 void SkBaseDevice::setPixelGeometry(SkPixelGeometry geo) {
65     fLeakyProperties->setPixelGeometry(geo);
66 }
67
68 SkSurface* SkBaseDevice::newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; }
69
70 const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
71
72 void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
73                               const SkRRect& inner, const SkPaint& paint) {
74     SkPath path;
75     path.addRRect(outer);
76     path.addRRect(inner);
77     path.setFillType(SkPath::kEvenOdd_FillType);
78
79     const SkMatrix* preMatrix = NULL;
80     const bool pathIsMutable = true;
81     this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
82 }
83
84 void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const SkColor colors[4],
85                              const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
86     SkPatchUtils::VertexData data;
87     
88     SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
89
90     // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
91     // If it fails to generate the vertices, then we do not draw. 
92     if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
93         this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
94                            data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
95                            paint);
96     }
97 }
98
99 void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
100                                 const SkPaint &paint) {
101
102     SkPaint runPaint = paint;
103
104     SkTextBlob::RunIterator it(blob);
105     while (!it.done()) {
106         size_t textLen = it.glyphCount() * sizeof(uint16_t);
107         const SkPoint& offset = it.offset();
108         // applyFontToPaint() always overwrites the exact same attributes,
109         // so it is safe to not re-seed the paint.
110         it.applyFontToPaint(&runPaint);
111
112         switch (it.positioning()) {
113         case SkTextBlob::kDefault_Positioning:
114             this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
115             break;
116         case SkTextBlob::kHorizontal_Positioning:
117             this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
118                               SkPoint::Make(x, y + offset.y()), runPaint);
119             break;
120         case SkTextBlob::kFull_Positioning:
121             this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
122                               SkPoint::Make(x, y), runPaint);
123             break;
124         default:
125             SkFAIL("unhandled positioning mode");
126         }
127
128         it.next();
129     }
130 }
131
132 bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
133 #ifdef SK_DEBUG
134     SkASSERT(info.width() > 0 && info.height() > 0);
135     SkASSERT(dstP);
136     SkASSERT(rowBytes >= info.minRowBytes());
137     SkASSERT(x >= 0 && y >= 0);
138
139     const SkImageInfo& srcInfo = this->imageInfo();
140     SkASSERT(x + info.width() <= srcInfo.width());
141     SkASSERT(y + info.height() <= srcInfo.height());
142 #endif
143     return this->onReadPixels(info, dstP, rowBytes, x, y);
144 }
145
146 bool SkBaseDevice::writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
147                                int x, int y) {
148 #ifdef SK_DEBUG
149     SkASSERT(info.width() > 0 && info.height() > 0);
150     SkASSERT(pixels);
151     SkASSERT(rowBytes >= info.minRowBytes());
152     SkASSERT(x >= 0 && y >= 0);
153
154     const SkImageInfo& dstInfo = this->imageInfo();
155     SkASSERT(x + info.width() <= dstInfo.width());
156     SkASSERT(y + info.height() <= dstInfo.height());
157 #endif
158     return this->onWritePixels(info, pixels, rowBytes, x, y);
159 }
160
161 bool SkBaseDevice::onWritePixels(const SkImageInfo&, const void*, size_t, int, int) {
162     return false;
163 }
164
165 bool SkBaseDevice::onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) {
166     return false;
167 }
168
169 void* SkBaseDevice::accessPixels(SkImageInfo* info, size_t* rowBytes) {
170     SkImageInfo tmpInfo;
171     size_t tmpRowBytes;
172     if (NULL == info) {
173         info = &tmpInfo;
174     }
175     if (NULL == rowBytes) {
176         rowBytes = &tmpRowBytes;
177     }
178     return this->onAccessPixels(info, rowBytes);
179 }
180
181 void* SkBaseDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
182     return NULL;
183 }
184
185 void SkBaseDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
186     // The base class doesn't perform any analysis but derived classes may
187 }
188
189 bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
190                                             const SkPaint*) {
191     // The base class doesn't perform any accelerated picture rendering
192     return false;
193 }