Merge changes from the android repo upstream to Skia

Review URL: https://codereview.appspot.com/5545070

git-svn-id: http://skia.googlecode.com/svn/trunk@3199 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
djsollen@google.com 2012-02-15 18:49:15 +00:00
parent 278dc6929b
commit 60abb078e5
15 changed files with 137 additions and 44 deletions

View File

@ -37,6 +37,7 @@
'../include/effects/SkPorterDuff.h', '../include/effects/SkPorterDuff.h',
'../include/effects/SkRectShape.h', '../include/effects/SkRectShape.h',
'../include/effects/SkTableColorFilter.h', '../include/effects/SkTableColorFilter.h',
'../include/effects/SkTableMaskFilter.h',
'../include/effects/SkTransparentShader.h', '../include/effects/SkTransparentShader.h',
'../src/effects/Sk1DPathEffect.cpp', '../src/effects/Sk1DPathEffect.cpp',
@ -71,6 +72,7 @@
'../src/effects/SkRadialGradient_Table.h', '../src/effects/SkRadialGradient_Table.h',
'../src/effects/SkRectShape.cpp', '../src/effects/SkRectShape.cpp',
'../src/effects/SkTableColorFilter.cpp', '../src/effects/SkTableColorFilter.cpp',
'../src/effects/SkTableMaskFilter.cpp',
'../src/effects/SkTestImageFilters.cpp', '../src/effects/SkTestImageFilters.cpp',
'../src/effects/SkTransparentShader.cpp', '../src/effects/SkTransparentShader.cpp',
], ],

View File

@ -90,6 +90,7 @@
'../src/ports/SkFontHost_gamma.cpp', '../src/ports/SkFontHost_gamma.cpp',
'../src/ports/SkFontHost_FreeType.cpp', '../src/ports/SkFontHost_FreeType.cpp',
'../src/ports/FontHostConfiguration_android.cpp', '../src/ports/FontHostConfiguration_android.cpp',
#TODO: include the ports/SkImageRef_ashmem.cpp for non-NDK builds
], ],
'dependencies': [ 'dependencies': [
'android_system.gyp:ft2', 'android_system.gyp:ft2',

View File

@ -47,6 +47,7 @@ public:
virtual bool filterImage(SkImageFilter*, const SkBitmap& src, virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
const SkMatrix& ctm, const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) = 0; SkBitmap* result, SkIPoint* offset) = 0;
virtual ~Proxy() {};
}; };
/** /**

View File

@ -849,9 +849,14 @@ public:
#ifdef SK_BUILD_FOR_ANDROID #ifdef SK_BUILD_FOR_ANDROID
const SkGlyph& getUnicharMetrics(SkUnichar); const SkGlyph& getUnicharMetrics(SkUnichar);
const SkGlyph& getGlyphMetrics(uint16_t);
const void* findImage(const SkGlyph&); const void* findImage(const SkGlyph&);
uint32_t getGenerationID() const; uint32_t getGenerationID() const;
/** Returns the base glyph count for the strike associated with this paint
*/
unsigned getBaseGlyphCount(SkUnichar text) const;
#endif #endif
// returns true if the paint's settings (e.g. xfermode + alpha) resolve to // returns true if the paint's settings (e.g. xfermode + alpha) resolve to

View File

@ -30,15 +30,15 @@
#define SK_BUILD_FOR_WIN32 #define SK_BUILD_FOR_WIN32
#elif defined(__SYMBIAN32__) #elif defined(__SYMBIAN32__)
#define SK_BUILD_FOR_WIN32 #define SK_BUILD_FOR_WIN32
#elif defined(ANDROID_NDK)
#define SK_BUILD_FOR_ANDROID_NDK
#elif defined(ANDROID)
#define SK_BUILD_FOR_ANDROID
#elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
#define SK_BUILD_FOR_UNIX #define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS #define SK_BUILD_FOR_IOS
#elif defined(ANDROID_NDK)
#define SK_BUILD_FOR_ANDROID_NDK
#elif defined(ANDROID)
#define SK_BUILD_FOR_ANDROID
#else #else
#define SK_BUILD_FOR_MAC #define SK_BUILD_FOR_MAC
#endif #endif

View File

