Upstreaming changes from android.
- fix compile warnings in the GPU code
- upstream android specific code (ifdef protected)
- fail gracefully when a custom allocator fails
git-svn-id: http://skia.googlecode.com/svn/trunk@936 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index c1a9998..a5f7d57 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -1237,10 +1237,11 @@
#include "SkMaskFilter.h"
#include "SkMatrix.h"
-void SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
+bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
Allocator *allocator, SkIPoint* offset) const {
SkDEBUGCODE(this->validate();)
+ SkBitmap tmpBitmap;
SkMatrix identity;
SkMask srcM, dstM;
@@ -1260,14 +1261,20 @@
dstM.fRowBytes = SkAlign4(dstM.fBounds.width());
} else {
NO_FILTER_CASE:
- dst->setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
+ tmpBitmap.setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
srcM.fRowBytes);
- dst->allocPixels(allocator, NULL);
- GetBitmapAlpha(*this, dst->getAddr8(0, 0), srcM.fRowBytes);
+ if (!tmpBitmap.allocPixels(allocator, NULL)) {
+ // Allocation of pixels for alpha bitmap failed.
+ SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
+ tmpBitmap.width(), tmpBitmap.height());
+ return false;
+ }
+ GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes);
if (offset) {
offset->set(0, 0);
}
- return;
+ tmpBitmap.swap(*dst);
+ return true;
}
SkAutoMaskImage srcCleanup(&srcM, true);
@@ -1279,14 +1286,22 @@
SkAutoMaskImage dstCleanup(&dstM, false);
- dst->setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
+ tmpBitmap.setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
dstM.fBounds.height(), dstM.fRowBytes);
- dst->allocPixels(allocator, NULL);
- memcpy(dst->getPixels(), dstM.fImage, dstM.computeImageSize());
+ if (!tmpBitmap.allocPixels(allocator, NULL)) {
+ // Allocation of pixels for alpha bitmap failed.
+ SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
+ tmpBitmap.width(), tmpBitmap.height());
+ return false;
+ }
+ memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize());
if (offset) {
offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
}
- SkDEBUGCODE(dst->validate();)
+ SkDEBUGCODE(tmpBitmap.validate();)
+
+ tmpBitmap.swap(*dst);
+ return true;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index a8d218a..2b7d588 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1401,6 +1401,22 @@
ITER_END
}
+#ifdef ANDROID
+void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint,
+ const SkPath& path, const SkMatrix* matrix) {
+
+ ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+
+ while (iter.next()) {
+ iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos,
+ paint, path, matrix);
+ }
+
+ ITER_END
+}
+#endif
+
void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 5e6376e..619a371 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -153,6 +153,14 @@
draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
}
+#ifdef ANDROID
+void SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
+ const SkPoint pos[], const SkPaint& paint,
+ const SkPath& path, const SkMatrix* matrix) {
+ draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
+}
+#endif
+
void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
int vertexCount,
const SkPoint verts[], const SkPoint textures[],
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 8378e73..ce0fa9b 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1940,6 +1940,70 @@
}
}
+#ifdef ANDROID
+void SkDraw::drawPosTextOnPath(const char text[], size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint,
+ const SkPath& path, const SkMatrix* matrix) const {
+ // nothing to draw
+ if (text == NULL || byteLength == 0 || fClip->isEmpty() ||
+ (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
+ return;
+ }
+
+ SkMatrix scaledMatrix;
+ SkPathMeasure meas(path, false);
+
+ SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(
+ SkPaint::kForward_TextBufferDirection, true);
+
+ // Copied (modified) from SkTextToPathIter constructor to setup paint
+ SkPaint tempPaint(paint);
+
+ tempPaint.setLinearText(true);
+ tempPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup
+
+ if (tempPaint.getPathEffect() == NULL && !(tempPaint.getStrokeWidth() > 0
+ && tempPaint.getStyle() != SkPaint::kFill_Style)) {
+ tempPaint.setStyle(SkPaint::kFill_Style);
+ tempPaint.setPathEffect(NULL);
+ }
+ // End copied from SkTextToPathIter constructor
+
+ // detach cache
+ SkGlyphCache* cache = tempPaint.detachCache(NULL);
+
+ // Must set scale, even if 1
+ SkScalar scale = SK_Scalar1;
+ scaledMatrix.setScale(scale, scale);
+
+ // Loop over all glyph ids
+ for (const char* stop = text + byteLength; text < stop; pos++) {
+
+ const SkGlyph& glyph = glyphCacheProc(cache, &text);
+ SkPath tmp;
+
+ const SkPath* glyphPath = cache->findPath(glyph);
+ if (glyphPath == NULL) {
+ continue;
+ }
+
+ SkMatrix m(scaledMatrix);
+ m.postTranslate(pos->fX, 0);
+
+ if (matrix) {
+ m.postConcat(*matrix);
+ }
+
+ morphpath(&tmp, *glyphPath, meas, m);
+ this->drawPath(tmp, tempPaint);
+
+ }
+
+ // re-attach cache
+ SkGlyphCache::AttachCache(cache);
+}
+#endif
+
///////////////////////////////////////////////////////////////////////////////
struct VertState {
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index cfe22fa..18dafb0 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -19,6 +19,10 @@
#include "SkTemplates.h"
#include "SkThread.h"
+#ifdef ANDROID
+#include <stdio.h>
+#endif
+
SkDEBUGCODE(int32_t gRgnAllocCounter;)
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -190,6 +194,35 @@
//////////////////////////////////////////////////////////////////////////////////////
+#ifdef ANDROID
+char* SkRegion::toString()
+{
+ Iterator iter(*this);
+ int count = 0;
+ while (!iter.done()) {
+ count++;
+ iter.next();
+ }
+ // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() and '\0'
+ const int max = (count*((11*4)+5))+11+1;
+ char* result = (char*)malloc(max);
+ if (result == NULL) {
+ return NULL;
+ }
+ count = sprintf(result, "SkRegion(");
+ iter.reset(*this);
+ while (!iter.done()) {
+ const SkIRect& r = iter.rect();
+ count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRight, r.fBottom);
+ iter.next();
+ }
+ count += sprintf(result+count, ")");
+ return result;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////
+
int SkRegion::count_runtype_values(int* itop, int* ibot) const
{
if (this == NULL)
diff --git a/src/effects/SkPorterDuff.cpp b/src/effects/SkPorterDuff.cpp
index 58447ad..980ce29 100644
--- a/src/effects/SkPorterDuff.cpp
+++ b/src/effects/SkPorterDuff.cpp
@@ -29,7 +29,10 @@
MAKE_PAIR(Lighten),
MAKE_PAIR(Multiply),
MAKE_PAIR(Screen),
- { SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode }
+ { SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode },
+#ifdef ANDROID
+ MAKE_PAIR(Overlay),
+#endif
};
static bool find_pdmode(SkXfermode::Mode src, SkPorterDuff::Mode* dst) {
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 5497734..1c0b269 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -345,7 +345,7 @@
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) {
-#if defined(SK_BUILD_FOR_MAC)
+#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
return NULL;
#else
SkAutoMutexAcquire ac(gFTMutex);
@@ -540,6 +540,21 @@
rec->setHinting(h);
}
+#ifdef ANDROID
+uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
+ SkAutoMutexAcquire ac(gFTMutex);
+ SkFaceRec *rec = ref_ft_face(fontID);
+ uint16_t unitsPerEm = 0;
+
+ if (rec != NULL && rec->fFace != NULL) {
+ unitsPerEm = rec->fFace->units_per_EM;
+ unref_ft_face(rec->fFace);
+ }
+
+ return (uint32_t)unitsPerEm;
+}
+#endif
+
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
: SkScalerContext(desc) {
SkAutoMutexAcquire ac(gFTMutex);
diff --git a/src/utils/SkCamera.cpp b/src/utils/SkCamera.cpp
index b02499f..87d2aad 100644
--- a/src/utils/SkCamera.cpp
+++ b/src/utils/SkCamera.cpp
@@ -400,6 +400,18 @@
fRec = next;
}
+#ifdef ANDROID
+void Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z)
+{
+ // the camera location is passed in inches, set in pt
+ SkScalar lz = z * SkFloatToScalar(72.0f);
+ fCamera.fLocation.set(x * SkFloatToScalar(72.0f), y * SkFloatToScalar(72.0f), lz);
+ fCamera.fObserver.set(0, 0, lz);
+ fCamera.update();
+
+}
+#endif
+
void Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z)
{
fRec->fMatrix.preTranslate(x, y, z);