summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Chromium Automerger <chromium-automerger@android>2014-05-02 17:30:19 +0000
committerAndroid Chromium Automerger <chromium-automerger@android>2014-05-02 17:30:19 +0000
commitf9ae730704cc91b8324622c2af3304ea106357ff (patch)
treed8b1b5022262f059c6b6ce52f1e010e631501768
parent086c0a576a202296234038042382954beaea8d71 (diff)
parentc54179f4375f836f4e53a9de6367e596e94d6e9d (diff)
downloadsrc-f9ae730704cc91b8324622c2af3304ea106357ff.tar.gz
Merge third_party/skia/src from https://chromium.googlesource.com/external/skia/src.git at c54179f4375f836f4e53a9de6367e596e94d6e9d
This commit was generated by merge_from_chromium.py. Change-Id: Iaaa720438124aea9957ddb67f8e0f0685661b0a1
-rw-r--r--core/ARGB32_Clamp_Bilinear_BitmapShader.h177
-rw-r--r--core/SkBitmapProcShader.cpp31
-rw-r--r--core/SkBitmapProcShader.h18
-rw-r--r--core/SkBlitter.cpp37
-rw-r--r--core/SkComposeShader.cpp46
-rw-r--r--core/SkDraw.cpp20
-rw-r--r--core/SkFilterShader.cpp27
-rw-r--r--core/SkFilterShader.h9
-rw-r--r--core/SkPictureShader.cpp30
-rw-r--r--core/SkPictureShader.h15
-rw-r--r--core/SkShader.cpp36
-rw-r--r--core/SkXfermode.cpp112
-rw-r--r--effects/SkBlurMaskFilter.cpp4
-rw-r--r--effects/SkMatrixConvolutionImageFilter.cpp3
-rw-r--r--effects/SkPerlinNoiseShader.cpp14
-rw-r--r--effects/SkTransparentShader.cpp16
-rw-r--r--effects/gradients/SkGradientShader.cpp5
-rw-r--r--effects/gradients/SkGradientShaderPriv.h4
-rw-r--r--effects/gradients/SkLinearGradient.cpp14
-rw-r--r--effects/gradients/SkLinearGradient.h7
-rw-r--r--effects/gradients/SkRadialGradient.cpp12
-rw-r--r--effects/gradients/SkRadialGradient.h7
-rw-r--r--effects/gradients/SkSweepGradient.cpp12
-rw-r--r--effects/gradients/SkSweepGradient.h7
-rw-r--r--effects/gradients/SkTwoPointConicalGradient.cpp15
-rw-r--r--effects/gradients/SkTwoPointConicalGradient.h8
-rw-r--r--effects/gradients/SkTwoPointRadialGradient.cpp20
-rw-r--r--effects/gradients/SkTwoPointRadialGradient.h13
-rw-r--r--gpu/SkGpuDevice.cpp5
-rw-r--r--gpu/gl/GrGLInterface.cpp12
-rw-r--r--gpu/gl/GrGLUtil.cpp6
-rw-r--r--ports/SkFontHost_win_dw.cpp309
-rw-r--r--sfnt/SkOTTable_EBDT.h109
-rw-r--r--sfnt/SkOTTable_EBLC.h152
-rw-r--r--sfnt/SkOTTable_EBSC.h41
-rw-r--r--utils/debugger/SkDebugCanvas.cpp2
36 files changed, 729 insertions, 626 deletions
diff --git a/core/ARGB32_Clamp_Bilinear_BitmapShader.h b/core/ARGB32_Clamp_Bilinear_BitmapShader.h
deleted file mode 100644
index 87121cfd..00000000
--- a/core/ARGB32_Clamp_Bilinear_BitmapShader.h
+++ /dev/null
@@ -1,177 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-class ARGB32_Clamp_Bilinear_BitmapShader : public SkBitmapShader {
-public:
- ARGB32_Clamp_Bilinear_BitmapShader(const SkBitmap& src)
- : SkBitmapShader(src, true,
- SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)
- {}
-
- virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
-};
-
-SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
- const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table);
-SkPMColor sample_bilerp(SkFixed fx, SkFixed fy, unsigned srcMaxX, unsigned srcMaxY,
- const SkPMColor* srcPixels, int srcRB, const SkFilterPtrProc* proc_table)
-{
- int ix = fx >> 16;
- int iy = fy >> 16;
-
- const SkPMColor *p00, *p01, *p10, *p11;
-
- p00 = p01 = ((const SkPMColor*)((const char*)srcPixels
- + SkClampMax(iy, srcMaxY) * srcRB))
- + SkClampMax(ix, srcMaxX);
-
- if ((unsigned)ix < srcMaxX)
- p01 += 1;
- p10 = p00;
- p11 = p01;
- if ((unsigned)iy < srcMaxY)
- {
- p10 = (const SkPMColor*)((const char*)p10 + srcRB);
- p11 = (const SkPMColor*)((const char*)p11 + srcRB);
- }
-
- SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(proc_table, fx, fy);
- return proc(p00, p01, p10, p11);
-}
-
-static inline SkPMColor sample_bilerpx(SkFixed fx, unsigned srcMaxX, const SkPMColor* srcPixels,
- int srcRB, const SkFilterPtrProc* proc_table)
-{
- int ix = fx >> 16;
-
- const SkPMColor *p00, *p01, *p10, *p11;
-
- p00 = p01 = srcPixels + SkClampMax(ix, srcMaxX);
- if ((unsigned)ix < srcMaxX)
- p01 += 1;
-
- p10 = (const SkPMColor*)((const char*)p00 + srcRB);
- p11 = (const SkPMColor*)((const char*)p01 + srcRB);
-
- SkFilterPtrProc proc = SkGetBilinearFilterPtrXProc(proc_table, fx);
- return proc(p00, p01, p10, p11);
-}
-
-void ARGB32_Clamp_Bilinear_BitmapShader::shadeSpan(int x, int y, SkPMColor dstC[], int count)
-{
- SkASSERT(count > 0);
-
- unsigned srcScale = SkAlpha255To256(this->getPaintAlpha());
-
- const SkMatrix& inv = this->getTotalInverse();
- const SkBitmap& srcBitmap = this->getSrcBitmap();
- unsigned srcMaxX = srcBitmap.width() - 1;
- unsigned srcMaxY = srcBitmap.height() - 1;
- unsigned srcRB = srcBitmap.rowBytes();
-
- const SkFilterPtrProc* proc_table = SkGetBilinearFilterPtrProcTable();
- const SkPMColor* srcPixels = (const SkPMColor*)srcBitmap.getPixels();
-
- if (this->getInverseClass() == kPerspective_MatrixClass)
- {
- SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, count);
-
- if (256 == srcScale)
- {
- while ((count = iter.next()) != 0)
- {
- const SkFixed* srcXY = iter.getXY();
- while (--count >= 0)
- {
- SkFixed fx = *srcXY++ - SK_FixedHalf;
- SkFixed fy = *srcXY++ - SK_FixedHalf;
- *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
- }
- }
- }
- else // scale by srcScale
- {
- while ((count = iter.next()) != 0)
- {
- const SkFixed* srcXY = iter.getXY();
- while (--count >= 0)
- {
- SkFixed fx = *srcXY++ - SK_FixedHalf;
- SkFixed fy = *srcXY++ - SK_FixedHalf;
- SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
- *dstC++ = SkAlphaMulQ(c, srcScale);
- }
- }
- }
- }
- else // linear case
- {
- SkFixed fx, fy, dx, dy;
-
- // now init fx, fy, dx, dy
- {
- SkPoint srcPt;
- this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf,
- &srcPt);
-
- fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
- fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
-
- if (this->getInverseClass() == kFixedStepInX_MatrixClass)
- (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
- else
- {
- dx = SkScalarToFixed(inv.getScaleX());
- dy = SkScalarToFixed(inv.getSkewY());
- }
- }
-
- if (dy == 0 && (unsigned)(fy >> 16) < srcMaxY)
- {
- srcPixels = (const SkPMColor*)((const char*)srcPixels + (fy >> 16) * srcRB);
- proc_table = SkGetBilinearFilterPtrProcYTable(proc_table, fy);
- if (256 == srcScale)
- {
- do {
- *dstC++ = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
- fx += dx;
- } while (--count != 0);
- }
- else
- {
- do {
- SkPMColor c = sample_bilerpx(fx, srcMaxX, srcPixels, srcRB, proc_table);
- *dstC++ = SkAlphaMulQ(c, srcScale);
- fx += dx;
- } while (--count != 0);
- }
- }
- else // dy is != 0
- {
- if (256 == srcScale)
- {
- do {
- *dstC++ = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
- fx += dx;
- fy += dy;
- } while (--count != 0);
- }
- else
- {
- do {
- SkPMColor c = sample_bilerp(fx, fy, srcMaxX, srcMaxY, srcPixels, srcRB, proc_table);
- *dstC++ = SkAlphaMulQ(c, srcScale);
- fx += dx;
- fy += dy;
- } while (--count != 0);
- }
- }
- }
-}
diff --git a/core/SkBitmapProcShader.cpp b/core/SkBitmapProcShader.cpp
index 44bdc6d3..46cf7db1 100644
--- a/core/SkBitmapProcShader.cpp
+++ b/core/SkBitmapProcShader.cpp
@@ -97,10 +97,7 @@ static bool valid_for_drawing(const SkBitmap& bm) {
return true;
}
-bool SkBitmapProcShader::validInternal(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse,
+bool SkBitmapProcShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse,
SkBitmapProcState* state) const {
if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) {
return false;
@@ -113,7 +110,7 @@ bool SkBitmapProcShader::validInternal(const SkBitmap& device,
}
// Do this first, so we know the matrix can be inverted.
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+ if (!this->INHERITED::validContext(rec, totalInverse)) {
return false;
}
@@ -121,28 +118,23 @@ bool SkBitmapProcShader::validInternal(const SkBitmap& device,
state->fTileModeX = fTileModeX;
state->fTileModeY = fTileModeY;
state->fOrigBitmap = fRawBitmap;
- return state->chooseProcs(*totalInverse, paint);
+ return state->chooseProcs(*totalInverse, *rec.fPaint);
}
-bool SkBitmapProcShader::validContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse) const {
+bool SkBitmapProcShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
SkBitmapProcState state;
- return this->validInternal(device, paint, matrix, totalInverse, &state);
+ return this->validInternal(rec, totalInverse, &state);
}
-SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
+SkShader::Context* SkBitmapProcShader::createContext(const ContextRec& rec, void* storage) const {
void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState);
- if (!this->validInternal(device, paint, matrix, NULL, state)) {
+ if (!this->validInternal(rec, NULL, state)) {
state->~SkBitmapProcState();
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext,
- (*this, device, paint, matrix, state));
+ return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state));
}
size_t SkBitmapProcShader::contextSize() const {
@@ -152,9 +144,8 @@ size_t SkBitmapProcShader::contextSize() const {
}
SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
- const SkBitmapProcShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix, SkBitmapProcState* state)
- : INHERITED(shader, device, paint, matrix)
+ const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
+ : INHERITED(shader, rec)
, fState(state)
{
const SkBitmap& bitmap = *fState->fBitmap;
@@ -182,7 +173,7 @@ SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
break;
}
- if (paint.isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
+ if (rec.fPaint->isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
// gradients can auto-dither in their 16bit sampler, but we don't so
// we clear the flag here.
flags &= ~kHasSpan16_Flag;
diff --git a/core/SkBitmapProcShader.h b/core/SkBitmapProcShader.h
index 78b46ce6..e32d35e2 100644
--- a/core/SkBitmapProcShader.h
+++ b/core/SkBitmapProcShader.h
@@ -23,12 +23,8 @@ public:
virtual bool isOpaque() const SK_OVERRIDE;
virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE;
- virtual bool validContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&,
- const SkMatrix&, void* storage) const SK_OVERRIDE;
+ virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
static bool CanDo(const SkBitmap&, TileMode tx, TileMode ty);
@@ -44,11 +40,7 @@ public:
public:
// The context takes ownership of the state. It will call its destructor
// but will NOT free the memory.
- BitmapProcShaderContext(const SkBitmapProcShader& shader,
- const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkBitmapProcState* state);
+ BitmapProcShaderContext(const SkBitmapProcShader&, const ContextRec&, SkBitmapProcState*);
virtual ~BitmapProcShaderContext();
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
@@ -72,9 +64,7 @@ protected:
uint8_t fTileModeX, fTileModeY;
private:
- bool validInternal(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse,
- SkBitmapProcState* state) const;
+ bool validInternal(const ContextRec&, SkMatrix* totalInverse, SkBitmapProcState*) const;
typedef SkShader INHERITED;
};
diff --git a/core/SkBlitter.cpp b/core/SkBlitter.cpp
index 41f37e65..74cd2982 100644
--- a/core/SkBlitter.cpp
+++ b/core/SkBlitter.cpp
@@ -591,51 +591,44 @@ public:
return size;
}
- virtual bool validContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse = NULL) const
- SK_OVERRIDE
- {
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+ virtual bool validContext(const ContextRec& rec, SkMatrix* totalInverse) const SK_OVERRIDE {
+ if (!this->INHERITED::validContext(rec, totalInverse)) {
return false;
}
if (fProxy) {
- return fProxy->validContext(device, paint, matrix);
+ return fProxy->validContext(rec);
}
return true;
}
- virtual SkShader::Context* createContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- void* storage) const SK_OVERRIDE
+ virtual SkShader::Context* createContext(const ContextRec& rec, void* storage) const SK_OVERRIDE
{
- if (!this->validContext(device, paint, matrix)) {
+ if (!this->validContext(rec, NULL)) {
return NULL;
}
SkShader::Context* proxyContext;
if (fProxy) {
char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
- proxyContext = fProxy->createContext(device, paint, matrix, proxyContextStorage);
+ proxyContext = fProxy->createContext(rec, proxyContextStorage);
SkASSERT(proxyContext);
} else {
proxyContext = NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, device, paint, matrix,
- proxyContext));
+ return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, rec, proxyContext));
}
class Sk3DShaderContext : public SkShader::Context {
public:
// Calls proxyContext's destructor but will NOT free its memory.
- Sk3DShaderContext(const Sk3DShader& shader, const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkShader::Context* proxyContext)
- : INHERITED(shader, device, paint, matrix)
+ Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
+ SkShader::Context* proxyContext)
+ : INHERITED(shader, rec)
, fMask(NULL)
, fProxyContext(proxyContext)
{
if (!fProxyContext) {
- fPMColor = SkPreMultiplyColor(paint.getColor());
+ fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
}
}
@@ -954,9 +947,10 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
*/
SkShader::Context* shaderContext;
if (shader) {
+ SkShader::ContextRec rec(device, *paint, matrix);
// Try to create the ShaderContext
void* storage = allocator->reserveT<SkShader::Context>(shader->contextSize());
- shaderContext = shader->createContext(device, *paint, matrix, storage);
+ shaderContext = shader->createContext(rec, storage);
if (!shaderContext) {
allocator->freeLast();
blitter = allocator->createT<SkNullBlitter>();
@@ -1040,7 +1034,8 @@ SkShaderBlitter::~SkShaderBlitter() {
bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
const SkMatrix& matrix) {
- if (!fShader->validContext(device, paint, matrix)) {
+ SkShader::ContextRec rec(device, paint, matrix);
+ if (!fShader->validContext(rec)) {
return false;
}
@@ -1050,7 +1045,7 @@ bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint&
// The new context will be of the same size as the old one because we use the same
// shader to create it. It is therefore safe to re-use the storage.
fShaderContext->~Context();
- fShaderContext = fShader->createContext(device, paint, matrix, (void*)fShaderContext);
+ fShaderContext = fShader->createContext(rec, (void*)fShaderContext);
SkASSERT(fShaderContext);
return true;
diff --git a/core/SkComposeShader.cpp b/core/SkComposeShader.cpp
index 2c27c9e7..df8215c1 100644
--- a/core/SkComposeShader.cpp
+++ b/core/SkComposeShader.cpp
@@ -78,11 +78,8 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
really is translucent, then we apply that after the fact.
*/
-bool SkComposeShader::validContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse) const {
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+bool SkComposeShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+ if (!this->INHERITED::validContext(rec, totalInverse)) {
return false;
}
@@ -90,48 +87,49 @@ bool SkComposeShader::validContext(const SkBitmap& device,
// before calling our sub-shaders
SkMatrix tmpM;
+ tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
- tmpM.setConcat(matrix, this->getLocalMatrix());
+ ContextRec newRec(rec);
+ newRec.fMatrix = &tmpM;
- return fShaderA->validContext(device, paint, tmpM) &&
- fShaderB->validContext(device, paint, tmpM);
+ return fShaderA->validContext(newRec) && fShaderB->validContext(newRec);
}
-SkShader::Context* SkComposeShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
+ // TODO : must fix this to not "cheat" and modify fPaint
+ SkAutoAlphaRestore restore(const_cast<SkPaint*>(rec.fPaint), 0xFF);
+
+ char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
+ char* bStorage = aStorage + fShaderA->contextSize();
+
// we preconcat our localMatrix (if any) with the device matrix
// before calling our sub-shaders
SkMatrix tmpM;
+ tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
- tmpM.setConcat(matrix, this->getLocalMatrix());
-
- SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
-
- char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
- char* bStorage = aStorage + fShaderA->contextSize();
+ ContextRec newRec(rec);
+ newRec.fMatrix = &tmpM;
- SkShader::Context* contextA = fShaderA->createContext(device, paint, tmpM, aStorage);
- SkShader::Context* contextB = fShaderB->createContext(device, paint, tmpM, bStorage);
+ SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage);
+ SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage);
// Both functions must succeed; otherwise validContext should have returned
// false.
SkASSERT(contextA);
SkASSERT(contextB);
- return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext,
- (*this, device, paint, matrix, contextA, contextB));
+ return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, contextA, contextB));
}
SkComposeShader::ComposeShaderContext::ComposeShaderContext(
- const SkComposeShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix,
+ const SkComposeShader& shader, const ContextRec& rec,
SkShader::Context* contextA, SkShader::Context* contextB)
- : INHERITED(shader, device, paint, matrix)
+ : INHERITED(shader, rec)
, fShaderContextA(contextA)
, fShaderContextB(contextB) {}
diff --git a/core/SkDraw.cpp b/core/SkDraw.cpp
index f9e06e52..c4f5f74e 100644
--- a/core/SkDraw.cpp
+++ b/core/SkDraw.cpp
@@ -2353,14 +2353,12 @@ class SkTriColorShader : public SkShader {
public:
SkTriColorShader() {}
- virtual SkShader::Context* createContext(
- const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void*) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class TriColorShaderContext : public SkShader::Context {
public:
- TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix);
+ TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&);
virtual ~TriColorShaderContext();
bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
@@ -2384,13 +2382,12 @@ private:
typedef SkShader INHERITED;
};
-SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTriColorShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
}
bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[],
@@ -2430,10 +2427,9 @@ static int ScalarTo256(SkScalar v) {
}
-SkTriColorShader::TriColorShaderContext::TriColorShaderContext(
- const SkTriColorShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix) {}
+SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader,
+ const ContextRec& rec)
+ : INHERITED(shader, rec) {}
SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
diff --git a/core/SkFilterShader.cpp b/core/SkFilterShader.cpp
index 5c5e8f31..f1cc68d0 100644
--- a/core/SkFilterShader.cpp
+++ b/core/SkFilterShader.cpp
@@ -55,41 +55,30 @@ uint32_t SkFilterShader::FilterShaderContext::getFlags() const {
return shaderF;
}
-SkShader::Context* SkFilterShader::createContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkFilterShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec, NULL)) {
return NULL;
}
char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
- SkShader::Context* shaderContext = fShader->createContext(device, paint, matrix,
- shaderContextStorage);
+ SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage);
SkASSERT(shaderContext);
- return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext,
- (*this, shaderContext, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec));
}
size_t SkFilterShader::contextSize() const {
return sizeof(FilterShaderContext) + fShader->contextSize();
}
-bool SkFilterShader::validContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse) const {
- return this->INHERITED::validContext(device, paint, matrix, totalInverse) &&
- fShader->validContext(device, paint, matrix);
+bool SkFilterShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+ return this->INHERITED::validContext(rec, totalInverse) && fShader->validContext(rec);
}
SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader,
SkShader::Context* shaderContext,
- const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix)
- : INHERITED(filterShader, device, paint, matrix)
+ const ContextRec& rec)
+ : INHERITED(filterShader, rec)
, fShaderContext(shaderContext) {}
SkFilterShader::FilterShaderContext::~FilterShaderContext() {
diff --git a/core/SkFilterShader.h b/core/SkFilterShader.h
index 4ef45772..629f3f8c 100644
--- a/core/SkFilterShader.h
+++ b/core/SkFilterShader.h
@@ -17,17 +17,14 @@ public:
SkFilterShader(SkShader* shader, SkColorFilter* filter);
virtual ~SkFilterShader();
- virtual bool validContext(const SkBitmap&, const SkPaint&,
- const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&,
- const SkMatrix&, void* storage) const SK_OVERRIDE;
+ virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class FilterShaderContext : public SkShader::Context {
public:
// Takes ownership of shaderContext and calls its destructor.
- FilterShaderContext(const SkFilterShader& filterShader, SkShader::Context* shaderContext,
- const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
+ FilterShaderContext(const SkFilterShader&, SkShader::Context*, const ContextRec&);
virtual ~FilterShaderContext();
virtual uint32_t getFlags() const SK_OVERRIDE;
diff --git a/core/SkPictureShader.cpp b/core/SkPictureShader.cpp
index 466c5e12..27cbb00f 100644
--- a/core/SkPictureShader.cpp
+++ b/core/SkPictureShader.cpp
@@ -106,35 +106,31 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const {
return fCachedBitmapShader;
}
-SkShader* SkPictureShader::validInternal(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const {
- if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+SkShader* SkPictureShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse) const {
+ if (!this->INHERITED::validContext(rec, totalInverse)) {
return NULL;
}
- SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(matrix));
- if (!bitmapShader || !bitmapShader->validContext(device, paint, matrix)) {
+ SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix));
+ if (!bitmapShader || !bitmapShader->validContext(rec)) {
return NULL;
}
return bitmapShader.detach();
}
-bool SkPictureShader::validContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const {
- SkAutoTUnref<SkShader> shader(this->validInternal(device, paint, matrix, totalInverse));
+bool SkPictureShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+ SkAutoTUnref<SkShader> shader(this->validInternal(rec, totalInverse));
return shader != NULL;
}
-SkShader::Context* SkPictureShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- SkAutoTUnref<SkShader> bitmapShader(this->validInternal(device, paint, matrix, NULL));
+SkShader::Context* SkPictureShader::createContext(const ContextRec& rec, void* storage) const {
+ SkAutoTUnref<SkShader> bitmapShader(this->validInternal(rec, NULL));
if (!bitmapShader) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext,
- (*this, device, paint, matrix, bitmapShader.detach()));
+ return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext, (*this, rec, bitmapShader.detach()));
}
size_t SkPictureShader::contextSize() const {
@@ -142,15 +138,13 @@ size_t SkPictureShader::contextSize() const {
}
SkPictureShader::PictureShaderContext::PictureShaderContext(
- const SkPictureShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix, SkShader* bitmapShader)
- : INHERITED(shader, device, paint, matrix)
+ const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader)
+ : INHERITED(shader, rec)
, fBitmapShader(bitmapShader)
{
SkASSERT(fBitmapShader);
fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize());
- fBitmapShaderContext = fBitmapShader->createContext(
- device, paint, matrix, fBitmapShaderContextStorage);
+ fBitmapShaderContext = fBitmapShader->createContext(rec, fBitmapShaderContextStorage);
SkASSERT(fBitmapShaderContext);
}
diff --git a/core/SkPictureShader.h b/core/SkPictureShader.h
index d1be0591..510c9888 100644
--- a/core/SkPictureShader.h
+++ b/core/SkPictureShader.h
@@ -24,18 +24,13 @@ public:
static SkPictureShader* Create(SkPicture*, TileMode, TileMode);
virtual ~SkPictureShader();
- virtual bool validContext(const SkBitmap&, const SkPaint&,
- const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
- virtual SkShader::Context* createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const
- SK_OVERRIDE;
+ virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class PictureShaderContext : public SkShader::Context {
public:
- PictureShaderContext(const SkPictureShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix,
- SkShader* bitmapShader);
+ PictureShaderContext(const SkPictureShader&, const ContextRec&, SkShader* bitmapShader);
virtual ~PictureShaderContext();
virtual uint32_t getFlags() const SK_OVERRIDE;
@@ -66,9 +61,7 @@ protected:
private:
SkPictureShader(SkPicture*, TileMode, TileMode);
- SkShader* validInternal(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const;
-
+ SkShader* validInternal(const ContextRec&, SkMatrix* totalInverse) const;
SkShader* refBitmapShader(const SkMatrix&) const;
SkPicture* fPicture;
diff --git a/core/SkShader.cpp b/core/SkShader.cpp
index a449d0fd..0f6ba4ce 100644
--- a/core/SkShader.cpp
+++ b/core/SkShader.cpp
@@ -56,15 +56,11 @@ bool SkShader::computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInvers
return m->invert(totalInverse);
}
-bool SkShader::validContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- SkMatrix* totalInverse) const {
- return this->computeTotalInverse(matrix, totalInverse);
+bool SkShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+ return this->computeTotalInverse(*rec.fMatrix, totalInverse);
}
-SkShader::Context* SkShader::createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const {
+SkShader::Context* SkShader::createContext(const ContextRec&, void* storage) const {
return NULL;
}
@@ -72,18 +68,17 @@ size_t SkShader::contextSize() const {
return 0;
}
-SkShader::Context::Context(const SkShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
+SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
: fShader(shader)
{
- SkASSERT(fShader.validContext(device, paint, matrix));
+ SkASSERT(fShader.validContext(rec));
// Because the context parameters must be valid at this point, we know that the matrix is
// invertible.
- SkAssertResult(fShader.computeTotalInverse(matrix, &fTotalInverse));
+ SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, &fTotalInverse));
fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
- fPaintAlpha = paint.getAlpha();
+ fPaintAlpha = rec.fPaint->getAlpha();
}
SkShader::Context::~Context() {}
@@ -250,23 +245,20 @@ uint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const {
return SkGetPackedA32(fPMColor);
}
-SkShader::Context* SkColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkColorShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec));
}
SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
- const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const ContextRec& rec)
+ : INHERITED(shader, rec)
{
SkColor color = shader.fColor;
- unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha()));
+ unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
unsigned r = SkColorGetR(color);
unsigned g = SkColorGetG(color);
@@ -285,7 +277,7 @@ SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shade
fFlags = kConstInY32_Flag;
if (255 == a) {
fFlags |= kOpaqueAlpha_Flag;
- if (paint.isDither() == false) {
+ if (rec.fPaint->isDither() == false) {
fFlags |= kHasSpan16_Flag;
}
}
diff --git a/core/SkXfermode.cpp b/core/SkXfermode.cpp
index 73d0b01e..182d3b71 100644
--- a/core/SkXfermode.cpp
+++ b/core/SkXfermode.cpp
@@ -774,118 +774,6 @@ void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
}
}
-///////////////////////////////////////////////////////////////////////////////
-#ifdef SK_SUPPORT_LEGACY_PROCXFERMODE
-
-void SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
- const SkPMColor* SK_RESTRICT src, int count,
- const SkAlpha* SK_RESTRICT aa) const {
- SkASSERT(dst && src && count >= 0);
-
- SkXfermodeProc proc = fProc;
-
- if (NULL != proc) {
- if (NULL == aa) {
- for (int i = count - 1; i >= 0; --i) {
- dst[i] = proc(src[i], dst[i]);
- }
- } else {
- for (int i = count - 1; i >= 0; --i) {
- unsigned a = aa[i];
- if (0 != a) {
- SkPMColor dstC = dst[i];
- SkPMColor C = proc(src[i], dstC);
- if (a != 0xFF) {
- C = SkFourByteInterp(C, dstC, a);
- }
- dst[i] = C;
- }
- }
- }
- }
-}
-
-void SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst,
- const SkPMColor* SK_RESTRICT src, int count,
- const SkAlpha* SK_RESTRICT aa) const {
- SkASSERT(dst && src && count >= 0);
-
- SkXfermodeProc proc = fProc;
-
- if (NULL != proc) {
- if (NULL == aa) {
- for (int i = count - 1; i >= 0; --i) {
- SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
- dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC));
- }
- } else {
- for (int i = count - 1; i >= 0; --i) {
- unsigned a = aa[i];
- if (0 != a) {
- SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
- SkPMColor C = proc(src[i], dstC);
- if (0xFF != a) {
- C = SkFourByteInterp(C, dstC, a);
- }
- dst[i] = SkPixel32ToPixel16_ToU16(C);
- }
- }
- }
- }
-}
-
-void SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
- const SkPMColor* SK_RESTRICT src, int count,
- const SkAlpha* SK_RESTRICT aa) const {
- SkASSERT(dst && src && count >= 0);
-
- SkXfermodeProc proc = fProc;
-
- if (NULL != proc) {
- if (NULL == aa) {
- for (int i = count - 1; i >= 0; --i) {
- SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT);
- dst[i] = SkToU8(SkGetPackedA32(res));
- }
- } else {
- for (int i = count - 1; i >= 0; --i) {
- unsigned a = aa[i];
- if (0 != a) {
- SkAlpha dstA = dst[i];
- SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT);
- unsigned A = SkGetPackedA32(res);
- if (0xFF != a) {
- A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
- }
- dst[i] = SkToU8(A);
- }
- }
- }
- }
-}
-
-SkProcXfermode::SkProcXfermode(SkReadBuffer& buffer)
- : SkXfermode(buffer) {
- fProc = NULL;
- if (!buffer.isCrossProcess()) {
- fProc = (SkXfermodeProc)buffer.readFunctionPtr();
- }
-}
-
-void SkProcXfermode::flatten(SkWriteBuffer& buffer) const {
- this->INHERITED::flatten(buffer);
- if (!buffer.isCrossProcess()) {
- buffer.writeFunctionPtr((void*)fProc);
- }
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkProcXfermode::toString(SkString* str) const {
- str->appendf("SkProcXfermode: %p", fProc);
-}
-#endif
-
-#endif
//////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
diff --git a/effects/SkBlurMaskFilter.cpp b/effects/SkBlurMaskFilter.cpp
index 5dffd6fd..2169a42c 100644
--- a/effects/SkBlurMaskFilter.cpp
+++ b/effects/SkBlurMaskFilter.cpp
@@ -28,6 +28,10 @@
#include "SkDraw.h"
#endif
+SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) {
+ return SkBlurMask::ConvertRadiusToSigma(radius);
+}
+
class SkBlurMaskFilterImpl : public SkMaskFilter {
public:
SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags);
diff --git a/effects/SkMatrixConvolutionImageFilter.cpp b/effects/SkMatrixConvolutionImageFilter.cpp
index 3c9fc877..be1dcb4c 100644
--- a/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/effects/SkMatrixConvolutionImageFilter.cpp
@@ -153,6 +153,9 @@ void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src,
SkBitmap* result,
const SkIRect& rect,
const SkIRect& bounds) const {
+ if (rect.isEmpty()) {
+ return;
+ }
for (int y = rect.fTop; y < rect.fBottom; ++y) {
SkPMColor* dptr = result->getAddr32(rect.fLeft - bounds.fLeft, y - bounds.fTop);
for (int x = rect.fLeft; x < rect.fRight; ++x) {
diff --git a/effects/SkPerlinNoiseShader.cpp b/effects/SkPerlinNoiseShader.cpp
index 5adb5825..a4944fb8 100644
--- a/effects/SkPerlinNoiseShader.cpp
+++ b/effects/SkPerlinNoiseShader.cpp
@@ -425,13 +425,12 @@ SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade(
return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
}
-SkShader::Context* SkPerlinNoiseShader::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkPerlinNoiseShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, rec));
}
size_t SkPerlinNoiseShader::contextSize() const {
@@ -439,11 +438,10 @@ size_t SkPerlinNoiseShader::contextSize() const {
}
SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
- const SkPerlinNoiseShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const SkPerlinNoiseShader& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
{
- SkMatrix newMatrix = matrix;
+ SkMatrix newMatrix = *rec.fMatrix;
newMatrix.postConcat(shader.getLocalMatrix());
SkMatrix invMatrix;
if (!newMatrix.invert(&invMatrix)) {
diff --git a/effects/SkTransparentShader.cpp b/effects/SkTransparentShader.cpp
index 0997e620..9a390ad6 100644
--- a/effects/SkTransparentShader.cpp
+++ b/effects/SkTransparentShader.cpp
@@ -11,15 +11,12 @@
#include "SkColorPriv.h"
#include "SkString.h"
-SkShader::Context* SkTransparentShader::createContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix,
- void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTransparentShader::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, rec));
}
size_t SkTransparentShader::contextSize() const {
@@ -27,10 +24,9 @@ size_t SkTransparentShader::contextSize() const {
}
SkTransparentShader::TransparentShaderContext::TransparentShaderContext(
- const SkTransparentShader& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
- , fDevice(&device) {}
+ const SkTransparentShader& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
+ , fDevice(rec.fDevice) {}
SkTransparentShader::TransparentShaderContext::~TransparentShaderContext() {}
diff --git a/effects/gradients/SkGradientShader.cpp b/effects/gradients/SkGradientShader.cpp
index 6d753a95..d376b222 100644
--- a/effects/gradients/SkGradientShader.cpp
+++ b/effects/gradients/SkGradientShader.cpp
@@ -253,9 +253,8 @@ bool SkGradientShaderBase::isOpaque() const {
}
SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
- const SkGradientShaderBase& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const SkGradientShaderBase& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
, fCache(shader.refCache(getPaintAlpha()))
{
const SkMatrix& inverse = this->getTotalInverse();
diff --git a/effects/gradients/SkGradientShaderPriv.h b/effects/gradients/SkGradientShaderPriv.h
index c1e253fd..a699c4ce 100644
--- a/effects/gradients/SkGradientShaderPriv.h
+++ b/effects/gradients/SkGradientShaderPriv.h
@@ -142,9 +142,7 @@ public:
class GradientShaderBaseContext : public SkShader::Context {
public:
- GradientShaderBaseContext(const SkGradientShaderBase& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix);
- ~GradientShaderBaseContext() {}
+ GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
virtual uint32_t getFlags() const SK_OVERRIDE { return fFlags; }
diff --git a/effects/gradients/SkLinearGradient.cpp b/effects/gradients/SkLinearGradient.cpp
index 70bbbf3b..b9de651f 100644
--- a/effects/gradients/SkLinearGradient.cpp
+++ b/effects/gradients/SkLinearGradient.cpp
@@ -76,24 +76,22 @@ size_t SkLinearGradient::contextSize() const {
return sizeof(LinearGradientContext);
}
-SkShader::Context* SkLinearGradient::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkLinearGradient::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, rec));
}
SkLinearGradient::LinearGradientContext::LinearGradientContext(
- const SkLinearGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const SkLinearGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
{
unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
if ((fDstToIndex.getType() & ~mask) == 0) {
// when we dither, we are (usually) not const-in-Y
- if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) {
+ if ((fFlags & SkShader::kHasSpan16_Flag) && !rec.fPaint->isDither()) {
// only claim this if we do have a 16bit mode (i.e. none of our
// colors have alpha), and if we are not dithering (which obviously
// is not const in Y).
diff --git a/effects/gradients/SkLinearGradient.h b/effects/gradients/SkLinearGradient.h
index 699d76ed..d9ffc77c 100644
--- a/effects/gradients/SkLinearGradient.h
+++ b/effects/gradients/SkLinearGradient.h
@@ -1,4 +1,3 @@
-
/*
* Copyright 2012 Google Inc.
*
@@ -15,14 +14,12 @@ class SkLinearGradient : public SkGradientShaderBase {
public:
SkLinearGradient(const SkPoint pts[2], const Descriptor&, const SkMatrix* localMatrix);
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class LinearGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
- LinearGradientContext(const SkLinearGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix);
+ LinearGradientContext(const SkLinearGradient&, const ContextRec&);
~LinearGradientContext() {}
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
diff --git a/effects/gradients/SkRadialGradient.cpp b/effects/gradients/SkRadialGradient.cpp
index f13d55c6..07ee680a 100644
--- a/effects/gradients/SkRadialGradient.cpp
+++ b/effects/gradients/SkRadialGradient.cpp
@@ -161,19 +161,17 @@ size_t SkRadialGradient::contextSize() const {
return sizeof(RadialGradientContext);
}
-SkShader::Context* SkRadialGradient::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkRadialGradient::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, RadialGradientContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, RadialGradientContext, (*this, rec));
}
SkRadialGradient::RadialGradientContext::RadialGradientContext(
- const SkRadialGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix) {}
+ const SkRadialGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec) {}
void SkRadialGradient::RadialGradientContext::shadeSpan16(int x, int y, uint16_t* dstCParam,
int count) {
diff --git a/effects/gradients/SkRadialGradient.h b/effects/gradients/SkRadialGradient.h
index 7aafe2d1..87302473 100644
--- a/effects/gradients/SkRadialGradient.h
+++ b/effects/gradients/SkRadialGradient.h
@@ -16,15 +16,12 @@ public:
SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&,
const SkMatrix* localMatrix);
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class RadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
- RadialGradientContext(const SkRadialGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix);
- ~RadialGradientContext() {}
+ RadialGradientContext(const SkRadialGradient&, const ContextRec&);
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
diff --git a/effects/gradients/SkSweepGradient.cpp b/effects/gradients/SkSweepGradient.cpp
index a65631c6..0baf5c71 100644
--- a/effects/gradients/SkSweepGradient.cpp
+++ b/effects/gradients/SkSweepGradient.cpp
@@ -56,19 +56,17 @@ size_t SkSweepGradient::contextSize() const {
return sizeof(SweepGradientContext);
}
-SkShader::Context* SkSweepGradient::createContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkSweepGradient::createContext(const ContextRec& rec, void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, rec));
}
SkSweepGradient::SweepGradientContext::SweepGradientContext(
- const SkSweepGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix) {}
+ const SkSweepGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec) {}
// returns angle in a circle [0..2PI) -> [0..255]
static unsigned SkATan2_255(float y, float x) {
diff --git a/effects/gradients/SkSweepGradient.h b/effects/gradients/SkSweepGradient.h
index 15c5b634..9ddd1e25 100644
--- a/effects/gradients/SkSweepGradient.h
+++ b/effects/gradients/SkSweepGradient.h
@@ -16,15 +16,12 @@ public:
SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor&,
const SkMatrix* localMatrix);
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class SweepGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
- SweepGradientContext(const SkSweepGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix);
- ~SweepGradientContext() {}
+ SweepGradientContext(const SkSweepGradient& shader, const ContextRec&);
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
diff --git a/effects/gradients/SkTwoPointConicalGradient.cpp b/effects/gradients/SkTwoPointConicalGradient.cpp
index 9d1f8f1a..e9c2efe3 100644
--- a/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -221,21 +221,18 @@ size_t SkTwoPointConicalGradient::contextSize() const {
return sizeof(TwoPointConicalGradientContext);
}
-SkShader::Context* SkTwoPointConicalGradient::createContext(
- const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTwoPointConicalGradient::createContext(const ContextRec& rec,
+ void* storage) const {
+ if (!this->validContext(rec)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext,
- (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext, (*this, rec));
}
SkTwoPointConicalGradient::TwoPointConicalGradientContext::TwoPointConicalGradientContext(
- const SkTwoPointConicalGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const SkTwoPointConicalGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
{
// we don't have a span16 proc
fFlags &= ~kHasSpan16_Flag;
diff --git a/effects/gradients/SkTwoPointConicalGradient.h b/effects/gradients/SkTwoPointConicalGradient.h
index 13ce3eaf..1c5e409a 100644
--- a/effects/gradients/SkTwoPointConicalGradient.h
+++ b/effects/gradients/SkTwoPointConicalGradient.h
@@ -48,16 +48,12 @@ public:
const SkMatrix* localMatrix);
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class TwoPointConicalGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
- TwoPointConicalGradientContext(const SkTwoPointConicalGradient& shader,
- const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix);
+ TwoPointConicalGradientContext(const SkTwoPointConicalGradient&, const ContextRec&);
~TwoPointConicalGradientContext() {}
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
diff --git a/effects/gradients/SkTwoPointRadialGradient.cpp b/effects/gradients/SkTwoPointRadialGradient.cpp
index 41e577fb..f691db29 100644
--- a/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -224,31 +224,27 @@ size_t SkTwoPointRadialGradient::contextSize() const {
return sizeof(TwoPointRadialGradientContext);
}
-bool SkTwoPointRadialGradient::validContext(const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, SkMatrix* totalInverse) const {
+bool SkTwoPointRadialGradient::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
// For now, we might have divided by zero, so detect that.
if (0 == fDiffRadius) {
return false;
}
- return this->INHERITED::validContext(device, paint, matrix, totalInverse);
+ return this->INHERITED::validContext(rec, totalInverse);
}
-SkShader::Context* SkTwoPointRadialGradient::createContext(
- const SkBitmap& device, const SkPaint& paint,
- const SkMatrix& matrix, void* storage) const {
- if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTwoPointRadialGradient::createContext(const ContextRec& rec,
+ void* storage) const {
+ if (!this->validContext(rec, NULL)) {
return NULL;
}
- return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext,
- (*this, device, paint, matrix));
+ return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext, (*this, rec));
}
SkTwoPointRadialGradient::TwoPointRadialGradientContext::TwoPointRadialGradientContext(
- const SkTwoPointRadialGradient& shader, const SkBitmap& device,
- const SkPaint& paint, const SkMatrix& matrix)
- : INHERITED(shader, device, paint, matrix)
+ const SkTwoPointRadialGradient& shader, const ContextRec& rec)
+ : INHERITED(shader, rec)
{
// we don't have a span16 proc
fFlags &= ~kHasSpan16_Flag;
diff --git a/effects/gradients/SkTwoPointRadialGradient.h b/effects/gradients/SkTwoPointRadialGradient.h
index 1b387e68..de5b5434 100644
--- a/effects/gradients/SkTwoPointRadialGradient.h
+++ b/effects/gradients/SkTwoPointRadialGradient.h
@@ -23,20 +23,13 @@ public:
virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
-
virtual size_t contextSize() const SK_OVERRIDE;
- virtual bool validContext(const SkBitmap&, const SkPaint&,
- const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
- virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
- void* storage) const SK_OVERRIDE;
+ virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE;
+ virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
class TwoPointRadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
- TwoPointRadialGradientContext(const SkTwoPointRadialGradient& shader,
- const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix);
- ~TwoPointRadialGradientContext() {}
+ TwoPointRadialGradientContext(const SkTwoPointRadialGradient&, const ContextRec&);
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
diff --git a/gpu/SkGpuDevice.cpp b/gpu/SkGpuDevice.cpp
index 4af16109..60b4e7c4 100644
--- a/gpu/SkGpuDevice.cpp
+++ b/gpu/SkGpuDevice.cpp
@@ -1289,6 +1289,11 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
SkCanvas::DrawBitmapRectFlags flags,
int tileSize,
bool bicubic) {
+ // The following pixel lock is technically redundant, but it is desirable
+ // to lock outside of the tile loop to prevent redecoding the whole image
+ // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
+ // is larger than the limit of the discardable memory pool.
+ SkAutoLockPixels alp(bitmap);
SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect);
int nx = bitmap.width() / tileSize;
diff --git a/gpu/gl/GrGLInterface.cpp b/gpu/gl/GrGLInterface.cpp
index 5bf0efb7..056a6018 100644
--- a/gpu/gl/GrGLInterface.cpp
+++ b/gpu/gl/GrGLInterface.cpp
@@ -116,9 +116,15 @@ GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) {
return clone;
}
-#define RETURN_FALSE_INTERFACE \
- SkDEBUGFAIL("GrGLInterface::validate() failed."); \
- return false; \
+#ifdef SK_DEBUG
+ static int kIsDebug = 1;
+#else
+ static int kIsDebug = 0;
+#endif
+
+#define RETURN_FALSE_INTERFACE \
+ if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \
+ return false;
bool GrGLInterface::validate() const {
diff --git a/gpu/gl/GrGLUtil.cpp b/gpu/gl/GrGLUtil.cpp
index ddfcfbf0..0fa2d2ce 100644
--- a/gpu/gl/GrGLUtil.cpp
+++ b/gpu/gl/GrGLUtil.cpp
@@ -99,7 +99,7 @@ bool get_gl_version_for_mesa(int mesaMajorVersion, int* major, int* minor) {
GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
if (NULL == versionString) {
- SkDEBUGFAIL("NULL GL version string.");
+ SkDebugf("NULL GL version string.");
return kNone_GrGLStandard;
}
@@ -139,7 +139,7 @@ bool GrGLIsChromiumFromRendererString(const char* rendererString) {
GrGLVersion GrGLGetVersionFromString(const char* versionString) {
if (NULL == versionString) {
- SkDEBUGFAIL("NULL GL version string.");
+ SkDebugf("NULL GL version string.");
return GR_GL_INVALID_VER;
}
@@ -178,7 +178,7 @@ GrGLVersion GrGLGetVersionFromString(const char* versionString) {
GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
if (NULL == versionString) {
- SkDEBUGFAIL("NULL GLSL version string.");
+ SkDebugf("NULL GLSL version string.");
return GR_GLSL_INVALID_VER;
}
diff --git a/ports/SkFontHost_win_dw.cpp b/ports/SkFontHost_win_dw.cpp
index 36ed4d4f..cd32fdbf 100644
--- a/ports/SkFontHost_win_dw.cpp
+++ b/ports/SkFontHost_win_dw.cpp
@@ -22,7 +22,10 @@
#include "SkGlyph.h"
#include "SkHRESULT.h"
#include "SkMaskGamma.h"
+#include "SkMatrix22.h"
#include "SkOnce.h"
+#include "SkOTTable_EBLC.h"
+#include "SkOTTable_EBSC.h"
#include "SkOTTable_head.h"
#include "SkOTTable_hhea.h"
#include "SkOTTable_OS_2.h"
@@ -449,7 +452,22 @@ private:
const void* drawDWMask(const SkGlyph& glyph);
SkTDArray<uint8_t> fBits;
+ /** The total matrix without the text height scale. */
+ SkMatrix fSkXform;
+ /** The total matrix without the text height scale. */
DWRITE_MATRIX fXform;
+ /** The non-rotational part of total matrix without the text height scale.
+ * This is used to find the magnitude of gdi compatible advances.
+ */
+ DWRITE_MATRIX fGsA;
+ /** The inverse of the rotational part of the total matrix.
+ * This is used to find the direction of gdi compatible advances.
+ */
+ SkMatrix fG_inv;
+ /** The text size to render with. */
+ SkScalar fTextSizeRender;
+ /** The text size to measure with. */
+ SkScalar fTextSizeMeasure;
SkAutoTUnref<DWriteFontTypeface> fTypeface;
int fGlyphCount;
DWRITE_RENDERING_MODE fRenderingMode;
@@ -570,32 +588,224 @@ static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle,
wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
}
+class AutoDWriteTable {
+public:
+ AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFace), fExists(FALSE) {
+ // Any errors are ignored, user must check fExists anyway.
+ fontFace->TryGetFontTable(beTag,
+ reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
+ }
+ ~AutoDWriteTable() {
+ if (fExists) {
+ fFontFace->ReleaseFontTable(fLock);
+ }
+ }
+
+ const uint8_t* fData;
+ UINT32 fSize;
+ BOOL fExists;
+private:
+ // Borrowed reference, the user must ensure the fontFace stays alive.
+ IDWriteFontFace* fFontFace;
+ void* fLock;
+};
+template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
+public:
+ static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2, T::TAG3);
+ AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
+
+ const T* get() const { return reinterpret_cast<const T*>(fData); }
+ const T* operator->() const { return reinterpret_cast<const T*>(fData); }
+};
+
+static bool hasBitmapStrike(DWriteFontTypeface* typeface, int size) {
+ {
+ AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWriteFontFace.get());
+ if (!eblc.fExists) {
+ return false;
+ }
+ if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) {
+ return false;
+ }
+ if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) {
+ return false;
+ }
+
+ uint32_t numSizes = SkEndianSwap32(eblc->numSizes);
+ if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation) +
+ sizeof(SkOTTableEmbeddedBitmapLocation::BitmapSizeTable) * numSizes)
+ {
+ return false;
+ }
+
+ const SkOTTableEmbeddedBitmapLocation::BitmapSizeTable* sizeTable =
+ SkTAfter<const SkOTTableEmbeddedBitmapLocation::BitmapSizeTable>(eblc.get());
+ for (uint32_t i = 0; i < numSizes; ++i, ++sizeTable) {
+ if (sizeTable->ppemX == size && sizeTable->ppemY == size) {
+ // TODO: determine if we should dig through IndexSubTableArray/IndexSubTable
+ // to determine the actual number of glyphs with bitmaps.
+
+ // TODO: Ensure that the bitmaps actually cover a significant portion of the strike.
+
+ //TODO: Endure that the bitmaps are bi-level.
+ if (sizeTable->endGlyphIndex >= sizeTable->startGlyphIndex + 3) {
+ return true;
+ }
+ }
+ }
+ }
+
+ {
+ AutoTDWriteTable<SkOTTableEmbeddedBitmapScaling> ebsc(typeface->fDWriteFontFace.get());
+ if (!ebsc.fExists) {
+ return false;
+ }
+ if (ebsc.fSize < sizeof(SkOTTableEmbeddedBitmapScaling)) {
+ return false;
+ }
+ if (ebsc->version != SkOTTableEmbeddedBitmapScaling::version_initial) {
+ return false;
+ }
+
+ uint32_t numSizes = SkEndianSwap32(ebsc->numSizes);
+ if (ebsc.fSize < sizeof(SkOTTableEmbeddedBitmapScaling) +
+ sizeof(SkOTTableEmbeddedBitmapScaling::BitmapScaleTable) * numSizes)
+ {
+ return false;
+ }
+
+ const SkOTTableEmbeddedBitmapScaling::BitmapScaleTable* scaleTable =
+ SkTAfter<const SkOTTableEmbeddedBitmapScaling::BitmapScaleTable>(ebsc.get());
+ for (uint32_t i = 0; i < numSizes; ++i, ++scaleTable) {
+ if (scaleTable->ppemX == size && scaleTable->ppemY == size) {
+ // EBSC tables are normally only found in bitmap only fonts.
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool bothZero(SkScalar a, SkScalar b) {
+ return 0 == a && 0 == b;
+}
+
+// returns false if there is any non-90-rotation or skew
+static bool isAxisAligned(const SkScalerContext::Rec& rec) {
+ return 0 == rec.fPreSkewX &&
+ (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
+ bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
+}
+
SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
const SkDescriptor* desc)
: SkScalerContext(typeface, desc)
, fTypeface(SkRef(typeface))
, fGlyphCount(-1) {
- fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]);
- fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]);
- fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]);
- fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]);
- fXform.dx = 0;
- fXform.dy = 0;
-
- if (SkMask::kBW_Format == fRec.fMaskFormat) {
+ // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC
+ // except when bi-level rendering is requested or there are embedded
+ // bi-level bitmaps (and the embedded bitmap flag is set and no rotation).
+ //
+ // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do
+ // this. As a result, determine the actual size of the text and then see if
+ // there are any embedded bi-level bitmaps of that size. If there are, then
+ // force bitmaps by requesting bi-level rendering.
+ //
+ // FreeType allows for separate ppemX and ppemY, but DirectWrite assumes
+ // square pixels and only uses ppemY. Therefore the transform must track any
+ // non-uniform x-scale.
+ //
+ // Also, rotated glyphs should have the same absolute advance widths as
+ // horizontal glyphs and the subpixel flag should not affect glyph shapes.
+
+ // A is the total matrix.
+ SkMatrix A;
+ fRec.getSingleMatrix(&A);
+
+ // h is where A maps the horizontal baseline.
+ SkPoint h = SkPoint::Make(SK_Scalar1, 0);
+ A.mapPoints(&h, 1);
+
+ // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
+ SkMatrix G;
+ SkComputeGivensRotation(h, &G);
+
+ // GA is the matrix A with rotation removed.
+ SkMatrix GA(G);
+ GA.preConcat(A);
+
+ // realTextSize is the actual device size we want (as opposed to the size the user requested).
+ // gdiTextSize is the size we request when GDI compatible.
+ // If the scale is negative, this means the matrix will do the flip anyway.
+ SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
+ // Due to floating point math, the lower bits are suspect. Round carefully.
+ SkScalar roundedTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64.0f;
+ SkScalar gdiTextSize = SkScalarFloorToScalar(roundedTextSize);
+ if (gdiTextSize == 0) {
+ gdiTextSize = SK_Scalar1;
+ }
+
+ bool hasBitmap = fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag &&
+ hasBitmapStrike(typeface, SkScalarTruncToInt(gdiTextSize));
+ bool axisAligned = isAxisAligned(fRec);
+ bool isBiLevel = SkMask::kBW_Format == fRec.fMaskFormat || (hasBitmap && axisAligned);
+
+ if (isBiLevel) {
+ fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_ALIASED;
fTextureType = DWRITE_TEXTURE_ALIASED_1x1;
+ fTextSizeMeasure = gdiTextSize;
+ fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
+ } else if (hasBitmap) {
+ // If rotated but the horizontal text would have used a bitmap,
+ // render high quality rotated glyphs using the bitmap metrics.
+ fTextSizeRender = gdiTextSize;
+ fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
+ fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
+ fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
} else {
+ fTextSizeRender = realTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
+ fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
}
if (this->isSubpixel()) {
+ fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
}
+
+ // Remove the realTextSize, as that is the text height scale currently in A.
+ SkScalar scale = SkScalarInvert(realTextSize);
+
+ // fSkXform is the total matrix A without the text height scale.
+ fSkXform = A;
+ fSkXform.preScale(scale, scale); //remove the text height scale.
+
+ fXform.m11 = SkScalarToFloat(fSkXform.getScaleX());
+ fXform.m12 = SkScalarToFloat(fSkXform.getSkewY());
+ fXform.m21 = SkScalarToFloat(fSkXform.getSkewX());
+ fXform.m22 = SkScalarToFloat(fSkXform.getScaleY());
+ fXform.dx = 0;
+ fXform.dy = 0;
+
+ // GsA is the non-rotational part of A without the text height scale.
+ SkMatrix GsA(GA);
+ GsA.preScale(scale, scale); //remove text height scale, G is rotational so reorders with scale.
+
+ fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX));
+ fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0.
+ fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX));
+ fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY));
+
+ // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational.
+ fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(SkMatrix::kMTransX),
+ -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(SkMatrix::kMTransY),
+ G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(SkMatrix::kMPersp2));
}
SkScalerContext_DW::~SkScalerContext_DW() {
@@ -631,9 +841,9 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
{
HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
- fRec.fTextSize,
+ fTextSizeMeasure,
1.0f, // pixelsPerDip
- &fXform,
+ &fGsA,
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode,
&glyphId, 1,
&gm),
@@ -645,7 +855,7 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
DWRITE_FONT_METRICS dwfm;
fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
- SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize,
+ SkScalar advanceX = SkScalarMulDiv(fTextSizeMeasure,
SkIntToScalar(gm.advanceWidth),
SkIntToScalar(dwfm.designUnitsPerEm));
@@ -654,9 +864,13 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
}
SkVector vecs[1] = { { advanceX, 0 } };
- SkMatrix mat;
- fRec.getMatrixFrom2x2(&mat);
- mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
+ if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
+ DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
+ {
+ fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
+ } else {
+ fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
+ }
glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX);
glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
@@ -683,7 +897,7 @@ void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
run.glyphCount = 1;
run.glyphAdvances = &advance;
run.fontFace = fTypeface->fDWriteFontFace.get();
- run.fontEmSize = SkScalarToFloat(fRec.fTextSize);
+ run.fontEmSize = SkScalarToFloat(fTextSizeRender);
run.bidiLevel = 0;
run.glyphIndices = &glyphId;
run.isSideways = FALSE;
@@ -728,7 +942,7 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
{
fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics(
- fRec.fTextSize,
+ fTextSizeRender,
1.0f, // pixelsPerDip
&fXform,
&dwfm);
@@ -738,28 +952,28 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm);
if (mx) {
- mx->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem;
+ mx->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
mx->fAscent = mx->fTop;
- mx->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem;
+ mx->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
mx->fBottom = mx->fDescent;
- mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
- mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
- mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem;
- mx->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem);
+ mx->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
+ mx->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
+ mx->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem;
+ mx->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem);
mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
}
if (my) {
- my->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem;
+ my->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
my->fAscent = my->fTop;
- my->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem;
+ my->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
my->fBottom = my->fDescent;
- my->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
- my->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
- my->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem;
- my->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem);
+ my->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
+ my->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
+ my->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underlinePosition) / upem;
+ my->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlineThickness) / upem);
my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
@@ -888,7 +1102,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
run.glyphCount = 1;
run.glyphAdvances = &advance;
run.fontFace = fTypeface->fDWriteFontFace.get();
- run.fontEmSize = SkScalarToFloat(fRec.fTextSize);
+ run.fontEmSize = SkScalarToFloat(fTextSizeRender);
run.bidiLevel = 0;
run.glyphIndices = &index;
run.isSideways = FALSE;
@@ -966,7 +1180,7 @@ void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
uint16_t glyphId = glyph.getGlyphID();
//TODO: convert to<->from DIUs? This would make a difference if hinting.
//It may not be needed, it appears that DirectWrite only hints at em size.
- HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fRec.fTextSize),
+ HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fTextSizeRender),
&glyphId,
NULL, //advances
NULL, //offsets
@@ -976,9 +1190,7 @@ void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
geometryToPath.get()),
"Could not create glyph outline.");
- SkMatrix mat;
- fRec.getMatrixFrom2x2(&mat);
- path->transform(mat);
+ path->transform(fSkXform);
}
void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
@@ -1146,28 +1358,6 @@ int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0;
}
-class AutoDWriteTable {
-public:
- AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFace), fExists(FALSE) {
- // Any errors are ignored, user must check fExists anyway.
- fontFace->TryGetFontTable(beTag,
- reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
- }
- ~AutoDWriteTable() {
- if (fExists) {
- fFontFace->ReleaseFontTable(fLock);
- }
- }
-
- const uint8_t* fData;
- UINT32 fSize;
- BOOL fExists;
-private:
- // Borrowed reference, the user must ensure the fontFace stays alive.
- IDWriteFontFace* fFontFace;
- void* fLock;
-};
-
size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
size_t length, void* data) const
{
@@ -1260,7 +1450,6 @@ void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
SkScalerContext::kForceAutohinting_Flag |
- SkScalerContext::kEmbeddedBitmapText_Flag |
SkScalerContext::kEmbolden_Flag |
SkScalerContext::kLCD_BGROrder_Flag |
SkScalerContext::kLCD_Vertical_Flag;
@@ -1362,14 +1551,6 @@ static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance
return true;
}
-template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
-public:
- static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2, T::TAG3);
- AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
-
- const T* operator->() const { return reinterpret_cast<const T*>(fData); }
-};
-
SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
const uint32_t* glyphIDs,
diff --git a/sfnt/SkOTTable_EBDT.h b/sfnt/SkOTTable_EBDT.h
new file mode 100644
index 00000000..89d7a3ab
--- /dev/null
+++ b/sfnt/SkOTTable_EBDT.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOTTable_EBDT_DEFINED
+#define SkOTTable_EBDT_DEFINED
+
+#include "SkEndian.h"
+#include "SkOTTableTypes.h"
+#include "SkOTTable_head.h"
+#include "SkOTTable_loca.h"
+#include "SkTypedEnum.h"
+
+#pragma pack(push, 1)
+
+struct SkOTTableEmbeddedBitmapData {
+ static const SK_OT_CHAR TAG0 = 'E';
+ static const SK_OT_CHAR TAG1 = 'B';
+ static const SK_OT_CHAR TAG2 = 'D';
+ static const SK_OT_CHAR TAG3 = 'T';
+ static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableEmbeddedBitmapData>::value;
+
+ SK_OT_Fixed version;
+ static const SK_OT_Fixed version_initial = SkTEndian_SwapBE32(0x00020000);
+
+ struct BigGlyphMetrics {
+ SK_OT_BYTE height;
+ SK_OT_BYTE width;
+ SK_OT_CHAR horiBearingX;
+ SK_OT_CHAR horiBearingY;
+ SK_OT_BYTE horiAdvance;
+ SK_OT_CHAR vertBearingX;
+ SK_OT_CHAR vertBearingY;
+ SK_OT_BYTE vertAdvance;
+ };
+
+ struct SmallGlyphMetrics {
+ SK_OT_BYTE height;
+ SK_OT_BYTE width;
+ SK_OT_CHAR bearingX;
+ SK_OT_CHAR bearingY;
+ SK_OT_BYTE advance;
+ };
+
+ // Small metrics, byte-aligned data.
+ struct Format1 {
+ SmallGlyphMetrics smallGlyphMetrics;
+ //SK_OT_BYTE[] byteAlignedBitmap;
+ };
+
+ // Small metrics, bit-aligned data.
+ struct Format2 {
+ SmallGlyphMetrics smallGlyphMetrics;
+ //SK_OT_BYTE[] bitAlignedBitmap;
+ };
+
+ // Format 3 is not used.
+
+ // EBLC metrics (IndexSubTable::header::indexFormat 2 or 5), compressed data.
+ // Only used on Mac.
+ struct Format4 {
+ SK_OT_ULONG whiteTreeOffset;
+ SK_OT_ULONG blackTreeOffset;
+ SK_OT_ULONG glyphDataOffset;
+ };
+
+ // EBLC metrics (IndexSubTable::header::indexFormat 2 or 5), bit-aligned data.
+ struct Format5 {
+ //SK_OT_BYTE[] bitAlignedBitmap;
+ };
+
+ // Big metrics, byte-aligned data.
+ struct Format6 {
+ BigGlyphMetrics bigGlyphMetrics;
+ //SK_OT_BYTE[] byteAlignedBitmap;
+ };
+
+ // Big metrics, bit-aligned data.
+ struct Format7 {
+ BigGlyphMetrics bigGlyphMetrics;
+ //SK_OT_BYTE[] bitAlignedBitmap;
+ };
+
+ struct EBDTComponent {
+ SK_OT_USHORT glyphCode; // Component glyph code
+ SK_OT_CHAR xOffset; // Position of component left
+ SK_OT_CHAR yOffset; // Position of component top
+ };
+
+ struct Format8 {
+ SmallGlyphMetrics smallMetrics; // Metrics information for the glyph
+ SK_OT_BYTE pad; // Pad to short boundary
+ SK_OT_USHORT numComponents; // Number of components
+ //EBDTComponent componentArray[numComponents]; // Glyph code, offset array
+ };
+
+ struct Format9 {
+ BigGlyphMetrics bigMetrics; // Metrics information for the glyph
+ SK_OT_USHORT numComponents; // Number of components
+ //EBDTComponent componentArray[numComponents]; // Glyph code, offset array
+ };
+};
+
+#pragma pack(pop)
+
+#endif
diff --git a/sfnt/SkOTTable_EBLC.h b/sfnt/SkOTTable_EBLC.h
new file mode 100644
index 00000000..845418d3
--- /dev/null
+++ b/sfnt/SkOTTable_EBLC.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOTTable_EBLC_DEFINED
+#define SkOTTable_EBLC_DEFINED
+
+#include "SkEndian.h"
+#include "SkOTTable_EBDT.h"
+#include "SkOTTableTypes.h"
+#include "SkTypedEnum.h"
+
+#pragma pack(push, 1)
+
+struct SkOTTableEmbeddedBitmapLocation {
+ static const SK_OT_CHAR TAG0 = 'E';
+ static const SK_OT_CHAR TAG1 = 'B';
+ static const SK_OT_CHAR TAG2 = 'L';
+ static const SK_OT_CHAR TAG3 = 'C';
+ static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableEmbeddedBitmapLocation>::value;
+
+ SK_OT_Fixed version;
+ static const SK_OT_Fixed version_initial = SkTEndian_SwapBE32(0x00020000);
+
+ SK_OT_ULONG numSizes;
+
+ struct SbitLineMetrics {
+ SK_OT_CHAR ascender;
+ SK_OT_CHAR descender;
+ SK_OT_BYTE widthMax;
+ SK_OT_CHAR caretSlopeNumerator;
+ SK_OT_CHAR caretSlopeDenominator;
+ SK_OT_CHAR caretOffset;
+ SK_OT_CHAR minOriginSB;
+ SK_OT_CHAR minAdvanceSB;
+ SK_OT_CHAR maxBeforeBL;
+ SK_OT_CHAR minAfterBL;
+ SK_OT_CHAR pad1;
+ SK_OT_CHAR pad2;
+ };
+
+ struct BitmapSizeTable {
+ SK_OT_ULONG indexSubTableArrayOffset; //offset to indexSubtableArray from beginning of EBLC.
+ SK_OT_ULONG indexTablesSize; //number of bytes in corresponding index subtables and array
+ SK_OT_ULONG numberOfIndexSubTables; //an index subtable for each range or format change
+ SK_OT_ULONG colorRef; //not used; set to 0.
+ SbitLineMetrics hori; //line metrics for text rendered horizontally
+ SbitLineMetrics vert; //line metrics for text rendered vertically
+ SK_OT_USHORT startGlyphIndex; //lowest glyph index for this size
+ SK_OT_USHORT endGlyphIndex; //highest glyph index for this size
+ SK_OT_BYTE ppemX; //horizontal pixels per Em
+ SK_OT_BYTE ppemY; //vertical pixels per Em
+ struct BitDepth {
+ SK_TYPED_ENUM(Value, SK_OT_BYTE,
+ ((BW, 1))
+ ((Gray4, 2))
+ ((Gray16, 4))
+ ((Gray256, 8))
+ SK_SEQ_END,
+ SK_SEQ_END)
+ SK_OT_BYTE value;
+ } bitDepth; //the Microsoft rasterizer v.1.7 or greater supports
+ union Flags {
+ struct Field {
+ //0-7
+ SK_OT_BYTE_BITFIELD(
+ Horizontal, // Horizontal small glyph metrics
+ Vertical, // Vertical small glyph metrics
+ Reserved02,
+ Reserved03,
+ Reserved04,
+ Reserved05,
+ Reserved06,
+ Reserved07)
+ } field;
+ struct Raw {
+ static const SK_OT_CHAR Horizontal = 1u << 0;
+ static const SK_OT_CHAR Vertical = 1u << 1;
+ SK_OT_CHAR value;
+ } raw;
+ } flags;
+ }; //bitmapSizeTable[numSizes];
+
+ struct IndexSubTableArray {
+ SK_OT_USHORT firstGlyphIndex; //first glyph code of this range
+ SK_OT_USHORT lastGlyphIndex; //last glyph code of this range (inclusive)
+ SK_OT_ULONG additionalOffsetToIndexSubtable; //add to BitmapSizeTable::indexSubTableArrayOffset to get offset from beginning of 'EBLC'
+ }; //indexSubTableArray[BitmapSizeTable::numberOfIndexSubTables];
+
+ struct IndexSubHeader {
+ SK_OT_USHORT indexFormat; //format of this indexSubTable
+ SK_OT_USHORT imageFormat; //format of 'EBDT' image data
+ SK_OT_ULONG imageDataOffset; //offset to image data in 'EBDT' table
+ };
+
+ // Variable metrics glyphs with 4 byte offsets
+ struct IndexSubTable1 {
+ IndexSubHeader header;
+ //SK_OT_ULONG offsetArray[lastGlyphIndex - firstGlyphIndex + 1 + 1]; //last element points to one past end of last glyph
+ //glyphData = offsetArray[glyphIndex - firstGlyphIndex] + imageDataOffset
+ };
+
+ // All Glyphs have identical metrics
+ struct IndexSubTable2 {
+ IndexSubHeader header;
+ SK_OT_ULONG imageSize; // all glyphs are of the same size
+ SkOTTableEmbeddedBitmapData::BigGlyphMetrics bigMetrics; // all glyphs have the same metrics; glyph data may be compressed, byte-aligned, or bit-aligned
+ };
+
+ // Variable metrics glyphs with 2 byte offsets
+ struct IndexSubTable3 {
+ IndexSubHeader header;
+ //SK_OT_USHORT offsetArray[lastGlyphIndex - firstGlyphIndex + 1 + 1]; //last element points to one past end of last glyph, may have extra element to force even number of elements
+ //glyphData = offsetArray[glyphIndex - firstGlyphIndex] + imageDataOffset
+ };
+
+ // Variable metrics glyphs with sparse glyph codes
+ struct IndexSubTable4 {
+ IndexSubHeader header;
+ SK_OT_ULONG numGlyphs;
+ struct CodeOffsetPair {
+ SK_OT_USHORT glyphCode;
+ SK_OT_USHORT offset; //location in EBDT
+ }; //glyphArray[numGlyphs+1]
+ };
+
+ // Constant metrics glyphs with sparse glyph codes
+ struct IndexSubTable5 {
+ IndexSubHeader header;
+ SK_OT_ULONG imageSize; //all glyphs have the same data size
+ SkOTTableEmbeddedBitmapData::BigGlyphMetrics bigMetrics; //all glyphs have the same metrics
+ SK_OT_ULONG numGlyphs;
+ //SK_OT_USHORT glyphCodeArray[numGlyphs] //must have even number of entries (set pad to 0)
+ };
+
+ union IndexSubTable {
+ IndexSubHeader header;
+ IndexSubTable1 format1;
+ IndexSubTable2 format2;
+ IndexSubTable3 format3;
+ IndexSubTable4 format4;
+ IndexSubTable5 format5;
+ };
+
+};
+
+#pragma pack(pop)
+
+#endif
diff --git a/sfnt/SkOTTable_EBSC.h b/sfnt/SkOTTable_EBSC.h
new file mode 100644
index 00000000..316c45d1
--- /dev/null
+++ b/sfnt/SkOTTable_EBSC.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkOTTable_EBSC_DEFINED
+#define SkOTTable_EBSC_DEFINED
+
+#include "SkEndian.h"
+#include "SkOTTable_EBLC.h"
+#include "SkOTTableTypes.h"
+
+#pragma pack(push, 1)
+
+struct SkOTTableEmbeddedBitmapScaling {
+ static const SK_OT_CHAR TAG0 = 'E';
+ static const SK_OT_CHAR TAG1 = 'S';
+ static const SK_OT_CHAR TAG2 = 'B';
+ static const SK_OT_CHAR TAG3 = 'C';
+ static const SK_OT_ULONG TAG = SkOTTableTAG<SkOTTableEmbeddedBitmapScaling>::value;
+
+ SK_OT_Fixed version;
+ static const SK_OT_Fixed version_initial = SkTEndian_SwapBE32(0x00020000);
+
+ SK_OT_ULONG numSizes;
+
+ struct BitmapScaleTable {
+ SkOTTableEmbeddedBitmapLocation::SbitLineMetrics hori;
+ SkOTTableEmbeddedBitmapLocation::SbitLineMetrics vert;
+ SK_OT_BYTE ppemX; //target horizontal pixels per EM
+ SK_OT_BYTE ppemY; //target vertical pixels per EM
+ SK_OT_BYTE substitutePpemX; //use bitmaps of this size
+ SK_OT_BYTE substitutePpemY; //use bitmaps of this size
+ }; //bitmapScaleTable[numSizes];
+};
+
+#pragma pack(pop)
+
+#endif
diff --git a/utils/debugger/SkDebugCanvas.cpp b/utils/debugger/SkDebugCanvas.cpp
index ec201789..14fbf888 100644
--- a/utils/debugger/SkDebugCanvas.cpp
+++ b/utils/debugger/SkDebugCanvas.cpp
@@ -125,8 +125,6 @@ public:
#endif
};
-// The OverdrawFilter modifies every paint to use an SkProcXfermode which
-// in turn invokes OverdrawXferModeProc
class SkOverdrawFilter : public SkDrawFilter {
public:
SkOverdrawFilter() {