@ -298,6 +298,10 @@ public:
void getFontMetrics(SkPaint::FontMetrics* mX, void getFontMetrics(SkPaint::FontMetrics* mX,
SkPaint::FontMetrics* mY); SkPaint::FontMetrics* mY);
#ifdef SK_BUILD_FOR_ANDROID
unsigned getBaseGlyphCount(SkUnichar charCode);
#endif
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec); static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
static SkScalerContext* Create(const SkDescriptor*); static SkScalerContext* Create(const SkDescriptor*);

View File

@ -1517,7 +1517,12 @@ void SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap,
const SkIRect& center, const SkRect& dst, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) { const SkPaint* paint) {
if (NULL == paint || paint->canComputeFastBounds()) { if (NULL == paint || paint->canComputeFastBounds()) {
if (this->quickReject(dst, paint2EdgeType(paint))) { SkRect storage;
const SkRect* bounds = &dst;
if (paint) {
bounds = &paint->computeFastBounds(dst, &storage);
}
if (this->quickReject(*bounds, paint2EdgeType(paint))) {
return; return;
} }
} }

View File

@ -73,6 +73,14 @@ public:
*/ */
unsigned getGlyphCount(); unsigned getGlyphCount();
#ifdef SK_BUILD_FOR_ANDROID
/** Returns the base glyph count for this strike.
*/
unsigned getBaseGlyphCount(SkUnichar charCode) const {
return fScalerContext->getBaseGlyphCount(charCode);
}
#endif
/** Return the image associated with the glyph. If it has not been generated /** Return the image associated with the glyph. If it has not been generated
this will trigger that. this will trigger that.
*/ */

View File

@ -22,6 +22,7 @@
#include "SkTypeface.h" #include "SkTypeface.h"
#include "SkXfermode.h" #include "SkXfermode.h"
#include "SkAutoKern.h" #include "SkAutoKern.h"
#include "SkGlyphCache.h"
// define this to get a printf for out-of-range parameter in setters // define this to get a printf for out-of-range parameter in setters
// e.g. setTextSize(-1) // e.g. setTextSize(-1)
@ -162,6 +163,14 @@ uint32_t SkPaint::getGenerationID() const {
} }
#endif #endif
#ifdef SK_BUILD_FOR_ANDROID
unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
SkAutoGlyphCache autoCache(*this, NULL);
SkGlyphCache* cache = autoCache.getCache();
return cache->getBaseGlyphCount(text);
}
#endif
void SkPaint::setHinting(Hinting hintingLevel) { void SkPaint::setHinting(Hinting hintingLevel) {
GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
fHinting = hintingLevel; fHinting = hintingLevel;
@ -397,6 +406,16 @@ const SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) {
return glyph; return glyph;
} }
const SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) {
SkGlyphCache* cache;
descriptorProc(NULL, DetachDescProc, &cache, true);
const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId);
SkGlyphCache::AttachCache(cache);
return glyph;
}
const void* SkPaint::findImage(const SkGlyph& glyph) { const void* SkPaint::findImage(const SkGlyph& glyph) {
// See ::detachCache() // See ::detachCache()
SkGlyphCache* cache; SkGlyphCache* cache;

View File

@ -175,6 +175,32 @@ SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
return ctx; return ctx;
} }
#ifdef SK_BUILD_FOR_ANDROID
/* This loops through all available fallback contexts (if needed) until it
finds some context that can handle the unichar and return it.
As this is somewhat expensive operation, it should only be done on the first
char of a run.
*/
unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
SkScalerContext* ctx = this;
unsigned glyphID;
for (;;) {
glyphID = ctx->generateCharToGlyph(uni);
if (glyphID) {
break; // found it
}
ctx = ctx->getNextContext();
if (NULL == ctx) {
SkDebugf("--- no context for char %x\n", uni);
// just return the original context (this)
return this->fBaseGlyphCount;
}
}
return ctx->fBaseGlyphCount;
}
#endif
/* This loops through all available fallback contexts (if needed) until it /* This loops through all available fallback contexts (if needed) until it
finds some context that can handle the unichar. If all fail, returns 0 finds some context that can handle the unichar. If all fail, returns 0
*/ */

View File

@ -61,7 +61,7 @@ public:
Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB); Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB);
fInVertices = new double[count * 3]; fInVertices = new double[count * 3];
} }
~GrTess() { virtual ~GrTess() {
Sk_gluDeleteTess(fTess); Sk_gluDeleteTess(fTess);
delete[] fInVertices; delete[] fInVertices;
} }

View File

