'../include/effects/SkPorterDuff.h',
'../include/effects/SkRectShape.h',
'../include/effects/SkTableColorFilter.h',
+ '../include/effects/SkTableMaskFilter.h',
'../include/effects/SkTransparentShader.h',
'../src/effects/Sk1DPathEffect.cpp',
'../src/effects/SkRadialGradient_Table.h',
'../src/effects/SkRectShape.cpp',
'../src/effects/SkTableColorFilter.cpp',
+ '../src/effects/SkTableMaskFilter.cpp',
'../src/effects/SkTestImageFilters.cpp',
'../src/effects/SkTransparentShader.cpp',
],
'../src/ports/SkFontHost_gamma.cpp',
'../src/ports/SkFontHost_FreeType.cpp',
'../src/ports/FontHostConfiguration_android.cpp',
+ #TODO: include the ports/SkImageRef_ashmem.cpp for non-NDK builds
],
'dependencies': [
'android_system.gyp:ft2',
virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) = 0;
+ virtual ~Proxy() {};
};
/**
#ifdef SK_BUILD_FOR_ANDROID
const SkGlyph& getUnicharMetrics(SkUnichar);
+ const SkGlyph& getGlyphMetrics(uint16_t);
const void* findImage(const SkGlyph&);
uint32_t getGenerationID() const;
+
+ /** Returns the base glyph count for the strike associated with this paint
+ */
+ unsigned getBaseGlyphCount(SkUnichar text) const;
#endif
// returns true if the paint's settings (e.g. xfermode + alpha) resolve to
#define SK_BUILD_FOR_WIN32
#elif defined(__SYMBIAN32__)
#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__) || \
defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
#define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS
- #elif defined(ANDROID_NDK)
- #define SK_BUILD_FOR_ANDROID_NDK
- #elif defined(ANDROID)
- #define SK_BUILD_FOR_ANDROID
#else
#define SK_BUILD_FOR_MAC
#endif
void getFontMetrics(SkPaint::FontMetrics* mX,
SkPaint::FontMetrics* mY);
+#ifdef SK_BUILD_FOR_ANDROID
+ unsigned getBaseGlyphCount(SkUnichar charCode);
+#endif
+
static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
static SkScalerContext* Create(const SkDescriptor*);
const SkIRect& center, const SkRect& dst,
const SkPaint* paint) {
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;
}
}
*/
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
this will trigger that.
*/
#include "SkTypeface.h"
#include "SkXfermode.h"
#include "SkAutoKern.h"
+#include "SkGlyphCache.h"
// define this to get a printf for out-of-range parameter in setters
// e.g. setTextSize(-1)
}
#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) {
GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
fHinting = hintingLevel;
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) {
// See ::detachCache()
SkGlyphCache* cache;
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
finds some context that can handle the unichar. If all fail, returns 0
*/
Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB);
fInVertices = new double[count * 3];
}
- ~GrTess() {
+ virtual ~GrTess() {
Sk_gluDeleteTess(fTess);
delete[] fInVertices;
}
/* calculate 'd', which will be 0..7 */
/* 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 */
alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1));
#else
-/*
+/* libs/graphics/ports/SkFontHost_android.cpp
**
** Copyright 2006, The Android Open Source Project
**
#include "FontHostConfiguration_android.h"
#include <stdio.h>
+#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
+
#ifndef SK_FONT_FILE_PREFIX
#define SK_FONT_FILE_PREFIX "/fonts/"
#endif
prev = curr;
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) {
// shouldn't get here
gNumSystemFonts = 0;
}
+// SkDebugf("---- We have %d system fonts", gNumSystemFonts);
for (size_t i = 0; i < gNumSystemFonts; ++i) {
gSystemFonts[i].fFileName = fontInfo[i].fFileName;
gSystemFonts[i].fNames = fontInfo[i].fNames;
+// SkDebugf("---- gSystemFonts[%d] fileName=%s", i, fontInfo[i].fFileName);
}
fontFamilies.deleteAll();
}
isFixedWidth) // filename
);
+// SkDebugf("---- SkTypeface[%d] %s fontID %d\n", i, rec[i].fFileName, tf->uniqueID());
+
if (rec[i].fNames != NULL) {
// see if this is one of our fallback fonts
if (rec[i].fNames == gFBNames) {
- // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
- // rec[i].fFileName, fallbackCount, tf->uniqueID());
+// SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
+// rec[i].fFileName, fallbackCount, tf->uniqueID());
gFallbackFonts[fallbackCount++] = tf->uniqueID();
}
stream->unref();
return face;
}
-
int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
if (err) {
- SkDebugf("------ ashmem_set_prot_region(%d) failed %d %d\n",
- fd, err, errno);
+ SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
+ fd, err);
+ close(fd);
return false;
}
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (-1 == (long)addr) {
- SkDebugf("---------- mmap failed for imageref_ashmem size=%d err=%d\n",
- size, errno);
+ SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
+ size);
+ close(fd);
return false;
}
SkDebugf("===== ashmem purged %d\n", fBitmap.getSize());
#endif
} else {
- SkDebugf("===== ashmem pin_region(%d) returned %d, treating as error %d\n",
- fRec.fFD, pin, errno);
+ SkDebugf("===== ashmem pin_region(%d) returned %d\n", fRec.fFD, pin);
// return null result for failure
if (ct) {
*ct = NULL;
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[],
const SkScalar vy, const SkScalar ty,
const SkRect& bounds, const int32_t xDivs[], int numXDivs,
SkScalar vx = bounds.fLeft;
verts->set(vx, vy); verts++;
texs->set(0, ty); texs++;
+
+ SkScalar prev = 0;
for (int x = 0; x < numXDivs; x++) {
- SkScalar tx = SkIntToScalar(xDivs[x]);
- if (stretchX >= 0) {
- if (x & 1) {
- vx += stretchX;
- } else {
- vx += tx;
- }
- } else {
- if (x & 1) {
- ; // do nothing
- } else {
- vx += SkScalarMul(tx, -stretchX);
- }
- }
+
+ const SkScalar tx = SkIntToScalar(xDivs[x]);
+ vx += computeVertexDelta(x & 1, tx, prev, stretchX);
+ prev = tx;
+
verts->set(vx, vy); verts++;
texs->set(tx, ty); texs++;
}
for (int i = 1; i < numXDivs; i += 2) {
stretchSize += xDivs[i] - xDivs[i-1];
}
- int fixed = bitmap.width() - stretchSize;
- stretchX = (bounds.width() - SkIntToScalar(fixed)) / numXStretch;
- if (stretchX < 0) {
- // reuse stretchX, but keep it negative as a signal
- stretchX = -SkIntToScalar(bitmap.width()) / fixed;
- }
+ const SkScalar fixed = SkIntToScalar(bitmap.width() - stretchSize);
+ if (bounds.width() >= fixed)
+ stretchX = (bounds.width() - fixed) / stretchSize;
+ else // reuse stretchX, but keep it negative as a signal
+ stretchX = SkScalarDiv(-bounds.width(), fixed);
}
if (numYStretch > 0) {
for (int i = 1; i < numYDivs; i += 2) {
stretchSize += yDivs[i] - yDivs[i-1];
}
- int fixed = bitmap.height() - stretchSize;
- stretchY = (bounds.height() - SkIntToScalar(fixed)) / numYStretch;
- if (stretchY < 0) {
- // reuse stretchY, but keep it negative as a signal
- stretchY = -SkIntToScalar(bitmap.height()) / fixed;
- }
+ const SkScalar fixed = SkIntToScalar(bitmap.height() - stretchSize);
+ if (bounds.height() >= fixed)
+ stretchY = (bounds.height() - fixed) / stretchSize;
+ else // reuse stretchX, but keep it negative as a signal
+ stretchY = SkScalarDiv(-bounds.height(), fixed);
}
#if 0