aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2011-04-14 09:57:06 -0400
committerDerek Sollenberger <djsollen@google.com>2011-04-14 15:01:11 -0400
commit87b8e645865f9633f410c02252a0fd3feb18f09b (patch)
tree21e2521ed6f69bf466849f7c9579c37aa6b22b06 /src
parent7f10e10e25231b613ebb242fa14ad8c924ce694f (diff)
downloadexternal_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.zip
external_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.tar.gz
external_skia-87b8e645865f9633f410c02252a0fd3feb18f09b.tar.bz2
Skia Merge (revision 1116)
There is a companion change in external/webkit Change-Id: I1c4110e7520bbef3f4e5f9551adb7ec79ac1e3ed
Diffstat (limited to 'src')
-rw-r--r--src/animator/SkDisplayXMLParser.cpp12
-rw-r--r--src/core/Makefile.am91
-rw-r--r--src/core/SkAlphaRuns.cpp58
-rw-r--r--src/core/SkAntiRun.h134
-rw-r--r--src/core/SkBitmap.cpp72
-rw-r--r--src/core/SkBlitter_4444.cpp98
-rw-r--r--src/core/SkBlitter_A1.cpp32
-rw-r--r--src/core/SkBlitter_A8.cpp4
-rw-r--r--src/core/SkCanvas.cpp219
-rw-r--r--src/core/SkDevice.cpp18
-rw-r--r--src/core/SkDraw.cpp107
-rw-r--r--src/core/SkFlate.cpp17
-rw-r--r--src/core/SkGlyphCache.h21
-rw-r--r--src/core/SkGraphics.cpp246
-rw-r--r--src/core/SkLineClipper.cpp43
-rw-r--r--src/core/SkMask.cpp6
-rw-r--r--src/core/SkMetaData.cpp345
-rw-r--r--src/core/SkPaint.cpp358
-rw-r--r--src/core/SkPath.cpp38
-rw-r--r--src/core/SkPicturePlayback.cpp2
-rw-r--r--src/core/SkPicturePlayback.h5
-rw-r--r--src/core/SkPixelRef.cpp8
-rw-r--r--src/core/SkRegion.cpp120
-rw-r--r--src/core/SkScalerContext.cpp122
-rw-r--r--src/core/SkScan_AntiPath.cpp116
-rw-r--r--src/core/SkScan_Antihair.cpp355
-rw-r--r--src/core/SkScan_Hairline.cpp35
-rw-r--r--src/core/SkScan_Path.cpp157
-rw-r--r--src/core/SkString.cpp288
-rw-r--r--src/core/SkTypeface.cpp3
-rw-r--r--src/core/SkUtils.cpp195
-rw-r--r--src/core/SkXfermode.cpp4
-rw-r--r--src/core/core_files.mk1
-rw-r--r--src/effects/SkBlurDrawLooper.cpp129
-rw-r--r--src/effects/SkGradientShader.cpp10
-rw-r--r--src/effects/SkLayerDrawLooper.cpp153
-rw-r--r--src/effects/SkPaintFlagsDrawFilter.cpp15
-rw-r--r--src/gpu/SkGpuDevice.cpp278
-rw-r--r--src/gpu/SkGr.cpp24
-rw-r--r--src/gpu/SkGrFontScaler.cpp25
-rw-r--r--src/gpu/SkGrTexturePixelRef.cpp72
-rw-r--r--src/ports/SkFontHost_FONTPATH.cpp3
-rw-r--r--src/ports/SkFontHost_FreeType.cpp49
-rw-r--r--src/ports/SkFontHost_mac_atsui.cpp3
-rw-r--r--src/ports/SkFontHost_mac_coretext.cpp292
-rw-r--r--src/ports/SkFontHost_none.cpp3
-rw-r--r--src/ports/SkFontHost_simple.cpp3
-rw-r--r--src/ports/SkFontHost_win.cpp10
-rw-r--r--src/ports/ports_files.mk6
-rw-r--r--src/svg/SkSVGPaintState.cpp2
-rw-r--r--src/utils/SkOSFile.cpp21
51 files changed, 2484 insertions, 1944 deletions
diff --git a/src/animator/SkDisplayXMLParser.cpp b/src/animator/SkDisplayXMLParser.cpp
index d2775e8..a94b848 100644
--- a/src/animator/SkDisplayXMLParser.cpp
+++ b/src/animator/SkDisplayXMLParser.cpp
@@ -164,6 +164,14 @@ bool SkDisplayXMLParser::onAddAttributeLen(const char attrName[], const char att
return false;
}
+#if defined(SK_BUILD_FOR_WIN32)
+ #define SK_strcasecmp stricmp
+ #define SK_strncasecmp strnicmp
+#else
+ #define SK_strcasecmp strcasecmp
+ #define SK_strncasecmp strncasecmp
+#endif
+
bool SkDisplayXMLParser::onEndElement(const char elem[])
{
int parentIndex = fParents.count() - 1;
@@ -199,7 +207,7 @@ bool SkDisplayXMLParser::onEndElement(const char elem[])
fParents.remove(parentIndex);
}
fCurrDisplayable = NULL;
- if (fInInclude == false && strcasecmp(elem, "screenplay") == 0) {
+ if (fInInclude == false && SK_strcasecmp(elem, "screenplay") == 0) {
if (fMaker.fInMovie == false) {
fMaker.fEnableTime = fMaker.getAppTime();
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
@@ -231,7 +239,7 @@ bool SkDisplayXMLParser::onStartElement(const char name[])
bool SkDisplayXMLParser::onStartElementLen(const char name[], size_t len) {
fCurrDisplayable = NULL; // init so we'll ignore attributes if we exit early
- if (strncasecmp(name, "screenplay", len) == 0) {
+ if (SK_strncasecmp(name, "screenplay", len) == 0) {
fInSkia = true;
if (fInInclude == false)
fMaker.idsSet(name, len, &fMaker.fScreenplay);
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
new file mode 100644
index 0000000..4adde0a
--- /dev/null
+++ b/src/core/Makefile.am
@@ -0,0 +1,91 @@
+AM_CPPFLAGS = -I$(top_builddir)/include/core
+
+noinst_LIBRARIES = libskia.a
+libskia_a_SOURCES = Sk64.cpp \
+SkAlphaRuns.cpp \
+SkBitmap.cpp \
+SkBitmapProcShader.cpp \
+SkBitmapProcState.cpp \
+SkBitmapProcState_matrixProcs.cpp \
+SkBitmapSampler.cpp \
+SkBitmapShader.cpp \
+SkBitmap_scroll.cpp \
+SkBlitRow_D16.cpp \
+SkBlitRow_D4444.cpp \
+SkBlitter.cpp \
+SkBlitter_4444.cpp \
+SkBlitter_A1.cpp \
+SkBlitter_A8.cpp \
+SkBlitter_ARGB32.cpp \
+SkBlitter_RGB16.cpp \
+SkBlitter_Sprite.cpp \
+SkBuffer.cpp \
+SkCanvas.cpp \
+SkChunkAlloc.cpp \
+SkColor.cpp \
+SkColorFilter.cpp \
+SkColorTable.cpp \
+SkComposeShader.cpp \
+SkConcaveToTriangles.cpp \
+SkCordic.cpp \
+skCubicClipper.cpp \
+SkDebug.cpp \
+SkDebug_stdio.cpp \
+SkDeque.cpp \
+SkDevice.cpp \
+SkDither.cpp \
+SkDraw.cpp \
+SkEdge.cpp \
+SkFilterProc.cpp \
+SkFlattenable.cpp \
+SkFloat.cpp \
+SkFloatBits.cpp \
+SkGeometry.cpp \
+SkGlobals.cpp \
+SkGlyphCache.cpp \
+SkGraphics.cpp \
+SkMMapStream.cpp \
+SkMask.cpp \
+SkMaskFilter.cpp \
+SkMath.cpp \
+SkMatrix.cpp \
+SkMemory_stdlib.cpp \
+SkPackBits.cpp \
+SkPaint.cpp \
+SkPath.cpp \
+SkPathEffect.cpp \
+SkPathHeap.cpp \
+SkPathMeasure.cpp \
+SkPicture.cpp \
+SkPictureFlat.cpp \
+SkPicturePlayback.cpp \
+SkPictureRecord.cpp \
+SkPixelRef.cpp \
+SkPoint.cpp \
+SkProcSpriteBlitter.cpp \
+SkPtrRecorder.cpp \
+SkRasterizer.cpp \
+SkRect.cpp \
+SkRefCnt.cpp \
+SkRegion.cpp \
+SkRegion_path.cpp \
+SkScalar.cpp \
+SkScalerContext.cpp \
+SkScan.cpp \
+SkScan_AntiPath.cpp \
+SkScan_Antihair.cpp \
+SkScan_Hairline.cpp \
+SkScan_Path.cpp \
+SkShader.cpp \
+SkSpriteBlitter_ARGB32.cpp \
+SkSpriteBlitter_RGB16.cpp \
+SkStream.cpp \
+SkString.cpp \
+SkStroke.cpp \
+SkStrokerPriv.cpp \
+SkTSearch.cpp \
+SkTypeface.cpp \
+SkUnPreMultiply.cpp \
+SkUtils.cpp \
+SkWriter32.cpp \
+SkXfermode.cpp
diff --git a/src/core/SkAlphaRuns.cpp b/src/core/SkAlphaRuns.cpp
index 46b0206..4125b58 100644
--- a/src/core/SkAlphaRuns.cpp
+++ b/src/core/SkAlphaRuns.cpp
@@ -17,8 +17,7 @@
#include "SkAntiRun.h"
-void SkAlphaRuns::reset(int width)
-{
+void SkAlphaRuns::reset(int width) {
SkASSERT(width > 0);
fRuns[0] = SkToS16(width);
@@ -29,8 +28,7 @@ void SkAlphaRuns::reset(int width)
SkDEBUGCODE(this->validate();)
}
-void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count)
-{
+void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count) {
SkASSERT(count > 0 && x >= 0);
// SkAlphaRuns::BreakAt(runs, alpha, x);
@@ -39,13 +37,11 @@ void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count)
int16_t* next_runs = runs + x;
uint8_t* next_alpha = alpha + x;
- while (x > 0)
- {
+ while (x > 0) {
int n = runs[0];
SkASSERT(n > 0);
- if (x < n)
- {
+ if (x < n) {
alpha[x] = alpha[0];
runs[0] = SkToS16(x);
runs[x] = SkToS16(n - x);
@@ -60,37 +56,34 @@ void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count)
alpha = next_alpha;
x = count;
- for (;;)
- {
+ for (;;) {
int n = runs[0];
SkASSERT(n > 0);
- if (x < n)
- {
+ if (x < n) {
alpha[x] = alpha[0];
runs[0] = SkToS16(x);
runs[x] = SkToS16(n - x);
break;
}
x -= n;
- if (x <= 0)
+ if (x <= 0) {
break;
-
+ }
runs += n;
alpha += n;
}
}
-void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue)
-{
+void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
+ U8CPU maxValue) {
SkASSERT(middleCount >= 0);
SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
int16_t* runs = fRuns;
uint8_t* alpha = fAlpha;
- if (startAlpha)
- {
+ if (startAlpha) {
SkAlphaRuns::Break(runs, alpha, x, 1);
/* I should be able to just add alpha[x] + startAlpha.
However, if the trailing edge of the previous span and the leading
@@ -106,8 +99,8 @@ void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
x = 0;
SkDEBUGCODE(this->validate();)
}
- if (middleCount)
- {
+
+ if (middleCount) {
SkAlphaRuns::Break(runs, alpha, x, middleCount);
alpha += x;
runs += x;
@@ -122,8 +115,8 @@ void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
} while (middleCount > 0);
SkDEBUGCODE(this->validate();)
}
- if (stopAlpha)
- {
+
+ if (stopAlpha) {
SkAlphaRuns::Break(runs, alpha, x, 1);
alpha[x] = SkToU8(alpha[x] + stopAlpha);
SkDEBUGCODE(this->validate();)
@@ -131,49 +124,44 @@ void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
}
#ifdef SK_DEBUG
- void SkAlphaRuns::assertValid(int y, int maxStep) const
- {
+ void SkAlphaRuns::assertValid(int y, int maxStep) const {
int max = (y + 1) * maxStep - (y == maxStep - 1);
const int16_t* runs = fRuns;
const uint8_t* alpha = fAlpha;
- while (*runs)
- {
+ while (*runs) {
SkASSERT(*alpha <= max);
alpha += *runs;
runs += *runs;
}
}
- void SkAlphaRuns::dump() const
- {
+ void SkAlphaRuns::dump() const {
const int16_t* runs = fRuns;
const uint8_t* alpha = fAlpha;
SkDebugf("Runs");
- while (*runs)
- {
+ while (*runs) {
int n = *runs;
SkDebugf(" %02x", *alpha);
- if (n > 1)
+ if (n > 1) {
SkDebugf(",%d", n);
+ }
alpha += n;
runs += n;
}
SkDebugf("\n");
}
- void SkAlphaRuns::validate() const
- {
+ void SkAlphaRuns::validate() const {
SkASSERT(fWidth > 0);
int count = 0;
const int16_t* runs = fRuns;
- while (*runs)
- {
+ while (*runs) {
SkASSERT(*runs > 0);
count += *runs;
SkASSERT(count <= fWidth);
diff --git a/src/core/SkAntiRun.h b/src/core/SkAntiRun.h
index 12930e6..89e5481 100644
--- a/src/core/SkAntiRun.h
+++ b/src/core/SkAntiRun.h
@@ -20,151 +20,29 @@
#include "SkBlitter.h"
-inline int sk_make_nonzero_neg_one(int x)
-{
- return (x | -x) >> 31;
-}
-
-#if 0
-template <int kShift> class SkAntiRun {
- static uint8_t coverage_to_alpha(int aa)
- {
- aa <<= 8 - 2*kShift;
- aa -= aa >> (8 - kShift - 1);
- return SkToU8(aa);
- }
-public:
- void set(int start, int stop)
- {
- SkASSERT(start >= 0 && stop > start);
-
-#if 1
- int fb = start & kMask;
- int fe = stop & kMask;
- int n = (stop >> kShift) - (start >> kShift) - 1;
-
- if (n < 0)
- {
- fb = fe - fb;
- n = 0;
- fe = 0;
- }
- else
- {
- if (fb == 0)
- n += 1;
- else
- fb = (1 << kShift) - fb;
- }
-
- fStartAlpha = coverage_to_alpha(fb);
- fMiddleCount = n;
- fStopAlpha = coverage_to_alpha(fe);
-#else
- int x0 = start >> kShift;
- int x1 = (stop - 1) >> kShift;
- int middle = x1 - x0;
- int aa;
-
- if (middle == 0)
- {
- aa = stop - start;
- aa <<= 8 - 2*kShift;
- aa -= aa >> (8 - kShift - 1);
- SkASSERT(aa > 0 && aa < kMax);
- fStartAlpha = SkToU8(aa);
- fMiddleCount = 0;
- fStopAlpha = 0;
- }
- else
- {
- int aa = start & kMask;
- aa <<= 8 - 2*kShift;
- aa -= aa >> (8 - kShift - 1);
- SkASSERT(aa >= 0 && aa < kMax);
- if (aa)
- fStartAlpha = SkToU8(kMax - aa);
- else
- {
- fStartAlpha = 0;
- middle += 1;
- }
- aa = stop & kMask;
- aa <<= 8 - 2*kShift;
- aa -= aa >> (8 - kShift - 1);
- SkASSERT(aa >= 0 && aa < kMax);
- middle += sk_make_nonzero_neg_one(aa);
-
- fStopAlpha = SkToU8(aa);
- fMiddleCount = middle;
- }
- SkASSERT(fStartAlpha < kMax);
- SkASSERT(fStopAlpha < kMax);
-#endif
- }
-
- void blit(int x, int y, SkBlitter* blitter)
- {
- int16_t runs[2];
- runs[0] = 1;
- runs[1] = 0;
-
- if (fStartAlpha)
- {
- blitter->blitAntiH(x, y, &fStartAlpha, runs);
- x += 1;
- }
- if (fMiddleCount)
- {
- blitter->blitH(x, y, fMiddleCount);
- x += fMiddleCount;
- }
- if (fStopAlpha)
- blitter->blitAntiH(x, y, &fStopAlpha, runs);
- }
-
- uint8_t getStartAlpha() const { return fStartAlpha; }
- int getMiddleCount() const { return fMiddleCount; }
- uint8_t getStopAlpha() const { return fStopAlpha; }
-
-private:
- uint8_t fStartAlpha, fStopAlpha;
- int fMiddleCount;
-
- enum {
- kMask = (1 << kShift) - 1,
- kMax = (1 << (8 - kShift)) - 1
- };
-};
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////
-
class SkAlphaRuns {
public:
int16_t* fRuns;
uint8_t* fAlpha;
- bool empty() const
- {
+ bool empty() const {
SkASSERT(fRuns[0] > 0);
return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
}
+
void reset(int width);
void add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue);
SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
SkDEBUGCODE(void dump() const;)
static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
- static void BreakAt(int16_t runs[], uint8_t alpha[], int x)
- {
- while (x > 0)
- {
+
+ static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
+ while (x > 0) {
int n = runs[0];
SkASSERT(n > 0);
- if (x < n)
- {
+ if (x < n) {
alpha[x] = alpha[0];
runs[0] = SkToS16(x);
runs[x] = SkToS16(n - x);
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index a5f7d57..c19e84d 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -865,61 +865,79 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
return false;
}
+ // if we have a texture, first get those pixels
+ SkBitmap tmpSrc;
+ const SkBitmap* src = this;
+
+ if (fPixelRef && fPixelRef->readPixels(&tmpSrc)) {
+ SkASSERT(tmpSrc.width() == this->width());
+ SkASSERT(tmpSrc.height() == this->height());
+
+ // did we get lucky and we can just return tmpSrc?
+ if (tmpSrc.config() == dstConfig && NULL == alloc) {
+ dst->swap(tmpSrc);
+ return true;
+ }
+
+ // fall through to the raster case
+ src = &tmpSrc;
+ }
+
// we lock this now, since we may need its colortable
- SkAutoLockPixels srclock(*this);
- if (!this->readyToDraw()) {
+ SkAutoLockPixels srclock(*src);
+ if (!src->readyToDraw()) {
return false;
}
-
- SkBitmap tmp;
- tmp.setConfig(dstConfig, this->width(), this->height());
-
+
+ SkBitmap tmpDst;
+ tmpDst.setConfig(dstConfig, src->width(), src->height());
+
// allocate colortable if srcConfig == kIndex8_Config
SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
- new SkColorTable(*this->getColorTable()) : NULL;
+ new SkColorTable(*src->getColorTable()) : NULL;
SkAutoUnref au(ctable);
- if (!tmp.allocPixels(alloc, ctable)) {
+ if (!tmpDst.allocPixels(alloc, ctable)) {
return false;
}
-
- SkAutoLockPixels dstlock(tmp);
- if (!tmp.readyToDraw()) {
+
+ SkAutoLockPixels dstlock(tmpDst);
+ if (!tmpDst.readyToDraw()) {
// allocator/lock failed
return false;
}
-
+
/* do memcpy for the same configs cases, else use drawing
*/
- if (this->config() == dstConfig) {
- if (tmp.getSize() == this->getSize()) {
- memcpy(tmp.getPixels(), this->getPixels(), this->getSafeSize());
+ if (src->config() == dstConfig) {
+ if (tmpDst.getSize() == src->getSize()) {
+ memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
} else {
- const char* srcP = reinterpret_cast<const char*>(this->getPixels());
- char* dstP = reinterpret_cast<char*>(tmp.getPixels());
+ const char* srcP = reinterpret_cast<const char*>(src->getPixels());
+ char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
// to be sure we don't read too much, only copy our logical pixels
- size_t bytesToCopy = tmp.width() * tmp.bytesPerPixel();
- for (int y = 0; y < tmp.height(); y++) {
+ size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
+ for (int y = 0; y < tmpDst.height(); y++) {
memcpy(dstP, srcP, bytesToCopy);
- srcP += this->rowBytes();
- dstP += tmp.rowBytes();
+ srcP += src->rowBytes();
+ dstP += tmpDst.rowBytes();
}
}
} else {
// if the src has alpha, we have to clear the dst first
- if (!this->isOpaque()) {
- tmp.eraseColor(0);
+ if (!src->isOpaque()) {
+ tmpDst.eraseColor(0);
}
- SkCanvas canvas(tmp);
+ SkCanvas canvas(tmpDst);
SkPaint paint;
paint.setDither(true);
- canvas.drawBitmap(*this, 0, 0, &paint);
+ canvas.drawBitmap(*src, 0, 0, &paint);
}
- tmp.setIsOpaque(this->isOpaque());
+ tmpDst.setIsOpaque(src->isOpaque());
- dst->swap(tmp);
+ dst->swap(tmpDst);
return true;
}
diff --git a/src/core/SkBlitter_4444.cpp b/src/core/SkBlitter_4444.cpp
index e1c519a..d976f2d 100644
--- a/src/core/SkBlitter_4444.cpp
+++ b/src/core/SkBlitter_4444.cpp
@@ -41,7 +41,8 @@ class SkARGB4444_Blitter : public SkRasterBlitter {
public:
SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& paint);
virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
+ const int16_t runs[]);
virtual void blitV(int x, int y, int height, SkAlpha alpha);
virtual void blitRect(int x, int y, int width, int height);
virtual void blitMask(const SkMask&, const SkIRect&);
@@ -60,9 +61,8 @@ private:
};
-SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& paint)
- : INHERITED(device)
-{
+SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device,
+ const SkPaint& paint) : INHERITED(device) {
// cache premultiplied versions in 4444
SkPMColor c = SkPreMultiplyColor(paint.getColor());
fPMColor16 = SkPixel32ToPixel4444(c);
@@ -82,13 +82,6 @@ SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& pa
fRawColor16Other = fRawColor16;
}
-#if 0 /// don't think this assertion is true, but need it be?
-
- // our dithered color will be the same or more opaque than the original
- // so use dithered to compute our scale
- SkASSERT(SkGetPackedA4444(fPMColor16Other) >= SkGetPackedA4444(fPMColor16));
-#endif
-
fScale16 = SkAlpha15To16(SkGetPackedA4444(fPMColor16Other));
if (16 == fScale16) {
// force the original to also be opaque
@@ -96,8 +89,7 @@ SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& pa
}
}
-const SkBitmap* SkARGB4444_Blitter::justAnOpaqueColor(uint32_t* value)
-{
+const SkBitmap* SkARGB4444_Blitter::justAnOpaqueColor(uint32_t* value) {
if (16 == fScale16) {
*value = fPMColor16;
return &fDevice;
@@ -106,8 +98,7 @@ const SkBitmap* SkARGB4444_Blitter::justAnOpaqueColor(uint32_t* value)
}
static void src_over_4444(SkPMColor16 dst[], SkPMColor16 color,
- SkPMColor16 other, unsigned invScale, int count)
-{
+ SkPMColor16 other, unsigned invScale, int count) {
int twice = count >> 1;
while (--twice >= 0) {
*dst = color + SkAlphaMulQ4(*dst, invScale);
@@ -120,15 +111,13 @@ static void src_over_4444(SkPMColor16 dst[], SkPMColor16 color,
}
}
-static inline uint32_t SkExpand_4444_Replicate(SkPMColor16 c)
-{
+static inline uint32_t SkExpand_4444_Replicate(SkPMColor16 c) {
uint32_t c32 = SkExpand_4444(c);
return c32 | (c32 << 4);
}
static void src_over_4444x(SkPMColor16 dst[], uint32_t color,
- uint32_t other, unsigned invScale, int count)
-{
+ uint32_t other, unsigned invScale, int count) {
int twice = count >> 1;
uint32_t tmp;
while (--twice >= 0) {
@@ -143,8 +132,7 @@ static void src_over_4444x(SkPMColor16 dst[], uint32_t color,
}
}
-void SkARGB4444_Blitter::blitH(int x, int y, int width)
-{
+void SkARGB4444_Blitter::blitH(int x, int y, int width) {
SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
if (0 == fScale16) {
@@ -161,16 +149,14 @@ void SkARGB4444_Blitter::blitH(int x, int y, int width)
if (16 == fScale16) {
sk_dither_memset16(device, color, other, width);
- }
- else {
+ } else {
src_over_4444x(device, SkExpand_4444_Replicate(color),
SkExpand_4444_Replicate(other),
16 - fScale16, width);
}
}
-void SkARGB4444_Blitter::blitV(int x, int y, int height, SkAlpha alpha)
-{
+void SkARGB4444_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
if (0 == alpha || 0 == fScale16) {
return;
}
@@ -208,9 +194,9 @@ void SkARGB4444_Blitter::blitV(int x, int y, int height, SkAlpha alpha)
}
}
-void SkARGB4444_Blitter::blitRect(int x, int y, int width, int height)
-{
- SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
+void SkARGB4444_Blitter::blitRect(int x, int y, int width, int height) {
+ SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() &&
+ y + height <= fDevice.height());
if (0 == fScale16) {
return;
@@ -243,8 +229,8 @@ void SkARGB4444_Blitter::blitRect(int x, int y, int width, int height)
}
}
-void SkARGB4444_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
-{
+void SkARGB4444_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
+ const int16_t runs[]) {
if (0 == fScale16) {
return;
}
@@ -295,19 +281,19 @@ void SkARGB4444_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], cons
}
}
-//////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#define solid_8_pixels(mask, dst, color) \
-do { \
-if (mask & 0x80) dst[0] = color; \
-if (mask & 0x40) dst[1] = color; \
-if (mask & 0x20) dst[2] = color; \
-if (mask & 0x10) dst[3] = color; \
-if (mask & 0x08) dst[4] = color; \
-if (mask & 0x04) dst[5] = color; \
-if (mask & 0x02) dst[6] = color; \
-if (mask & 0x01) dst[7] = color; \
-} while (0)
+ do { \
+ if (mask & 0x80) dst[0] = color; \
+ if (mask & 0x40) dst[1] = color; \
+ if (mask & 0x20) dst[2] = color; \
+ if (mask & 0x10) dst[3] = color; \
+ if (mask & 0x08) dst[4] = color; \
+ if (mask & 0x04) dst[5] = color; \
+ if (mask & 0x02) dst[6] = color; \
+ if (mask & 0x01) dst[7] = color; \
+ } while (0)
#define SK_BLITBWMASK_NAME SkARGB4444_BlitBW
#define SK_BLITBWMASK_ARGS , SkPMColor16 color
@@ -316,17 +302,17 @@ if (mask & 0x01) dst[7] = color; \
#define SK_BLITBWMASK_DEVTYPE uint16_t
#include "SkBlitBWMaskTemplate.h"
-#define blend_8_pixels(mask, dst, sc, dst_scale) \
-do { \
-if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ4(dst[0], dst_scale); } \
-if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ4(dst[1], dst_scale); } \
-if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ4(dst[2], dst_scale); } \
-if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ4(dst[3], dst_scale); } \
-if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ4(dst[4], dst_scale); } \
-if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ4(dst[5], dst_scale); } \
-if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ4(dst[6], dst_scale); } \
-if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ4(dst[7], dst_scale); } \
-} while (0)
+#define blend_8_pixels(mask, dst, sc, dst_scale) \
+ do { \
+ if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ4(dst[0], dst_scale); } \
+ if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ4(dst[1], dst_scale); } \
+ if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ4(dst[2], dst_scale); } \
+ if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ4(dst[3], dst_scale); } \
+ if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ4(dst[4], dst_scale); } \
+ if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ4(dst[5], dst_scale); } \
+ if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ4(dst[6], dst_scale); } \
+ if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ4(dst[7], dst_scale); } \
+ } while (0)
#define SK_BLITBWMASK_NAME SkARGB4444_BlendBW
#define SK_BLITBWMASK_ARGS , uint16_t sc, unsigned dst_scale
@@ -335,8 +321,7 @@ if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ4(dst[7], dst_scale); } \
#define SK_BLITBWMASK_DEVTYPE uint16_t
#include "SkBlitBWMaskTemplate.h"
-void SkARGB4444_Blitter::blitMask(const SkMask& mask, const SkIRect& clip)
-{
+void SkARGB4444_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
SkASSERT(mask.fBounds.contains(clip));
if (0 == fScale16) {
@@ -375,7 +360,7 @@ void SkARGB4444_Blitter::blitMask(const SkMask& mask, const SkIRect& clip)
} while (--height != 0);
}
-//////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
class SkARGB4444_Shader_Blitter : public SkShaderBlitter {
SkXfermode* fXfermode;
@@ -386,8 +371,7 @@ class SkARGB4444_Shader_Blitter : public SkShaderBlitter {
public:
SkARGB4444_Shader_Blitter(const SkBitmap& device, const SkPaint& paint)
- : INHERITED(device, paint)
-{
+ : INHERITED(device, paint) {
const int width = device.width();
fBuffer = (SkPMColor*)sk_malloc_throw(width * sizeof(SkPMColor) + width);
fAAExpand = (uint8_t*)(fBuffer + width);
diff --git a/src/core/SkBlitter_A1.cpp b/src/core/SkBlitter_A1.cpp
index 1a91a26..d1416ff 100644
--- a/src/core/SkBlitter_A1.cpp
+++ b/src/core/SkBlitter_A1.cpp
@@ -18,18 +18,17 @@
#include "SkCoreBlitters.h"
SkA1_Blitter::SkA1_Blitter(const SkBitmap& device, const SkPaint& paint)
- : INHERITED(device)
-{
- fSrcA = SkToU8(SkColorGetA(paint.getColor()));
+ : 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());
+void SkA1_Blitter::blitH(int x, int y, int width) {
+ SkASSERT(x >= 0 && y >= 0 &&
+ (unsigned)(x + width) <= (unsigned)fDevice.width());
- if (fSrcA <= 0x7F)
+ if (fSrcA <= 0x7F) {
return;
-
+ }
uint8_t* dst = fDevice.getAddr1(x, y);
int right = x + width;
@@ -37,23 +36,20 @@ void SkA1_Blitter::blitH(int x, int y, int width)
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)
- {
+ // 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)
+ if (left_mask == 0xFF) {
full_runs -= 1;
-
- if (full_runs < 0)
- {
+ }
+ if (full_runs < 0) {
SkASSERT((left_mask & rite_mask) != 0);
*dst |= (left_mask & rite_mask);
- }
- else
- {
+ } else {
*dst++ |= left_mask;
memset(dst, 0xFF, full_runs);
dst += full_runs;
diff --git a/src/core/SkBlitter_A8.cpp b/src/core/SkBlitter_A8.cpp
index f74fbe3..2eb762f 100644
--- a/src/core/SkBlitter_A8.cpp
+++ b/src/core/SkBlitter_A8.cpp
@@ -21,8 +21,8 @@
#include "SkXfermode.h"
SkA8_Blitter::SkA8_Blitter(const SkBitmap& device, const SkPaint& paint)
- : INHERITED(device) {
- fSrcA = SkColorGetA(paint.getColor());
+ : INHERITED(device) {
+ fSrcA = paint.getAlpha();
}
const SkBitmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index a31623e..16cfc4b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -24,6 +24,7 @@
#include "SkScalarCompare.h"
#include "SkShape.h"
#include "SkTemplates.h"
+#include "SkTLazy.h"
#include "SkUtils.h"
#include <new>
@@ -50,6 +51,8 @@
#define dec_canvas()
#endif
+typedef SkTLazy<SkPaint> SkLazyPaint;
+
///////////////////////////////////////////////////////////////////////////////
// Helpers for computing fast bounds for quickReject tests
@@ -279,65 +282,69 @@ private:
class AutoDrawLooper {
public:
- AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, SkDrawFilter::Type t)
- : fCanvas(canvas), fPaint((SkPaint*)&paint), fType(t) {
- if ((fLooper = paint.getLooper()) != NULL) {
- fLooper->init(canvas, (SkPaint*)&paint);
- } else {
- fOnce = true;
- }
+ AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint) : fOrigPaint(paint) {
+ fCanvas = canvas;
+ fLooper = paint.getLooper();
fFilter = canvas->getDrawFilter();
- fNeedFilterRestore = false;
- }
+ fPaint = NULL;
+ fSaveCount = canvas->getSaveCount();
+ fDone = false;
- ~AutoDrawLooper() {
- if (fNeedFilterRestore) {
- SkASSERT(fFilter);
- fFilter->restore(fCanvas, fPaint, fType);
- }
- if (NULL != fLooper) {
- fLooper->restore();
+ if (fLooper) {
+ fLooper->init(canvas);
}
}
-
- bool next() {
- SkDrawFilter* filter = fFilter;
-
- // if we drew earlier with a filter, then we need to restore first
- if (fNeedFilterRestore) {
- SkASSERT(filter);
- filter->restore(fCanvas, fPaint, fType);
- fNeedFilterRestore = false;
- }
-
- bool result;
-
- if (NULL != fLooper) {
- result = fLooper->next();
- } else {
- result = fOnce;
- fOnce = false;
- }
-
- // if we're gonna draw, give the filter a chance to do its work
- if (result && NULL != filter) {
- fNeedFilterRestore = result = filter->filter(fCanvas, fPaint,
- fType);
- }
- return result;
+
+ ~AutoDrawLooper() {
+ SkASSERT(fCanvas->getSaveCount() == fSaveCount);
}
-
+
+ const SkPaint& paint() const {
+ SkASSERT(fPaint);
+ return *fPaint;
+ }
+
+ bool next(SkDrawFilter::Type drawType);
+
private:
+ SkLazyPaint fLazyPaint;
+ SkCanvas* fCanvas;
+ const SkPaint& fOrigPaint;
SkDrawLooper* fLooper;
SkDrawFilter* fFilter;
- SkCanvas* fCanvas;
- SkPaint* fPaint;
- SkDrawFilter::Type fType;
- bool fOnce;
- bool fNeedFilterRestore;
-
+ const SkPaint* fPaint;
+ int fSaveCount;
+ bool fDone;
};
+bool AutoDrawLooper::next(SkDrawFilter::Type drawType) {
+ if (fDone) {
+ fPaint = NULL;
+ return false;
+ }
+ if (!fLooper && !fFilter) {
+ fDone = true;
+ fPaint = &fOrigPaint;
+ return true;
+ }
+
+ SkPaint* paint = fLazyPaint.set(fOrigPaint);
+ if (fLooper && !fLooper->next(fCanvas, paint)) {
+ fDone = true;
+ fPaint = NULL;
+ return false;
+ }
+ if (fFilter) {
+ fFilter->filter(paint, drawType);
+ if (NULL == fLooper) {
+ // no looper means we only draw once
+ fDone = true;
+ }
+ }
+ fPaint = paint;
+ return true;
+}
+
/* Stack helper for managing a SkBounder. In the destructor, if we were
given a bounder, we call its commit() method, signifying that we are
done accumulating bounds for that draw.
@@ -379,14 +386,14 @@ private:
////////// macros to place around the internal draw calls //////////////////
-#define ITER_BEGIN(paint, type) \
+#define LOOPER_BEGIN(paint, type) \
/* AutoValidator validator(fMCRec->fTopLayer->fDevice); */ \
- AutoDrawLooper looper(this, paint, type); \
- while (looper.next()) { \
+ AutoDrawLooper looper(this, paint); \
+ while (looper.next(type)) { \
SkAutoBounderCommit ac(fBounder); \
SkDrawIter iter(this);
-#define ITER_END }
+#define LOOPER_END }
////////////////////////////////////////////////////////////////////////////
@@ -472,6 +479,10 @@ SkDevice* SkCanvas::getDevice() const {
return rec->fLayer->fDevice;
}
+SkDevice* SkCanvas::getTopDevice() const {
+ return fMCRec->fTopLayer->fDevice;
+}
+
SkDevice* SkCanvas::setDevice(SkDevice* device) {
// return root device
SkDeque::F2BIter iter(fMCStack);
@@ -832,12 +843,11 @@ void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect
return;
}
+ SkLazyPaint lazy;
if (NULL == paint) {
- SkPaint tmpPaint;
- this->commonDrawBitmap(bitmap, srcRect, matrix, tmpPaint);
- } else {
- this->commonDrawBitmap(bitmap, srcRect, matrix, *paint);
+ paint = lazy.init();
}
+ this->commonDrawBitmap(bitmap, srcRect, matrix, *paint);
}
void SkCanvas::drawDevice(SkDevice* device, int x, int y,
@@ -848,12 +858,12 @@ void SkCanvas::drawDevice(SkDevice* device, int x, int y,
paint = &tmp;
}
- ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
iter.fDevice->drawDevice(iter, device, x - iter.getX(), y - iter.getY(),
- *paint);
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
/////////////////////////////////////////////////////////////////////////////
@@ -1185,13 +1195,13 @@ SkDevice* SkCanvas::createDevice(SkBitmap::Config config, int width, int height,
//////////////////////////////////////////////////////////////////////////////
void SkCanvas::drawPaint(const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kPaint_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type)
while (iter.next()) {
- iter.fDevice->drawPaint(iter, paint);
+ iter.fDevice->drawPaint(iter, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
@@ -1202,13 +1212,13 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
SkASSERT(pts != NULL);
- ITER_BEGIN(paint, SkDrawFilter::kPoint_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type)
while (iter.next()) {
- iter.fDevice->drawPoints(iter, mode, count, pts, paint);
+ iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
@@ -1220,13 +1230,13 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
}
}
- ITER_BEGIN(paint, SkDrawFilter::kRect_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type)
while (iter.next()) {
- iter.fDevice->drawRect(iter, r, paint);
+ iter.fDevice->drawRect(iter, r, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
@@ -1239,13 +1249,13 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
}
}
- ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
while (iter.next()) {
- iter.fDevice->drawPath(iter, path, paint);
+ iter.fDevice->drawPath(iter, path, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
@@ -1305,7 +1315,9 @@ void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
SkIRect tmpISrc;
if (src) {
tmpISrc.set(0, 0, bitmap.width(), bitmap.height());
- tmpISrc.intersect(*src);
+ if (!tmpISrc.intersect(*src)) {
+ return;
+ }
src = &tmpISrc;
}
this->internalDrawBitmap(*bitmapPtr, src, matrix, paint);
@@ -1321,13 +1333,13 @@ void SkCanvas::commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect,
const SkMatrix& matrix, const SkPaint& paint) {
SkDEBUGCODE(bitmap.validate();)
- ITER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
- iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, paint);
+ iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
@@ -1343,13 +1355,13 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
paint = &tmp;
}
- ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
+ LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
while (iter.next()) {
iter.fDevice->drawSprite(iter, bitmap, x - iter.getX(), y - iter.getY(),
- *paint);
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
class SkDeviceFilteredPaint {
@@ -1357,7 +1369,7 @@ public:
SkDeviceFilteredPaint(SkDevice* device, const SkPaint& paint) {
SkDevice::TextFlags flags;
if (device->filterTextFlags(paint, &flags)) {
- SkPaint* newPaint = new (fStorage) SkPaint(paint);
+ SkPaint* newPaint = fLazy.set(paint);
newPaint->setFlags(flags.fFlags);
newPaint->setHinting(flags.fHinting);
fPaint = newPaint;
@@ -1366,71 +1378,63 @@ public:
}
}
- ~SkDeviceFilteredPaint() {
- if (reinterpret_cast<SkPaint*>(fStorage) == fPaint) {
- fPaint->~SkPaint();
- }
- }
-
const SkPaint& paint() const { return *fPaint; }
private:
- // points to either fStorage or the caller's paint
const SkPaint* fPaint;
- // we rely on the fPaint above to ensure proper alignment of fStorage
- char fStorage[sizeof(SkPaint)];
+ SkLazyPaint fLazy;
};
void SkCanvas::drawText(const void* text, size_t byteLength,
SkScalar x, SkScalar y, const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2,
dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
- SkDeviceFilteredPaint dfp(iter.fDevice, paint);
+ SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1,
dfp.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
- matrix, paint);
+ matrix, looper.paint());
}
- ITER_END
+ LOOPER_END
}
#ifdef ANDROID
@@ -1438,14 +1442,14 @@ void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) {
- ITER_BEGIN(paint, SkDrawFilter::kText_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos,
- paint, path, matrix);
+ looper.paint(), path, matrix);
}
- ITER_END
+ LOOPER_END
}
#endif
@@ -1454,14 +1458,15 @@ void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
- ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
+ LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
while (iter.next()) {
iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
- colors, xmode, indices, indexCount, paint);
+ colors, xmode, indices, indexCount,
+ looper.paint());
}
- ITER_END
+ LOOPER_END
}
void SkCanvas::drawData(const void* data, size_t length) {
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 8231848..69d0c1c 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -1,15 +1,16 @@
#include "SkDevice.h"
#include "SkDraw.h"
+#include "SkMetaData.h"
#include "SkRect.h"
SkDeviceFactory::~SkDeviceFactory() {}
-SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {
+SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas), fMetaData(NULL) {
fOrigin.setZero();
}
SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
- : fCanvas(canvas), fBitmap(bitmap) {
+ : fCanvas(canvas), fBitmap(bitmap), fMetaData(NULL) {
fOrigin.setZero();
// auto-allocate if we're for offscreen drawing
if (isForLayer) {
@@ -22,6 +23,19 @@ SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
}
}
+SkDevice::~SkDevice() {
+ delete fMetaData;
+}
+
+SkMetaData& SkDevice::getMetaData() {
+ // metadata users are rare, so we lazily allocate it. If that changes we
+ // can decide to just make it a field in the device (rather than a ptr)
+ if (NULL == fMetaData) {
+ fMetaData = new SkMetaData;
+ }
+ return *fMetaData;
+}
+
void SkDevice::lockPixels() {
fBitmap.lockPixels();
}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index ce0fa9b..14e5a80 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -679,6 +679,49 @@ static inline SkPoint* as_rightbottom(SkRect* r) {
return ((SkPoint*)(void*)r) + 1;
}
+static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
+ SkPoint* strokeSize) {
+ if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
+ paint.getStrokeMiter() < SK_ScalarSqrt2) {
+ return false;
+ }
+
+ SkASSERT(matrix.rectStaysRect());
+ SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
+ matrix.mapVectors(strokeSize, &pt, 1);
+ strokeSize->fX = SkScalarAbs(strokeSize->fX);
+ strokeSize->fY = SkScalarAbs(strokeSize->fY);
+ return true;
+}
+
+SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
+ const SkMatrix& matrix,
+ SkPoint* strokeSize) {
+ RectType rtype;
+ const SkScalar width = paint.getStrokeWidth();
+ const bool zeroWidth = (0 == width);
+ SkPaint::Style style = paint.getStyle();
+
+ if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
+ style = SkPaint::kFill_Style;
+ }
+
+ if (paint.getPathEffect() || paint.getMaskFilter() ||
+ paint.getRasterizer() || !matrix.rectStaysRect() ||
+ SkPaint::kStrokeAndFill_Style == style) {
+ rtype = kPath_RectType;
+ } else if (SkPaint::kFill_Style == style) {
+ rtype = kFill_RectType;
+ } else if (zeroWidth) {
+ rtype = kHair_RectType;
+ } else if (easy_rect_join(paint, matrix, strokeSize)) {
+ rtype = kStroke_RectType;
+ } else {
+ rtype = kPath_RectType;
+ }
+ return rtype;
+}
+
void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
SkDEBUGCODE(this->validate();)
@@ -688,11 +731,16 @@ void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
return;
}
- // complex enough to draw as a path
- if (paint.getPathEffect() || paint.getMaskFilter() ||
- paint.getRasterizer() || !fMatrix->rectStaysRect() ||
- (paint.getStyle() != SkPaint::kFill_Style &&
- SkScalarHalf(paint.getStrokeWidth()) > 0)) {
+ SkPoint strokeSize;
+ RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
+
+#ifdef SK_DISABLE_FAST_AA_STROKE_RECT
+ if (kStroke_RectType == rtype && paint.isAntiAlias()) {
+ rtype = kPath_RectType;
+ }
+#endif
+
+ if (kPath_RectType == rtype) {
SkPath tmp;
tmp.addRect(rect);
tmp.setFillType(SkPath::kWinding_FillType);
@@ -733,18 +781,30 @@ void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
// we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
// case we are also hairline (if we've gotten to here), which devolves to
// effectively just kFill
- if (paint.getStyle() != SkPaint::kStroke_Style) {
- if (paint.isAntiAlias()) {
- SkScan::AntiFillRect(devRect, clip, blitter);
- } else {
- SkScan::FillRect(devRect, clip, blitter);
- }
- } else {
- if (paint.isAntiAlias()) {
- SkScan::AntiHairRect(devRect, clip, blitter);
- } else {
- SkScan::HairRect(devRect, clip, blitter);
- }
+ switch (rtype) {
+ case kFill_RectType:
+ if (paint.isAntiAlias()) {
+ SkScan::AntiFillRect(devRect, clip, blitter);
+ } else {
+ SkScan::FillRect(devRect, clip, blitter);
+ }
+ break;
+ case kStroke_RectType:
+ if (paint.isAntiAlias()) {
+ SkScan::AntiFrameRect(devRect, strokeSize, clip, blitter);
+ } else {
+ SkScan::FrameRect(devRect, strokeSize, clip, blitter);
+ }
+ break;
+ case kHair_RectType:
+ if (paint.isAntiAlias()) {
+ SkScan::AntiHairRect(devRect, clip, blitter);
+ } else {
+ SkScan::HairRect(devRect, clip, blitter);
+ }
+ break;
+ default:
+ SkASSERT(!"bad rtype");
}
}
@@ -1568,7 +1628,7 @@ void SkDraw::drawText(const char text[], size_t byteLength,
// apply the bias here, so we don't have to add 1/2 in the loop
fx += SK_FixedHalf;
fy += SK_FixedHalf;
- fy &= finalFYMask;
+ fyMask &= finalFYMask;
SkAutoKern autokern;
SkDraw1Glyph d1g;
@@ -2364,8 +2424,8 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
}
}
-////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
@@ -2386,7 +2446,12 @@ void SkDraw::validate() const {
#endif
-//////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+SkBounder::SkBounder() {
+ // initialize up front. This gets reset by SkCanvas before each draw call.
+ fClip = &SkRegion::GetEmptyRegion();
+}
bool SkBounder::doIRect(const SkIRect& r) {
SkIRect rr;
diff --git a/src/core/SkFlate.cpp b/src/core/SkFlate.cpp
index ade1658..99b331e 100644
--- a/src/core/SkFlate.cpp
+++ b/src/core/SkFlate.cpp
@@ -24,19 +24,22 @@ bool SkFlate::Inflate(SkStream*, SkDynamicMemoryWStream*) { return false; }
#else
// static
-const size_t SkFlate::kBufferSize = 1024;
-
-// static
bool SkFlate::HaveFlate() {
+#ifdef SK_DEBUG
+ return false;
+#else
return true;
+#endif
}
namespace {
#include SK_ZLIB_INCLUDE
-bool doFlate(bool compress, const size_t kBufferSize, SkStream* src,
- SkDynamicMemoryWStream* dst) {
+// static
+const size_t kBufferSize = 1024;
+
+bool doFlate(bool compress, SkStream* src, SkDynamicMemoryWStream* dst) {
uint8_t inputBuffer[kBufferSize];
uint8_t outputBuffer[kBufferSize];
z_stream flateData;
@@ -117,12 +120,12 @@ bool doFlate(bool compress, const size_t kBufferSize, SkStream* src,
// static
bool SkFlate::Deflate(SkStream* src, SkDynamicMemoryWStream* dst) {
- return doFlate(true, kBufferSize, src, dst);
+ return doFlate(true, src, dst);
}
// static
bool SkFlate::Inflate(SkStream* src, SkDynamicMemoryWStream* dst) {
- return doFlate(false, kBufferSize, src, dst);
+ return doFlate(false, src, dst);
}
#endif
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 92e3795..adf0466 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -280,30 +280,27 @@ private:
class SkAutoGlyphCache {
public:
SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {}
- SkAutoGlyphCache(const SkDescriptor* desc)
- {
+ SkAutoGlyphCache(const SkDescriptor* desc) {
fCache = SkGlyphCache::DetachCache(desc);
}
- SkAutoGlyphCache(const SkPaint& paint, const SkMatrix* matrix)
- {
+ SkAutoGlyphCache(const SkPaint& paint, const SkMatrix* matrix) {
fCache = paint.detachCache(matrix);
}
- ~SkAutoGlyphCache()
- {
- if (fCache)
+ ~SkAutoGlyphCache() {
+ if (fCache) {
SkGlyphCache::AttachCache(fCache);
+ }
}
- SkGlyphCache* getCache() const { return fCache; }
+ SkGlyphCache* getCache() const { return fCache; }
- void release()
- {
- if (fCache)
- {
+ void release() {
+ if (fCache) {
SkGlyphCache::AttachCache(fCache);
fCache = NULL;
}
}
+
private:
SkGlyphCache* fCache;
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp
index 40f0ea3..8638504 100644
--- a/src/core/SkGraphics.cpp
+++ b/src/core/SkGraphics.cpp
@@ -37,48 +37,8 @@
#include "SkUtils.h"
#include "SkXfermode.h"
-#if 0
-
-#define SK_SORT_TEMPLATE_TYPE int
-#define SK_SORT_TEMPLATE_NAME sort_int
-#define SK_SORT_TEMPLATE_CMP(a, b) ((a) - (b))
-#include "SkSortTemplate.h"
-
-#define SK_SORT_TEMPLATE_TYPE int*
-#define SK_SORT_TEMPLATE_NAME sort_intptr
-#define SK_SORT_TEMPLATE_CMP(a, b) (*(a) - *(b))
-#include "SkSortTemplate.h"
-
-static void test_sort()
-{
- int array[] = { 4, 3, 7, 5, 2, 5, 1, 2, 9, 6, 7, 4, 5, 3, 1, 0 };
- int* ptr[SK_ARRAY_COUNT(array)];
- int i, N = SK_ARRAY_COUNT(array) - 1;
-
- for (i = 0; i < N; i++)
- printf(" %d", array[i]);
- printf("\n");
-
- for (i = 0; i < N; i++)
- ptr[i] = &array[i];
- sort_intptr(ptr, N);
- for (i = 0; i < N; i++)
- printf(" %d", *ptr[i]);
- printf("\n");
-
- sort_int(array, N);
- for (i = 0; i < N; i++)
- printf(" %d", array[i]);
- printf("\n");
-
-}
-#endif
-
-#define SPEED_TESTx
-
#define typesizeline(type) { #type , sizeof(type) }
-
#ifdef BUILD_EMBOSS_TABLE
extern void SkEmbossMask_BuildTable();
#endif
@@ -87,65 +47,6 @@ static void test_sort()
extern void SkRadialGradient_BuildTable();
#endif
-#define BIG_LOOP_COUNT 1000000
-#define TEXT_LOOP_COUNT 1000
-
-#ifdef SPEED_TEST
-static int test_s64(int i)
-{
- Sk64 a, b, c;
-
- c.set(0);
- a.set(i);
- b.setMul(i, i);
- a.add(b);
- a.add(c);
- return c.getFixed();
-}
-
-static int test_native_64(int i)
-{
- int16_t a, b, c;
-
- c = 0;
- a = i;
- b = (int64_t)i * i;
- a += b;
- a += c;
- return (int)(c >> 16);
-}
-
-static void test_drawText(SkBitmap::Config config, SkColor color)
-{
- SkBitmap bm;
-
- bm.setConfig(config, 320, 240);
- bm.allocPixels();
-
- SkCanvas canvas(bm);
- SkPaint paint;
-
- paint.setAntiAlias(true);
- paint.setTextSize(SkIntToScalar(12));
- paint.setColor(color);
-
- SkScalar x = SkIntToScalar(20);
- SkScalar y = SkIntToScalar(100);
- const char* text = "Hamburgefons";
- size_t len = strlen(text);
-
- // draw once to populate the cache
- canvas.drawText(text, len, x, y, paint);
-
- SkMSec now = SkTime::GetMSecs();
- for (int i = 0; i < TEXT_LOOP_COUNT; i++)
- canvas.drawText(text, len, x, y, paint);
- printf("----------- Config: %d, Color=%x, CPS = %g\n", config, color,
- len * TEXT_LOOP_COUNT * 1000.0 / (SkTime::GetMSecs() - now));
-}
-
-#endif
-
void SkGraphics::Init() {
SkGlobals::Init();
@@ -210,154 +111,9 @@ void SkGraphics::Init() {
}
#endif
-
- if (false) // test asm fixmul
- {
- int j;
- SkMSec now = SkTime::GetMSecs();
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkFixedMul_portable(0x8000, 0x150000);
- }
- SkMSec now2 = SkTime::GetMSecs();
- printf("-------- SkFixedMul_portable = %d\n", now2 - now);
-
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkFixedMul(0x8000, 0x150000);
- }
- printf("-------- SkFixedMul = %d\n", SkTime::GetMSecs() - now2);
-
- SkRandom rand;
- for (j = 0; j < 10000; j++) {
- SkFixed a = rand.nextS() >> 8;
- SkFixed b = rand.nextS() >> 8;
- SkFixed c1 = SkFixedMul_portable(a, b);
- SkFixed c2 = SkFixedMul(a, b);
- if (SkAbs32(c1 - c2) > 1)
- printf("------ FixMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2);
- }
- }
-
- if (false) // test asm fractmul
- {
- int j;
- SkMSec now = SkTime::GetMSecs();
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkFractMul_portable(0x800000, 0x1500000);
- }
- SkMSec now2 = SkTime::GetMSecs();
- printf("-------- SkFractMul_portable = %d\n", now2 - now);
-
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkFractMul(0x800000, 0x1500000);
- }
- printf("-------- SkFractMul = %d\n", SkTime::GetMSecs() - now2);
-
- SkRandom rand;
- for (j = 0; j < 10000; j++) {
- SkFixed a = rand.nextS() >> 1;
- SkFixed b = rand.nextS() >> 1;
- SkFixed c1 = SkFractMul_portable(a, b);
- SkFixed c2 = SkFractMul(a, b);
- if (SkAbs32(c1 - c2) > 1)
- printf("------ FractMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2);
- }
- }
-
- if (false) // test asm clz
- {
- int j;
- SkMSec now = SkTime::GetMSecs();
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkCLZ_portable(now);
- }
- SkMSec now2 = SkTime::GetMSecs();
- printf("-------- SkCLZ_portable = %d\n", now2 - now);
-
- for (j = 0; j < BIG_LOOP_COUNT; j++) {
- (void)SkCLZ(now);
- }
- printf("-------- SkCLZ = %d\n", SkTime::GetMSecs() - now2);
-
- SkRandom rand;
- for (j = 0; j < 10000; j++) {
- uint32_t a = rand.nextU();
- int c1 = SkCLZ_portable(a);
- int c2 = SkCLZ(a);
- if (c1 != c2)
- printf("------ CLZ disagreement: (%x) slow=%x fast=%x\n", a, c1, c2);
- }
- }
-
-#ifdef SPEED_TEST
- if (false) {
- int i;
- int (*proc)(int);
-
- static const struct {
- int (*proc)(int);
- const char* name;
- } gList[] = {
- { test_s64, "Sk64" },
- { test_native_64, "native" }
- };
-
- for (size_t j = 0; j < SK_ARRAY_COUNT(gList); j++) {
- SkMSec now = SkTime::GetMSecs();
- proc = gList[j].proc;
- for (i = 0; i < BIG_LOOP_COUNT; i++) {
- proc(i);
- }
- printf("-------- %s = %d\n", gList[j].name, SkTime::GetMSecs() - now);
- }
- }
-#endif
-
- if (false) {
- size_t i, size = 480;
- char* buffer = (char*)sk_malloc_throw(size);
- uint16_t* buffer16 = (uint16_t*)buffer;
- uint32_t* buffer32 = (uint32_t*)buffer;
-
- SkMSec now = SkTime::GetMSecs();
- for (i = 0; i < 100000; i++) {
- sk_memset16(buffer16, (uint16_t)i, size >> 1);
- }
- SkMSec now2 = SkTime::GetMSecs();
- for (i = 0; i < 100000; i++) {
- sk_memset16_portable(buffer16, (uint16_t)i, size >> 1);
- }
- SkMSec now3 = SkTime::GetMSecs();
- printf("----------- memset16: native %d, portable %d\n", now2 - now, now3 - now2);
-
- now = SkTime::GetMSecs();
- for (i = 0; i < 100000; i++) {
- sk_memset32(buffer32, i, size >> 2);
- }
- now2 = SkTime::GetMSecs();
- for (i = 0; i < 100000; i++) {
- sk_memset32_portable(buffer32, i, size >> 2);
- }
- now3 = SkTime::GetMSecs();
- printf("----------- memset32: native %d, portable %d\n", now2 - now, now3 - now2);
-
- sk_free(buffer);
- }
-
-#ifdef SPEED_TEST
- if (false) {
- test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorBLACK);
- test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorRED);
- test_drawText(SkBitmap::kRGB_565_Config, SK_ColorBLACK);
- test_drawText(SkBitmap::kRGB_565_Config, SK_ColorRED);
- }
-#endif
-
-// if (true) {
-// test_sort();
-// }
}
-////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#include "SkGlyphCache.h"
diff --git a/src/core/SkLineClipper.cpp b/src/core/SkLineClipper.cpp
index 057f546..ab49773 100644
--- a/src/core/SkLineClipper.cpp
+++ b/src/core/SkLineClipper.cpp
@@ -6,8 +6,19 @@ static SkScalar sect_with_horizontal(const SkPoint src[2], SkScalar Y) {
if (SkScalarNearlyZero(dy)) {
return SkScalarAve(src[0].fX, src[1].fX);
} else {
+#ifdef SK_SCALAR_IS_FLOAT
+ // need the extra precision so we don't compute a value that exceeds
+ // our original limits
+ double X0 = src[0].fX;
+ double Y0 = src[0].fY;
+ double X1 = src[1].fX;
+ double Y1 = src[1].fY;
+ double result = X0 + ((double)Y - Y0) * (X1 - X0) / (Y1 - Y0);
+ return (float)result;
+#else
return src[0].fX + SkScalarMulDiv(Y - src[0].fY, src[1].fX - src[0].fX,
dy);
+#endif
}
}
@@ -17,8 +28,19 @@ static SkScalar sect_with_vertical(const SkPoint src[2], SkScalar X) {
if (SkScalarNearlyZero(dx)) {
return SkScalarAve(src[0].fY, src[1].fY);
} else {
+#ifdef SK_SCALAR_IS_FLOAT
+ // need the extra precision so we don't compute a value that exceeds
+ // our original limits
+ double X0 = src[0].fX;
+ double Y0 = src[0].fY;
+ double X1 = src[1].fX;
+ double Y1 = src[1].fY;
+ double result = Y0 + ((double)X - X0) * (Y1 - Y0) / (X1 - X0);
+ return (float)result;
+#else
return src[0].fY + SkScalarMulDiv(X - src[0].fX, src[1].fY - src[0].fY,
dx);
+#endif
}
}
@@ -106,6 +128,19 @@ bool SkLineClipper::IntersectLine(const SkPoint src[2], const SkRect& clip,
return true;
}
+#ifdef SK_DEBUG
+// return value between the two limits, where the limits are either ascending
+// or descending.
+static bool is_between_unsorted(SkScalar value,
+ SkScalar limit0, SkScalar limit1) {
+ if (limit0 < limit1) {
+ return limit0 <= value && value <= limit1;
+ } else {
+ return limit1 <= value && value <= limit0;
+ }
+}
+#endif
+
int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
SkPoint lines[]) {
int index0, index1;
@@ -135,9 +170,11 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
// now compute intersections
if (pts[index0].fY < clip.fTop) {
tmp[index0].set(sect_with_horizontal(pts, clip.fTop), clip.fTop);
+ SkASSERT(is_between_unsorted(tmp[index0].fX, pts[0].fX, pts[1].fX));
}
if (tmp[index1].fY > clip.fBottom) {
tmp[index1].set(sect_with_horizontal(pts, clip.fBottom), clip.fBottom);
+ SkASSERT(is_between_unsorted(tmp[index1].fX, pts[0].fX, pts[1].fX));
}
// Chop it into 1..3 segments that are wholly within the clip in X.
@@ -173,14 +210,16 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
if (tmp[index0].fX < clip.fLeft) {
r->set(clip.fLeft, tmp[index0].fY);
r += 1;
- r->set(clip.fLeft, sect_with_vertical(pts, clip.fLeft));
+ r->set(clip.fLeft, sect_with_vertical(tmp, clip.fLeft));
+ SkASSERT(is_between_unsorted(r->fY, tmp[0].fY, tmp[1].fY));
} else {
*r = tmp[index0];
}
r += 1;
if (tmp[index1].fX > clip.fRight) {
- r->set(clip.fRight, sect_with_vertical(pts, clip.fRight));
+ r->set(clip.fRight, sect_with_vertical(tmp, clip.fRight));
+ SkASSERT(is_between_unsorted(r->fY, tmp[0].fY, tmp[1].fY));
r += 1;
r->set(clip.fRight, tmp[index1].fY);
} else {
diff --git a/src/core/SkMask.cpp b/src/core/SkMask.cpp
index 337204b..34f122b 100644
--- a/src/core/SkMask.cpp
+++ b/src/core/SkMask.cpp
@@ -45,16 +45,14 @@ size_t SkMask::computeTotalImageSize() const {
/** We explicitly use this allocator for SkBimap pixels, so that we can
freely assign memory allocated by one class to the other.
*/
-uint8_t* SkMask::AllocImage(size_t size)
-{
+uint8_t* SkMask::AllocImage(size_t size) {
return (uint8_t*)sk_malloc_throw(SkAlign4(size));
}
/** We explicitly use this allocator for SkBimap pixels, so that we can
freely assign memory allocated by one class to the other.
*/
-void SkMask::FreeImage(void* image)
-{
+void SkMask::FreeImage(void* image) {
sk_free(image);
}
diff --git a/src/core/SkMetaData.cpp b/src/core/SkMetaData.cpp
new file mode 100644
index 0000000..b1901dc
--- /dev/null
+++ b/src/core/SkMetaData.cpp
@@ -0,0 +1,345 @@
+/* libs/graphics/views/SkMetaData.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkMetaData.h"
+#include "SkRefCnt.h"
+
+struct PtrPair {
+ void* fPtr;
+ SkMetaData::PtrProc fProc;
+};
+
+void* SkMetaData::RefCntProc(void* ptr, bool doRef) {
+ SkASSERT(ptr);
+ SkRefCnt* refcnt = reinterpret_cast<SkRefCnt*>(ptr);
+
+ if (doRef) {
+ refcnt->ref();
+ } else {
+ refcnt->unref();
+ }
+ return ptr;
+}
+
+SkMetaData::SkMetaData() : fRec(NULL)
+{
+}
+
+SkMetaData::SkMetaData(const SkMetaData& src) : fRec(NULL)
+{
+ *this = src;
+}
+
+SkMetaData::~SkMetaData()
+{
+ this->reset();
+}
+
+void SkMetaData::reset()
+{
+ Rec* rec = fRec;
+ while (rec) {
+ if (kPtr_Type == rec->fType) {
+ PtrPair* pair = (PtrPair*)rec->data();
+ if (pair->fProc && pair->fPtr) {
+ pair->fPtr = pair->fProc(pair->fPtr, false);
+ }
+ }
+ Rec* next = rec->fNext;
+ Rec::Free(rec);
+ rec = next;
+ }
+ fRec = NULL;
+}
+
+SkMetaData& SkMetaData::operator=(const SkMetaData& src)
+{
+ this->reset();
+
+ const Rec* rec = src.fRec;
+ while (rec)
+ {
+ this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount);
+ rec = rec->fNext;
+ }
+ return *this;
+}
+
+void SkMetaData::setS32(const char name[], int32_t value)
+{
+ (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1);
+}
+
+void SkMetaData::setScalar(const char name[], SkScalar value)
+{
+ (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1);
+}
+
+SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[])
+{
+ SkASSERT(count > 0);
+ if (count > 0)
+ return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count);
+ return NULL;
+}
+
+void SkMetaData::setString(const char name[], const char value[])
+{
+ (void)this->set(name, value, sizeof(char), kString_Type, strlen(value) + 1);
+}
+
+void SkMetaData::setPtr(const char name[], void* ptr, PtrProc proc) {
+ PtrPair pair = { ptr, proc };
+ (void)this->set(name, &pair, sizeof(PtrPair), kPtr_Type, 1);
+}
+
+void SkMetaData::setBool(const char name[], bool value)
+{
+ (void)this->set(name, &value, sizeof(bool), kBool_Type, 1);
+}
+
+void SkMetaData::setData(const char name[], const void* data, size_t byteCount) {
+ (void)this->set(name, data, sizeof(char), kData_Type, byteCount);
+}
+
+void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count)
+{
+ SkASSERT(name);
+ SkASSERT(dataSize);
+ SkASSERT(count > 0);
+
+ (void)this->remove(name, type);
+
+ size_t len = strlen(name);
+ Rec* rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1);
+
+#ifndef SK_DEBUG
+ rec->fType = SkToU8(type);
+#else
+ rec->fType = type;
+#endif
+ rec->fDataLen = SkToU8(dataSize);
+ rec->fDataCount = SkToU16(count);
+ if (data)
+ memcpy(rec->data(), data, dataSize * count);
+ memcpy(rec->name(), name, len + 1);
+
+ if (kPtr_Type == type) {
+ PtrPair* pair = (PtrPair*)rec->data();
+ if (pair->fProc && pair->fPtr) {
+ pair->fPtr = pair->fProc(pair->fPtr, true);
+ }
+ }
+
+ rec->fNext = fRec;
+ fRec = rec;
+ return rec->data();
+}
+
+bool SkMetaData::findS32(const char name[], int32_t* value) const
+{
+ const Rec* rec = this->find(name, kS32_Type);
+ if (rec)
+ {
+ SkASSERT(rec->fDataCount == 1);
+ if (value)
+ *value = *(const int32_t*)rec->data();
+ return true;
+ }
+ return false;
+}
+
+bool SkMetaData::findScalar(const char name[], SkScalar* value) const
+{
+ const Rec* rec = this->find(name, kScalar_Type);
+ if (rec)
+ {
+ SkASSERT(rec->fDataCount == 1);
+ if (value)
+ *value = *(const SkScalar*)rec->data();
+ return true;
+ }
+ return false;
+}
+
+const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const
+{
+ const Rec* rec = this->find(name, kScalar_Type);
+ if (rec)
+ {
+ if (count)
+ *count = rec->fDataCount;
+ if (values)
+ memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen);
+ return (const SkScalar*)rec->data();
+ }
+ return NULL;
+}
+
+bool SkMetaData::findPtr(const char name[], void** ptr, PtrProc* proc) const {
+ const Rec* rec = this->find(name, kPtr_Type);
+ if (rec) {
+ SkASSERT(rec->fDataCount == 1);
+ const PtrPair* pair = (const PtrPair*)rec->data();
+ if (ptr) {
+ *ptr = pair->fPtr;
+ }
+ if (proc) {
+ *proc = pair->fProc;
+ }
+ return true;
+ }
+ return false;
+}
+
+const char* SkMetaData::findString(const char name[]) const
+{
+ const Rec* rec = this->find(name, kString_Type);
+ SkASSERT(rec == NULL || rec->fDataLen == sizeof(char));
+ return rec ? (const char*)rec->data() : NULL;
+}
+
+bool SkMetaData::findBool(const char name[], bool* value) const
+{
+ const Rec* rec = this->find(name, kBool_Type);
+ if (rec)
+ {
+ SkASSERT(rec->fDataCount == 1);
+ if (value)
+ *value = *(const bool*)rec->data();
+ return true;
+ }
+ return false;
+}
+
+const void* SkMetaData::findData(const char name[], size_t* length) const {
+ const Rec* rec = this->find(name, kData_Type);
+ if (rec) {
+ SkASSERT(rec->fDataLen == sizeof(char));
+ if (length) {
+ *length = rec->fDataCount;
+ }
+ return rec->data();
+ }
+ return NULL;
+}
+
+const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const
+{
+ const Rec* rec = fRec;
+ while (rec)
+ {
+ if (rec->fType == type && !strcmp(rec->name(), name))
+ return rec;
+ rec = rec->fNext;
+ }
+ return NULL;
+}
+
+bool SkMetaData::remove(const char name[], Type type) {
+ Rec* rec = fRec;
+ Rec* prev = NULL;
+ while (rec) {
+ Rec* next = rec->fNext;
+ if (rec->fType == type && !strcmp(rec->name(), name)) {
+ if (prev) {
+ prev->fNext = next;
+ } else {
+ fRec = next;
+ }
+
+ if (kPtr_Type == type) {
+ PtrPair* pair = (PtrPair*)rec->data();
+ if (pair->fProc && pair->fPtr) {
+ (void)pair->fProc(pair->fPtr, false);
+ }
+ }
+ Rec::Free(rec);
+ return true;
+ }
+ prev = rec;
+ rec = next;
+ }
+ return false;
+}
+
+bool SkMetaData::removeS32(const char name[])
+{
+ return this->remove(name, kS32_Type);
+}
+
+bool SkMetaData::removeScalar(const char name[])
+{
+ return this->remove(name, kScalar_Type);
+}
+
+bool SkMetaData::removeString(const char name[])
+{
+ return this->remove(name, kString_Type);
+}
+
+bool SkMetaData::removePtr(const char name[])
+{
+ return this->remove(name, kPtr_Type);
+}
+
+bool SkMetaData::removeBool(const char name[])
+{
+ return this->remove(name, kBool_Type);
+}
+
+bool SkMetaData::removeData(const char name[]) {
+ return this->remove(name, kData_Type);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkMetaData::Iter::Iter(const SkMetaData& metadata) {
+ fRec = metadata.fRec;
+}
+
+void SkMetaData::Iter::reset(const SkMetaData& metadata) {
+ fRec = metadata.fRec;
+}
+
+const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) {
+ const char* name = NULL;
+
+ if (fRec) {
+ if (t) {
+ *t = (SkMetaData::Type)fRec->fType;
+ }
+ if (count) {
+ *count = fRec->fDataCount;
+ }
+ name = fRec->name();
+
+ fRec = fRec->fNext;
+ }
+ return name;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) {
+ return (Rec*)sk_malloc_throw(size);
+}
+
+void SkMetaData::Rec::Free(Rec* rec) {
+ sk_free(rec);
+}
+
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 5c0f922..95b8ed3 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -35,6 +35,14 @@
#define SK_DefaultFlags 0 //(kNativeHintsText_Flag)
+#ifdef ANDROID
+#define GEN_ID_INC fGenerationID++
+#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; }
+#else
+#define GEN_ID_INC
+#define GEN_ID_INC_EVAL(expression)
+#endif
+
SkPaint::SkPaint() {
// since we may have padding, we zero everything so that our memcmp() call
// in operator== will work correctly.
@@ -65,7 +73,9 @@ SkPaint::SkPaint() {
fStyle = kFill_Style;
fTextEncoding = kUTF8_TextEncoding;
fHinting = kNormal_Hinting;
+#ifdef ANDROID
fGenerationID = 0;
+#endif
}
SkPaint::SkPaint(const SkPaint& src) {
@@ -113,9 +123,13 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
SkSafeUnref(fRasterizer);
SkSafeUnref(fLooper);
+#ifdef ANDROID
uint32_t oldGenerationID = fGenerationID;
+#endif
memcpy(this, &src, sizeof(src));
+#ifdef ANDROID
fGenerationID = oldGenerationID + 1;
+#endif
return *this;
}
@@ -127,293 +141,206 @@ int operator==(const SkPaint& a, const SkPaint& b) {
void SkPaint::reset() {
SkPaint init;
+#ifdef ANDROID
uint32_t oldGenerationID = fGenerationID;
+#endif
*this = init;
+#ifdef ANDROID
fGenerationID = oldGenerationID + 1;
+#endif
}
+#ifdef ANDROID
uint32_t SkPaint::getGenerationID() const {
return fGenerationID;
}
+#endif
-void SkPaint::setFlags(uint32_t flags)
-{
- if (fFlags != flags) {
- fFlags = flags;
- fGenerationID++;
- }
+void SkPaint::setHinting(Hinting hintingLevel) {
+ GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
+ fHinting = hintingLevel;
}
-void SkPaint::setAntiAlias(bool doAA)
-{
- if (doAA != isAntiAlias()) {
- this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
- fGenerationID++;
- }
+void SkPaint::setFlags(uint32_t flags) {
+ GEN_ID_INC_EVAL(fFlags != flags);
+ fFlags = flags;
}
-void SkPaint::setDither(bool doDither)
-{
- if (doDither != isDither()) {
- this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
- fGenerationID++;
- }
+void SkPaint::setAntiAlias(bool doAA) {
+ GEN_ID_INC_EVAL(doAA != isAntiAlias());
+ this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
}
-void SkPaint::setSubpixelText(bool doSubpixel)
-{
- if (doSubpixel != isSubpixelText()) {
- this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
- fGenerationID++;
- }
+void SkPaint::setDither(bool doDither) {
+ GEN_ID_INC_EVAL(doDither != isDither());
+ this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
}
-void SkPaint::setLCDRenderText(bool doLCDRender)
-{
- if (doLCDRender != isLCDRenderText()) {
- this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
- fGenerationID++;
- }
+void SkPaint::setSubpixelText(bool doSubpixel) {
+ GEN_ID_INC_EVAL(doSubpixel != isSubpixelText());
+ this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
}
-void SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText)
-{
- if (doEmbeddedBitmapText != isEmbeddedBitmapText()) {
- this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
- fGenerationID++;
- }
+void SkPaint::setLCDRenderText(bool doLCDRender) {
+ GEN_ID_INC_EVAL(doLCDRender != isLCDRenderText());
+ this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
+}
+
+void SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) {
+ GEN_ID_INC_EVAL(doEmbeddedBitmapText != isEmbeddedBitmapText());
+ this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
}
-void SkPaint::setAutohinted(bool useAutohinter)
-{
+void SkPaint::setAutohinted(bool useAutohinter) {
+ GEN_ID_INC_EVAL(useAutohinter != isAutohinted());
this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag));
}
-void SkPaint::setLinearText(bool doLinearText)
-{
- if (doLinearText != isLinearText()) {
- this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
- fGenerationID++;
- }
+void SkPaint::setLinearText(bool doLinearText) {
+ GEN_ID_INC_EVAL(doLinearText != isLinearText());
+ this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
}
-void SkPaint::setUnderlineText(bool doUnderline)
-{
- if (doUnderline != isUnderlineText()) {
- this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
- fGenerationID++;
- }
+void SkPaint::setUnderlineText(bool doUnderline) {
+ GEN_ID_INC_EVAL(doUnderline != isUnderlineText());
+ this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
}
-void SkPaint::setStrikeThruText(bool doStrikeThru)
-{
- if (doStrikeThru != isStrikeThruText()) {
- this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
- fGenerationID++;
- }
+void SkPaint::setStrikeThruText(bool doStrikeThru) {
+ GEN_ID_INC_EVAL(doStrikeThru != isStrikeThruText());
+ this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
}
-void SkPaint::setFakeBoldText(bool doFakeBold)
-{
- if (doFakeBold != isFakeBoldText()) {
- this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
- fGenerationID++;
- }
+void SkPaint::setFakeBoldText(bool doFakeBold) {
+ GEN_ID_INC_EVAL(doFakeBold != isFakeBoldText());
+ this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
}
-void SkPaint::setDevKernText(bool doDevKern)
-{
- if (doDevKern != isDevKernText()) {
- this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
- fGenerationID++;
- }
+void SkPaint::setDevKernText(bool doDevKern) {
+ GEN_ID_INC_EVAL(doDevKern != isDevKernText());
+ this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
}
-void SkPaint::setFilterBitmap(bool doFilter)
-{
- if (doFilter != isFilterBitmap()) {
- this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
- fGenerationID++;
- }
+void SkPaint::setFilterBitmap(bool doFilter) {
+ GEN_ID_INC_EVAL(doFilter != isFilterBitmap());
+ this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
}
-void SkPaint::setStyle(Style style)
-{
+void SkPaint::setStyle(Style style) {
if ((unsigned)style < kStyleCount) {
- if ((unsigned)style != fStyle) {
- fStyle = style;
- fGenerationID++;
- }
- }
-#ifdef SK_DEBUG
- else {
- SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
+ GEN_ID_INC_EVAL((unsigned)style != fStyle);
+ fStyle = style;
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setStyle(%d) out of range\n", style);)
}
-#endif
}
-void SkPaint::setColor(SkColor color)
-{
- if (color != fColor) {
- fColor = color;
- fGenerationID++;
- }
+void SkPaint::setColor(SkColor color) {
+ GEN_ID_INC_EVAL(color != fColor);
+ fColor = color;
}
-void SkPaint::setAlpha(U8CPU a)
-{
- U8CPU oldA = SkColorGetA(fColor);
- if (a != oldA) {
- fColor = SkColorSetARGB(a, SkColorGetR(fColor), SkColorGetG(fColor), SkColorGetB(fColor));
- fGenerationID++;
- }
+void SkPaint::setAlpha(U8CPU a) {
+ this->setColor(SkColorSetARGB(a, SkColorGetR(fColor),
+ SkColorGetG(fColor), SkColorGetB(fColor)));
}
-void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
-{
- SkColor oldColor = fColor;
- fColor = SkColorSetARGB(a, r, g, b);
- if (oldColor != fColor) {
- fGenerationID++;
- }
+void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
+ this->setColor(SkColorSetARGB(a, r, g, b));
}
-void SkPaint::setStrokeWidth(SkScalar width)
-{
+void SkPaint::setStrokeWidth(SkScalar width) {
if (width >= 0) {
- if (width != fWidth) {
- fWidth = width;
- fGenerationID++;
- }
- }
-#ifdef SK_DEBUG
- else {
- SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
+ GEN_ID_INC_EVAL(width != fWidth);
+ fWidth = width;
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");)
}
-#endif
}
-void SkPaint::setStrokeMiter(SkScalar limit)
-{
+void SkPaint::setStrokeMiter(SkScalar limit) {
if (limit >= 0) {
- if (limit != fMiterLimit) {
- fMiterLimit = limit;
- fGenerationID++;
- }
- }
-#ifdef SK_DEBUG
- else {
- SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
+ GEN_ID_INC_EVAL(limit != fMiterLimit);
+ fMiterLimit = limit;
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");)
}
-#endif
}
-void SkPaint::setStrokeCap(Cap ct)
-{
+void SkPaint::setStrokeCap(Cap ct) {
if ((unsigned)ct < kCapCount) {
- if ((unsigned)ct != fCapType) {
- fCapType = SkToU8(ct);
- fGenerationID++;
- }
+ GEN_ID_INC_EVAL((unsigned)ct != fCapType);
+ fCapType = SkToU8(ct);
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);)
}
-#ifdef SK_DEBUG
- else
- SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
-#endif
}
-void SkPaint::setStrokeJoin(Join jt)
-{
+void SkPaint::setStrokeJoin(Join jt) {
if ((unsigned)jt < kJoinCount) {
- if ((unsigned)jt != fJoinType) {
- fJoinType = SkToU8(jt);
- fGenerationID++;
- }
+ GEN_ID_INC_EVAL((unsigned)jt != fJoinType);
+ fJoinType = SkToU8(jt);
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);)
}
-#ifdef SK_DEBUG
- else
- SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
-#endif
}
-//////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-void SkPaint::setTextAlign(Align align)
-{
+void SkPaint::setTextAlign(Align align) {
if ((unsigned)align < kAlignCount) {
- if ((unsigned)align != fTextAlign) {
- fTextAlign = SkToU8(align);
- fGenerationID++;
- }
+ GEN_ID_INC_EVAL((unsigned)align != fTextAlign);
+ fTextAlign = SkToU8(align);
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);)
}
-#ifdef SK_DEBUG
- else
- SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
-#endif
}
-void SkPaint::setTextSize(SkScalar ts)
-{
+void SkPaint::setTextSize(SkScalar ts) {
if (ts > 0) {
- if (ts != fTextSize) {
- fTextSize = ts;
- fGenerationID++;
- }
+ GEN_ID_INC_EVAL(ts != fTextSize);
+ fTextSize = ts;
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setTextSize() called with negative value\n");)
}
-#ifdef SK_DEBUG
- else
- SkDebugf("SkPaint::setTextSize() called with negative value\n");
-#endif
}
-void SkPaint::setTextScaleX(SkScalar scaleX)
-{
- if (scaleX != fTextScaleX) {
- fTextScaleX = scaleX;
- fGenerationID++;
- }
+void SkPaint::setTextScaleX(SkScalar scaleX) {
+ GEN_ID_INC_EVAL(scaleX != fTextScaleX);
+ fTextScaleX = scaleX;
}
-void SkPaint::setTextSkewX(SkScalar skewX)
-{
- if (skewX != fTextSkewX) {
- fTextSkewX = skewX;
- fGenerationID++;
- }
+void SkPaint::setTextSkewX(SkScalar skewX) {
+ GEN_ID_INC_EVAL(skewX != fTextSkewX);
+ fTextSkewX = skewX;
}
-void SkPaint::setTextEncoding(TextEncoding encoding)
-{
+void SkPaint::setTextEncoding(TextEncoding encoding) {
if ((unsigned)encoding <= kGlyphID_TextEncoding) {
- if ((unsigned)encoding != fTextEncoding) {
- fTextEncoding = encoding;
- fGenerationID++;
- }
+ GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding);
+ fTextEncoding = encoding;
+ } else {
+ SkDEBUGCODE(SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);)
}
-#ifdef SK_DEBUG
- else
- SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
-#endif
}
-///////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-SkTypeface* SkPaint::setTypeface(SkTypeface* font)
-{
+SkTypeface* SkPaint::setTypeface(SkTypeface* font) {
SkRefCnt_SafeAssign(fTypeface, font);
- fGenerationID++;
+ GEN_ID_INC;
return font;
}
SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) {
SkRefCnt_SafeAssign(fRasterizer, r);
- fGenerationID++;
+ GEN_ID_INC;
return r;
}
SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) {
SkRefCnt_SafeAssign(fLooper, looper);
- fGenerationID++;
+ GEN_ID_INC;
return looper;
}
@@ -426,6 +353,7 @@ static void DetachDescProc(const SkDescriptor* desc, void* context) {
*((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
}
+#ifdef ANDROID
const SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) {
SkGlyphCache* cache;
descriptorProc(NULL, DetachDescProc, &cache, true);
@@ -446,6 +374,7 @@ const void* SkPaint::findImage(const SkGlyph& glyph) {
SkGlyphCache::AttachCache(cache);
return image;
}
+#endif
int SkPaint::textToGlyphs(const void* textData, size_t byteLength,
uint16_t glyphs[]) const {
@@ -1601,29 +1530,20 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
///////////////////////////////////////////////////////////////////////////////
-SkShader* SkPaint::setShader(SkShader* shader)
-{
- if (shader != fShader) {
- fGenerationID++;
- }
+SkShader* SkPaint::setShader(SkShader* shader) {
+ GEN_ID_INC_EVAL(shader != fShader);
SkRefCnt_SafeAssign(fShader, shader);
return shader;
}
-SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter)
-{
- if (filter != fColorFilter) {
- fGenerationID++;
- }
+SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
+ GEN_ID_INC_EVAL(filter != fColorFilter);
SkRefCnt_SafeAssign(fColorFilter, filter);
return filter;
}
-SkXfermode* SkPaint::setXfermode(SkXfermode* mode)
-{
- if (mode != fXfermode) {
- fGenerationID++;
- }
+SkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
+ GEN_ID_INC_EVAL(mode != fXfermode);
SkRefCnt_SafeAssign(fXfermode, mode);
return mode;
}
@@ -1631,24 +1551,18 @@ SkXfermode* SkPaint::setXfermode(SkXfermode* mode)
SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
SkSafeUnref(fXfermode);
fXfermode = SkXfermode::Create(mode);
- fGenerationID++;
+ GEN_ID_INC;
return fXfermode;
}
-SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect)
-{
- if (effect != fPathEffect) {
- fGenerationID++;
- }
+SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
+ GEN_ID_INC_EVAL(effect != fPathEffect);
SkRefCnt_SafeAssign(fPathEffect, effect);
return effect;
}
-SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter)
-{
- if (filter != fMaskFilter) {
- fGenerationID++;
- }
+SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
+ GEN_ID_INC_EVAL(filter != fMaskFilter);
SkRefCnt_SafeAssign(fMaskFilter, filter);
return filter;
}
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index a01d8e1..5ddc31d 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -96,15 +96,19 @@ static void compute_pt_bounds(SkRect* bounds, const SkTDArray<SkPoint>& pts) {
////////////////////////////////////////////////////////////////////////////
SkPath::SkPath() : fBoundsIsDirty(true), fFillType(kWinding_FillType) {
- fIsConvex = false;
+ fIsConvex = false; // really should be kUnknown
+#ifdef ANDROID
fGenerationID = 0;
+#endif
}
SkPath::SkPath(const SkPath& src) {
SkDEBUGCODE(src.validate();)
- uint32_t currentGenID = fGenerationID;
*this = src;
- fGenerationID = currentGenID;
+#ifdef ANDROID
+ // the assignment operator above increments the ID so correct for that here
+ fGenerationID--;
+#endif
}
SkPath::~SkPath() {
@@ -121,7 +125,7 @@ SkPath& SkPath::operator=(const SkPath& src) {
fFillType = src.fFillType;
fBoundsIsDirty = src.fBoundsIsDirty;
fIsConvex = src.fIsConvex;
- fGenerationID++;
+ GEN_ID_INC;
}
SkDEBUGCODE(this->validate();)
return *this;
@@ -144,20 +148,22 @@ void SkPath::swap(SkPath& other) {
SkTSwap<uint8_t>(fFillType, other.fFillType);
SkTSwap<uint8_t>(fBoundsIsDirty, other.fBoundsIsDirty);
SkTSwap<uint8_t>(fIsConvex, other.fIsConvex);
- fGenerationID++;
+ GEN_ID_INC;
}
}
+#ifdef ANDROID
uint32_t SkPath::getGenerationID() const {
return fGenerationID;
}
+#endif
void SkPath::reset() {
SkDEBUGCODE(this->validate();)
fPts.reset();
fVerbs.reset();
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
fIsConvex = false; // really should be kUnknown
}
@@ -167,7 +173,7 @@ void SkPath::rewind() {
fPts.rewind();
fVerbs.rewind();
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
fIsConvex = false; // really should be kUnknown
}
@@ -225,7 +231,7 @@ void SkPath::setLastPt(SkScalar x, SkScalar y) {
this->moveTo(x, y);
} else {
fPts[count - 1].set(x, y);
- fGenerationID++;
+ GEN_ID_INC;
}
}
@@ -263,7 +269,7 @@ void SkPath::moveTo(SkScalar x, SkScalar y) {
}
pt->set(x, y);
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
}
@@ -283,7 +289,7 @@ void SkPath::lineTo(SkScalar x, SkScalar y) {
fPts.append()->set(x, y);
*fVerbs.append() = kLine_Verb;
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
}
@@ -306,7 +312,7 @@ void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
pts[1].set(x2, y2);
*fVerbs.append() = kQuad_Verb;
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
}
@@ -330,7 +336,7 @@ void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
pts[2].set(x3, y3);
*fVerbs.append() = kCubic_Verb;
- fGenerationID++;
+ GEN_ID_INC;
fBoundsIsDirty = true;
}
@@ -352,7 +358,7 @@ void SkPath::close() {
case kQuad_Verb:
case kCubic_Verb:
*fVerbs.append() = kClose_Verb;
- fGenerationID++;
+ GEN_ID_INC;
break;
default:
// don't add a close if the prev wasn't a primitive
@@ -970,7 +976,7 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
matrix.mapRect(&dst->fBounds, fBounds);
dst->fBoundsIsDirty = false;
} else {
- dst->fGenerationID++;
+ GEN_ID_PTR_INC(dst);
dst->fBoundsIsDirty = true;
}
@@ -1277,8 +1283,8 @@ void SkPath::unflatten(SkFlattenableReadBuffer& buffer) {
fFillType = buffer.readS32();
buffer.read(fPts.begin(), sizeof(SkPoint) * fPts.count());
buffer.read(fVerbs.begin(), fVerbs.count());
-
- fGenerationID++;
+
+ GEN_ID_INC;
fBoundsIsDirty = true;
SkDEBUGCODE(this->validate();)
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 4a4c7f8..d17599d 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -528,7 +528,9 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
SkipClipRec skipRect, skipRegion, skipPath;
#endif
+#ifdef ANDROID
SkAutoMutexAcquire autoMutex(fDrawMutex);
+#endif
TextContainer text;
fReader.rewind();
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index f5bf038..350df78 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -12,7 +12,10 @@
#include "SkRegion.h"
#include "SkPictureFlat.h"
#include "SkShape.h"
+
+#ifdef ANDROID
#include "SkThread.h"
+#endif
class SkPictureRecord;
class SkStream;
@@ -173,7 +176,9 @@ private:
SkRefCntPlayback fRCPlayback;
SkTypefacePlayback fTFPlayback;
SkFactoryPlayback* fFactoryPlayback;
+#ifdef ANDROID
SkMutex fDrawMutex;
+#endif
};
#endif
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index f558f52..9b12226 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -79,6 +79,14 @@ void SkPixelRef::setImmutable() {
fIsImmutable = true;
}
+bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
+ return this->onReadPixels(dst, subset);
+}
+
+bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
#define MAX_PAIR_COUNT 16
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index 18dafb0..e08d2f8 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -85,36 +85,29 @@ bool SkRegion::ComputeRunBounds(const SkRegion::RunType runs[], int count, SkIRe
//////////////////////////////////////////////////////////////////////////
-SkRegion::SkRegion()
-{
+SkRegion::SkRegion() {
fBounds.set(0, 0, 0, 0);
fRunHead = SkRegion_gEmptyRunHeadPtr;
}
-SkRegion::SkRegion(const SkRegion& src)
-{
+SkRegion::SkRegion(const SkRegion& src) {
fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
this->setRegion(src);
}
-SkRegion::SkRegion(const SkIRect& rect)
-{
+SkRegion::SkRegion(const SkIRect& rect) {
fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
this->setRect(rect);
}
-SkRegion::~SkRegion()
-{
+SkRegion::~SkRegion() {
this->freeRuns();
}
-void SkRegion::freeRuns()
-{
- if (fRunHead->isComplex())
- {
+void SkRegion::freeRuns() {
+ if (fRunHead->isComplex()) {
SkASSERT(fRunHead->fRefCnt >= 1);
- if (sk_atomic_dec(&fRunHead->fRefCnt) == 1)
- {
+ if (sk_atomic_dec(&fRunHead->fRefCnt) == 1) {
//SkASSERT(gRgnAllocCounter > 0);
//SkDEBUGCODE(sk_atomic_dec(&gRgnAllocCounter));
//SkDEBUGF(("************** gRgnAllocCounter::free %d\n", gRgnAllocCounter));
@@ -123,76 +116,68 @@ void SkRegion::freeRuns()
}
}
-void SkRegion::allocateRuns(int count)
-{
+void SkRegion::allocateRuns(int count) {
fRunHead = RunHead::Alloc(count);
}
-SkRegion& SkRegion::operator=(const SkRegion& src)
-{
+SkRegion& SkRegion::operator=(const SkRegion& src) {
(void)this->setRegion(src);
return *this;
}
-void SkRegion::swap(SkRegion& other)
-{
+void SkRegion::swap(SkRegion& other) {
SkTSwap<SkIRect>(fBounds, other.fBounds);
SkTSwap<RunHead*>(fRunHead, other.fRunHead);
}
-bool SkRegion::setEmpty()
-{
+bool SkRegion::setEmpty() {
this->freeRuns();
fBounds.set(0, 0, 0, 0);
fRunHead = SkRegion_gEmptyRunHeadPtr;
return false;
}
-bool SkRegion::setRect(int32_t left, int32_t top, int32_t right, int32_t bottom)
-{
- if (left >= right || top >= bottom)
+bool SkRegion::setRect(int32_t left, int32_t top,
+ int32_t right, int32_t bottom) {
+ if (left >= right || top >= bottom) {
return this->setEmpty();
-
+ }
this->freeRuns();
fBounds.set(left, top, right, bottom);
fRunHead = SkRegion_gRectRunHeadPtr;
return true;
}
-bool SkRegion::setRect(const SkIRect& r)
-{
+bool SkRegion::setRect(const SkIRect& r) {
return this->setRect(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
-bool SkRegion::setRegion(const SkRegion& src)
-{
- if (this != &src)
- {
+bool SkRegion::setRegion(const SkRegion& src) {
+ if (this != &src) {
this->freeRuns();
fBounds = src.fBounds;
fRunHead = src.fRunHead;
- if (fRunHead->isComplex())
+ if (fRunHead->isComplex()) {
sk_atomic_inc(&fRunHead->fRefCnt);
+ }
}
return fRunHead != SkRegion_gEmptyRunHeadPtr;
}
-bool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op)
-{
+bool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op) {
SkRegion tmp(rect);
return this->op(tmp, rgn, op);
}
-bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op)
-{
+bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op) {
SkRegion tmp(rect);
return this->op(rgn, tmp, op);
}
-//////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#ifdef ANDROID
char* SkRegion::toString()
@@ -482,52 +467,48 @@ bool SkRegion::intersects(const SkRegion& rgn) const {
/////////////////////////////////////////////////////////////////////////////////////
-int operator==(const SkRegion& a, const SkRegion& b)
-{
+bool operator==(const SkRegion& a, const SkRegion& b) {
SkDEBUGCODE(a.validate();)
SkDEBUGCODE(b.validate();)
- if (&a == &b)
+ if (&a == &b) {
return true;
- if (a.fBounds != b.fBounds)
+ }
+ if (a.fBounds != b.fBounds) {
return false;
+ }
const SkRegion::RunHead* ah = a.fRunHead;
const SkRegion::RunHead* bh = b.fRunHead;
// this catches empties and rects being equal
- if (ah == bh)
+ if (ah == bh) {
return true;
-
+ }
// now we insist that both are complex (but different ptrs)
- if (!ah->isComplex() || !bh->isComplex())
+ if (!ah->isComplex() || !bh->isComplex()) {
return false;
-
+ }
return ah->fRunCount == bh->fRunCount &&
!memcmp(ah->readonly_runs(), bh->readonly_runs(),
ah->fRunCount * sizeof(SkRegion::RunType));
}
-void SkRegion::translate(int dx, int dy, SkRegion* dst) const
-{
+void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
SkDEBUGCODE(this->validate();)
- if (NULL == dst)
+ if (NULL == dst) {
return;
-
- if (this->isEmpty())
+ }
+ if (this->isEmpty()) {
dst->setEmpty();
- else if (this->isRect())
+ } else if (this->isRect()) {
dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy,
fBounds.fRight + dx, fBounds.fBottom + dy);
- else
- {
- if (this == dst)
- {
+ } else {
+ if (this == dst) {
dst->fRunHead = dst->fRunHead->ensureWritable();
- }
- else
- {
+ } else {
SkRegion tmp;
tmp.allocateRuns(fRunHead->fRunCount);
tmp.fBounds = fBounds;
@@ -540,17 +521,17 @@ void SkRegion::translate(int dx, int dy, SkRegion* dst) const
RunType* druns = dst->fRunHead->writable_runs();
*druns++ = (SkRegion::RunType)(*sruns++ + dy); // top
- for (;;)
- {
+ for (;;) {
int bottom = *sruns++;
- if (bottom == kRunTypeSentinel)
+ if (bottom == kRunTypeSentinel) {
break;
+ }
*druns++ = (SkRegion::RunType)(bottom + dy); // bottom;
- for (;;)
- {
+ for (;;) {
int x = *sruns++;
- if (x == kRunTypeSentinel)
+ if (x == kRunTypeSentinel) {
break;
+ }
*druns++ = (SkRegion::RunType)(x + dx);
*druns++ = (SkRegion::RunType)(*sruns++ + dx);
}
@@ -1086,7 +1067,14 @@ uint32_t SkRegion::unflatten(const void* storage) {
return buffer.pos();
}
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+const SkRegion& SkRegion::GetEmptyRegion() {
+ static SkRegion gEmpty;
+ return gEmpty;
+}
+
+///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index ff8e168..6b5f663 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -27,10 +27,6 @@
#include "SkStroke.h"
#include "SkThread.h"
-#ifdef SK_DEBUG
-// #define TRACK_MISSING_CHARS
-#endif
-
#define ComputeBWRowBytes(width) (((unsigned)(width) + 7) >> 3)
static const uint8_t* gBlackGammaTable;
@@ -49,14 +45,14 @@ size_t SkGlyph::computeImageSize() const {
const size_t size = this->rowBytes() * fHeight;
switch (fMaskFormat) {
- case SkMask::kHorizontalLCD_Format:
- return SkAlign4(size) + sizeof(uint32_t) * ((fWidth + 2) * fHeight);
- case SkMask::kVerticalLCD_Format:
- return SkAlign4(size) + sizeof(uint32_t) * (fWidth * (fHeight + 2));
- case SkMask::k3D_Format:
- return 3 * size;
- default:
- return size;
+ case SkMask::kHorizontalLCD_Format:
+ return SkAlign4(size) + sizeof(uint32_t) * ((fWidth + 2) * fHeight);
+ case SkMask::kVerticalLCD_Format:
+ return SkAlign4(size) + sizeof(uint32_t) * (fWidth * (fHeight + 2));
+ case SkMask::k3D_Format:
+ return 3 * size;
+ default:
+ return size;
}
}
@@ -154,14 +150,16 @@ SkScalerContext::SkScalerContext(const SkDescriptor* desc)
#ifdef DUMP_REC
desc->assertChecksum();
- SkDebugf("SkScalarContext checksum %x count %d length %d\n", desc->getChecksum(), desc->getCount(), desc->getLength());
+ SkDebugf("SkScalarContext checksum %x count %d length %d\n",
+ desc->getChecksum(), desc->getCount(), desc->getLength());
SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n",
rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0],
rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]);
SkDebugf(" frame %g miter %g hints %d framefill %d format %d join %d\n",
rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill,
rec->fMaskFormat, rec->fStrokeJoin);
- SkDebugf(" pathEffect %x maskFilter %x\n", desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
+ SkDebugf(" pathEffect %x maskFilter %x\n",
+ desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
desc->findEntry(kMaskFilter_SkDescriptorTag, NULL));
#endif
@@ -452,8 +450,9 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
draw.drawPath(devPath, paint);
}
- if (lcdMode)
+ if (lcdMode) {
glyph->expandA8ToLCD();
+ }
} else {
this->getGlyphContext(*glyph)->generateImage(*glyph);
}
@@ -501,28 +500,26 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
(fRec.fFlags & (kGammaForBlack_Flag | kGammaForWhite_Flag)) != 0)
{
const uint8_t* table = (fRec.fFlags & kGammaForBlack_Flag) ? gBlackGammaTable : gWhiteGammaTable;
- if (NULL != table)
- {
+ if (NULL != table) {
uint8_t* dst = (uint8_t*)origGlyph.fImage;
unsigned rowBytes = origGlyph.rowBytes();
- for (int y = origGlyph.fHeight - 1; y >= 0; --y)
- {
- for (int x = origGlyph.fWidth - 1; x >= 0; --x)
+ for (int y = origGlyph.fHeight - 1; y >= 0; --y) {
+ for (int x = origGlyph.fWidth - 1; x >= 0; --x) {
dst[x] = table[dst[x]];
+ }
dst += rowBytes;
}
}
}
}
-void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path)
-{
+void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
this->internalGetPath(glyph, NULL, path, NULL);
}
-void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my)
-{
+void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* mx,
+ SkPaint::FontMetrics* my) {
this->generateFontMetrics(mx, my);
}
@@ -530,16 +527,15 @@ SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
return 0;
}
-///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, SkPath* devPath, SkMatrix* fillToDevMatrix)
-{
+void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
+ SkPath* devPath, SkMatrix* fillToDevMatrix) {
SkPath path;
this->getGlyphContext(glyph)->generatePath(glyph, &path);
- if (fRec.fFrameWidth > 0 || fPathEffect != NULL)
- {
+ if (fRec.fFrameWidth > 0 || fPathEffect != NULL) {
// need the path in user-space, with only the point-size applied
// so that our stroking and effects will operate the same way they
// would if the user had extracted the path themself, and then
@@ -554,16 +550,15 @@ void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, Sk
SkScalar width = fRec.fFrameWidth;
- if (fPathEffect)
- {
+ if (fPathEffect) {
SkPath effectPath;
- if (fPathEffect->filterPath(&effectPath, localPath, &width))
+ if (fPathEffect->filterPath(&effectPath, localPath, &width)) {
localPath.swap(effectPath);
+ }
}
- if (width > 0)
- {
+ if (width > 0) {
SkStroke stroker;
SkPath outline;
@@ -576,41 +571,42 @@ void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, Sk
}
// now return stuff to the caller
- if (fillToDevMatrix)
+ if (fillToDevMatrix) {
*fillToDevMatrix = matrix;
-
- if (devPath)
+ }
+ if (devPath) {
localPath.transform(matrix, devPath);
-
- if (fillPath)
+ }
+ if (fillPath) {
fillPath->swap(localPath);
- }
- else // nothing tricky to do
- {
- if (fillToDevMatrix)
+ }
+ } else { // nothing tricky to do
+ if (fillToDevMatrix) {
fillToDevMatrix->reset();
-
- if (devPath)
- {
- if (fillPath == NULL)
+ }
+ if (devPath) {
+ if (fillPath == NULL) {
devPath->swap(path);
- else
+ } else {
*devPath = path;
+ }
}
- if (fillPath)
+ if (fillPath) {
fillPath->swap(path);
+ }
}
- if (devPath)
+ if (devPath) {
devPath->updateBoundsCache();
- if (fillPath)
+ }
+ if (fillPath) {
fillPath->updateBoundsCache();
+ }
}
-void SkScalerContext::Rec::getMatrixFrom2x2(SkMatrix* dst) const
-{
+void SkScalerContext::Rec::getMatrixFrom2x2(SkMatrix* dst) const {
dst->reset();
dst->setScaleX(fPost2x2[0][0]);
dst->setSkewX( fPost2x2[0][1]);
@@ -618,23 +614,20 @@ void SkScalerContext::Rec::getMatrixFrom2x2(SkMatrix* dst) const
dst->setScaleY(fPost2x2[1][1]);
}
-void SkScalerContext::Rec::getLocalMatrix(SkMatrix* m) const
-{
+void SkScalerContext::Rec::getLocalMatrix(SkMatrix* m) const {
m->setScale(SkScalarMul(fTextSize, fPreScaleX), fTextSize);
- if (fPreSkewX)
+ if (fPreSkewX) {
m->postSkew(fPreSkewX, 0);
+ }
}
-void SkScalerContext::Rec::getSingleMatrix(SkMatrix* m) const
-{
+void SkScalerContext::Rec::getSingleMatrix(SkMatrix* m) const {
this->getLocalMatrix(m);
// now concat the device matrix
- {
- SkMatrix deviceMatrix;
- this->getMatrixFrom2x2(&deviceMatrix);
- m->postConcat(deviceMatrix);
- }
+ SkMatrix deviceMatrix;
+ this->getMatrixFrom2x2(&deviceMatrix);
+ m->postConcat(deviceMatrix);
}
///////////////////////////////////////////////////////////////////////////////
@@ -673,8 +666,7 @@ protected:
extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
-SkScalerContext* SkScalerContext::Create(const SkDescriptor* desc)
-{
+SkScalerContext* SkScalerContext::Create(const SkDescriptor* desc) {
SkScalerContext* c = NULL; //SkCreateColorScalerContext(desc);
if (NULL == c) {
c = SkFontHost::CreateScalerContext(desc);
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index 90a1f68..5457b59 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -26,7 +26,10 @@
#define SCALE (1 << SHIFT)
#define MASK (SCALE - 1)
-///////////////////////////////////////////////////////////////////////////////////////////
+//#define FORCE_SUPERMASK
+//#define FORCE_RLE
+
+///////////////////////////////////////////////////////////////////////////////
class BaseSuperBlitter : public SkBlitter {
public:
@@ -99,12 +102,9 @@ SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
fRuns.reset(width);
}
-void SuperBlitter::flush()
-{
- if (fCurrIY >= 0)
- {
- if (!fRuns.empty())
- {
+void SuperBlitter::flush() {
+ if (fCurrIY >= 0) {
+ if (!fRuns.empty()) {
// SkDEBUGCODE(fRuns.dump();)
fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
fRuns.reset(fWidth);
@@ -114,8 +114,7 @@ void SuperBlitter::flush()
}
}
-static inline int coverage_to_alpha(int aa)
-{
+static inline int coverage_to_alpha(int aa) {
aa <<= 8 - 2*SHIFT;
aa -= aa >> (8 - SHIFT - 1);
return aa;
@@ -123,15 +122,13 @@ static inline int coverage_to_alpha(int aa)
#define SUPER_Mask ((1 << SHIFT) - 1)
-void SuperBlitter::blitH(int x, int y, int width)
-{
+void SuperBlitter::blitH(int x, int y, int width) {
int iy = y >> SHIFT;
SkASSERT(iy >= fCurrIY);
x -= fSuperLeft;
// hack, until I figure out why my cubics (I think) go beyond the bounds
- if (x < 0)
- {
+ if (x < 0) {
width += x;
x = 0;
}
@@ -142,8 +139,7 @@ void SuperBlitter::blitH(int x, int y, int width)
fCurrY = y;
#endif
- if (iy != fCurrIY) // new scanline
- {
+ if (iy != fCurrIY) { // new scanline
this->flush();
fCurrIY = iy;
}
@@ -155,7 +151,8 @@ void SuperBlitter::blitH(int x, int y, int width)
#if 0
SkAntiRun<SHIFT> arun;
arun.set(x, x + width);
- fRuns.add(x >> SHIFT, arun.getStartAlpha(), arun.getMiddleCount(), arun.getStopAlpha(), maxValue);
+ fRuns.add(x >> SHIFT, arun.getStartAlpha(), arun.getMiddleCount(),
+ arun.getStopAlpha(), maxValue);
#else
{
int start = x;
@@ -166,18 +163,16 @@ void SuperBlitter::blitH(int x, int y, int width)
int fe = stop & SUPER_Mask;
int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
- if (n < 0)
- {
+ if (n < 0) {
fb = fe - fb;
n = 0;
fe = 0;
- }
- else
- {
- if (fb == 0)
+ } else {
+ if (fb == 0) {
n += 1;
- else
+ } else {
fb = (1 << SHIFT) - fb;
+ }
}
fRuns.add(x >> SHIFT, coverage_to_alpha(fb), n, coverage_to_alpha(fe),
(1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
@@ -190,8 +185,7 @@ void SuperBlitter::blitH(int x, int y, int width)
#endif
}
-void SuperBlitter::blitRect(int x, int y, int width, int height)
-{
+void SuperBlitter::blitRect(int x, int y, int width, int height) {
for (int i = 0; i < height; ++i) {
blitH(x, y + i, width);
}
@@ -211,8 +205,10 @@ public:
virtual void blitH(int x, int y, int width);
- static bool CanHandleRect(const SkIRect& bounds)
- {
+ static bool CanHandleRect(const SkIRect& bounds) {
+#ifdef FORCE_RLE
+ return false;
+#endif
int width = bounds.width();
int rb = SkAlign4(width);
@@ -222,8 +218,13 @@ public:
private:
enum {
+#ifdef FORCE_SUPERMASK
+ kMAX_WIDTH = 2048,
+ kMAX_STORAGE = 1024 * 1024 * 2
+#else
kMAX_WIDTH = 32, // so we don't try to do very wide things, where the RLE blitter would be faster
kMAX_STORAGE = 1024
+#endif
};
SkMask fMask;
@@ -251,8 +252,7 @@ MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
}
-static void add_aa_span(uint8_t* alpha, U8CPU startAlpha)
-{
+static void add_aa_span(uint8_t* alpha, U8CPU startAlpha) {
/* I should be able to just add alpha[x] + startAlpha.
However, if the trailing edge of the previous span and the leading
edge of the current span round to the same super-sampled x value,
@@ -263,8 +263,16 @@ static void add_aa_span(uint8_t* alpha, U8CPU startAlpha)
*alpha = SkToU8(tmp - (tmp >> 8));
}
-static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue)
-{
+static inline uint32_t quadplicate_byte(U8CPU value) {
+ uint32_t pair = (value << 8) | value;
+ return (pair << 16) | pair;
+}
+
+// minimum count before we want to setup an inner loop, adding 4-at-a-time
+#define MIN_COUNT_FOR_QUAD_LOOP 16
+
+static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount,
+ U8CPU stopAlpha, U8CPU maxValue) {
SkASSERT(middleCount >= 0);
/* I should be able to just add alpha[x] + startAlpha.
@@ -276,8 +284,27 @@ static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount, U8CPU
SkASSERT(tmp <= 256);
*alpha++ = SkToU8(tmp - (tmp >> 8));
- while (--middleCount >= 0)
- {
+ if (middleCount >= MIN_COUNT_FOR_QUAD_LOOP) {
+ // loop until we're quad-byte aligned
+ while (SkTCast<intptr_t>(alpha) & 0x3) {
+ alpha[0] = SkToU8(alpha[0] + maxValue);
+ alpha += 1;
+ middleCount -= 1;
+ }
+
+ int bigCount = middleCount >> 2;
+ uint32_t* qptr = reinterpret_cast<uint32_t*>(alpha);
+ uint32_t qval = quadplicate_byte(maxValue);
+ do {
+ *qptr++ += qval;
+ } while (--bigCount > 0);
+
+ middleCount &= 3;
+ alpha = reinterpret_cast<uint8_t*> (qptr);
+ // fall through to the following while-loop
+ }
+
+ while (--middleCount >= 0) {
alpha[0] = SkToU8(alpha[0] + maxValue);
alpha += 1;
}
@@ -289,8 +316,7 @@ static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount, U8CPU
*alpha = SkToU8(*alpha + stopAlpha);
}
-void MaskSuperBlitter::blitH(int x, int y, int width)
-{
+void MaskSuperBlitter::blitH(int x, int y, int width) {
int iy = (y >> SHIFT);
SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
@@ -313,8 +339,7 @@ void MaskSuperBlitter::blitH(int x, int y, int width)
x -= (fMask.fBounds.fLeft << SHIFT);
// hack, until I figure out why my cubics (I think) go beyond the bounds
- if (x < 0)
- {
+ if (x < 0) {
width += x;
x = 0;
}
@@ -334,14 +359,11 @@ void MaskSuperBlitter::blitH(int x, int y, int width)
int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
- if (n < 0)
- {
+ if (n < 0) {
SkASSERT(row >= fMask.fImage);
SkASSERT(row < fMask.fImage + kMAX_STORAGE + 1);
add_aa_span(row, coverage_to_alpha(fe - fb));
- }
- else
- {
+ } else {
fb = (1 << SHIFT) - fb;
SkASSERT(row >= fMask.fImage);
SkASSERT(row + n + 1 < fMask.fImage + kMAX_STORAGE + 1);
@@ -407,8 +429,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
SkIRect superRect, *superClipRect = NULL;
- if (clipRect)
- {
+ if (clipRect) {
superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT,
clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT);
superClipRect = &superRect;
@@ -418,14 +439,11 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
// MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
// if we're an inverse filltype
- if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir))
- {
+ if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir)) {
MaskSuperBlitter superBlit(blitter, ir, clip);
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
- }
- else
- {
+ } else {
SuperBlitter superBlit(blitter, ir, clip);
sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
}
diff --git a/src/core/SkScan_Antihair.cpp b/src/core/SkScan_Antihair.cpp
index 0003298..99bd2c8 100644
--- a/src/core/SkScan_Antihair.cpp
+++ b/src/core/SkScan_Antihair.cpp
@@ -1,6 +1,6 @@
/* libs/graphics/sgl/SkScan_Antihair.cpp
**
-** Copyright 2006, The Android Open Source Project
+** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -51,14 +51,11 @@ static inline int SmallDot6Scale(int value, int dot6) {
static uint8_t gGammaTable[256];
#define ApplyGamma(table, alpha) (table)[alpha]
- static void build_gamma_table()
- {
+ static void build_gamma_table() {
static bool gInit = false;
- if (gInit == false)
- {
- for (int i = 0; i < 256; i++)
- {
+ if (gInit == false) {
+ for (int i = 0; i < 256; i++) {
SkFixed n = i * 257;
n += n >> 15;
SkASSERT(n >= 0 && n <= SK_Fixed1);
@@ -76,8 +73,8 @@ static inline int SmallDot6Scale(int value, int dot6) {
///////////////////////////////////////////////////////////////////////////////
-static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count, U8CPU alpha)
-{
+static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count,
+ U8CPU alpha) {
SkASSERT(count > 0);
int16_t runs[HLINE_STACK_BUFFER + 1];
@@ -86,9 +83,9 @@ static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count, U8CP
aa[0] = ApplyGamma(gGammaTable, alpha);
do {
int n = count;
- if (n > HLINE_STACK_BUFFER)
+ if (n > HLINE_STACK_BUFFER) {
n = HLINE_STACK_BUFFER;
-
+ }
runs[0] = SkToS16(n);
runs[n] = 0;
blitter->blitAntiH(x, y, aa, runs);
@@ -97,8 +94,8 @@ static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count, U8CP
} while (count > 0);
}
-static SkFixed hline(int x, int stopx, SkFixed fy, SkFixed /*slope*/, SkBlitter* blitter, int mod64)
-{
+static SkFixed hline(int x, int stopx, SkFixed fy, SkFixed /*slope*/,
+ SkBlitter* blitter, int mod64) {
SkASSERT(x < stopx);
int count = stopx - x;
fy += SK_Fixed1/2;
@@ -121,8 +118,8 @@ static SkFixed hline(int x, int stopx, SkFixed fy, SkFixed /*slope*/, SkBlitter*
return fy - SK_Fixed1/2;
}
-static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter* blitter, int mod64)
-{
+static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy,
+ SkBlitter* blitter, int mod64) {
SkASSERT(x < stopx);
#ifdef TEST_GAMMA
@@ -139,8 +136,7 @@ static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter* blitt
int lower_y = fy >> 16;
uint8_t a = (uint8_t)(fy >> 8);
unsigned ma = SmallDot6Scale(a, mod64);
- if (ma)
- {
+ if (ma) {
aa[0] = ApplyGamma(gamma, ma);
blitter->blitAntiH(x, lower_y, aa, runs);
// the clipping blitters might edit runs, but should not affect us
@@ -148,8 +144,7 @@ static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter* blitt
SkASSERT(runs[1] == 0);
}
ma = SmallDot6Scale(255 - a, mod64);
- if (ma)
- {
+ if (ma) {
aa[0] = ApplyGamma(gamma, ma);
blitter->blitAntiH(x, lower_y - 1, aa, runs);
// the clipping blitters might edit runs, but should not affect us
@@ -162,8 +157,8 @@ static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter* blitt
return fy - SK_Fixed1/2;
}
-static SkFixed vline(int y, int stopy, SkFixed fx, SkFixed /*slope*/, SkBlitter* blitter, int mod64)
-{
+static SkFixed vline(int y, int stopy, SkFixed fx, SkFixed /*slope*/,
+ SkBlitter* blitter, int mod64) {
SkASSERT(y < stopy);
fx += SK_Fixed1/2;
@@ -171,17 +166,19 @@ static SkFixed vline(int y, int stopy, SkFixed fx, SkFixed /*slope*/, SkBlitter*
int a = (uint8_t)(fx >> 8);
unsigned ma = SmallDot6Scale(a, mod64);
- if (ma)
+ if (ma) {
blitter->blitV(x, y, stopy - y, ApplyGamma(gGammaTable, ma));
+ }
ma = SmallDot6Scale(255 - a, mod64);
- if (ma)
+ if (ma) {
blitter->blitV(x - 1, y, stopy - y, ApplyGamma(gGammaTable, ma));
+ }
return fx - SK_Fixed1/2;
}
-static SkFixed vertish(int y, int stopy, SkFixed fx, SkFixed dx, SkBlitter* blitter, int mod64)
-{
+static SkFixed vertish(int y, int stopy, SkFixed fx, SkFixed dx,
+ SkBlitter* blitter, int mod64) {
SkASSERT(y < stopy);
#ifdef TEST_GAMMA
const uint8_t* gamma = gGammaTable;
@@ -211,23 +208,21 @@ static SkFixed vertish(int y, int stopy, SkFixed fx, SkFixed dx, SkBlitter* blit
return fx - SK_Fixed1/2;
}
-typedef SkFixed (*LineProc)(int istart, int istop, SkFixed fstart, SkFixed slope, SkBlitter*, int);
+typedef SkFixed (*LineProc)(int istart, int istop, SkFixed fstart,
+ SkFixed slope, SkBlitter*, int);
-static inline SkFixed fastfixdiv(SkFDot6 a, SkFDot6 b)
-{
+static inline SkFixed fastfixdiv(SkFDot6 a, SkFDot6 b) {
SkASSERT((a << 16 >> 16) == a);
SkASSERT(b != 0);
return (a << 16) / b;
}
static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
- const SkIRect* clip, SkBlitter* blitter)
-{
+ const SkIRect* clip, SkBlitter* blitter) {
// check that we're no larger than 511 pixels (so we can do a faster div).
// if we are, subdivide and call again
- if (SkAbs32(x1 - x0) > SkIntToFDot6(511) || SkAbs32(y1 - y0) > SkIntToFDot6(511))
- {
+ if (SkAbs32(x1 - x0) > SkIntToFDot6(511) || SkAbs32(y1 - y0) > SkIntToFDot6(511)) {
/* instead of (x0 + x1) >> 1, we shift each separately. This is less
precise, but avoids overflowing the intermediate result if the
values are huge. A better fix might be to clip the original pts
@@ -246,8 +241,7 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
SkFixed fstart, slope;
LineProc proc;
- if (SkAbs32(x1 - x0) > SkAbs32(y1 - y0)) // mostly horizontal
- {
+ if (SkAbs32(x1 - x0) > SkAbs32(y1 - y0)) { // mostly horizontal
if (x0 > x1) { // we want to go left-to-right
SkTSwap<SkFDot6>(x0, x1);
SkTSwap<SkFDot6>(y0, y1);
@@ -276,12 +270,11 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
scaleStop = x1 & 63;
}
- if (clip)
- {
- if (istart >= clip->fRight || istop <= clip->fLeft)
+ if (clip){
+ if (istart >= clip->fRight || istop <= clip->fLeft) {
return;
- if (istart < clip->fLeft)
- {
+ }
+ if (istart < clip->fLeft) {
fstart += slope * (clip->fLeft - istart);
istart = clip->fLeft;
scaleStart = 64;
@@ -291,18 +284,15 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
scaleStop = 64;
}
SkASSERT(istart <= istop);
- if (istart == istop)
+ if (istart == istop) {
return;
-
+ }
// now test if our Y values are completely inside the clip
int top, bottom;
- if (slope >= 0) // T2B
- {
+ if (slope >= 0) { // T2B
top = SkFixedFloor(fstart - SK_FixedHalf);
bottom = SkFixedCeil(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
- }
- else // B2T
- {
+ } else { // B2T
bottom = SkFixedCeil(fstart + SK_FixedHalf);
top = SkFixedFloor(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
}
@@ -310,16 +300,15 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
top -= 1;
bottom += 1;
#endif
- if (top >= clip->fBottom || bottom <= clip->fTop)
+ if (top >= clip->fBottom || bottom <= clip->fTop) {
return;
- if (clip->fTop <= top && clip->fBottom >= bottom)
+ }
+ if (clip->fTop <= top && clip->fBottom >= bottom) {
clip = NULL;
+ }
}
- }
- else // mostly vertical
- {
- if (y0 > y1) // we want to go top-to-bottom
- {
+ } else { // mostly vertical
+ if (y0 > y1) { // we want to go top-to-bottom
SkTSwap<SkFDot6>(x0, x1);
SkTSwap<SkFDot6>(y0, y1);
}
@@ -327,16 +316,13 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
istart = SkFDot6Floor(y0);
istop = SkFDot6Ceil(y1);
fstart = SkFDot6ToFixed(x0);
- if (x0 == x1)
- {
+ if (x0 == x1) {
if (y0 == y1) { // are we zero length?
return; // nothing to do
}
slope = 0;
proc = vline;
- }
- else
- {
+ } else {
slope = fastfixdiv(x1 - x0, y1 - y0);
SkASSERT(slope <= SK_Fixed1 && slope >= -SK_Fixed1);
fstart += (slope * (32 - (y0 & 63)) + 32) >> 6;
@@ -353,12 +339,11 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
scaleStop = y1 & 63;
}
- if (clip)
- {
- if (istart >= clip->fBottom || istop <= clip->fTop)
+ if (clip) {
+ if (istart >= clip->fBottom || istop <= clip->fTop) {
return;
- if (istart < clip->fTop)
- {
+ }
+ if (istart < clip->fTop) {
fstart += slope * (clip->fTop - istart);
istart = clip->fTop;
scaleStart = 64;
@@ -373,13 +358,10 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
// now test if our X values are completely inside the clip
int left, right;
- if (slope >= 0) // L2R
- {
+ if (slope >= 0) { // L2R
left = SkFixedFloor(fstart - SK_FixedHalf);
right = SkFixedCeil(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
- }
- else // R2L
- {
+ } else { // R2L
right = SkFixedCeil(fstart + SK_FixedHalf);
left = SkFixedFloor(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
}
@@ -387,16 +369,17 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
left -= 1;
right += 1;
#endif
- if (left >= clip->fRight || right <= clip->fLeft)
+ if (left >= clip->fRight || right <= clip->fLeft) {
return;
- if (clip->fLeft <= left && clip->fRight >= right)
+ }
+ if (clip->fLeft <= left && clip->fRight >= right) {
clip = NULL;
+ }
}
}
SkRectClipBlitter rectClipper;
- if (clip)
- {
+ if (clip) {
rectClipper.init(blitter, *clip);
blitter = &rectClipper;
}
@@ -413,10 +396,10 @@ static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
}
void SkScan::AntiHairLine(const SkPoint& pt0, const SkPoint& pt1,
- const SkRegion* clip, SkBlitter* blitter)
-{
- if (clip && clip->isEmpty())
+ const SkRegion* clip, SkBlitter* blitter) {
+ if (clip && clip->isEmpty()) {
return;
+ }
SkASSERT(clip == NULL || !clip->getBounds().isEmpty());
@@ -480,8 +463,8 @@ void SkScan::AntiHairLine(const SkPoint& pt0, const SkPoint& pt1,
do_anti_hairline(x0, y0, x1, y1, NULL, blitter);
}
-void SkScan::AntiHairRect(const SkRect& rect, const SkRegion* clip, SkBlitter* blitter)
-{
+void SkScan::AntiHairRect(const SkRect& rect, const SkRegion* clip,
+ SkBlitter* blitter) {
SkPoint p0, p1;
p0.set(rect.fLeft, rect.fTop);
@@ -495,7 +478,7 @@ void SkScan::AntiHairRect(const SkRect& rect, const SkRegion* clip, SkBlitter* b
SkScan::AntiHairLine(p0, p1, clip, blitter);
}
-//////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
typedef int FDot8; // 24.8 integer fixed point
@@ -503,77 +486,76 @@ static inline FDot8 SkFixedToFDot8(SkFixed x) {
return (x + 0x80) >> 8;
}
-static void do_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha, SkBlitter* blitter)
-{
+static void do_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha,
+ SkBlitter* blitter) {
SkASSERT(L < R);
- if ((L >> 8) == ((R - 1) >> 8)) // 1x1 pixel
- {
+ if ((L >> 8) == ((R - 1) >> 8)) { // 1x1 pixel
blitter->blitV(L >> 8, top, 1, SkAlphaMul(alpha, R - L));
return;
}
int left = L >> 8;
- if (L & 0xFF)
- {
+ if (L & 0xFF) {
blitter->blitV(left, top, 1, SkAlphaMul(alpha, 256 - (L & 0xFF)));
left += 1;
}
int rite = R >> 8;
int width = rite - left;
- if (width > 0)
+ if (width > 0) {
call_hline_blitter(blitter, left, top, width, alpha);
-
- if (R & 0xFF)
+ }
+ if (R & 0xFF) {
blitter->blitV(rite, top, 1, SkAlphaMul(alpha, R & 0xFF));
+ }
}
-static void antifillrect(const SkXRect& xr, SkBlitter* blitter)
-{
- FDot8 L = SkFixedToFDot8(xr.fLeft);
- FDot8 T = SkFixedToFDot8(xr.fTop);
- FDot8 R = SkFixedToFDot8(xr.fRight);
- FDot8 B = SkFixedToFDot8(xr.fBottom);
-
+static void antifilldot8(FDot8 L, FDot8 T, FDot8 R, FDot8 B, SkBlitter* blitter,
+ bool fillInner) {
// check for empty now that we're in our reduced precision space
- if (L >= R || T >= B)
+ if (L >= R || T >= B) {
return;
-
+ }
int top = T >> 8;
- if (top == ((B - 1) >> 8)) // just one scanline high
- {
+ if (top == ((B - 1) >> 8)) { // just one scanline high
do_scanline(L, top, R, B - T - 1, blitter);
return;
}
- if (T & 0xFF)
- {
+ if (T & 0xFF) {
do_scanline(L, top, R, 256 - (T & 0xFF), blitter);
top += 1;
}
int bot = B >> 8;
int height = bot - top;
- if (height > 0)
- {
+ if (height > 0) {
int left = L >> 8;
- if (L & 0xFF)
- {
+ if (L & 0xFF) {
blitter->blitV(left, top, height, 256 - (L & 0xFF));
left += 1;
}
int rite = R >> 8;
int width = rite - left;
- if (width > 0)
+ if (width > 0 && fillInner) {
blitter->blitRect(left, top, width, height);
- if (R & 0xFF)
+ }
+ if (R & 0xFF) {
blitter->blitV(rite, top, height, R & 0xFF);
+ }
}
- if (B & 0xFF)
+ if (B & 0xFF) {
do_scanline(L, bot, R, B & 0xFF, blitter);
+ }
+}
+
+static void antifillrect(const SkXRect& xr, SkBlitter* blitter) {
+ antifilldot8(SkFixedToFDot8(xr.fLeft), SkFixedToFDot8(xr.fTop),
+ SkFixedToFDot8(xr.fRight), SkFixedToFDot8(xr.fBottom),
+ blitter, true);
}
///////////////////////////////////////////////////////////////////////////////
@@ -667,6 +649,165 @@ void SkScan::AntiFillRect(const SkRect& origR, const SkRegion* clip,
}
}
+///////////////////////////////////////////////////////////////////////////////
+
+#define SkAlphaMulRound(a, b) SkMulDiv255Round(a, b)
+
+// calls blitRect() if the rectangle is non-empty
+static void fillcheckrect(int L, int T, int R, int B, SkBlitter* blitter) {
+ if (L < R && T < B) {
+ blitter->blitRect(L, T, R - L, B - T);
+ }
+}
+
+static inline FDot8 SkScalarToFDot8(SkScalar x) {
+#ifdef SK_SCALAR_IS_FLOAT
+ return (int)(x * 256);
+#else
+ return x >> 8;
+#endif
+}
+
+static inline int FDot8Floor(FDot8 x) {
+ return x >> 8;
+}
+
+static inline int FDot8Ceil(FDot8 x) {
+ return (x + 0xFF) >> 8;
+}
+
+// 1 - (1 - a)*(1 - b)
+static inline U8CPU InvAlphaMul(U8CPU a, U8CPU b) {
+ // need precise rounding (not just SkAlphaMul) so that values like
+ // a=228, b=252 don't overflow the result
+ return SkToU8(a + b - SkAlphaMulRound(a, b));
+}
+
+static void inner_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha,
+ SkBlitter* blitter) {
+ SkASSERT(L < R);
+
+ if ((L >> 8) == ((R - 1) >> 8)) { // 1x1 pixel
+ blitter->blitV(L >> 8, top, 1, InvAlphaMul(alpha, R - L));
+ return;
+ }
+
+ int left = L >> 8;
+ if (L & 0xFF) {
+ blitter->blitV(left, top, 1, InvAlphaMul(alpha, L & 0xFF));
+ left += 1;
+ }
+
+ int rite = R >> 8;
+ int width = rite - left;
+ if (width > 0) {
+ call_hline_blitter(blitter, left, top, width, alpha);
+ }
+
+ if (R & 0xFF) {
+ blitter->blitV(rite, top, 1, InvAlphaMul(alpha, ~R & 0xFF));
+ }
+}
+
+static void innerstrokedot8(FDot8 L, FDot8 T, FDot8 R, FDot8 B,
+ SkBlitter* blitter) {
+ SkASSERT(L < R && T < B);
+
+ int top = T >> 8;
+ if (top == ((B - 1) >> 8)) { // just one scanline high
+ inner_scanline(L, top, R, B - T, blitter);
+ return;
+ }
+
+ if (T & 0xFF) {
+ inner_scanline(L, top, R, T & 0xFF, blitter);
+ top += 1;
+ }
+
+ int bot = B >> 8;
+ int height = bot - top;
+ if (height > 0) {
+ if (L & 0xFF) {
+ blitter->blitV(L >> 8, top, height, L & 0xFF);
+ }
+ if (R & 0xFF) {
+ blitter->blitV(R >> 8, top, height, ~R & 0xFF);
+ }
+ }
+
+ if (B & 0xFF) {
+ inner_scanline(L, bot, R, ~B & 0xFF, blitter);
+ }
+}
+
+void SkScan::AntiFrameRect(const SkRect& r, const SkPoint& strokeSize,
+ const SkRegion* clip, SkBlitter* blitter) {
+ SkASSERT(strokeSize.fX >= 0 && strokeSize.fY >= 0);
+
+ SkScalar rx = SkScalarHalf(strokeSize.fX);
+ SkScalar ry = SkScalarHalf(strokeSize.fY);
+
+ // outset by the radius
+ FDot8 L = SkScalarToFDot8(r.fLeft - rx);
+ FDot8 T = SkScalarToFDot8(r.fTop - ry);
+ FDot8 R = SkScalarToFDot8(r.fRight + rx);
+ FDot8 B = SkScalarToFDot8(r.fBottom + ry);
+
+ SkIRect outer;
+ // set outer to the outer rect of the outer section
+ outer.set(FDot8Floor(L), FDot8Floor(T), FDot8Ceil(R), FDot8Ceil(B));
+
+ SkBlitterClipper clipper;
+ if (clip) {
+ if (clip->quickReject(outer)) {
+ return;
+ }
+ if (!clip->contains(outer)) {
+ blitter = clipper.apply(blitter, clip, &outer);
+ }
+ // now we can ignore clip for the rest of the function
+ }
+
+ // stroke the outer hull
+ antifilldot8(L, T, R, B, blitter, false);
+
+ // set outer to the outer rect of the middle section
+ outer.set(FDot8Ceil(L), FDot8Ceil(T), FDot8Floor(R), FDot8Floor(B));
+
+ // in case we lost a bit with diameter/2
+ rx = strokeSize.fX - rx;
+ ry = strokeSize.fY - ry;
+ // inset by the radius
+ L = SkScalarToFDot8(r.fLeft + rx);
+ T = SkScalarToFDot8(r.fTop + ry);
+ R = SkScalarToFDot8(r.fRight - rx);
+ B = SkScalarToFDot8(r.fBottom - ry);
+
+ if (L >= R || T >= B) {
+ fillcheckrect(outer.fLeft, outer.fTop, outer.fRight, outer.fBottom,
+ blitter);
+ } else {
+ SkIRect inner;
+ // set inner to the inner rect of the middle section
+ inner.set(FDot8Floor(L), FDot8Floor(T), FDot8Ceil(R), FDot8Ceil(B));
+
+ // draw the frame in 4 pieces
+ fillcheckrect(outer.fLeft, outer.fTop, outer.fRight, inner.fTop,
+ blitter);
+ fillcheckrect(outer.fLeft, inner.fTop, inner.fLeft, inner.fBottom,
+ blitter);
+ fillcheckrect(inner.fRight, inner.fTop, outer.fRight, inner.fBottom,
+ blitter);
+ fillcheckrect(outer.fLeft, inner.fBottom, outer.fRight, outer.fBottom,
+ blitter);
+
+ // now stroke the inner rect, which is similar to antifilldot8() except that
+ // it treats the fractional coordinates with the inverse bias (since its
+ // inner).
+ innerstrokedot8(L, T, R, B, blitter);
+ }
+}
+
#endif
diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp
index 0dee814..ac2c19c 100644
--- a/src/core/SkScan_Hairline.cpp
+++ b/src/core/SkScan_Hairline.cpp
@@ -76,8 +76,8 @@ void SkScan::HairLine(const SkPoint& pt0, const SkPoint& pt1, const SkRegion* cl
// outset the right and bottom, to account for how hairlines are
// actually drawn, which may hit the pixel to the right or below of
// the coordinate
- ptsR.fRight += SK_FDot61;
- ptsR.fBottom += SK_FDot61;
+ ptsR.fRight += SK_FDot6One;
+ ptsR.fBottom += SK_FDot6One;
if (!SkIRect::Intersects(ptsR, clipR)) {
return;
@@ -317,36 +317,39 @@ void SkScan::AntiHairPath(const SkPath& path, const SkRegion* clip, SkBlitter* b
hair_path(path, clip, blitter, SkScan::AntiHairLine);
}
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-void SkScan::FrameRect(const SkRect& r, SkScalar diameter, const SkRegion* clip, SkBlitter* blitter)
-{
- SkASSERT(diameter > 0);
+void SkScan::FrameRect(const SkRect& r, const SkPoint& strokeSize,
+ const SkRegion* clip, SkBlitter* blitter) {
+ SkASSERT(strokeSize.fX >= 0 && strokeSize.fY >= 0);
- if (r.isEmpty())
+ if (strokeSize.fX < 0 || strokeSize.fY < 0) {
return;
+ }
- SkScalar radius = diameter / 2;
+ const SkScalar dx = strokeSize.fX;
+ const SkScalar dy = strokeSize.fY;
+ SkScalar rx = SkScalarHalf(dx);
+ SkScalar ry = SkScalarHalf(dy);
SkRect outer, tmp;
- outer.set( r.fLeft - radius, r.fTop - radius,
- r.fRight + radius, r.fBottom + radius);
+ outer.set(r.fLeft - rx, r.fTop - ry,
+ r.fRight + rx, r.fBottom + ry);
- if (r.width() <= diameter || r.height() <= diameter)
- {
+ if (r.width() <= dx || r.height() <= dx) {
SkScan::FillRect(outer, clip, blitter);
return;
}
- tmp.set(outer.fLeft, outer.fTop, outer.fRight, outer.fTop + diameter);
+ tmp.set(outer.fLeft, outer.fTop, outer.fRight, outer.fTop + dy);
SkScan::FillRect(tmp, clip, blitter);
- tmp.fTop = outer.fBottom - diameter;
+ tmp.fTop = outer.fBottom - dy;
tmp.fBottom = outer.fBottom;
SkScan::FillRect(tmp, clip, blitter);
- tmp.set(outer.fLeft, outer.fTop + diameter, outer.fLeft + diameter, outer.fBottom - diameter);
+ tmp.set(outer.fLeft, outer.fTop + dy, outer.fLeft + dx, outer.fBottom - dy);
SkScan::FillRect(tmp, clip, blitter);
- tmp.fLeft = outer.fRight - diameter;
+ tmp.fLeft = outer.fRight - dx;
tmp.fRight = outer.fRight;
SkScan::FillRect(tmp, clip, blitter);
}
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index c5088a1..af5d4b1 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -30,12 +30,10 @@
#define kEDGE_TAIL_Y SK_MaxS32
#ifdef SK_DEBUG
- static void validate_sort(const SkEdge* edge)
- {
+ static void validate_sort(const SkEdge* edge) {
int y = kEDGE_HEAD_Y;
- while (edge->fFirstY != SK_MaxS32)
- {
+ while (edge->fFirstY != SK_MaxS32) {
edge->validate();
SkASSERT(y <= edge->fFirstY);
@@ -47,14 +45,12 @@
#define validate_sort(edge)
#endif
-static inline void remove_edge(SkEdge* edge)
-{
+static inline void remove_edge(SkEdge* edge) {
edge->fPrev->fNext = edge->fNext;
edge->fNext->fPrev = edge->fPrev;
}
-static inline void swap_edges(SkEdge* prev, SkEdge* next)
-{
+static inline void swap_edges(SkEdge* prev, SkEdge* next) {
SkASSERT(prev->fNext == next && next->fPrev == prev);
// remove prev from the list
@@ -68,31 +64,27 @@ static inline void swap_edges(SkEdge* prev, SkEdge* next)
prev->fPrev = next;
}
-static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, curr_y))
-{
+static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, curr_y)) {
SkFixed x = edge->fX;
- for (;;)
- {
+ for (;;) {
SkEdge* prev = edge->fPrev;
// add 1 to curr_y since we may have added new edges (built from curves)
// that start on the next scanline
SkASSERT(prev && prev->fFirstY <= curr_y + 1);
- if (prev->fX <= x)
+ if (prev->fX <= x) {
break;
-
+ }
swap_edges(prev, edge);
}
}
-static void insert_new_edges(SkEdge* newEdge, int curr_y)
-{
+static void insert_new_edges(SkEdge* newEdge, int curr_y) {
SkASSERT(newEdge->fFirstY >= curr_y);
- while (newEdge->fFirstY == curr_y)
- {
+ while (newEdge->fFirstY == curr_y) {
SkEdge* next = newEdge->fNext;
backward_insert_edge_based_on_x(newEdge SkPARAM(curr_y));
newEdge = next;
@@ -100,10 +92,8 @@ static void insert_new_edges(SkEdge* newEdge, int curr_y)
}
#ifdef SK_DEBUG
-static void validate_edges_for_y(const SkEdge* edge, int curr_y)
-{
- while (edge->fFirstY <= curr_y)
- {
+static void validate_edges_for_y(const SkEdge* edge, int curr_y) {
+ while (edge->fFirstY <= curr_y) {
SkASSERT(edge->fPrev && edge->fNext);
SkASSERT(edge->fPrev->fNext == edge);
SkASSERT(edge->fNext->fPrev == edge);
@@ -128,16 +118,14 @@ typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline);
static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
SkBlitter* blitter, int start_y, int stop_y,
- PrePostProc proc)
-{
+ PrePostProc proc) {
validate_sort(prevHead->fNext);
int curr_y = start_y;
// returns 1 for evenodd, -1 for winding, regardless of inverse-ness
int windingMask = (fillType & 1) ? 1 : -1;
- for (;;)
- {
+ for (;;) {
int w = 0;
int left SK_INIT_TO_AVOID_WARNING;
bool in_interval = false;
@@ -150,23 +138,19 @@ static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
proc(blitter, curr_y, PREPOST_START); // pre-proc
}
- while (currE->fFirstY <= curr_y)
- {
+ while (currE->fFirstY <= curr_y) {
SkASSERT(currE->fLastY >= curr_y);
int x = (currE->fX + SK_Fixed1/2) >> 16;
w += currE->fWinding;
- if ((w & windingMask) == 0) // we finished an interval
- {
+ if ((w & windingMask) == 0) { // we finished an interval
SkASSERT(in_interval);
int width = x - left;
SkASSERT(width >= 0);
if (width)
blitter->blitH(left, curr_y, width);
in_interval = false;
- }
- else if (!in_interval)
- {
+ } else if (!in_interval) {
left = x;
in_interval = true;
}
@@ -174,38 +158,31 @@ static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
SkEdge* next = currE->fNext;
SkFixed newX;
- if (currE->fLastY == curr_y) // are we done with this edge?
- {
- if (currE->fCurveCount < 0)
- {
- if (((SkCubicEdge*)currE)->updateCubic())
- {
+ if (currE->fLastY == curr_y) { // are we done with this edge?
+ if (currE->fCurveCount < 0) {
+ if (((SkCubicEdge*)currE)->updateCubic()) {
SkASSERT(currE->fFirstY == curr_y + 1);
newX = currE->fX;
goto NEXT_X;
}
- }
- else if (currE->fCurveCount > 0)
- {
- if (((SkQuadraticEdge*)currE)->updateQuadratic())
- {
+ } else if (currE->fCurveCount > 0) {
+ if (((SkQuadraticEdge*)currE)->updateQuadratic()) {
newX = currE->fX;
goto NEXT_X;
}
}
remove_edge(currE);
- }
- else
- {
+ } else {
SkASSERT(currE->fLastY > curr_y);
newX = currE->fX + currE->fDX;
currE->fX = newX;
NEXT_X:
- if (newX < prevX) // ripple currE backwards until it is x-sorted
+ if (newX < prevX) { // ripple currE backwards until it is x-sorted
backward_insert_edge_based_on_x(currE SkPARAM(curr_y));
- else
+ } else {
prevX = newX;
+ }
}
currE = next;
SkASSERT(currE);
@@ -216,9 +193,9 @@ static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
}
curr_y += 1;
- if (curr_y >= stop_y)
+ if (curr_y >= stop_y) {
break;
-
+ }
// now currE points to the first edge with a Yint larger than curr_y
insert_new_edges(currE, curr_y);
}
@@ -291,19 +268,6 @@ static void PrePostInverseBlitterProc(SkBlitter* blitter, int y, bool isStart) {
#pragma warning ( pop )
#endif
-/* Our line edge relies on the maximum span being <= 512, so that it can
- use FDot6 and keep the dx,dy in 16bits (for much faster slope divide).
- This function returns true if the specified line is too big.
-*/
-static inline bool line_too_big(const SkPoint pts[2])
-{
- SkScalar dx = pts[1].fX - pts[0].fX;
- SkScalar dy = pts[1].fY - pts[0].fY;
-
- return SkScalarAbs(dx) > SkIntToScalar(511) ||
- SkScalarAbs(dy) > SkIntToScalar(511);
-}
-
#ifdef USE_NEW_BUILDER
#include "SkEdgeBuilder.h"
#else
@@ -379,31 +343,29 @@ static int build_edges(SkEdge edge[], const SkPath& path,
/* 'quick' computation of the max sized needed to allocated for
our edgelist.
*/
-static int worst_case_edge_count(const SkPath& path, size_t* storage)
-{
+static int worst_case_edge_count(const SkPath& path, size_t* storage) {
size_t size = 0;
int edgeCount = 0;
SkPath::Iter iter(path, true);
SkPath::Verb verb;
- while ((verb = iter.next(NULL)) != SkPath::kDone_Verb)
- {
+ while ((verb = iter.next(NULL)) != SkPath::kDone_Verb) {
switch (verb) {
- case SkPath::kLine_Verb:
- edgeCount += 1;
- size += sizeof(SkQuadraticEdge); // treat line like Quad (in case its > 512)
- break;
- case SkPath::kQuad_Verb:
- edgeCount += 2; // might need 2 edges when we chop on Y extrema
- size += 2 * sizeof(SkQuadraticEdge);
- break;
- case SkPath::kCubic_Verb:
- edgeCount += 3; // might need 3 edges when we chop on Y extrema
- size += 3 * sizeof(SkCubicEdge);
- break;
- default:
- break;
+ case SkPath::kLine_Verb:
+ edgeCount += 1;
+ size += sizeof(SkQuadraticEdge); // treat line like Quad (in case its > 512)
+ break;
+ case SkPath::kQuad_Verb:
+ edgeCount += 2; // might need 2 edges when we chop on Y extrema
+ size += 2 * sizeof(SkQuadraticEdge);
+ break;
+ case SkPath::kCubic_Verb:
+ edgeCount += 3; // might need 3 edges when we chop on Y extrema
+ size += 3 * sizeof(SkCubicEdge);
+ break;
+ default:
+ break;
}
}
@@ -477,8 +439,8 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
// clipRect (if no null) has already been shifted up
//
void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitter,
- int start_y, int stop_y, int shiftEdgesUp, const SkRegion& clipRgn)
-{
+ int start_y, int stop_y, int shiftEdgesUp,
+ const SkRegion& clipRgn) {
SkASSERT(&path && blitter);
#ifdef USE_NEW_BUILDER
@@ -583,35 +545,30 @@ void sk_blit_below(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip)
}
}
-/////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-SkScanClipper::SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& ir)
-{
+SkScanClipper::SkScanClipper(SkBlitter* blitter, const SkRegion* clip,
+ const SkIRect& ir) {
fBlitter = NULL; // null means blit nothing
fClipRect = NULL;
- if (clip)
- {
+ if (clip) {
fClipRect = &clip->getBounds();
- if (!SkIRect::Intersects(*fClipRect, ir)) // completely clipped out
+ if (!SkIRect::Intersects(*fClipRect, ir)) { // completely clipped out
return;
+ }
- if (clip->isRect())
- {
- if (fClipRect->contains(ir))
+ if (clip->isRect()) {
+ if (fClipRect->contains(ir)) {
fClipRect = NULL;
- else
- {
+ } else {
// only need a wrapper blitter if we're horizontally clipped
- if (fClipRect->fLeft > ir.fLeft || fClipRect->fRight < ir.fRight)
- {
+ if (fClipRect->fLeft > ir.fLeft || fClipRect->fRight < ir.fRight) {
fRectBlitter.init(blitter, *fClipRect);
blitter = &fRectBlitter;
}
}
- }
- else
- {
+ } else {
fRgnBlitter.init(blitter, clip);
blitter = &fRgnBlitter;
}
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index b8f99c7..49182ea 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -42,15 +42,13 @@ static const size_t kBufferSize = 256;
///////////////////////////////////////////////////////////////////////////////
-bool SkStrStartsWith(const char string[], const char prefix[])
-{
+bool SkStrStartsWith(const char string[], const char prefix[]) {
SkASSERT(string);
SkASSERT(prefix);
return !strncmp(string, prefix, strlen(prefix));
}
-bool SkStrEndsWith(const char string[], const char suffix[])
-{
+bool SkStrEndsWith(const char string[], const char suffix[]) {
SkASSERT(string);
SkASSERT(suffix);
size_t strLen = strlen(string);
@@ -59,50 +57,50 @@ bool SkStrEndsWith(const char string[], const char suffix[])
!strncmp(string + strLen - suffixLen, suffix, suffixLen);
}
-int SkStrStartsWithOneOf(const char string[], const char prefixes[])
-{
+int SkStrStartsWithOneOf(const char string[], const char prefixes[]) {
int index = 0;
do {
const char* limit = strchr(prefixes, '\0');
- if (!strncmp(string, prefixes, limit - prefixes))
+ if (!strncmp(string, prefixes, limit - prefixes)) {
return index;
+ }
prefixes = limit + 1;
index++;
} while (prefixes[0]);
return -1;
}
-char* SkStrAppendS32(char string[], int32_t dec)
-{
+char* SkStrAppendS32(char string[], int32_t dec) {
SkDEBUGCODE(char* start = string;)
char buffer[SkStrAppendS32_MaxSize];
char* p = buffer + sizeof(buffer);
bool neg = false;
- if (dec < 0)
- {
+ if (dec < 0) {
neg = true;
dec = -dec;
}
+
do {
*--p = SkToU8('0' + dec % 10);
dec /= 10;
} while (dec != 0);
- if (neg)
+
+ if (neg) {
*--p = '-';
+ }
SkASSERT(p >= buffer);
char* stop = buffer + sizeof(buffer);
- while (p < stop)
+ while (p < stop) {
*string++ = *p++;
-
+ }
SkASSERT(string - start <= SkStrAppendS32_MaxSize);
return string;
}
-char* SkStrAppendS64(char string[], int64_t dec, int minDigits)
-{
+char* SkStrAppendS64(char string[], int64_t dec, int minDigits) {
SkDEBUGCODE(char* start = string;)
char buffer[SkStrAppendS64_MaxSize];
@@ -113,18 +111,21 @@ char* SkStrAppendS64(char string[], int64_t dec, int minDigits)
neg = true;
dec = -dec;
}
+
do {
*--p = SkToU8('0' + dec % 10);
dec /= 10;
minDigits--;
} while (dec != 0);
+
while (minDigits > 0) {
*--p = '0';
minDigits--;
}
- if (neg)
- *--p = '-';
+ if (neg) {
+ *--p = '-';
+ }
SkASSERT(p >= buffer);
size_t cp_len = buffer + sizeof(buffer) - p;
memcpy(string, p, cp_len);
@@ -135,8 +136,7 @@ char* SkStrAppendS64(char string[], int64_t dec, int minDigits)
}
#ifdef SK_CAN_USE_FLOAT
-char* SkStrAppendFloat(char string[], float value)
-{
+char* SkStrAppendFloat(char string[], float value) {
// since floats have at most 8 significant digits, we limit our %g to that.
static const char gFormat[] = "%.8g";
// make it 1 larger for the terminating 0
@@ -148,27 +148,24 @@ char* SkStrAppendFloat(char string[], float value)
}
#endif
-char* SkStrAppendFixed(char string[], SkFixed x)
-{
+char* SkStrAppendFixed(char string[], SkFixed x) {
SkDEBUGCODE(char* start = string;)
- if (x < 0)
- {
+ if (x < 0) {
*string++ = '-';
x = -x;
}
unsigned frac = x & 0xFFFF;
x >>= 16;
- if (frac == 0xFFFF) // need to do this to "round up", since 65535/65536 is closer to 1 than to .9999
- {
+ if (frac == 0xFFFF) {
+ // need to do this to "round up", since 65535/65536 is closer to 1 than to .9999
x += 1;
frac = 0;
}
string = SkStrAppendS32(string, x);
// now handle the fractional part (if any)
- if (frac)
- {
+ if (frac) {
static const uint16_t gTens[] = { 1000, 100, 10, 1 };
const uint16_t* tens = gTens;
@@ -189,7 +186,7 @@ char* SkStrAppendFixed(char string[], SkFixed x)
return string;
}
-////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#define kMaxRefCnt_SkString SK_MaxU16
@@ -198,47 +195,43 @@ const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 };
#define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec)
-SkString::Rec* SkString::AllocRec(const char text[], U16CPU len)
-{
+SkString::Rec* SkString::AllocRec(const char text[], U16CPU len) {
Rec* rec;
- if (len == 0)
+ if (len == 0) {
rec = const_cast<Rec*>(&gEmptyRec);
- else
- {
+ } else {
// add 1 for terminating 0, then align4 so we can have some slop when growing the string
rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1));
rec->fLength = SkToU16(len);
rec->fRefCnt = 1;
- if (text)
+ if (text) {
memcpy(rec->data(), text, len);
+ }
rec->data()[len] = 0;
}
return rec;
}
-SkString::Rec* SkString::RefRec(Rec* src)
-{
- if (src != &gEmptyRec)
- {
+SkString::Rec* SkString::RefRec(Rec* src) {
+ if (src != &gEmptyRec) {
if (src->fRefCnt == kMaxRefCnt_SkString) {
src = AllocRec(src->data(), src->fLength);
- } else
+ } else {
src->fRefCnt += 1;
+ }
}
return src;
}
#ifdef SK_DEBUG
-void SkString::validate() const
-{
+void SkString::validate() const {
// make sure know one has written over our global
SkASSERT(gEmptyRec.fLength == 0);
SkASSERT(gEmptyRec.fRefCnt == 0);
SkASSERT(gEmptyRec.data()[0] == 0);
- if (fRec != &gEmptyRec)
- {
+ if (fRec != &gEmptyRec) {
SkASSERT(fRec->fLength > 0);
SkASSERT(fRec->fRefCnt > 0);
SkASSERT(fRec->data()[fRec->fLength] == 0);
@@ -247,7 +240,7 @@ void SkString::validate() const
}
#endif
-///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) {
#ifdef SK_DEBUG
@@ -255,8 +248,7 @@ SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) {
#endif
}
-SkString::SkString(size_t len)
-{
+SkString::SkString(size_t len) {
SkASSERT(SkToU16(len) == len); // can't handle larger than 64K
fRec = AllocRec(NULL, (U16CPU)len);
@@ -265,8 +257,7 @@ SkString::SkString(size_t len)
#endif
}
-SkString::SkString(const char text[])
-{
+SkString::SkString(const char text[]) {
size_t len = text ? strlen(text) : 0;
fRec = AllocRec(text, (U16CPU)len);
@@ -275,16 +266,14 @@ SkString::SkString(const char text[])
#endif
}
-SkString::SkString(const char text[], size_t len)
-{
+SkString::SkString(const char text[], size_t len) {
fRec = AllocRec(text, (U16CPU)len);
#ifdef SK_DEBUG
fStr = fRec->data();
#endif
}
-SkString::SkString(const SkString& src)
-{
+SkString::SkString(const SkString& src) {
src.validate();
fRec = RefRec(src.fRec);
@@ -293,56 +282,49 @@ SkString::SkString(const SkString& src)
#endif
}
-SkString::~SkString()
-{
+SkString::~SkString() {
this->validate();
- if (fRec->fLength)
- {
+ if (fRec->fLength) {
SkASSERT(fRec->fRefCnt > 0);
- if (--fRec->fRefCnt == 0)
+ if (--fRec->fRefCnt == 0) {
sk_free(fRec);
+ }
}
}
-bool SkString::equals(const SkString& src) const
-{
+bool SkString::equals(const SkString& src) const {
return fRec == src.fRec || this->equals(src.c_str(), src.size());
}
-bool SkString::equals(const char text[]) const
-{
+bool SkString::equals(const char text[]) const {
return this->equals(text, text ? strlen(text) : 0);
}
-bool SkString::equals(const char text[], size_t len) const
-{
+bool SkString::equals(const char text[], size_t len) const {
SkASSERT(len == 0 || text != NULL);
return fRec->fLength == len && !memcmp(fRec->data(), text, len);
}
-SkString& SkString::operator=(const SkString& src)
-{
+SkString& SkString::operator=(const SkString& src) {
this->validate();
- if (fRec != src.fRec)
- {
+ if (fRec != src.fRec) {
SkString tmp(src);
this->swap(tmp);
}
return *this;
}
-void SkString::reset()
-{
+void SkString::reset() {
this->validate();
- if (fRec->fLength)
- {
+ if (fRec->fLength) {
SkASSERT(fRec->fRefCnt > 0);
- if (--fRec->fRefCnt == 0)
+ if (--fRec->fRefCnt == 0) {
sk_free(fRec);
+ }
}
fRec = const_cast<Rec*>(&gEmptyRec);
@@ -351,14 +333,11 @@ void SkString::reset()
#endif
}
-char* SkString::writable_str()
-{
+char* SkString::writable_str() {
this->validate();
- if (fRec->fLength)
- {
- if (fRec->fRefCnt > 1)
- {
+ if (fRec->fLength) {
+ if (fRec->fRefCnt > 1) {
fRec->fRefCnt -= 1;
fRec = AllocRec(fRec->data(), fRec->fLength);
#ifdef SK_DEBUG
@@ -369,86 +348,79 @@ char* SkString::writable_str()
return fRec->data();
}
-void SkString::set(const char text[])
-{
+void SkString::set(const char text[]) {
this->set(text, text ? strlen(text) : 0);
}
-void SkString::set(const char text[], size_t len)
-{
- if (len == 0)
+void SkString::set(const char text[], size_t len) {
+ if (len == 0) {
this->reset();
- else if (fRec->fRefCnt == 1 && len <= fRec->fLength) // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))
- {
+ } else if (fRec->fRefCnt == 1 && len <= fRec->fLength) {
+ // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))?
// just use less of the buffer without allocating a smaller one
char* p = this->writable_str();
- if (text)
+ if (text) {
memcpy(p, text, len);
+ }
p[len] = 0;
fRec->fLength = SkToU16(len);
- }
- else if (fRec->fRefCnt == 1 && ((unsigned)fRec->fLength >> 2) == (len >> 2))
- {
+ } else if (fRec->fRefCnt == 1 && ((unsigned)fRec->fLength >> 2) == (len >> 2)) {
// we have spare room in the current allocation, so don't alloc a larger one
char* p = this->writable_str();
- if (text)
+ if (text) {
memcpy(p, text, len);
+ }
p[len] = 0;
fRec->fLength = SkToU16(len);
- }
- else
- {
+ } else {
SkString tmp(text, len);
this->swap(tmp);
}
}
-void SkString::setUTF16(const uint16_t src[])
-{
+void SkString::setUTF16(const uint16_t src[]) {
int count = 0;
- while (src[count])
+ while (src[count]) {
count += 1;
+ }
setUTF16(src, count);
}
-void SkString::setUTF16(const uint16_t src[], size_t count)
-{
- if (count == 0)
+void SkString::setUTF16(const uint16_t src[], size_t count) {
+ if (count == 0) {
this->reset();
- else if (count <= fRec->fLength) // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))
- {
- if (count < fRec->fLength)
+ } else if (count <= fRec->fLength) {
+ // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))
+ if (count < fRec->fLength) {
this->resize(count);
+ }
char* p = this->writable_str();
- for (size_t i = 0; i < count; i++)
+ for (size_t i = 0; i < count; i++) {
p[i] = SkToU8(src[i]);
+ }
p[count] = 0;
- }
- else
- {
- SkString tmp(count); // puts a null terminator at the end of the string
- char* p = tmp.writable_str();
+ } else {
+ SkString tmp(count); // puts a null terminator at the end of the string
+ char* p = tmp.writable_str();
- for (size_t i = 0; i < count; i++)
+ for (size_t i = 0; i < count; i++) {
p[i] = SkToU8(src[i]);
-
+ }
this->swap(tmp);
}
}
-void SkString::insert(size_t offset, const char text[])
-{
+void SkString::insert(size_t offset, const char text[]) {
this->insert(offset, text, text ? strlen(text) : 0);
}
-void SkString::insert(size_t offset, const char text[], size_t len)
-{
- if (len)
- {
+void SkString::insert(size_t offset, const char text[], size_t len) {
+ if (len) {
size_t length = fRec->fLength;
- if (offset > length)
+ if (offset > length) {
offset = length;
+ }
/* If we're the only owner, and we have room in our allocation for the insert,
do it in place, rather than allocating a new buffer.
@@ -460,61 +432,59 @@ void SkString::insert(size_t offset, const char text[], size_t len)
which is equivalent for testing to (length + 1 + 3) >> 2 == (length + 1 + 3 + len) >> 2
and we can then eliminate the +1+3 since that doesn't affec the answer
*/
- if (fRec->fRefCnt == 1 && (length >> 2) == ((length + len) >> 2))
- {
+ if (fRec->fRefCnt == 1 && (length >> 2) == ((length + len) >> 2)) {
char* dst = this->writable_str();
- if (offset < length)
+ if (offset < length) {
memmove(dst + offset + len, dst + offset, length - offset);
+ }
memcpy(dst + offset, text, len);
dst[length + len] = 0;
fRec->fLength = SkToU16(length + len);
- }
- else
- {
+ } else {
/* Seems we should use realloc here, since that is safe if it fails
(we have the original data), and might be faster than alloc/copy/free.
*/
SkString tmp(fRec->fLength + len);
char* dst = tmp.writable_str();
- if (offset > 0)
+ if (offset > 0) {
memcpy(dst, fRec->data(), offset);
+ }
memcpy(dst + offset, text, len);
- if (offset < fRec->fLength)
- memcpy(dst + offset + len, fRec->data() + offset, fRec->fLength - offset);
+ if (offset < fRec->fLength) {
+ memcpy(dst + offset + len, fRec->data() + offset,
+ fRec->fLength - offset);
+ }
this->swap(tmp);
}
}
}
-void SkString::insertUnichar(size_t offset, SkUnichar uni)
-{
+void SkString::insertUnichar(size_t offset, SkUnichar uni) {
char buffer[kMaxBytesInUTF8Sequence];
size_t len = SkUTF8_FromUnichar(uni, buffer);
- if (len)
+ if (len) {
this->insert(offset, buffer, len);
+ }
}
-void SkString::insertS32(size_t offset, int32_t dec)
-{
+void SkString::insertS32(size_t offset, int32_t dec) {
char buffer[SkStrAppendS32_MaxSize];
char* stop = SkStrAppendS32(buffer, dec);
this->insert(offset, buffer, stop - buffer);
}
-void SkString::insertS64(size_t offset, int64_t dec, int minDigits)
-{
+void SkString::insertS64(size_t offset, int64_t dec, int minDigits) {
char buffer[SkStrAppendS64_MaxSize];
char* stop = SkStrAppendS64(buffer, dec, minDigits);
this->insert(offset, buffer, stop - buffer);
}
-void SkString::insertHex(size_t offset, uint32_t hex, int minDigits)
-{
+void SkString::insertHex(size_t offset, uint32_t hex, int minDigits) {
minDigits = SkPin32(minDigits, 0, 8);
static const char gHex[] = "0123456789ABCDEF";
@@ -527,15 +497,16 @@ void SkString::insertHex(size_t offset, uint32_t hex, int minDigits)
hex >>= 4;
minDigits -= 1;
} while (hex != 0);
- while (--minDigits >= 0)
+
+ while (--minDigits >= 0) {
*--p = '0';
+ }
SkASSERT(p >= buffer);
this->insert(offset, p, buffer + sizeof(buffer) - p);
}
-void SkString::insertScalar(size_t offset, SkScalar value)
-{
+void SkString::insertScalar(size_t offset, SkScalar value) {
char buffer[SkStrAppendScalar_MaxSize];
char* stop = SkStrAppendScalar(buffer, value);
this->insert(offset, buffer, stop - buffer);
@@ -566,30 +537,26 @@ void SkString::prependf(const char format[], ...) {
///////////////////////////////////////////////////////////////////////////////
-void SkString::remove(size_t offset, size_t length)
-{
+void SkString::remove(size_t offset, size_t length) {
size_t size = this->size();
- if (offset < size)
- {
- if (offset + length > size)
+ if (offset < size) {
+ if (offset + length > size) {
length = size - offset;
- if (length > 0)
- {
+ }
+ if (length > 0) {
SkASSERT(size > length);
SkString tmp(size - length);
char* dst = tmp.writable_str();
const char* src = this->c_str();
- if (offset)
- {
+ if (offset) {
SkASSERT(offset <= tmp.size());
memcpy(dst, src, offset);
}
size_t tail = size - offset - length;
SkASSERT((int32_t)tail >= 0);
- if (tail)
- {
+ if (tail) {
// SkASSERT(offset + length <= tmp.size());
memcpy(dst + offset, src + offset + length, tail);
}
@@ -599,8 +566,7 @@ void SkString::remove(size_t offset, size_t length)
}
}
-void SkString::swap(SkString& other)
-{
+void SkString::swap(SkString& other) {
this->validate();
other.validate();
@@ -610,25 +576,23 @@ void SkString::swap(SkString& other)
#endif
}
-/////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-SkAutoUCS2::SkAutoUCS2(const char utf8[])
-{
+SkAutoUCS2::SkAutoUCS2(const char utf8[]) {
size_t len = strlen(utf8);
fUCS2 = (uint16_t*)sk_malloc_throw((len + 1) * sizeof(uint16_t));
uint16_t* dst = fUCS2;
- for (;;)
- {
- SkUnichar uni = SkUTF8_NextUnichar(&utf8);
+ for (;;) {
+ SkUnichar uni = SkUTF8_NextUnichar(&utf8);
*dst++ = SkToU16(uni);
- if (uni == 0)
+ if (uni == 0) {
break;
+ }
}
fCount = (int)(dst - fUCS2);
}
-SkAutoUCS2::~SkAutoUCS2()
-{
- delete[] fUCS2;
+SkAutoUCS2::~SkAutoUCS2() {
+ sk_free(fUCS2);
}
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 7eeaf19..9a764fc 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypeface.h"
#include "SkFontHost.h"
@@ -76,6 +77,6 @@ SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
}
SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
- bool perGlyphInfo) const {
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) const {
return SkFontHost::GetAdvancedTypefaceMetrics(fUniqueID, perGlyphInfo);
}
diff --git a/src/core/SkUtils.cpp b/src/core/SkUtils.cpp
index 9fb85c2..6aa57ee 100644
--- a/src/core/SkUtils.cpp
+++ b/src/core/SkUtils.cpp
@@ -43,18 +43,17 @@
} while (0)
#endif
-///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-void sk_memset16_portable(uint16_t dst[], uint16_t value, int count)
-{
+void sk_memset16_portable(uint16_t dst[], uint16_t value, int count) {
SkASSERT(dst != NULL && count >= 0);
- if (count <= 0)
+ if (count <= 0) {
return;
+ }
// not sure if this helps to short-circuit on small values of count
- if (count < 8)
- {
+ if (count < 8) {
do {
*dst++ = (uint16_t)value;
} while (--count != 0);
@@ -62,8 +61,7 @@ void sk_memset16_portable(uint16_t dst[], uint16_t value, int count)
}
// ensure we're on a long boundary
- if ((size_t)dst & 2)
- {
+ if ((size_t)dst & 2) {
*dst++ = (uint16_t)value;
count -= 1;
}
@@ -73,8 +71,7 @@ void sk_memset16_portable(uint16_t dst[], uint16_t value, int count)
// handle the bulk with our unrolled macro
{
int sixteenlongs = count >> 5;
- if (sixteenlongs)
- {
+ if (sixteenlongs) {
uint32_t* dst32 = (uint32_t*)dst;
do {
assign_16_longs(dst32, value32);
@@ -87,8 +84,7 @@ void sk_memset16_portable(uint16_t dst[], uint16_t value, int count)
// handle (most) of the rest
{
int longs = count >> 1;
- if (longs)
- {
+ if (longs) {
do {
*(uint32_t*)dst = value32;
dst += 2;
@@ -97,27 +93,23 @@ void sk_memset16_portable(uint16_t dst[], uint16_t value, int count)
}
// cleanup a possible trailing short
- if (count & 1)
+ if (count & 1) {
*dst = (uint16_t)value;
+ }
}
-void sk_memset32_portable(uint32_t dst[], uint32_t value, int count)
-{
+void sk_memset32_portable(uint32_t dst[], uint32_t value, int count) {
SkASSERT(dst != NULL && count >= 0);
- {
- int sixteenlongs = count >> 4;
- if (sixteenlongs)
- {
- do {
- assign_16_longs(dst, value);
- } while (--sixteenlongs != 0);
- count &= 15;
- }
+ int sixteenlongs = count >> 4;
+ if (sixteenlongs) {
+ do {
+ assign_16_longs(dst, value);
+ } while (--sixteenlongs != 0);
+ count &= 15;
}
- if (count)
- {
+ if (count) {
do {
*dst++ = value;
} while (--count != 0);
@@ -125,8 +117,7 @@ void sk_memset32_portable(uint32_t dst[], uint32_t value, int count)
}
#if !defined(ANDROID) || defined(SK_BUILD_FOR_ANDROID_NDK)
-static void sk_memset16_stub(uint16_t dst[], uint16_t value, int count)
-{
+static void sk_memset16_stub(uint16_t dst[], uint16_t value, int count) {
SkMemset16Proc proc = SkMemset16GetPlatformProc();
sk_memset16 = proc ? proc : sk_memset16_portable;
sk_memset16(dst, value, count);
@@ -134,8 +125,7 @@ static void sk_memset16_stub(uint16_t dst[], uint16_t value, int count)
SkMemset16Proc sk_memset16 = sk_memset16_stub;
-static void sk_memset32_stub(uint32_t dst[], uint32_t value, int count)
-{
+static void sk_memset32_stub(uint32_t dst[], uint32_t value, int count) {
SkMemset32Proc proc = SkMemset32GetPlatformProc();
sk_memset32 = proc ? proc : sk_memset32_portable;
sk_memset32(dst, value, count);
@@ -145,7 +135,7 @@ SkMemset32Proc sk_memset32 = sk_memset32_stub;
#endif
-//////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
/* 0xxxxxxx 1 total
10xxxxxx // never a leading byte
@@ -159,14 +149,12 @@ SkMemset32Proc sk_memset32 = sk_memset32_stub;
*/
#ifdef SK_DEBUG
- static void assert_utf8_leadingbyte(unsigned c)
- {
+ static void assert_utf8_leadingbyte(unsigned c) {
SkASSERT(c <= 0xF7); // otherwise leading byte is too big (more than 4 bytes)
SkASSERT((c & 0xC0) != 0x80); // can't begin with a middle char
}
- int SkUTF8_LeadByteToCount(unsigned c)
- {
+ int SkUTF8_LeadByteToCount(unsigned c) {
assert_utf8_leadingbyte(c);
return (((0xE5 << 24) >> (c >> 4 << 1)) & 3) + 1;
}
@@ -174,41 +162,36 @@ SkMemset32Proc sk_memset32 = sk_memset32_stub;
#define assert_utf8_leadingbyte(c)
#endif
-int SkUTF8_CountUnichars(const char utf8[])
-{
+int SkUTF8_CountUnichars(const char utf8[]) {
SkASSERT(utf8);
int count = 0;
- for (;;)
- {
+ for (;;) {
int c = *(const uint8_t*)utf8;
- if (c == 0)
+ if (c == 0) {
break;
-
+ }
utf8 += SkUTF8_LeadByteToCount(c);
count += 1;
}
return count;
}
-int SkUTF8_CountUnichars(const char utf8[], size_t byteLength)
-{
+int SkUTF8_CountUnichars(const char utf8[], size_t byteLength) {
SkASSERT(NULL != utf8 || 0 == byteLength);
int count = 0;
const char* stop = utf8 + byteLength;
- while (utf8 < stop)
- {
+ while (utf8 < stop) {
utf8 += SkUTF8_LeadByteToCount(*(const uint8_t*)utf8);
count += 1;
}
return count;
}
-SkUnichar SkUTF8_ToUnichar(const char utf8[])
-{
+SkUnichar SkUTF8_ToUnichar(const char utf8[]) {
SkASSERT(NULL != utf8);
const uint8_t* p = (const uint8_t*)utf8;
@@ -217,8 +200,7 @@ SkUnichar SkUTF8_ToUnichar(const char utf8[])
assert_utf8_leadingbyte(c);
- if (hic < 0)
- {
+ if (hic < 0) {
uint32_t mask = (uint32_t)~0x3F;
hic <<= 1;
do {
@@ -230,8 +212,7 @@ SkUnichar SkUTF8_ToUnichar(const char utf8[])
return c;
}
-SkUnichar SkUTF8_NextUnichar(const char** ptr)
-{
+SkUnichar SkUTF8_NextUnichar(const char** ptr) {
SkASSERT(NULL != ptr && NULL != *ptr);
const uint8_t* p = (const uint8_t*)*ptr;
@@ -240,8 +221,7 @@ SkUnichar SkUTF8_NextUnichar(const char** ptr)
assert_utf8_leadingbyte(c);
- if (hic < 0)
- {
+ if (hic < 0) {
uint32_t mask = (uint32_t)~0x3F;
hic <<= 1;
do {
@@ -254,32 +234,31 @@ SkUnichar SkUTF8_NextUnichar(const char** ptr)
return c;
}
-SkUnichar SkUTF8_PrevUnichar(const char** ptr)
-{
+SkUnichar SkUTF8_PrevUnichar(const char** ptr) {
SkASSERT(NULL != ptr && NULL != *ptr);
const char* p = *ptr;
- if (*--p & 0x80)
- while (*--p & 0x40)
+ if (*--p & 0x80) {
+ while (*--p & 0x40) {
;
+ }
+ }
*ptr = (char*)p;
return SkUTF8_NextUnichar(&p);
}
-size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[])
-{
- if ((uint32_t)uni > 0x10FFFF)
- {
+size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[]) {
+ if ((uint32_t)uni > 0x10FFFF) {
SkASSERT(!"bad unichar");
return 0;
}
- if (uni <= 127)
- {
- if (utf8)
+ if (uni <= 127) {
+ if (utf8) {
*utf8 = (char)uni;
+ }
return 1;
}
@@ -289,19 +268,18 @@ size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[])
SkDEBUGCODE(SkUnichar orig = uni;)
- while (uni > 0x7F >> count)
- {
+ while (uni > 0x7F >> count) {
*p++ = (char)(0x80 | (uni & 0x3F));
uni >>= 6;
count += 1;
}
- if (utf8)
- {
+ if (utf8) {
p = tmp;
utf8 += count;
- while (p < tmp + count - 1)
+ while (p < tmp + count - 1) {
*--utf8 = *p++;
+ }
*--utf8 = (char)(~(0xFF >> count) | uni);
}
@@ -309,19 +287,16 @@ size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[])
return count;
}
-////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-int SkUTF16_CountUnichars(const uint16_t src[])
-{
+int SkUTF16_CountUnichars(const uint16_t src[]) {
SkASSERT(src);
int count = 0;
unsigned c;
- while ((c = *src++) != 0)
- {
+ while ((c = *src++) != 0) {
SkASSERT(!SkUTF16_IsLowSurrogate(c));
- if (SkUTF16_IsHighSurrogate(c))
- {
+ if (SkUTF16_IsHighSurrogate(c)) {
c = *src++;
SkASSERT(SkUTF16_IsLowSurrogate(c));
}
@@ -330,18 +305,15 @@ int SkUTF16_CountUnichars(const uint16_t src[])
return count;
}
-int SkUTF16_CountUnichars(const uint16_t src[], int numberOf16BitValues)
-{
+int SkUTF16_CountUnichars(const uint16_t src[], int numberOf16BitValues) {
SkASSERT(src);
const uint16_t* stop = src + numberOf16BitValues;
int count = 0;
- while (src < stop)
- {
+ while (src < stop) {
unsigned c = *src++;
SkASSERT(!SkUTF16_IsLowSurrogate(c));
- if (SkUTF16_IsHighSurrogate(c))
- {
+ if (SkUTF16_IsHighSurrogate(c)) {
SkASSERT(src < stop);
c = *src++;
SkASSERT(SkUTF16_IsLowSurrogate(c));
@@ -351,16 +323,14 @@ int SkUTF16_CountUnichars(const uint16_t src[], int numberOf16BitValues)
return count;
}
-SkUnichar SkUTF16_NextUnichar(const uint16_t** srcPtr)
-{
+SkUnichar SkUTF16_NextUnichar(const uint16_t** srcPtr) {
SkASSERT(srcPtr && *srcPtr);
const uint16_t* src = *srcPtr;
SkUnichar c = *src++;
SkASSERT(!SkUTF16_IsLowSurrogate(c));
- if (SkUTF16_IsHighSurrogate(c))
- {
+ if (SkUTF16_IsHighSurrogate(c)) {
unsigned c2 = *src++;
SkASSERT(SkUTF16_IsLowSurrogate(c2));
@@ -372,16 +342,14 @@ SkUnichar SkUTF16_NextUnichar(const uint16_t** srcPtr)
return c;
}
-SkUnichar SkUTF16_PrevUnichar(const uint16_t** srcPtr)
-{
+SkUnichar SkUTF16_PrevUnichar(const uint16_t** srcPtr) {
SkASSERT(srcPtr && *srcPtr);
const uint16_t* src = *srcPtr;
SkUnichar c = *--src;
SkASSERT(!SkUTF16_IsHighSurrogate(c));
- if (SkUTF16_IsLowSurrogate(c))
- {
+ if (SkUTF16_IsLowSurrogate(c)) {
unsigned c2 = *--src;
SkASSERT(SkUTF16_IsHighSurrogate(c2));
c = (c2 << 10) + c + (0x10000 - (0xD800 << 10) - 0xDC00);
@@ -390,16 +358,13 @@ SkUnichar SkUTF16_PrevUnichar(const uint16_t** srcPtr)
return c;
}
-size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t dst[])
-{
+size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t dst[]) {
SkASSERT((unsigned)uni <= 0x10FFFF);
int extra = (uni > 0xFFFF);
- if (dst)
- {
- if (extra)
- {
+ if (dst) {
+ if (extra) {
// dst[0] = SkToU16(0xD800 | ((uni - 0x10000) >> 10));
// dst[0] = SkToU16(0xD800 | ((uni >> 10) - 64));
dst[0] = SkToU16((0xD800 - 64) + (uni >> 10));
@@ -407,9 +372,7 @@ size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t dst[])
SkASSERT(SkUTF16_IsHighSurrogate(dst[0]));
SkASSERT(SkUTF16_IsLowSurrogate(dst[1]));
- }
- else
- {
+ } else {
dst[0] = SkToU16(uni);
SkASSERT(!SkUTF16_IsHighSurrogate(dst[0]));
SkASSERT(!SkUTF16_IsLowSurrogate(dst[0]));
@@ -418,46 +381,44 @@ size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t dst[])
return 1 + extra;
}
-size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues, char utf8[])
-{
+size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
+ char utf8[]) {
SkASSERT(numberOf16BitValues >= 0);
- if (numberOf16BitValues <= 0)
+ if (numberOf16BitValues <= 0) {
return 0;
+ }
SkASSERT(utf16 != NULL);
const uint16_t* stop = utf16 + numberOf16BitValues;
size_t size = 0;
- if (utf8 == NULL) // just count
- {
- while (utf16 < stop)
+ if (utf8 == NULL) { // just count
+ while (utf16 < stop) {
size += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), NULL);
- }
- else
- {
+ }
+ } else {
char* start = utf8;
- while (utf16 < stop)
+ while (utf16 < stop) {
utf8 += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), utf8);
+ }
size = utf8 - start;
}
return size;
}
-////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#if 0
-static int round_to_K(size_t bytes)
-{
+static int round_to_K(size_t bytes) {
return (bytes + 512) >> 10;
}
#endif
SkAutoMemoryUsageProbe::SkAutoMemoryUsageProbe(const char label[])
- : fLabel(label)
-{
+ : fLabel(label) {
#if 0
struct mallinfo mi = mallinfo();
@@ -465,14 +426,14 @@ SkAutoMemoryUsageProbe::SkAutoMemoryUsageProbe(const char label[])
#endif
}
-SkAutoMemoryUsageProbe::~SkAutoMemoryUsageProbe()
-{
+SkAutoMemoryUsageProbe::~SkAutoMemoryUsageProbe() {
#if 0
struct mallinfo mi = mallinfo();
printf("SkAutoMemoryUsageProbe ");
- if (fLabel)
+ if (fLabel) {
printf("<%s> ", fLabel);
+ }
printf("delta %dK, current total allocated %dK\n",
round_to_K(mi.uordblks - fBytesAllocated),
round_to_K(mi.uordblks));
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index a5b9f13..110ccb3 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -448,8 +448,8 @@ static const ProcCoeff gProcCoeffs[] = {
{ dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
{ xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
- { plus_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
- { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff },
+ { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
{ screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
{ overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
{ darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
diff --git a/src/core/core_files.mk b/src/core/core_files.mk
index 252644e..b3427b0 100644
--- a/src/core/core_files.mk
+++ b/src/core/core_files.mk
@@ -56,6 +56,7 @@ SOURCE := \
SkMath.cpp \
SkMatrix.cpp \
SkMemory_stdlib.cpp \
+ SkMetaData.cpp \
SkPackBits.cpp \
SkPaint.cpp \
SkPath.cpp \
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index 9585112..bde04ed 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -7,11 +7,10 @@
SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
SkColor color, uint32_t flags)
- : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags)
-{
+ : fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
+
SkASSERT(flags <= kAll_BlurFlag);
- if (radius > 0)
- {
+ if (radius > 0) {
uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
SkBlurMaskFilter::kNone_BlurFlag;
@@ -23,28 +22,23 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
fBlur = SkBlurMaskFilter::Create(radius,
SkBlurMaskFilter::kNormal_BlurStyle,
blurFlags);
- }
- else
- {
+ } else {
fBlur = NULL;
}
- if (flags & kOverrideColor_BlurFlag)
- {
+ if (flags & kOverrideColor_BlurFlag) {
// Set alpha to 1 for the override since transparency will already
// be baked into the blurred mask.
SkColor opaqueColor = SkColorSetA(color, 255);
//The SrcIn xfer mode will multiply 'color' by the incoming alpha
- fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, SkXfermode::kSrcIn_Mode);
- }
- else
- {
+ fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
+ SkXfermode::kSrcIn_Mode);
+ } else {
fColorFilter = NULL;
}
}
-SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
-{
+SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) {
fDx = buffer.readScalar();
fDy = buffer.readScalar();
fBlurColor = buffer.readU32();
@@ -53,14 +47,12 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
fBlurFlags = buffer.readU32() & kAll_BlurFlag;
}
-SkBlurDrawLooper::~SkBlurDrawLooper()
-{
+SkBlurDrawLooper::~SkBlurDrawLooper() {
SkSafeUnref(fBlur);
SkSafeUnref(fColorFilter);
}
-void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
-{
+void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
buffer.writeScalar(fDx);
buffer.writeScalar(fDy);
buffer.write32(fBlurColor);
@@ -69,70 +61,47 @@ void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
buffer.write32(fBlurFlags);
}
-void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
-{
- // we do nothing if a maskfilter is already installed
- if (paint->getMaskFilter() != NULL)
- fState = kDone;
- else
- {
- fState = kBeforeEdge;
- fPaint = paint;
- fCanvas = canvas;
- fSaveCount = canvas->getSaveCount();
- }
+void SkBlurDrawLooper::init(SkCanvas* canvas) {
+ fState = kBeforeEdge;
}
-bool SkBlurDrawLooper::next()
-{
- SkColor blurColor;
- SkAlpha alpha;
+bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
switch (fState) {
- case kBeforeEdge:
- fSavedColor = fPaint->getColor();
- blurColor = fBlurColor;
- alpha = SkColorGetA(blurColor);
- if (alpha == 255) {
- blurColor = SkColorSetA(blurColor, fPaint->getAlpha());
- }
- fPaint->setColor(blurColor);
- fPaint->setMaskFilter(fBlur);
- fPaint->setColorFilter(fColorFilter);
- fCanvas->save(SkCanvas::kMatrix_SaveFlag);
- if (fBlurFlags & kIgnoreTransform_BlurFlag)
- {
- SkMatrix transform(fCanvas->getTotalMatrix());
- transform.postTranslate(fDx, fDy);
- fCanvas->setMatrix(transform);
- }
- else
- {
- fCanvas->translate(fDx, fDy);
- }
- fState = kAfterEdge;
- return true;
- case kAfterEdge:
- fPaint->setColor(fSavedColor);
- fPaint->setMaskFilter(NULL);
- fPaint->setColorFilter(NULL);
- fCanvas->restore(); // to remove the translate we did earlier
- fState = kDone;
- return true;
- default:
- SkASSERT(kDone == fState);
- return false;
- }
-}
-
-void SkBlurDrawLooper::restore()
-{
- if (kAfterEdge == fState)
- {
- fPaint->setColor(fSavedColor);
- fPaint->setMaskFilter(NULL);
- fPaint->setColorFilter(NULL);
- fCanvas->restore(); // to remove the translate we did earlier
- fState = kDone;
+ case kBeforeEdge:
+ // we do nothing if a maskfilter is already installed
+ if (paint->getMaskFilter()) {
+ fState = kDone;
+ return false;
+ }
+#ifdef ANDROID
+ SkColor blurColor;
+ blurColor = fBlurColor;
+ if (SkColorGetA(blurColor) == 255) {
+ blurColor = SkColorSetA(blurColor, paint->getAlpha());
+ }
+ paint->setColor(blurColor);
+#else
+ paint->setColor(fBlurColor);
+#endif
+ paint->setMaskFilter(fBlur);
+ paint->setColorFilter(fColorFilter);
+ canvas->save(SkCanvas::kMatrix_SaveFlag);
+ if (fBlurFlags & kIgnoreTransform_BlurFlag) {
+ SkMatrix transform(canvas->getTotalMatrix());
+ transform.postTranslate(fDx, fDy);
+ canvas->setMatrix(transform);
+ } else {
+ canvas->translate(fDx, fDy);
+ }
+ fState = kAfterEdge;
+ return true;
+ case kAfterEdge:
+ canvas->restore();
+ fState = kDone;
+ return true;
+ default:
+ SkASSERT(kDone == fState);
+ return false;
}
}
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 3452212..dca87b0 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -1397,9 +1397,13 @@ public:
SkScalarSquare(fDiff.fY));
}
if (matrix) {
- SkScalar invDiffL = SkScalarInvert(diffL);
- matrix->setSinCos(-SkScalarMul(invDiffL, fDiff.fY),
- SkScalarMul(invDiffL, fDiff.fX));
+ if (diffL) {
+ SkScalar invDiffL = SkScalarInvert(diffL);
+ matrix->setSinCos(-SkScalarMul(invDiffL, fDiff.fY),
+ SkScalarMul(invDiffL, fDiff.fX));
+ } else {
+ matrix->reset();
+ }
matrix->preConcat(fPtsToUnit);
}
if (xy) {
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index f2d8ba8..b3f3886 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -1,6 +1,15 @@
#include "SkCanvas.h"
+#include "SkColor.h"
#include "SkLayerDrawLooper.h"
#include "SkPaint.h"
+#include "SkUnPreMultiply.h"
+
+SkLayerDrawLooper::LayerInfo::LayerInfo() {
+ fPaintBits = 0; // ignore out paint
+ fColorMode = SkXfermode::kDst_Mode; // ignore our color
+ fOffset.set(0, 0);
+ fPostTranslate = false;
+}
SkLayerDrawLooper::SkLayerDrawLooper() {
fRecs = NULL;
@@ -15,43 +24,128 @@ SkLayerDrawLooper::~SkLayerDrawLooper() {
rec = next;
}
}
-
-SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
+
+SkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
fCount += 1;
Rec* rec = SkNEW(Rec);
rec->fNext = fRecs;
- rec->fOffset.set(dx, dy);
+ rec->fInfo = info;
fRecs = rec;
return &rec->fPaint;
}
-void SkLayerDrawLooper::init(SkCanvas* canvas, SkPaint* paint) {
- fIter.fSavedPaint = *paint;
- fIter.fPaint = paint;
- fIter.fCanvas = canvas;
- fIter.fRec = fRecs;
+SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
+ LayerInfo info;
+
+ info.fOffset.set(dx, dy);
+ return this->addLayer(info);
+}
+
+void SkLayerDrawLooper::init(SkCanvas* canvas) {
+ fCurrRec = fRecs;
canvas->save(SkCanvas::kMatrix_SaveFlag);
}
-bool SkLayerDrawLooper::next() {
- Rec* rec = fIter.fRec;
- if (rec) {
- *fIter.fPaint = rec->fPaint;
- fIter.fCanvas->restore();
- fIter.fCanvas->save(SkCanvas::kMatrix_SaveFlag);
- fIter.fCanvas->translate(rec->fOffset.fX, rec->fOffset.fY);
+static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
+ switch (mode) {
+ case SkXfermode::kSrc_Mode:
+ return src;
+ case SkXfermode::kDst_Mode:
+ return dst;
+ default: {
+ SkPMColor pmS = SkPreMultiplyColor(src);
+ SkPMColor pmD = SkPreMultiplyColor(dst);
+ SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
+ return SkUnPreMultiply::PMColorToColor(result);
+ }
+ }
+}
+
+void SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src,
+ BitFlags bits, SkXfermode::Mode colorMode) {
+ dst->setColor(xferColor(src.getColor(), dst->getColor(), colorMode));
+
+ if (0 == bits) {
+ return;
+ }
+ if (kEntirePaint_Bits == bits) {
+ // we've already compute the color, so save it from the assignment
+ SkColor c = dst->getColor();
+ *dst = src;
+ dst->setColor(c);
+ return;
+ }
+
+ if (bits & kStyle_Bit) {
+ dst->setStyle(src.getStyle());
+ dst->setStrokeWidth(src.getStrokeWidth());
+ dst->setStrokeMiter(src.getStrokeMiter());
+ dst->setStrokeCap(src.getStrokeCap());
+ dst->setStrokeJoin(src.getStrokeJoin());
+ }
+
+ if (bits & kTextSkewX_Bit) {
+ dst->setTextSkewX(src.getTextSkewX());
+ }
- fIter.fRec = rec->fNext;
- return true;
+ if (bits & kPathEffect_Bit) {
+ dst->setPathEffect(src.getPathEffect());
+ }
+ if (bits & kMaskFilter_Bit) {
+ dst->setMaskFilter(src.getMaskFilter());
+ }
+ if (bits & kShader_Bit) {
+ dst->setShader(src.getShader());
}
- return false;
+ if (bits & kColorFilter_Bit) {
+ dst->setColorFilter(src.getColorFilter());
+ }
+ if (bits & kXfermode_Bit) {
+ dst->setXfermode(src.getXfermode());
+ }
+
+ // we never copy these
+#if 0
+ dst->setFlags(src.getFlags());
+ dst->setTypeface(src.getTypeface());
+ dst->setTextSize(src.getTextSize());
+ dst->setTextScaleX(src.getTextScaleX());
+ dst->setTextSkewX(src.getTextSkewX());
+ dst->setRasterizer(src.getRasterizer());
+ dst->setLooper(src.getLooper());
+ dst->setTextEncoding(src.getTextEncoding());
+ dst->setHinting(src.getHinting());
+#endif
}
-void SkLayerDrawLooper::restore() {
- fIter.fCanvas->restore();
- *fIter.fPaint = fIter.fSavedPaint;
+// Should we add this to canvas?
+static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
+ SkMatrix m = canvas->getTotalMatrix();
+ m.postTranslate(dx, dy);
+ canvas->setMatrix(m);
+}
+
+bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
+ canvas->restore();
+ if (NULL == fCurrRec) {
+ return false;
+ }
+
+ ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fInfo.fPaintBits,
+ fCurrRec->fInfo.fColorMode);
+
+ canvas->save(SkCanvas::kMatrix_SaveFlag);
+ if (fCurrRec->fInfo.fPostTranslate) {
+ postTranslate(canvas, fCurrRec->fInfo.fOffset.fX,
+ fCurrRec->fInfo.fOffset.fY);
+ } else {
+ canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY);
+ }
+ fCurrRec = fCurrRec->fNext;
+
+ return true;
}
SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
@@ -87,8 +181,11 @@ void SkLayerDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
Rec* rec = fRecs;
for (int i = 0; i < fCount; i++) {
- buffer.writeScalar(rec->fOffset.fX);
- buffer.writeScalar(rec->fOffset.fY);
+ buffer.writeInt(rec->fInfo.fPaintBits);
+ buffer.writeInt(rec->fInfo.fColorMode);
+ buffer.writeScalar(rec->fInfo.fOffset.fX);
+ buffer.writeScalar(rec->fInfo.fOffset.fY);
+ buffer.writeBool(rec->fInfo.fPostTranslate);
rec->fPaint.flatten(buffer);
rec = rec->fNext;
}
@@ -102,9 +199,13 @@ SkLayerDrawLooper::SkLayerDrawLooper(SkFlattenableReadBuffer& buffer)
int count = buffer.readInt();
for (int i = 0; i < count; i++) {
- SkScalar dx = buffer.readScalar();
- SkScalar dy = buffer.readScalar();
- this->addLayer(dx, dy)->unflatten(buffer);
+ LayerInfo info;
+ info.fPaintBits = buffer.readInt();
+ info.fColorMode = (SkXfermode::Mode)buffer.readInt();
+ info.fOffset.fX = buffer.readScalar();
+ info.fOffset.fY = buffer.readScalar();
+ info.fPostTranslate = buffer.readBool();
+ this->addLayer(info)->unflatten(buffer);
}
SkASSERT(count == fCount);
diff --git a/src/effects/SkPaintFlagsDrawFilter.cpp b/src/effects/SkPaintFlagsDrawFilter.cpp
index ed2df88..62eb53a 100644
--- a/src/effects/SkPaintFlagsDrawFilter.cpp
+++ b/src/effects/SkPaintFlagsDrawFilter.cpp
@@ -2,21 +2,12 @@
#include "SkPaint.h"
SkPaintFlagsDrawFilter::SkPaintFlagsDrawFilter(uint32_t clearFlags,
- uint32_t setFlags)
-{
+ uint32_t setFlags) {
fClearFlags = SkToU16(clearFlags & SkPaint::kAllFlags);
fSetFlags = SkToU16(setFlags & SkPaint::kAllFlags);
}
-bool SkPaintFlagsDrawFilter::filter(SkCanvas*, SkPaint* paint, Type)
-{
- fPrevFlags = paint->getFlags();
- paint->setFlags((fPrevFlags & ~fClearFlags) | fSetFlags);
- return true;
+void SkPaintFlagsDrawFilter::filter(SkPaint* paint, Type) {
+ paint->setFlags((paint->getFlags() & ~fClearFlags) | fSetFlags);
}
-void SkPaintFlagsDrawFilter::restore(SkCanvas*, SkPaint* paint, Type)
-{
- paint->setFlags(fPrevFlags);
-}
-
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 3707b67..723c635 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -24,6 +24,7 @@
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
+#include "SkUtils.h"
#define CACHE_LAYER_TEXTURES 1
@@ -171,11 +172,15 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
this->width(), this->height());
GrAssert(false);
}
- } else if (Current3DApiRenderTarget() == renderTargetOrNull) {
- fRenderTarget = fContext->createRenderTargetFrom3DApiState();
} else {
- fRenderTarget = renderTargetOrNull;
- fRenderTarget->ref();
+ if (Current3DApiRenderTarget() == renderTargetOrNull) {
+ fRenderTarget = fContext->createRenderTargetFrom3DApiState();
+ } else {
+ fRenderTarget = renderTargetOrNull;
+ fRenderTarget->ref();
+ }
+ SkGrRenderTargetPixelRef* pr = new SkGrRenderTargetPixelRef(fRenderTarget);
+ this->setPixelRef(pr, 0)->unref();
}
}
@@ -232,16 +237,15 @@ bool SkGpuDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
return false;
}
- SkAutoLockPixels alp(tmp);
- fContext->setRenderTarget(fRenderTarget);
- // we aren't setting the clip or matrix, so mark as dirty
- // we don't need to set them for this call and don't have them anyway
- fNeedPrepareRenderTarget = true;
+ tmp.lockPixels();
- if (!fContext->readPixels(bounds.fLeft, bounds.fTop,
- bounds.width(), bounds.height(),
- GrTexture::kRGBA_8888_PixelConfig,
- tmp.getPixels())) {
+ bool read = fContext->readRenderTargetPixels(fRenderTarget,
+ bounds.fLeft, bounds.fTop,
+ bounds.width(), bounds.height(),
+ kRGBA_8888_GrPixelConfig,
+ tmp.getPixels());
+ tmp.unlockPixels();
+ if (!read) {
return false;
}
@@ -254,8 +258,8 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
if (!bitmap.readyToDraw()) {
return;
}
- GrTexture::PixelConfig config = SkGr::BitmapConfig2PixelConfig(bitmap.config(),
- bitmap.isOpaque());
+ GrPixelConfig config = SkGr::BitmapConfig2PixelConfig(bitmap.config(),
+ bitmap.isOpaque());
fContext->setRenderTarget(fRenderTarget);
// we aren't setting the clip or matrix, so mark as dirty
// we don't need to set them for this call and don't have them anyway
@@ -305,8 +309,8 @@ void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
const SkClipStack& clipStack) {
this->INHERITED::setMatrixClip(matrix, clip, clipStack);
-
- convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
+ // We don't need to set them now because the context may not reflect this device.
+ fNeedPrepareRenderTarget = true;
}
void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
@@ -643,37 +647,180 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
#endif
}
+///////////////////////////////////////////////////////////////////////////////
+
+static void setInsetFan(GrPoint pts[4], const GrRect& r,
+ GrScalar dx, GrScalar dy) {
+ pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy);
+}
+
+static GrColor getColorForMesh(const GrPaint& paint) {
+ if (NULL == paint.getTexture()) {
+ return paint.fColor;
+ } else {
+ unsigned a = GrColorUnpackA(paint.fColor);
+ return GrColorPackRGBA(a, a, a, a);
+ }
+}
+
+static const uint16_t gFillAARectIdx1[] = {
+ 0, 1, 5, 5, 4, 0,
+ 1, 2, 6, 6, 5, 1,
+ 2, 3, 7, 7, 6, 2,
+ 3, 0, 4, 4, 7, 3,
+ 4, 5, 6, 6, 7, 4,
+};
+
+static void fillDevAARect(GrContext* ctx, const GrPaint& paint,
+ const GrRect& rect) {
+ if (rect.isEmpty()) {
+ return;
+ }
+
+ GrAutoMatrix avm(ctx, GrMatrix::I());
+
+ GrPoint verts[8];
+ GrPoint* texs = NULL;
+ GrColor colors[8];
+
+ setInsetFan(&verts[ 0], rect, -0.5f, -0.5f);
+ setInsetFan(&verts[ 4], rect, 0.5f, 0.5f);
+
+ sk_memset32(&colors[ 0], 0, 4);
+ sk_memset32(&colors[ 4], getColorForMesh(paint), 4);
+
+ ctx->drawVertices(paint, kTriangles_PrimitiveType,
+ 8, verts, texs, colors,
+ gFillAARectIdx1, SK_ARRAY_COUNT(gFillAARectIdx1));
+}
+
+static const uint16_t gStrokeAARectIdx[] = {
+ 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
+ 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
+ 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
+ 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0,
+
+ 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4,
+ 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4,
+ 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4,
+ 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4,
+
+ 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8,
+ 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8,
+ 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8,
+ 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8,
+};
+
+static void strokeDevAARect(GrContext* ctx, const GrPaint& paint,
+ const GrRect& rect, const SkPoint& strokeSize) {
+ const GrScalar dx = SkScalarToGrScalar(strokeSize.fX);
+ const GrScalar dy = SkScalarToGrScalar(strokeSize.fY);
+ const GrScalar rx = dx * 0.5f;
+ const GrScalar ry = dy * 0.5f;
+
+ GrScalar spare;
+ {
+ GrScalar w = rect.width() - dx;
+ GrScalar h = rect.height() - dy;
+ spare = GrMin(w, h);
+ }
+
+ if (spare <= 0) {
+ GrRect r(rect);
+ r.inset(-rx, -ry);
+ fillDevAARect(ctx, paint, r);
+ return;
+ }
+
+ GrAutoMatrix avm(ctx, GrMatrix::I());
+
+ GrPoint verts[16];
+ GrPoint* texs = NULL;
+ GrColor colors[16];
+
+ setInsetFan(&verts[ 0], rect, -rx - 0.5f, -ry - 0.5f);
+ setInsetFan(&verts[ 4], rect, -rx + 0.5f, -ry + 0.5f);
+ setInsetFan(&verts[ 8], rect, rx - 0.5f, ry - 0.5f);
+ setInsetFan(&verts[12], rect, rx + 0.5f, ry + 0.5f);
+
+ sk_memset32(&colors[ 0], 0, 4);
+ sk_memset32(&colors[ 4], getColorForMesh(paint), 8);
+ sk_memset32(&colors[12], 0, 4);
+
+ ctx->drawVertices(paint, kTriangles_PrimitiveType,
+ 16, verts, texs, colors,
+ gStrokeAARectIdx, SK_ARRAY_COUNT(gStrokeAARectIdx));
+}
+
+/*
+ * If the paint has a texture, preconcat the ctx's inverse, since when we
+ * draw verts which are already in device coordinates, we need to "undo" that
+ * before we run our vertex shaders, which expect the coordinates to be local.
+ */
+static void preConcatInverseToTextureMatrix(GrContext* ctx, GrPaint* paint) {
+ if (paint->getTexture()) {
+ GrMatrix inverse;
+ if (ctx->getMatrix().invert(&inverse)) {
+ paint->fSampler.preConcatMatrix(inverse);
+ }
+ }
+}
+
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
const SkPaint& paint) {
CHECK_SHOULD_DRAW(draw);
- bool doStroke = paint.getStyle() == SkPaint::kStroke_Style;
- SkScalar width = paint.getStrokeWidth();
+ const SkMatrix& matrix = *draw.fMatrix;
+ SkPoint strokeSize;
+ SkDraw::RectType type = SkDraw::ComputeRectType(paint, matrix, &strokeSize);
- /*
- We have special code for hairline strokes, miter-strokes, and fills.
- Anything else we just call our path code.
- */
- bool usePath = doStroke && width > 0 &&
- paint.getStrokeJoin() != SkPaint::kMiter_Join;
- // another reason we might need to call drawPath...
- if (paint.getMaskFilter()) {
- usePath = true;
- }
-
- if (usePath) {
+ if (SkDraw::kPath_RectType == type) {
SkPath path;
path.addRect(rect);
this->drawPath(draw, path, paint, NULL, true);
- return;
- }
+ } else {
+ GrPaint grPaint;
+ SkAutoCachedTexture act;
+ if (!this->skPaint2GrPaintShader(paint, &act, matrix, &grPaint)) {
+ return;
+ }
- GrPaint grPaint;
- SkAutoCachedTexture act;
- if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
- return;
+ bool doAA = paint.isAntiAlias();
+
+ if (SkDraw::kHair_RectType == type && doAA) {
+ strokeSize.set(SK_Scalar1, SK_Scalar1);
+ type = SkDraw::kStroke_RectType;
+ }
+
+ switch (type) {
+ case SkDraw::kHair_RectType:
+ SkASSERT(!doAA);
+ fContext->drawRect(grPaint, Sk2Gr(rect), 0);
+ break;
+ case SkDraw::kFill_RectType:
+ if (doAA) {
+ SkRect devRect;
+ matrix.mapRect(&devRect, rect);
+ preConcatInverseToTextureMatrix(fContext, &grPaint);
+ fillDevAARect(fContext, grPaint, Sk2Gr(devRect));
+ } else {
+ fContext->drawRect(grPaint, Sk2Gr(rect), -1);
+ }
+ break;
+ case SkDraw::kStroke_RectType:
+ if (doAA) {
+ SkRect devRect;
+ matrix.mapRect(&devRect, rect);
+ preConcatInverseToTextureMatrix(fContext, &grPaint);
+ strokeDevAARect(fContext, grPaint, Sk2Gr(devRect), strokeSize);
+ } else {
+ fContext->drawRect(grPaint, Sk2Gr(rect), paint.getStrokeWidth());
+ }
+ break;
+ default:
+ SkASSERT(!"bad value for RectType");
+ }
}
- fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1);
}
#include "SkMaskFilter.h"
@@ -715,7 +862,7 @@ static bool drawWithMaskFilter(GrContext* context, const SkPath& path,
GrGpu::kNone_AALevel,
dstM.fBounds.width(),
dstM.fBounds.height(),
- GrTexture::kAlpha_8_PixelConfig
+ kAlpha_8_GrPixelConfig
};
GrTexture* texture = context->createUncachedTexture(desc, dstM.fImage,
@@ -771,7 +918,22 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
// at this point we're done with prePathMatrix
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
- if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
+ // This "if" is not part of the SkDraw::drawPath() lift.
+ // When we get a 1.0 wide stroke we hairline stroke it instead of creating
+ // a new stroked-path. This is motivated by canvas2D sites that draw
+ // lines as 1.0 wide stroked paths. We can consider doing an alpha-modulated-
+ // hairline for width < 1.0 when AA is enabled.
+ static const int gMatrixMask = ~(SkMatrix::kIdentity_Mask |
+ SkMatrix::kTranslate_Mask);
+ if (!paint.getPathEffect() &&
+ SkPaint::kStroke_Style == paint.getStyle() &&
+ !(draw.fMatrix->getType() & gMatrixMask) &&
+ SK_Scalar1 == paint.getStrokeWidth()) {
+ doFill = false;
+ }
+
+ if (doFill && (paint.getPathEffect() ||
+ paint.getStyle() != SkPaint::kFill_Style)) {
doFill = paint.getFillPath(*pathPtr, &tmpPath);
pathPtr = &tmpPath;
}
@@ -1099,8 +1261,18 @@ static void SkGPU_Draw1Glyph(const SkDraw1Glyph& state,
if (NULL == procs->fFontScaler) {
procs->fFontScaler = get_gr_font_scaler(state.fCache);
}
+
+ /*
+ * Skia calls us with fx,fy already biased by 1/2. It does this to speed
+ * up rounding these, so that all of its procs (like us) can just call
+ * SkFixedFloor and get the "rounded" value.
+ *
+ * We take advantage of that for fx, where we pass a rounded value, but
+ * we want the fractional fy, so we have to unbias it first.
+ */
procs->fTextContext->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), fx, 0),
- SkIntToFixed(SkFixedFloor(fx)), fy,
+ SkIntToFixed(SkFixedFloor(fx)),
+ fy - SK_FixedHalf,
procs->fFontScaler);
}
@@ -1265,9 +1437,7 @@ void SkGpuDevice::unlockCachedTexture(TexCache* cache) {
///////////////////////////////////////////////////////////////////////////////
SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
- GrRenderTarget* rootRenderTarget)
- : fContext(context) {
-
+ GrRenderTarget* rootRenderTarget) {
GrAssert(NULL != context);
GrAssert(NULL != rootRenderTarget);
@@ -1280,13 +1450,32 @@ SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
fRootRenderTarget = rootRenderTarget;
rootRenderTarget->ref();
}
+
+ fContext = context;
context->ref();
+ fRootTexture = NULL;
+}
+
+SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context, GrTexture* rootRenderTargetTexture) {
+ GrAssert(NULL != context);
+ GrAssert(NULL != rootRenderTargetTexture);
+ GrAssert(NULL != rootRenderTargetTexture->asRenderTarget());
+
+ fRootTexture = rootRenderTargetTexture;
+ rootRenderTargetTexture->ref();
+
+ fRootRenderTarget = rootRenderTargetTexture->asRenderTarget();
+ fRootRenderTarget->ref();
+
+ fContext = context;
+ context->ref();
}
SkGpuDeviceFactory::~SkGpuDeviceFactory() {
fContext->unref();
fRootRenderTarget->unref();
+ GrSafeUnref(fRootTexture);
}
SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
@@ -1297,4 +1486,3 @@ SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
bm.setIsOpaque(isOpaque);
return new SkGpuDevice(fContext, bm, isLayer ? NULL : fRootRenderTarget);
}
-
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index e57f88a..e7e2365 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -166,10 +166,9 @@ void SkGrClipIterator::reset(const SkClipStack& clipStack) {
GrClipType SkGrClipIterator::getType() const {
GrAssert(!this->isDone());
- if (NULL != fCurr->fRect) {
+ if (NULL == fCurr->fPath) {
return kRect_ClipType;
} else {
- GrAssert(NULL != fCurr->fPath);
return kPath_ClipType;
}
}
@@ -214,30 +213,25 @@ GrPathFill SkGrClipIterator::getPathFill() const {
///////////////////////////////////////////////////////////////////////////////
-GrTexture::PixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
+GrPixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
bool isOpaque) {
switch (config) {
case SkBitmap::kA8_Config:
- return GrTexture::kAlpha_8_PixelConfig;
+ return kAlpha_8_GrPixelConfig;
case SkBitmap::kIndex8_Config:
- return GrTexture::kIndex_8_PixelConfig;
+ return kIndex_8_GrPixelConfig;
case SkBitmap::kRGB_565_Config:
- return GrTexture::kRGB_565_PixelConfig;
+ return kRGB_565_GrPixelConfig;
case SkBitmap::kARGB_4444_Config:
- return GrTexture::kRGBA_4444_PixelConfig;
+ return kRGBA_4444_GrPixelConfig;
case SkBitmap::kARGB_8888_Config:
if (isOpaque) {
- return GrTexture::kRGBX_8888_PixelConfig;
+ return kRGBX_8888_GrPixelConfig;
} else {
- return GrTexture::kRGBA_8888_PixelConfig;
+ return kRGBA_8888_GrPixelConfig;
}
default:
- return GrTexture::kUnknown_PixelConfig;
+ return kUnknown_GrPixelConfig;
}
}
-void SkGr::AbandonAllTextures(GrContext* ctx) {
- ctx->abandonAllTextures();
-}
-
-
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp
index 16e44b9..e58f035 100644
--- a/src/gpu/SkGrFontScaler.cpp
+++ b/src/gpu/SkGrFontScaler.cpp
@@ -86,6 +86,8 @@ SkGrFontScaler::~SkGrFontScaler() {
GrMaskFormat SkGrFontScaler::getMaskFormat() {
SkMask::Format format = fStrike->getMaskFormat();
switch (format) {
+ case SkMask::kBW_Format:
+ // fall through to kA8 -- we store BW glyphs in our 8-bit cache
case SkMask::kA8_Format:
return kA8_GrMaskFormat;
case SkMask::kLCD16_Format:
@@ -113,6 +115,18 @@ bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
}
+static void bits_to_bytes(const uint8_t bits[], uint8_t bytes[], int count) {
+ while (count > 0) {
+ unsigned mask = *bits++;
+ for (int i = 7; i >= 0; --i) {
+ *bytes++ = (mask & (1 << i)) ? 0xFF : 0;
+ if (--count == 0) {
+ return;
+ }
+ }
+ }
+}
+
bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
int width, int height,
int dstRB, void* dst) {
@@ -127,7 +141,16 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
}
int srcRB = glyph.rowBytes();
- if (srcRB == dstRB) {
+ if (SkMask::kBW_Format == fStrike->getMaskFormat()) {
+ // expand bits to bytes
+ const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
+ uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
+ for (int y = 0; y < height; y++) {
+ bits_to_bytes(bits, bytes, width);
+ bits += srcRB;
+ bytes += dstRB;
+ }
+ } else if (srcRB == dstRB) {
memcpy(dst, src, dstRB * height);
} else {
const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
diff --git a/src/gpu/SkGrTexturePixelRef.cpp b/src/gpu/SkGrTexturePixelRef.cpp
index da9ac1a..8becfd4 100644
--- a/src/gpu/SkGrTexturePixelRef.cpp
+++ b/src/gpu/SkGrTexturePixelRef.cpp
@@ -16,8 +16,12 @@
#include "SkGrTexturePixelRef.h"
+
#include "GrTexture.h"
+#include "SkRect.h"
+#include "SkBitmap.h"
+
SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) {
fTexture = tex;
GrSafeRef(tex);
@@ -27,4 +31,72 @@ SkGrTexturePixelRef::~SkGrTexturePixelRef() {
GrSafeUnref(fTexture);
}
+bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
+ if (NULL != fTexture && fTexture->isValid()) {
+ int left, top, width, height;
+ if (NULL != subset) {
+ left = subset->fLeft;
+ width = subset->width();
+ top = subset->fTop;
+ height = subset->height();
+ } else {
+ left = 0;
+ width = fTexture->width();
+ top = 0;
+ height = fTexture->height();
+ }
+ dst->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ dst->allocPixels();
+ SkAutoLockPixels al(*dst);
+ void* buffer = dst->getPixels();
+ return fTexture->readPixels(left, top, width, height,
+ kRGBA_8888_GrPixelConfig,
+ buffer);
+ } else {
+ return false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SkGrRenderTargetPixelRef::SkGrRenderTargetPixelRef(GrRenderTarget* rt) {
+ fRenderTarget = rt;
+ GrSafeRef(fRenderTarget);
+}
+SkGrRenderTargetPixelRef::~SkGrRenderTargetPixelRef() {
+ GrSafeUnref(fRenderTarget);
+}
+
+SkGpuTexture* SkGrRenderTargetPixelRef::getTexture() {
+ if (NULL != fRenderTarget) {
+ return (SkGpuTexture*) fRenderTarget->asTexture();
+ }
+ return NULL;
+}
+
+bool SkGrRenderTargetPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
+ if (NULL != fRenderTarget && fRenderTarget->isValid()) {
+ int left, top, width, height;
+ if (NULL != subset) {
+ left = subset->fLeft;
+ width = subset->width();
+ top = subset->fTop;
+ height = subset->height();
+ } else {
+ left = 0;
+ width = fRenderTarget->width();
+ top = 0;
+ height = fRenderTarget->height();
+ }
+ dst->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ dst->allocPixels();
+ SkAutoLockPixels al(*dst);
+ void* buffer = dst->getPixels();
+ return fRenderTarget->readPixels(left, top, width, height,
+ kRGBA_8888_GrPixelConfig,
+ buffer);
+ } else {
+ return false;
+ }
+}
diff --git a/src/ports/SkFontHost_FONTPATH.cpp b/src/ports/SkFontHost_FONTPATH.cpp
index 98f4ba5..afab874 100644
--- a/src/ports/SkFontHost_FONTPATH.cpp
+++ b/src/ports/SkFontHost_FONTPATH.cpp
@@ -271,7 +271,8 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
sk_throw(); // not implemented
return NULL;
}
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 7cecb7f..280e0a1 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -98,12 +98,8 @@ InitFreetype() {
// Setup LCD filtering. This reduces colour fringes for LCD rendered
// glyphs.
-//#ifdef ANDROID
-// gLCDSupport = false;
-//#else
err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT);
gLCDSupport = err == 0;
-//#endif
gLCDSupportValid = true;
return true;
@@ -345,7 +341,8 @@ static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
return NULL;
#else
@@ -387,12 +384,6 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
}
}
- SkASSERT(!FT_HAS_VERTICAL(face));
-#ifdef FT_IS_CID_KEYED
- SkASSERT(FT_IS_CID_KEYED(face) ==
- (info->fType == SkAdvancedTypefaceMetrics::kType1CID_Font));
-#endif
-
info->fStyle = 0;
if (FT_IS_FIXED_WIDTH(face))
info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
@@ -464,8 +455,12 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
face->bbox.xMax, face->bbox.yMin);
- if (perGlyphInfo && canEmbed(face) && FT_IS_SCALABLE(face) &&
- info->fType != SkAdvancedTypefaceMetrics::kOther_Font) {
+ if (!canEmbed(face) || !FT_IS_SCALABLE(face) ||
+ info->fType == SkAdvancedTypefaceMetrics::kOther_Font) {
+ perGlyphInfo = SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo;
+ }
+
+ if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
if (FT_IS_FIXED_WIDTH(face)) {
appendRange(&info->fGlyphWidths, 0);
int16_t advance = face->max_advance_width;
@@ -493,18 +488,24 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fGlyphWidths.reset(
getAdvanceData(face, face->num_glyphs, &getWidthAdvance));
}
+ }
- if (info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {
- // Postscript fonts may contain more than 255 glyphs, so we end up
- // using multiple font descriptions with a glyph ordering. Record
- // the name of each glyph.
- info->fGlyphNames.reset(
- new SkAutoTArray<SkString>(face->num_glyphs));
- for (int gID = 0; gID < face->num_glyphs; gID++) {
- char glyphName[128]; // PS limit for names is 127 bytes.
- FT_Get_Glyph_Name(face, gID, glyphName, 128);
- info->fGlyphNames->get()[gID].set(glyphName);
- }
+ if (perGlyphInfo & SkAdvancedTypefaceMetrics::kVAdvance_PerGlyphInfo &&
+ FT_HAS_VERTICAL(face)) {
+ SkASSERT(false); // Not implemented yet.
+ }
+
+ if (perGlyphInfo & SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo &&
+ info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {
+ // Postscript fonts may contain more than 255 glyphs, so we end up
+ // using multiple font descriptions with a glyph ordering. Record
+ // the name of each glyph.
+ info->fGlyphNames.reset(
+ new SkAutoTArray<SkString>(face->num_glyphs));
+ for (int gID = 0; gID < face->num_glyphs; gID++) {
+ char glyphName[128]; // PS limit for names is 127 bytes.
+ FT_Get_Glyph_Name(face, gID, glyphName, 128);
+ info->fGlyphNames->get()[gID].set(glyphName);
}
}
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index 1d40a42..5bc438a 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -481,7 +481,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL;
}
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index ae39361..2def427 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -18,28 +18,18 @@
#include "SkFontHost.h"
#include "SkDescriptor.h"
-#include "SkString.h"
-#include "SkPaint.h"
#include "SkFloatingPoint.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTypeface_mac.h"
#include "SkUtils.h"
-
-//============================================================================
-// Constants
-//----------------------------------------------------------------------------
static const SkFontID kSkInvalidFontID = 0;
static const size_t FONT_CACHE_MEMORY_BUDGET = 1024 * 1024;
static const char FONT_DEFAULT_NAME[] = "Lucida Sans";
-static const float FONT_CANONICAL_POINTSIZE = 1.0f;
-
-
-//============================================================================
-// Types
-//----------------------------------------------------------------------------
-// Native font info
typedef struct {
SkString name;
SkTypeface::Style style;
@@ -47,13 +37,8 @@ typedef struct {
CTFontRef fontRef;
} SkNativeFontInfo;
-typedef std::vector<SkNativeFontInfo> SkNativeFontInfoList;
-typedef SkNativeFontInfoList::iterator SkNativeFontInfoListIterator;
-typedef SkNativeFontInfoList::const_iterator SkNativeFontInfoListConstIterator;
-
-
-
-
+typedef std::vector<SkNativeFontInfo> SkNativeFontInfoList;
+typedef SkNativeFontInfoList::iterator SkNativeFontInfoListIterator;
//============================================================================
// Macros
@@ -73,7 +58,21 @@ typedef SkNativeFontInfoList::const_iterator SkNativeFont
#endif
+static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isMonospace) {
+ unsigned style = SkTypeface::kNormal;
+ CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
+ if (traits & kCTFontBoldTrait) {
+ style |= SkTypeface::kBold;
+ }
+ if (traits & kCTFontItalicTrait) {
+ style |= SkTypeface::kItalic;
+ }
+ if (isMonospace) {
+ *isMonospace = (traits & kCTFontMonoSpaceTrait) != 0;
+ }
+ return (SkTypeface::Style)style;
+}
//============================================================================
@@ -82,34 +81,24 @@ typedef SkNativeFontInfoList::const_iterator SkNativeFont
#pragma mark -
class SkNativeFontCache {
public:
- SkNativeFontCache(void);
- virtual ~SkNativeFontCache(void);
-
-
- // Is a font ID valid?
- bool IsValid(SkFontID fontID);
-
+ SkNativeFontCache(void);
+ virtual ~SkNativeFontCache(void);
- // Get a font
- CTFontRef GetFont(SkFontID fontID);
- SkNativeFontInfo GetFontInfo(const SkString &theName, SkTypeface::Style theStyle);
-
-
- // Create a font
- SkNativeFontInfo CreateFont(const SkString &theName, SkTypeface::Style theStyle);
-
-
- // Get the font table
- static SkNativeFontCache *Get(void);
+ bool IsValid(SkFontID fontID);
+ CTFontRef GetFont(SkFontID fontID);
+ SkNativeFontInfo GetFontInfo(const char familyName[], SkTypeface::Style);
+ SkNativeFontInfo CreateFont(const char familyName[], SkTypeface::Style);
+ SkNativeFontInfo CreateFromCTFont(CTFontRef);
+ static SkNativeFontCache* Get(void);
private:
- CTFontRef CreateNativeFont(const SkString &name, SkTypeface::Style style);
+ CTFontRef CreateNativeFont(const char familyName[], SkTypeface::Style style);
private:
- SkNativeFontInfoList mFonts;
- SkMutex mMutex;
+ SkNativeFontInfoList mFonts;
+ SkMutex mMutex;
};
SkNativeFontCache::SkNativeFontCache(void)
@@ -168,64 +157,76 @@ CTFontRef SkNativeFontCache::GetFont(SkFontID fontID)
return(mFonts.at(fontID).fontRef);
}
-SkNativeFontInfo SkNativeFontCache::GetFontInfo(const SkString &theName, SkTypeface::Style theStyle)
+SkNativeFontInfo SkNativeFontCache::GetFontInfo(const char familyName[],
+ SkTypeface::Style theStyle)
{ SkAutoMutexAcquire acquireLock(mMutex);
SkNativeFontInfo fontInfo;
SkNativeFontInfoListIterator theIter;
-
// Validate our parameters
- SkASSERT(!theName.isEmpty());
-
+ SkASSERT(familyName && *familyName);
// Get the state we need
fontInfo.style = SkTypeface::kNormal;
fontInfo.fontID = kSkInvalidFontID;
fontInfo.fontRef = NULL;
-
// Get the font
- for (theIter = mFonts.begin(); theIter != mFonts.end(); theIter++)
- {
- if (theIter->name == theName && theIter->style == theStyle)
- return(*theIter);
+ for (theIter = mFonts.begin(); theIter != mFonts.end(); theIter++) {
+ if (theIter->style == theStyle && theIter->name.equals(familyName)) {
+ return *theIter;
}
+ }
- return(fontInfo);
+ return fontInfo;
}
-SkNativeFontInfo SkNativeFontCache::CreateFont(const SkString &theName, SkTypeface::Style theStyle)
-{ SkAutoMutexAcquire acquireLock(mMutex);
+SkNativeFontInfo SkNativeFontCache::CreateFont(const char familyName[],
+ SkTypeface::Style theStyle) {
+ SkAutoMutexAcquire acquireLock(mMutex);
SkNativeFontInfo fontInfo;
-
-
+
+
// Validate our parameters
- SkASSERT(!theName.isEmpty());
-
-
+ SkASSERT(familyName && *familyName);
+
+
// Create the font
- fontInfo.name = theName;
- fontInfo.style = theStyle;
- fontInfo.fontID = mFonts.size();
- fontInfo.fontRef = CreateNativeFont(theName, theStyle);
-
+ fontInfo.name.set(familyName);
+ fontInfo.fontID = mFonts.size();
+ fontInfo.fontRef = CreateNativeFont(familyName, theStyle);
+ fontInfo.style = computeStyleBits(fontInfo.fontRef, NULL);
+
mFonts.push_back(fontInfo);
return(fontInfo);
}
-SkNativeFontCache *SkNativeFontCache::Get(void)
-{ static SkNativeFontCache sInstance;
-
+SkNativeFontInfo SkNativeFontCache::CreateFromCTFont(CTFontRef font) {
+ SkAutoMutexAcquire acquireLock(mMutex);
+ SkNativeFontInfo fontInfo;
+
+ // TODO: need to query the font's name
+// fontInfo.name.set(familyName);
+ fontInfo.fontID = mFonts.size();
+ fontInfo.fontRef = font;
+ CFRetain(font);
+ fontInfo.style = computeStyleBits(font, NULL);
+
+ mFonts.push_back(fontInfo);
+ return(fontInfo);
+}
- // Get the instance
- //
+SkNativeFontCache *SkNativeFontCache::Get(void) {
+ static SkNativeFontCache sInstance;
// We use a local static for well-defined static initialisation order.
- return(&sInstance);
+ return &sInstance;
}
///////////////////////////////////////////////////////////////////////////
-CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypeface::Style theStyle)
-{ CFMutableDictionaryRef cfAttributes, cfTraits;
+
+CTFontRef SkNativeFontCache::CreateNativeFont(const char familyName[],
+ SkTypeface::Style theStyle) {
+ CFMutableDictionaryRef cfAttributes, cfTraits;
CFNumberRef cfFontTraits;
CTFontSymbolicTraits ctFontTraits;
CTFontDescriptorRef ctFontDesc;
@@ -246,31 +247,25 @@ CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypefac
// Create the font info
- cfFontName = CFStringCreateWithCString(NULL, theName.c_str(), kCFStringEncodingUTF8);
+ cfFontName = CFStringCreateWithCString(NULL, familyName, kCFStringEncodingUTF8);
cfFontTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits);
cfAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
cfTraits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Create the font
- //
- // Fonts are scaled using the Sk matrix, so we always request a font
- // at a canonical size FONT_CANONICAL_POINTSIZE
- if (cfFontName != NULL && cfFontTraits != NULL && cfAttributes != NULL && cfTraits != NULL)
- {
+ if (cfFontName != NULL && cfFontTraits != NULL && cfAttributes != NULL && cfTraits != NULL) {
CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits);
CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName);
CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits);
ctFontDesc = CTFontDescriptorCreateWithAttributes(cfAttributes);
- if (ctFontDesc != NULL)
- ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, FONT_CANONICAL_POINTSIZE, NULL);
-
+ if (ctFontDesc != NULL) {
+ ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, 0, NULL);
}
+ }
-
- // Clean up
CFSafeRelease(cfFontName);
CFSafeRelease(cfFontTraits);
CFSafeRelease(cfAttributes);
@@ -280,28 +275,27 @@ CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypefac
return(ctFont);
}
-
-
-
-
//============================================================================
// SkTypeface_Mac
//----------------------------------------------------------------------------
#pragma mark -
class SkTypeface_Mac : public SkTypeface {
public:
- SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID);
+ SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID);
};
SkTypeface_Mac::SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID)
- : SkTypeface(style, fontID)
-{
+ : SkTypeface(style, fontID) {
}
-
-
+SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef font) {
+ SkNativeFontInfo info;
+
+ info = SkNativeFontCache::Get()->CreateFromCTFont(font);
+ return new SkTypeface_Mac(info.style, info.fontID);
+}
//============================================================================
// SkScalerContext_Mac
@@ -358,15 +352,15 @@ SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc)
mColorSpaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
mColorSpaceGray = CGColorSpaceCreateDeviceGray();
- const float inv = 1.0f / FONT_CANONICAL_POINTSIZE;
- mTransform = CGAffineTransformMake(SkScalarToFloat(skMatrix[SkMatrix::kMScaleX]) * inv,
- -SkScalarToFloat(skMatrix[SkMatrix::kMSkewY]) * inv,
- -SkScalarToFloat(skMatrix[SkMatrix::kMSkewX]) * inv,
- SkScalarToFloat(skMatrix[SkMatrix::kMScaleY]) * inv,
- SkScalarToFloat(skMatrix[SkMatrix::kMTransX]) * inv,
- SkScalarToFloat(skMatrix[SkMatrix::kMTransY]) * inv);
+ mTransform = CGAffineTransformMake(SkScalarToFloat(skMatrix[SkMatrix::kMScaleX]),
+ -SkScalarToFloat(skMatrix[SkMatrix::kMSkewY]),
+ -SkScalarToFloat(skMatrix[SkMatrix::kMSkewX]),
+ SkScalarToFloat(skMatrix[SkMatrix::kMScaleY]),
+ SkScalarToFloat(skMatrix[SkMatrix::kMTransX]),
+ SkScalarToFloat(skMatrix[SkMatrix::kMTransY]));
- mFont = CTFontCreateCopyWithAttributes(ctFont, 0.0, &mTransform, NULL);
+ // since our matrix includes everything, we pass 1 for pointSize
+ mFont = CTFontCreateCopyWithAttributes(ctFont, 1, &mTransform, NULL);
mGlyphCount = (uint16_t) numGlyphs;
}
@@ -445,6 +439,19 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph)
#include "SkColorPriv.h"
+static void bytes_to_bits(uint8_t dst[], const uint8_t src[], int count) {
+ while (count > 0) {
+ uint8_t mask = 0;
+ for (int i = 7; i >= 0; --i) {
+ mask |= (*src++ >> 7) << i;
+ if (0 == --count) {
+ break;
+ }
+ }
+ *dst++ = mask;
+ }
+}
+
static inline uint16_t rgb_to_lcd16(uint32_t rgb) {
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
@@ -480,6 +487,7 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
void* image = glyph.fImage;
size_t rowBytes = glyph.rowBytes();
float grayColor = 1; // white
+ bool doAA = true;
/* For LCD16, we first create a temp offscreen cg-context in 32bit,
* erase to white, and then draw a black glyph into it. Then we can
@@ -496,6 +504,12 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
// we draw black-on-white (and invert in rgb_to_lcd16)
sk_memset32((uint32_t*)image, 0xFFFFFFFF, size >> 2);
grayColor = 0; // black
+ } else if (SkMask::kBW_Format == glyph.fMaskFormat) {
+ rowBytes = SkAlign4(glyph.fWidth);
+ size_t size = glyph.fHeight * rowBytes;
+ image = storage.realloc(size);
+ sk_bzero(image, size);
+ doAA = false;
}
cgContext = CGBitmapContextCreate(image, glyph.fWidth, glyph.fHeight, 8,
@@ -503,13 +517,15 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
// Draw the glyph
if (cgFont != NULL && cgContext != NULL) {
+#ifdef WE_ARE_RUNNING_ON_10_6_OR_LATER
CGContextSetAllowsFontSubpixelQuantization(cgContext, true);
CGContextSetShouldSubpixelQuantizeFonts(cgContext, true);
-
+#endif
+ CGContextSetShouldAntialias(cgContext, doAA);
CGContextSetGrayFillColor( cgContext, grayColor, 1.0);
CGContextSetTextDrawingMode(cgContext, kCGTextFill);
CGContextSetFont( cgContext, cgFont);
- CGContextSetFontSize( cgContext, FONT_CANONICAL_POINTSIZE);
+ CGContextSetFontSize( cgContext, 1); // cgFont know's its size
CGContextSetTextMatrix( cgContext, mTransform);
CGContextShowGlyphsAtPoint( cgContext, -glyph.fLeft, glyph.fTop + glyph.fHeight, &cgGlyph, 1);
@@ -526,6 +542,16 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
src = (const uint32_t*)((const char*)src + rowBytes);
dst = (uint16_t*)((char*)dst + dstRB);
}
+ } else if (SkMask::kBW_Format == glyph.fMaskFormat) {
+ // downsample from A8 to A1
+ const uint8_t* src = (const uint8_t*)image;
+ uint8_t* dst = (uint8_t*)glyph.fImage;
+ size_t dstRB = glyph.rowBytes();
+ for (int y = 0; y < glyph.fHeight; y++) {
+ bytes_to_bits(dst, src, glyph.fWidth);
+ src += rowBytes;
+ dst += dstRB;
+ }
}
}
@@ -616,48 +642,55 @@ void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element
}
+static const char* map_css_names(const char* name) {
+ static const struct {
+ const char* fFrom;
+ const char* fTo;
+ } gPairs[] = {
+ { "sans-serif", "Helvetica" },
+ { "serif", "Times" },
+ { "monospace", "Courier" }
+ };
-
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
+ if (strcmp(name, gPairs[i].fFrom) == 0) {
+ return gPairs[i].fTo;
+ }
+ }
+ return name; // no change
+}
///////////////////////////////////////////////////////////////////////////
#pragma mark -
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[],
- const void* data, size_t bytelength,
- SkTypeface::Style style)
-{ SkTypeface *theTypeface;
- SkNativeFontCache *fontTable;
- SkNativeFontInfo fontInfo;
- SkString fontName;
-
-
- // Get the state we need
- fontName = SkString(familyName);
- fontTable = SkNativeFontCache::Get();
+ const char familyName[],
+ const void* data, size_t bytelength,
+ SkTypeface::Style style) {
+ if (familyName) {
+ familyName = map_css_names(familyName);
+ }
+ SkNativeFontCache* fontTable = SkNativeFontCache::Get();
// Clone an existing typeface
// TODO: only clone if style matches the familyFace's style...
- if (familyName == NULL && familyFace != NULL)
- {
+ if (familyName == NULL && familyFace != NULL) {
familyFace->ref();
- return(const_cast<SkTypeface*>(familyFace));
- }
-
+ return const_cast<SkTypeface*>(familyFace);
+ }
- if (fontName.isEmpty()) {
- fontName.set(FONT_DEFAULT_NAME);
+ if (!familyName || !*familyName) {
+ familyName = FONT_DEFAULT_NAME;
}
- // Get the native font
- fontInfo = fontTable->GetFontInfo(fontName, style);
- if (fontInfo.fontID == kSkInvalidFontID)
- fontInfo = fontTable->CreateFont(fontName, style);
+ // Get the native font
+ SkNativeFontInfo fontInfo = fontTable->GetFontInfo(familyName, style);
+ if (fontInfo.fontID == kSkInvalidFontID) {
+ fontInfo = fontTable->CreateFont(familyName, style);
+ }
- // Create the typeface
- theTypeface = new SkTypeface_Mac(fontInfo.style, fontInfo.fontID);
- return(theTypeface);
+ return new SkTypeface_Mac(fontInfo.style, fontInfo.fontID);
}
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
@@ -674,7 +707,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL;
}
diff --git a/src/ports/SkFontHost_none.cpp b/src/ports/SkFontHost_none.cpp
index d56c94a..91546f8 100644
--- a/src/ports/SkFontHost_none.cpp
+++ b/src/ports/SkFontHost_none.cpp
@@ -35,7 +35,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL;
}
diff --git a/src/ports/SkFontHost_simple.cpp b/src/ports/SkFontHost_simple.cpp
index 60334e7..54d326e 100644
--- a/src/ports/SkFontHost_simple.cpp
+++ b/src/ports/SkFontHost_simple.cpp
@@ -592,7 +592,8 @@ SkStream* SkFontHost::OpenStream(uint32_t fontID) {
#if 0
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
return NULL;
}
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index a4f430c..a75b002 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -449,7 +449,11 @@ void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
COLORREF color = SetTextColor(dc, 0); // black
SkASSERT(color != CLR_INVALID);
uint16_t glyphID = glyph.getGlyphID();
+#if defined(UNICODE)
ExtTextOut(dc, 0, 0, ETO_GLYPH_INDEX, NULL, (LPCWSTR)&glyphID, 1, NULL);
+#else
+ ExtTextOut(dc, 0, 0, ETO_GLYPH_INDEX, NULL, (LPCSTR)&glyphID, 1, NULL);
+#endif
GdiFlush();
// downsample from rgba to rgb565
@@ -609,7 +613,8 @@ static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
- uint32_t fontID, bool perGlyphInfo) {
+ uint32_t fontID,
+ SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
SkAutoMutexAcquire ac(gFTMutex);
LogFontTypeface* rec = LogFontTypeface::FindById(fontID);
LOGFONT lf = rec->logFont();
@@ -717,7 +722,8 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
// If bit 2 is set, the embedding is read-only.
if (otm.otmfsType & 0x1) {
info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
- } else if (perGlyphInfo) {
+ } else if (perGlyphInfo &
+ SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
info->fGlyphWidths.reset(
getAdvanceData(hdc, glyphCount, &getWidthAdvance));
}
diff --git a/src/ports/ports_files.mk b/src/ports/ports_files.mk
new file mode 100644
index 0000000..563f20b
--- /dev/null
+++ b/src/ports/ports_files.mk
@@ -0,0 +1,6 @@
+SOURCE := \
+ SkDebug_stdio.cpp \
+ SkGlobals_global.cpp \
+ SkOSFile_stdio.cpp \
+ SkThread_pthread.cpp \
+ SkTime_Unix.cpp
diff --git a/src/svg/SkSVGPaintState.cpp b/src/svg/SkSVGPaintState.cpp
index 7fc90c7..f3c65e7 100644
--- a/src/svg/SkSVGPaintState.cpp
+++ b/src/svg/SkSVGPaintState.cpp
@@ -321,7 +321,7 @@ fillStrokeAttrCommon:
if (strncmp(attrValue, "url(", 4) == 0) {
SkASSERT(attrValue[4] == '#');
const char* idStart = attrValue + 5;
- char* idEnd = strrchr(attrValue, ')');
+ const char* idEnd = strrchr(attrValue, ')');
SkASSERT(idStart < idEnd);
SkString id(idStart, idEnd - idStart);
SkSVGElement* found;
diff --git a/src/utils/SkOSFile.cpp b/src/utils/SkOSFile.cpp
index 982bc08..c1b6943 100644
--- a/src/utils/SkOSFile.cpp
+++ b/src/utils/SkOSFile.cpp
@@ -31,18 +31,19 @@ SkUTF16_Str::SkUTF16_Str(const char src[])
size_t len = strlen(src);
fStr = (uint16_t*)sk_malloc_throw((len + 1) * sizeof(uint16_t));
- for (size_t i = 0; i < len; i++)
+ size_t i;
+ for (i = 0; i < len; i++)
fStr[i] = src[i];
fStr[i] = 0;
}
////////////////////////////////////////////////////////////////////////////
-SkOSFile::Iter::Iter() : fHandle(0), fPath16(nil)
+SkOSFile::Iter::Iter() : fHandle(0), fPath16(NULL)
{
}
-SkOSFile::Iter::Iter(const char path[], const char suffix[]) : fHandle(0), fPath16(nil)
+SkOSFile::Iter::Iter(const char path[], const char suffix[]) : fHandle(0), fPath16(NULL)
{
this->reset(path, suffix);
}
@@ -61,7 +62,7 @@ void SkOSFile::Iter::reset(const char path[], const char suffix[])
::FindClose(fHandle);
fHandle = 0;
}
- if (path == nil)
+ if (NULL == path)
path = "";
sk_free(fPath16);
@@ -78,7 +79,7 @@ static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPt
{
WIN32_FIND_DATAW data;
- if (dataPtr == nil)
+ if (NULL == dataPtr)
{
if (::FindNextFileW(handle, &data))
dataPtr = &data;
@@ -90,7 +91,7 @@ static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPt
{
if (getDir)
{
- if ((dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !is_magic_dir(dataPtr->cFileName))
+ if ((dataPtr->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !is_magic_dir((uint16_t*)dataPtr->cFileName))
break;
}
else
@@ -103,21 +104,21 @@ static bool get_the_file(HANDLE handle, SkString* name, WIN32_FIND_DATAW* dataPt
}
// if we get here, we've found a file/dir
if (name)
- name->setUTF16(dataPtr->cFileName);
+ name->setUTF16((uint16_t*)dataPtr->cFileName);
return true;
}
bool SkOSFile::Iter::next(SkString* name, bool getDir)
{
WIN32_FIND_DATAW data;
- WIN32_FIND_DATAW* dataPtr = nil;
+ WIN32_FIND_DATAW* dataPtr = NULL;
if (fHandle == 0) // our first time
{
- if (fPath16 == nil || *fPath16 == 0) // check for no path
+ if (fPath16 == NULL || *fPath16 == 0) // check for no path
return false;
- fHandle = ::FindFirstFileW(fPath16, &data);
+ fHandle = ::FindFirstFileW((LPCWSTR)fPath16, &data);
if (fHandle != 0 && fHandle != (HANDLE)~0)
dataPtr = &data;
}