@ -988,7 +988,7 @@ static void S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst,
/* calculate 'd', which will be 0..7 */ /* calculate 'd', which will be 0..7 */
/* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */ /* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */
#if SK_BUILD_FOR_ANDROID #if defined(SK_BUILD_FOR_ANDROID)
/* SkAlpha255To256() semantic a+1 vs a+a>>7 */ /* SkAlpha255To256() semantic a+1 vs a+a>>7 */
alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1)); alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1));
#else #else

View File

@ -1,4 +1,4 @@
/* /* libs/graphics/ports/SkFontHost_android.cpp
** **
** Copyright 2006, The Android Open Source Project ** Copyright 2006, The Android Open Source Project
** **
@ -26,6 +26,8 @@
#include "FontHostConfiguration_android.h" #include "FontHostConfiguration_android.h"
#include <stdio.h> #include <stdio.h>
#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
#ifndef SK_FONT_FILE_PREFIX #ifndef SK_FONT_FILE_PREFIX
#define SK_FONT_FILE_PREFIX "/fonts/" #define SK_FONT_FILE_PREFIX "/fonts/"
#endif #endif
@ -179,7 +181,7 @@ static void detach_and_delete_family(FamilyRec* family) {
prev = curr; prev = curr;
curr = next; curr = next;
} }
SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
} }
static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
@ -462,9 +464,11 @@ static void load_font_info() {
// shouldn't get here // shouldn't get here
gNumSystemFonts = 0; gNumSystemFonts = 0;
} }
// SkDebugf("---- We have %d system fonts", gNumSystemFonts);
for (size_t i = 0; i < gNumSystemFonts; ++i) { for (size_t i = 0; i < gNumSystemFonts; ++i) {
gSystemFonts[i].fFileName = fontInfo[i].fFileName; gSystemFonts[i].fFileName = fontInfo[i].fFileName;
gSystemFonts[i].fNames = fontInfo[i].fNames; gSystemFonts[i].fNames = fontInfo[i].fNames;
// SkDebugf("---- gSystemFonts[%d] fileName=%s", i, fontInfo[i].fFileName);
} }
fontFamilies.deleteAll(); fontFamilies.deleteAll();
} }
@ -509,11 +513,13 @@ static void load_system_fonts() {
isFixedWidth) // filename isFixedWidth) // filename
); );
// SkDebugf("---- SkTypeface[%d] %s fontID %d\n", i, rec[i].fFileName, tf->uniqueID());
if (rec[i].fNames != NULL) { if (rec[i].fNames != NULL) {
// see if this is one of our fallback fonts // see if this is one of our fallback fonts
if (rec[i].fNames == gFBNames) { if (rec[i].fNames == gFBNames) {
// SkDebugf("---- adding %s as fallback[%d] fontID %d\n", // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
// rec[i].fFileName, fallbackCount, tf->uniqueID()); // rec[i].fFileName, fallbackCount, tf->uniqueID());
gFallbackFonts[fallbackCount++] = tf->uniqueID(); gFallbackFonts[fallbackCount++] = tf->uniqueID();
} }
@ -760,4 +766,3 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
stream->unref(); stream->unref();
return face; return face;
} }

View File

@ -91,15 +91,17 @@ public:
int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
if (err) { if (err) {
SkDebugf("------ ashmem_set_prot_region(%d) failed %d %d\n", SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
fd, err, errno); fd, err);
close(fd);
return false; return false;
} }
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (-1 == (long)addr) { if (-1 == (long)addr) {
SkDebugf("---------- mmap failed for imageref_ashmem size=%d err=%d\n", SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
size, errno); size);
close(fd);
return false; return false;
} }
@ -178,8 +180,7 @@ void* SkImageRef_ashmem::onLockPixels(SkColorTable** ct) {
SkDebugf("===== ashmem purged %d\n", fBitmap.getSize()); SkDebugf("===== ashmem purged %d\n", fBitmap.getSize());
#endif #endif
} else { } else {
SkDebugf("===== ashmem pin_region(%d) returned %d, treating as error %d\n", SkDebugf("===== ashmem pin_region(%d) returned %d\n", fRec.fFD, pin);
fRec.fFD, pin, errno);
// return null result for failure // return null result for failure
if (ct) { if (ct) {
*ct = NULL; *ct = NULL;

View File

@ -46,6 +46,31 @@ static int fillIndices(uint16_t indices[], int xCount, int yCount) {
return indices - startIndices; return indices - startIndices;
} }
// Computes the delta between vertices along a single axis
static SkScalar computeVertexDelta(bool isStretchyVertex,
SkScalar currentVertex,
SkScalar prevVertex,
SkScalar stretchFactor) {
// the standard delta between vertices if no stretching is required
SkScalar delta = currentVertex - prevVertex;
// if the stretch factor is negative or zero we need to shrink the 9-patch
// to fit within the target bounds. This means that we will eliminate all
// stretchy areas and scale the fixed areas to fit within the target bounds.
if (stretchFactor <= 0) {
if (isStretchyVertex)
delta = 0; // collapse stretchable areas
else
delta = SkScalarMul(delta, -stretchFactor); // scale fixed areas
// if the stretch factor is positive then we use the standard delta for
// fixed and scale the stretchable areas to fill the target bounds.
} else if (isStretchyVertex) {
delta = SkScalarMul(delta, stretchFactor);
}
return delta;
}
static void fillRow(SkPoint verts[], SkPoint texs[], static void fillRow(SkPoint verts[], SkPoint texs[],
const SkScalar vy, const SkScalar ty, const SkScalar vy, const SkScalar ty,
const SkRect& bounds, const int32_t xDivs[], int numXDivs, const SkRect& bounds, const int32_t xDivs[], int numXDivs,
@ -53,21 +78,14 @@ static void fillRow(SkPoint verts[], SkPoint texs[],
SkScalar vx = bounds.fLeft; SkScalar vx = bounds.fLeft;
verts->set(vx, vy); verts++; verts->set(vx, vy); verts++;
texs->set(0, ty); texs++; texs->set(0, ty); texs++;
SkScalar prev = 0;
for (int x = 0; x < numXDivs; x++) { for (int x = 0; x < numXDivs; x++) {
SkScalar tx = SkIntToScalar(xDivs[x]);
if (stretchX >= 0) { const SkScalar tx = SkIntToScalar(xDivs[x]);
if (x & 1) { vx += computeVertexDelta(x & 1, tx, prev, stretchX);
vx += stretchX; prev = tx;
} else {
vx += tx;
}
} else {
if (x & 1) {
; // do nothing
} else {
vx += SkScalarMul(tx, -stretchX);
}
}
verts->set(vx, vy); verts++; verts->set(vx, vy); verts++;
texs->set(tx, ty); texs++; texs->set(tx, ty); texs++;
} }
@ -139,12 +157,11 @@ void SkNinePatch::DrawMesh(SkCanvas* canvas, const SkRect& bounds,
for (int i = 1; i < numXDivs; i += 2) { for (int i = 1; i < numXDivs; i += 2) {
stretchSize += xDivs[i] - xDivs[i-1]; stretchSize += xDivs[i] - xDivs[i-1];
} }
int fixed = bitmap.width() - stretchSize; const SkScalar fixed = SkIntToScalar(bitmap.width() - stretchSize);
stretchX = (bounds.width() - SkIntToScalar(fixed)) / numXStretch; if (bounds.width() >= fixed)
if (stretchX < 0) { stretchX = (bounds.width() - fixed) / stretchSize;
// reuse stretchX, but keep it negative as a signal else // reuse stretchX, but keep it negative as a signal
stretchX = -SkIntToScalar(bitmap.width()) / fixed; stretchX = SkScalarDiv(-bounds.width(), fixed);
}
} }
if (numYStretch > 0) { if (numYStretch > 0) {
@ -152,12 +169,11 @@ void SkNinePatch::DrawMesh(SkCanvas* canvas, const SkRect& bounds,
for (int i = 1; i < numYDivs; i += 2) { for (int i = 1; i < numYDivs; i += 2) {
stretchSize += yDivs[i] - yDivs[i-1]; stretchSize += yDivs[i] - yDivs[i-1];
} }
int fixed = bitmap.height() - stretchSize; const SkScalar fixed = SkIntToScalar(bitmap.height() - stretchSize);
stretchY = (bounds.height() - SkIntToScalar(fixed)) / numYStretch; if (bounds.height() >= fixed)
if (stretchY < 0) { stretchY = (bounds.height() - fixed) / stretchSize;
// reuse stretchY, but keep it negative as a signal else // reuse stretchX, but keep it negative as a signal
stretchY = -SkIntToScalar(bitmap.height()) / fixed; stretchY = SkScalarDiv(-bounds.height(), fixed);
}
} }
#if 0 #if 0