2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "SkDeviceProperties.h"
11 #include "SkMetaData.h"
12 #include "SkPatchUtils.h"
14 #include "SkTextBlob.h"
16 SkBaseDevice::SkBaseDevice()
17 : fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType)))
19 , fAttachedToCanvas(false)
26 SkBaseDevice::~SkBaseDevice() {
27 SkDELETE(fLeakyProperties);
31 SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) {
32 return this->onCreateDevice(info, kGeneral_Usage);
35 SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) {
36 return this->onCreateDevice(info, kSaveLayer_Usage);
39 SkBaseDevice* SkBaseDevice::createCompatibleDeviceForImageFilter(const SkImageInfo& info) {
40 return this->onCreateDevice(info, kImageFilter_Usage);
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;
52 SkImageInfo SkBaseDevice::imageInfo() const {
53 return SkImageInfo::MakeUnknown();
56 const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
57 const SkBitmap& bitmap = this->onAccessBitmap();
59 bitmap.notifyPixelsChanged();
64 void SkBaseDevice::setPixelGeometry(SkPixelGeometry geo) {
65 fLeakyProperties->setPixelGeometry(geo);
68 SkSurface* SkBaseDevice::newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; }
70 const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
72 void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
73 const SkRRect& inner, const SkPaint& paint) {
77 path.setFillType(SkPath::kEvenOdd_FillType);
79 const SkMatrix* preMatrix = NULL;
80 const bool pathIsMutable = true;
81 this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
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;
88 SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
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,
99 void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
100 const SkPaint &paint) {
102 SkPaint runPaint = paint;
104 SkTextBlob::RunIterator it(blob);
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);
112 switch (it.positioning()) {
113 case SkTextBlob::kDefault_Positioning:
114 this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
116 case SkTextBlob::kHorizontal_Positioning:
117 this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
118 SkPoint::Make(x, y + offset.y()), runPaint);
120 case SkTextBlob::kFull_Positioning:
121 this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
122 SkPoint::Make(x, y), runPaint);
125 SkFAIL("unhandled positioning mode");
132 bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
134 SkASSERT(info.width() > 0 && info.height() > 0);
136 SkASSERT(rowBytes >= info.minRowBytes());
137 SkASSERT(x >= 0 && y >= 0);
139 const SkImageInfo& srcInfo = this->imageInfo();
140 SkASSERT(x + info.width() <= srcInfo.width());
141 SkASSERT(y + info.height() <= srcInfo.height());
143 return this->onReadPixels(info, dstP, rowBytes, x, y);
146 bool SkBaseDevice::writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
149 SkASSERT(info.width() > 0 && info.height() > 0);
151 SkASSERT(rowBytes >= info.minRowBytes());
152 SkASSERT(x >= 0 && y >= 0);
154 const SkImageInfo& dstInfo = this->imageInfo();
155 SkASSERT(x + info.width() <= dstInfo.width());
156 SkASSERT(y + info.height() <= dstInfo.height());
158 return this->onWritePixels(info, pixels, rowBytes, x, y);
161 bool SkBaseDevice::onWritePixels(const SkImageInfo&, const void*, size_t, int, int) {
165 bool SkBaseDevice::onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) {
169 void* SkBaseDevice::accessPixels(SkImageInfo* info, size_t* rowBytes) {
175 if (NULL == rowBytes) {
176 rowBytes = &tmpRowBytes;
178 return this->onAccessPixels(info, rowBytes);
181 void* SkBaseDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
185 void SkBaseDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
186 // The base class doesn't perform any analysis but derived classes may
189 bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
191 // The base class doesn't perform any accelerated picture rendering