Reverting r12427
git-svn-id: http://skia.googlecode.com/svn/trunk@12428 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 429d092..9d4aa87 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -161,7 +161,6 @@
int bpp;
switch (config) {
case kNo_Config:
- case kA1_Config:
bpp = 0; // not applicable
break;
case kA8_Config:
@@ -194,11 +193,6 @@
switch (c) {
case kNo_Config:
break;
- case kA1_Config:
- rowBytes.set(width);
- rowBytes.add(7);
- rowBytes.shiftRight(3);
- break;
case kA8_Config:
case kIndex8_Config:
rowBytes.set(width);
@@ -275,7 +269,6 @@
case SkBitmap::kNo_Config:
alphaType = kIgnore_SkAlphaType;
break;
- case SkBitmap::kA1_Config:
case SkBitmap::kA8_Config:
if (kUnpremul_SkAlphaType == alphaType) {
alphaType = kPremul_SkAlphaType;
@@ -291,6 +284,8 @@
case SkBitmap::kRGB_565_Config:
alphaType = kOpaque_SkAlphaType;
break;
+ default:
+ return false;
}
if (canonical) {
*canonical = alphaType;
@@ -606,8 +601,6 @@
case SkBitmap::kIndex8_Config:
base += x;
break;
- case SkBitmap::kA1_Config:
- base += x >> 3;
break;
default:
SkDEBUGFAIL("Can't return addr for config");
@@ -623,15 +616,6 @@
SkASSERT((unsigned)y < (unsigned)this->height());
switch (this->config()) {
- case SkBitmap::kA1_Config: {
- uint8_t* addr = this->getAddr1(x, y);
- uint8_t mask = 1 << (7 - (x % 8));
- if (addr[0] & mask) {
- return SK_ColorBLACK;
- } else {
- return 0;
- }
- }
case SkBitmap::kA8_Config: {
uint8_t* addr = this->getAddr8(x, y);
return SkColorSetA(0, addr[0]);
@@ -654,6 +638,7 @@
return SkUnPreMultiply::PMColorToColor(addr[0]);
}
case kNo_Config:
+ default:
SkASSERT(false);
return 0;
}
@@ -671,9 +656,6 @@
const int width = bm.width();
switch (bm.config()) {
- case SkBitmap::kA1_Config: {
- // TODO
- } break;
case SkBitmap::kA8_Config: {
unsigned a = 0xFF;
for (int y = 0; y < height; ++y) {
@@ -779,38 +761,6 @@
}
switch (fConfig) {
- case kA1_Config: {
- uint8_t* p = this->getAddr1(area.fLeft, area.fTop);
- const int left = area.fLeft >> 3;
- const int right = area.fRight >> 3;
-
- int middle = right - left - 1;
-
- uint8_t leftMask = 0xFF >> (area.fLeft & 7);
- uint8_t rightMask = ~(0xFF >> (area.fRight & 7));
- if (left == right) {
- leftMask &= rightMask;
- rightMask = 0;
- }
-
- a = (a >> 7) ? 0xFF : 0;
- while (--height >= 0) {
- uint8_t* startP = p;
-
- *p = (*p & ~leftMask) | (a & leftMask);
- p++;
- if (middle > 0) {
- memset(p, a, middle);
- p += middle;
- }
- if (rightMask) {
- *p = (*p & ~rightMask) | (a & rightMask);
- }
-
- p = startP + rowBytes;
- }
- break;
- }
case kA8_Config: {
uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
while (--height >= 0) {
@@ -896,7 +846,6 @@
break;
case SkBitmap::kNo_Config:
- case SkBitmap::kA1_Config:
default:
return SUB_OFFSET_FAILURE;
}
@@ -939,8 +888,6 @@
case SkBitmap::kNo_Config:
// Fall through.
- case SkBitmap::kA1_Config:
- // Fall through.
default:
return false;
}
@@ -1021,7 +968,6 @@
case kRGB_565_Config:
case kARGB_8888_Config:
break;
- case kA1_Config:
case kIndex8_Config:
if (!sameConfigs) {
return false;
@@ -1032,12 +978,6 @@
default:
return false;
}
-
- // do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
- if (this->config() == kA1_Config && !sameConfigs) {
- return false;
- }
-
return true;
}
@@ -1683,7 +1623,7 @@
void SkBitmap::toString(SkString* str) const {
static const char* gConfigNames[kConfigCount] = {
- "NONE", "A1", "A8", "INDEX8", "565", "4444", "8888"
+ "NONE", "A8", "INDEX8", "565", "4444", "8888"
};
str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(),
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index dc7946a..9682d55 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -945,11 +945,6 @@
switch (device.config()) {
- case SkBitmap::kA1_Config:
- SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
- storage, storageSize, (device, *paint));
- break;
-
case SkBitmap::kA8_Config:
if (drawCoverage) {
SkASSERT(NULL == shader);
diff --git a/src/core/SkBlitter_A1.cpp b/src/core/SkBlitter_A1.cpp
deleted file mode 100644
index b64afe2..0000000
--- a/src/core/SkBlitter_A1.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#include "SkCoreBlitters.h"
-
-SkA1_Blitter::SkA1_Blitter(const SkBitmap& device, const SkPaint& paint)
- : INHERITED(device) {
- fSrcA = paint.getAlpha();
-}
-
-void SkA1_Blitter::blitH(int x, int y, int width) {
- SkASSERT(x >= 0 && y >= 0 &&
- (unsigned)(x + width) <= (unsigned)fDevice.width());
-
- if (fSrcA <= 0x7F) {
- return;
- }
- uint8_t* dst = fDevice.getAddr1(x, y);
- int right = x + width;
-
- int left_mask = 0xFF >> (x & 7);
- int rite_mask = 0xFF << (8 - (right & 7));
- int full_runs = (right >> 3) - ((x + 7) >> 3);
-
- // check for empty right mask, so we don't read off the end
- // (or go slower than we need to)
- if (rite_mask == 0) {
- SkASSERT(full_runs >= 0);
- full_runs -= 1;
- rite_mask = 0xFF;
- }
- if (left_mask == 0xFF) {
- full_runs -= 1;
- }
- if (full_runs < 0) {
- SkASSERT((left_mask & rite_mask) != 0);
- *dst |= (left_mask & rite_mask);
- } else {
- *dst++ |= left_mask;
- memset(dst, 0xFF, full_runs);
- dst += full_runs;
- *dst |= rite_mask;
- }
-}
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 673b874..1605a52 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -162,22 +162,6 @@
///////////////////////////////////////////////////////////////////////////////
-class SkA1_Blitter : public SkRasterBlitter {
-public:
- SkA1_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual void blitH(int x, int y, int width) SK_OVERRIDE;
-
-private:
- uint8_t fSrcA;
-
- // illegal
- SkA1_Blitter& operator=(const SkA1_Blitter&);
-
- typedef SkRasterBlitter INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
/* These return the correct subclass of blitter for their device config.
Currently, they make the following assumptions about the state of the
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index faa3f89..a78b197 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -87,8 +87,6 @@
fGlyphArray.setReserve(kMinGlyphCount);
- fMetricsCount = 0;
- fAdvanceCount = 0;
fAuxProcList = NULL;
}
@@ -320,11 +318,9 @@
if (kJustAdvance_MetricsType == mtype) {
fScalerContext->getAdvance(glyph);
- fAdvanceCount += 1;
} else {
SkASSERT(kFull_MetricsType == mtype);
fScalerContext->getMetrics(glyph);
- fMetricsCount += 1;
}
return glyph;
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 52a8132..7b2ebb8 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -211,8 +211,6 @@
SkTDArray<SkGlyph*> fGlyphArray;
SkChunkAlloc fGlyphAlloc;
- int fMetricsCount, fAdvanceCount;
-
struct CharGlyphRec {
uint32_t fID; // unichar + subpixel
SkGlyph* fGlyph;
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index d6948dd..91a76e1 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -2005,11 +2005,7 @@
};
// The size of a flat paint's POD fields
-// Include an SkScalar for hinting scale factor whether it is
-// supported or not so that an SKP is valid whether it was
-// created with support or not.
-
-static const uint32_t kPODPaintSize = 6 * sizeof(SkScalar) +
+static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) +
1 * sizeof(SkColor) +
1 * sizeof(uint16_t) +
6 * sizeof(uint8_t);
@@ -2046,8 +2042,6 @@
ptr = write_scalar(ptr, this->getTextSize());
ptr = write_scalar(ptr, this->getTextScaleX());
ptr = write_scalar(ptr, this->getTextSkewX());
- // Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
- ptr = write_scalar(ptr, SK_Scalar1);
ptr = write_scalar(ptr, this->getStrokeWidth());
ptr = write_scalar(ptr, this->getStrokeMiter());
*ptr++ = this->getColor();
@@ -2064,8 +2058,6 @@
buffer.writeScalar(fTextSize);
buffer.writeScalar(fTextScaleX);
buffer.writeScalar(fTextSkewX);
- // Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
- buffer.writeScalar(SK_Scalar1);
buffer.writeScalar(fWidth);
buffer.writeScalar(fMiterLimit);
buffer.writeColor(fColor);
@@ -2120,8 +2112,6 @@
this->setTextSize(read_scalar(pod));
this->setTextScaleX(read_scalar(pod));
this->setTextSkewX(read_scalar(pod));
- // Skip the hinting scalar factor, which is not supported.
- read_scalar(pod);
this->setStrokeWidth(read_scalar(pod));
this->setStrokeMiter(read_scalar(pod));
this->setColor(*pod++);
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 4acc549..2520e6b 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -266,11 +266,20 @@
#include "SkStream.h"
+static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
+
bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
if (NULL == stream) {
return false;
}
+ // Check magic bytes.
+ char magic[sizeof(kMagic)];
+ stream->read(magic, sizeof(kMagic));
+ if (0 != memcmp(magic, kMagic, sizeof(kMagic))) {
+ return false;
+ }
+
SkPictInfo info;
if (!stream->read(&info, sizeof(SkPictInfo))) {
return false;
@@ -341,6 +350,10 @@
info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
}
+ // Write 8 magic bytes to ID this file format.
+ SkASSERT(sizeof(kMagic) == 8);
+ stream->write(kMagic, sizeof(kMagic));
+
stream->write(&info, sizeof(info));
if (playback) {
stream->writeBool(true);
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index ea29843..55eadb8 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -49,7 +49,7 @@
return hash;
}
-struct Key {
+struct SkScaledImageCache::Key {
Key(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
@@ -129,22 +129,24 @@
#include "SkTDynamicHash.h"
namespace { // can't use static functions w/ template parameters
-const Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
+const SkScaledImageCache::Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
return rec.fKey;
}
-uint32_t hash_from_key(const Key& key) {
+uint32_t hash_from_key(const SkScaledImageCache::Key& key) {
return key.fHash;
}
-bool eq_rec_key(const SkScaledImageCache::Rec& rec, const Key& key) {
+bool eq_rec_key(const SkScaledImageCache::Rec& rec, const SkScaledImageCache::Key& key) {
return rec.fKey == key;
}
}
class SkScaledImageCache::Hash : public SkTDynamicHash<SkScaledImageCache::Rec,
- Key, key_from_rec, hash_from_key,
- eq_rec_key> {};
+ SkScaledImageCache::Key,
+ key_from_rec,
+ hash_from_key,
+ eq_rec_key> {};
///////////////////////////////////////////////////////////////////////////////
@@ -187,17 +189,22 @@
////////////////////////////////////////////////////////////////////////////////
-/**
- This private method is the fully general record finder. All other
- record finders should call this funtion. */
+
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
const SkIRect& bounds) {
- if (bounds.isEmpty()) {
+ const Key key(genID, scaleX, scaleY, bounds);
+ return this->findAndLock(key);
+}
+
+/**
+ This private method is the fully general record finder. All other
+ record finders should call this function or the one above. */
+SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
+ if (key.fBounds.isEmpty()) {
return NULL;
}
- Key key(genID, scaleX, scaleY, bounds);
#ifdef USE_HASH
Rec* rec = fHash->find(key);
#else
@@ -275,8 +282,14 @@
/**
This private method is the fully general record adder. All other
record adders should call this funtion. */
-void SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
+SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
SkASSERT(rec);
+ // See if we already have this key (racy inserts, etc.)
+ Rec* existing = this->findAndLock(rec->fKey);
+ if (existing != NULL) {
+ return rec_to_id(existing);
+ }
+
this->addToHead(rec);
SkASSERT(1 == rec->fLockCount);
#ifdef USE_HASH
@@ -285,6 +298,7 @@
#endif
// We may (now) be overbudget, so see if we need to purge something.
this->purgeAsNeeded();
+ return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
@@ -293,8 +307,7 @@
const SkBitmap& bitmap) {
Key key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
- this->addAndLock(rec);
- return rec_to_id(rec);
+ return this->addAndLock(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
@@ -311,8 +324,7 @@
}
Key key(orig.getGenerationID(), scaleX, scaleY, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
- this->addAndLock(rec);
- return rec_to_id(rec);
+ return this->addAndLock(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
@@ -323,8 +335,7 @@
}
Key key(orig.getGenerationID(), 0, 0, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, mip));
- this->addAndLock(rec);
- return rec_to_id(rec);
+ return this->addAndLock(rec);
}
void SkScaledImageCache::unlock(SkScaledImageCache::ID* id) {
diff --git a/src/core/SkScaledImageCache.h b/src/core/SkScaledImageCache.h
index fee69d2..44ef1f8 100644
--- a/src/core/SkScaledImageCache.h
+++ b/src/core/SkScaledImageCache.h
@@ -126,6 +126,7 @@
public:
struct Rec;
+ struct Key;
private:
Rec* fHead;
Rec* fTail;
@@ -139,7 +140,8 @@
Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
const SkIRect& bounds);
- void addAndLock(Rec* rec);
+ Rec* findAndLock(const Key& key);
+ ID* addAndLock(Rec* rec);
void purgeAsNeeded();
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 1d6c2f7..4996a73 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -352,16 +352,16 @@
glyph->fHeight = SkToU16(ir.height());
if (glyph->fWidth > 0) {
- switch (fRec.fMaskFormat) {
- case SkMask::kLCD16_Format:
- case SkMask::kLCD32_Format:
- glyph->fWidth += 2;
- glyph->fLeft -= 1;
- break;
- default:
- break;
+ switch (fRec.fMaskFormat) {
+ case SkMask::kLCD16_Format:
+ case SkMask::kLCD32_Format:
+ glyph->fWidth += 2;
+ glyph->fLeft -= 1;
+ break;
+ default:
+ break;
+ }
}
- }
}
}
@@ -523,10 +523,54 @@
}
}
+static inline int convert_8_to_1(unsigned byte) {
+ SkASSERT(byte <= 0xFF);
+ return byte >> 7;
+}
+
+static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
+ unsigned bits = 0;
+ for (int i = 0; i < 8; ++i) {
+ bits <<= 1;
+ bits |= convert_8_to_1(alpha[i]);
+ }
+ return SkToU8(bits);
+}
+
+static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
+ const int height = mask.fBounds.height();
+ const int width = mask.fBounds.width();
+ const int octs = width >> 3;
+ const int leftOverBits = width & 7;
+
+ uint8_t* dst = mask.fImage;
+ const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
+ SkASSERT(dstPad >= 0);
+
+ const int srcPad = srcRB - width;
+ SkASSERT(srcPad >= 0);
+
+ for (int y = 0; y < height; ++y) {
+ for (int i = 0; i < octs; ++i) {
+ *dst++ = pack_8_to_1(src);
+ src += 8;
+ }
+ if (leftOverBits > 0) {
+ unsigned bits = 0;
+ int shift = 7;
+ for (int i = 0; i < leftOverBits; ++i, --shift) {
+ bits |= convert_8_to_1(*src++ >> 7) << shift;
+ }
+ *dst++ = bits;
+ }
+ src += srcPad;
+ dst += dstPad;
+ }
+}
+
static void generateMask(const SkMask& mask, const SkPath& path,
const SkMaskGamma::PreBlend& maskPreBlend) {
- SkBitmap::Config config;
- SkPaint paint;
+ SkPaint paint;
int srcW = mask.fBounds.width();
int srcH = mask.fBounds.height();
@@ -538,27 +582,25 @@
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
- if (SkMask::kBW_Format == mask.fFormat) {
- config = SkBitmap::kA1_Config;
- paint.setAntiAlias(false);
- } else {
- config = SkBitmap::kA8_Config;
- paint.setAntiAlias(true);
- switch (mask.fFormat) {
- case SkMask::kA8_Format:
- break;
- case SkMask::kLCD16_Format:
- case SkMask::kLCD32_Format:
- // TODO: trigger off LCD orientation
- dstW = 4*dstW - 8;
- matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
- -SkIntToScalar(mask.fBounds.fTop));
- matrix.postScale(SkIntToScalar(4), SK_Scalar1);
- dstRB = 0; // signals we need a copy
- break;
- default:
- SkDEBUGFAIL("unexpected mask format");
- }
+ SkBitmap::Config config = SkBitmap::kA8_Config;
+ paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
+ switch (mask.fFormat) {
+ case SkMask::kBW_Format:
+ dstRB = 0; // signals we need a copy
+ break;
+ case SkMask::kA8_Format:
+ break;
+ case SkMask::kLCD16_Format:
+ case SkMask::kLCD32_Format:
+ // TODO: trigger off LCD orientation
+ dstW = 4*dstW - 8;
+ matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
+ -SkIntToScalar(mask.fBounds.fTop));
+ matrix.postScale(SkIntToScalar(4), SK_Scalar1);
+ dstRB = 0; // signals we need a copy
+ break;
+ default:
+ SkDEBUGFAIL("unexpected mask format");
}
SkRasterClip clip;
@@ -587,6 +629,9 @@
draw.drawPath(path, paint);
switch (mask.fFormat) {
+ case SkMask::kBW_Format:
+ packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
+ break;
case SkMask::kA8_Format:
if (maskPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, maskPreBlend.fG);
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index 2820b5a..e4950ed 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -202,16 +202,57 @@
Rec fRec;
unsigned fBaseGlyphCount;
- virtual unsigned generateGlyphCount() = 0;
- virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
- virtual void generateAdvance(SkGlyph*) = 0;
- virtual void generateMetrics(SkGlyph*) = 0;
- virtual void generateImage(const SkGlyph&) = 0;
- virtual void generatePath(const SkGlyph&, SkPath*) = 0;
+ /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
+ * May call getMetrics if that would be just as fast.
+ */
+ virtual void generateAdvance(SkGlyph* glyph) = 0;
+
+ /** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
+ * as well as fAdvanceX and fAdvanceY if not already set.
+ *
+ * TODO: fMaskFormat is set by getMetrics later; cannot be set here.
+ */
+ virtual void generateMetrics(SkGlyph* glyph) = 0;
+
+ /** Generates the contents of glyph.fImage.
+ * When called, glyph.fImage will be pointing to a pre-allocated,
+ * uninitialized region of memory of size glyph.computeImageSize().
+ * This method may change glyph.fMaskFormat if the new image size is
+ * less than or equal to the old image size.
+ *
+ * Because glyph.computeImageSize() will determine the size of fImage,
+ * generateMetrics will be called before generateImage.
+ */
+ virtual void generateImage(const SkGlyph& glyph) = 0;
+
+ /** Sets the passed path to the glyph outline.
+ * If this cannot be done the path is set to empty;
+ * this is indistinguishable from a glyph with an empty path.
+ * This does not set glyph.fPath.
+ *
+ * TODO: path is always glyph.fPath, no reason to pass separately.
+ */
+ virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
+
+ /** Retrieves font metrics.
+ * TODO: there is now a vertical bit, no need for two parameters.
+ */
virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
SkPaint::FontMetrics* mY) = 0;
- // default impl returns 0, indicating failure.
- virtual SkUnichar generateGlyphToChar(uint16_t);
+
+ /** Returns the number of glyphs in the font. */
+ virtual unsigned generateGlyphCount() = 0;
+
+ /** Returns the glyph id for the given unichar.
+ * If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
+ */
+ virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
+
+ /** Returns the unichar for the given glyph id.
+ * If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
+ * The default implementation always returns 0, indicating failure.
+ */
+ virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index e30b89f..643dfb1 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -634,5 +634,17 @@
return formattedOutput;
}
+void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
+ const char* end = str + strlen(str);
+ while (str != end) {
+ // Find a token.
+ const size_t len = strcspn(str, delimiters);
+ out->push_back().set(str, len);
+ str += len;
+ // Skip any delimiters.
+ str += strspn(str, delimiters);
+ }
+}
+
#undef VSNPRINTF
#undef SNPRINTF
diff --git a/src/core/SkValidatingReadBuffer.cpp b/src/core/SkValidatingReadBuffer.cpp
index a92c1b9..4a8ac47 100644
--- a/src/core/SkValidatingReadBuffer.cpp
+++ b/src/core/SkValidatingReadBuffer.cpp
@@ -203,7 +203,7 @@
uint32_t SkValidatingReadBuffer::getArrayCount() {
const size_t inc = sizeof(uint32_t);
fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
- return *(uint32_t*)fReader.peek();
+ return fError ? 0 : *(uint32_t*)fReader.peek();
}
void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {