summaryrefslogtreecommitdiff
path: root/gfx/skia/patches
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/skia/patches
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/skia/patches')
-rw-r--r--gfx/skia/patches/README2
-rw-r--r--gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch66
-rw-r--r--gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch34
-rw-r--r--gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch26
-rw-r--r--gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch38
-rw-r--r--gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch30
-rw-r--r--gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch50
-rw-r--r--gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch39
-rw-r--r--gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch280
-rw-r--r--gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch684
-rw-r--r--gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch36
-rw-r--r--gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch472
-rw-r--r--gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch198
-rw-r--r--gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch147
-rw-r--r--gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch27
-rw-r--r--gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch702
-rw-r--r--gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch168
-rw-r--r--gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch173
-rw-r--r--gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch35
-rw-r--r--gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch28
-rw-r--r--gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch40
-rw-r--r--gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch23
-rw-r--r--gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch36
-rw-r--r--gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch698
-rw-r--r--gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch22
-rw-r--r--gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch28
-rw-r--r--gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch31
-rw-r--r--gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch29
-rw-r--r--gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch22
-rw-r--r--gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch26
-rw-r--r--gfx/skia/patches/archive/0013-Bug-761890-fonts.patch162
-rw-r--r--gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch29
-rw-r--r--gfx/skia/patches/archive/0015-Bug-766017-warnings.patch865
-rw-r--r--gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch400
-rw-r--r--gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch73
-rw-r--r--gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch14
-rw-r--r--gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch39
-rw-r--r--gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch39
-rw-r--r--gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch217
-rw-r--r--gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch26
-rw-r--r--gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch83
-rw-r--r--gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch94
-rw-r--r--gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch39
-rw-r--r--gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch148
-rw-r--r--gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch27
-rw-r--r--gfx/skia/patches/archive/SkPostConfig.patch32
-rw-r--r--gfx/skia/patches/archive/arm-fixes.patch191
-rw-r--r--gfx/skia/patches/archive/arm-opts.patch41
-rw-r--r--gfx/skia/patches/archive/fix-comma-end-enum-list.patch380
-rw-r--r--gfx/skia/patches/archive/fix-gradient-clamp.patch211
-rw-r--r--gfx/skia/patches/archive/getpostextpath.patch70
-rw-r--r--gfx/skia/patches/archive/mingw-fix.patch57
-rw-r--r--gfx/skia/patches/archive/new-aa.patch22
-rw-r--r--gfx/skia/patches/archive/old-android-fonthost.patch530
-rw-r--r--gfx/skia/patches/archive/radial-gradients.patch25
-rw-r--r--gfx/skia/patches/archive/skia_restrict_problem.patch461
-rw-r--r--gfx/skia/patches/archive/uninitialized-margin.patch22
-rw-r--r--gfx/skia/patches/archive/user-config.patch40
58 files changed, 8527 insertions, 0 deletions
diff --git a/gfx/skia/patches/README b/gfx/skia/patches/README
new file mode 100644
index 0000000000..8fd2c5396a
--- /dev/null
+++ b/gfx/skia/patches/README
@@ -0,0 +1,2 @@
+We no longer keep a local patch queue of patches against upstream. The protocol now
+is to upstream all patches before they are landed in mozilla-central.
diff --git a/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch b/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch
new file mode 100644
index 0000000000..f8e76dbb90
--- /dev/null
+++ b/gfx/skia/patches/archive/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch
@@ -0,0 +1,66 @@
+From 27a914815e757ed12523edf968c9da134dabeaf8 Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:10:44 -0400
+Subject: [PATCH 01/10] Bug 755869 - [4] Re-apply bug 687189 - Implement
+ SkPaint::getPosTextPath r=mattwoodrow
+
+---
+ gfx/skia/include/core/SkPaint.h | 3 +++
+ gfx/skia/src/core/SkPaint.cpp | 27 +++++++++++++++++++++++++++
+ 2 files changed, 30 insertions(+), 0 deletions(-)
+
+diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
+index 1930db1..ff37d77 100644
+--- a/gfx/skia/include/core/SkPaint.h
++++ b/gfx/skia/include/core/SkPaint.h
+@@ -813,6 +813,9 @@ public:
+ void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
+ SkPath* path) const;
+
++ void getPosTextPath(const void* text, size_t length,
++ const SkPoint pos[], SkPath* path) const;
++
+ #ifdef SK_BUILD_FOR_ANDROID
+ const SkGlyph& getUnicharMetrics(SkUnichar);
+ const SkGlyph& getGlyphMetrics(uint16_t);
+diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
+index 1b74fa1..4c119aa 100644
+--- a/gfx/skia/src/core/SkPaint.cpp
++++ b/gfx/skia/src/core/SkPaint.cpp
+@@ -1355,6 +1355,33 @@ void SkPaint::getTextPath(const void* textData, size_t length,
+ }
+ }
+
++void SkPaint::getPosTextPath(const void* textData, size_t length,
++ const SkPoint pos[], SkPath* path) const {
++ SkASSERT(length == 0 || textData != NULL);
++
++ const char* text = (const char*)textData;
++ if (text == NULL || length == 0 || path == NULL) {
++ return;
++ }
++
++ SkTextToPathIter iter(text, length, *this, false);
++ SkMatrix matrix;
++ SkPoint prevPos;
++ prevPos.set(0, 0);
++
++ matrix.setScale(iter.getPathScale(), iter.getPathScale());
++ path->reset();
++
++ unsigned int i = 0;
++ const SkPath* iterPath;
++ while ((iterPath = iter.next(NULL)) != NULL) {
++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
++ path->addPath(*iterPath, matrix);
++ prevPos = pos[i];
++ i++;
++ }
++}
++
+ static void add_flattenable(SkDescriptor* desc, uint32_t tag,
+ SkFlattenableWriteBuffer* buffer) {
+ buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch b/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch
new file mode 100644
index 0000000000..8fe0135fbb
--- /dev/null
+++ b/gfx/skia/patches/archive/0001-Bug-777614-Re-add-our-SkUserConfig.h-r-nrc.patch
@@ -0,0 +1,34 @@
+From 2dd8c789fc4ad3b5323c2c29f3e982d185f5b5d9 Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 13 Sep 2012 22:33:38 -0400
+Subject: [PATCH 1/9] Bug 777614 - Re-add our SkUserConfig.h r=nrc
+
+---
+ gfx/skia/include/config/SkUserConfig.h | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
+index 353272c..fbfbfe0 100644
+--- a/gfx/skia/include/config/SkUserConfig.h
++++ b/gfx/skia/include/config/SkUserConfig.h
+@@ -184,5 +184,16 @@
+ directories from your include search path when you're not building the GPU
+ backend. Defaults to 1 (build the GPU code).
+ */
+-//#define SK_SUPPORT_GPU 1
++#define SK_SUPPORT_GPU 0
++
++/* Don't dither 32bit gradients, to match what the canvas test suite expects.
++ */
++#define SK_DISABLE_DITHER_32BIT_GRADIENT
++
++/* Don't include stdint.h on windows as it conflicts with our build system.
++ */
++#ifdef SK_BUILD_FOR_WIN32
++ #define SK_IGNORE_STDINT_DOT_H
++#endif
++
+ #endif
+--
+1.7.11.4
+
diff --git a/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch b/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch
new file mode 100644
index 0000000000..20155977e2
--- /dev/null
+++ b/gfx/skia/patches/archive/0001-Bug-803063-Skia-cross-compilation-for-Windows-fails-.patch
@@ -0,0 +1,26 @@
+From 81ff1a8f5c2a7cc9e8b853101b995433a0c0fa37 Mon Sep 17 00:00:00 2001
+From: Jacek Caban <jacek@codeweavers.com>
+Date: Thu, 18 Oct 2012 15:25:08 +0200
+Subject: [PATCH] Bug 803063 - Skia cross compilation for Windows fails on
+ case sensitive OS
+
+---
+ gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp b/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
+index 370616e..b647ada 100644
+--- a/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
++++ b/gfx/skia/src/core/SkAdvancedTypefaceMetrics.cpp
+@@ -13,7 +13,7 @@
+ SK_DEFINE_INST_COUNT(SkAdvancedTypefaceMetrics)
+
+ #if defined(SK_BUILD_FOR_WIN)
+-#include <DWrite.h>
++#include <dwrite.h>
+ #endif
+
+ #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
+--
+1.7.8.6
+
diff --git a/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch b/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch
new file mode 100644
index 0000000000..aa1fadb435
--- /dev/null
+++ b/gfx/skia/patches/archive/0001-Bug-895086-Remove-unused-find_from_uniqueID-function.patch
@@ -0,0 +1,38 @@
+From 58861c38751adf1f4ef3f67f8e85f5c36f1c43a5 Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Wed, 17 Jul 2013 16:28:07 -0400
+Subject: [PATCH] Bug 895086 - Remove unused find_from_uniqueID() function from
+ SkFontHost_linux
+
+---
+ gfx/skia/src/ports/SkFontHost_linux.cpp | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/gfx/skia/src/ports/SkFontHost_linux.cpp b/gfx/skia/src/ports/SkFontHost_linux.cpp
+index df21014..05b73dc 100644
+--- a/gfx/skia/src/ports/SkFontHost_linux.cpp
++++ b/gfx/skia/src/ports/SkFontHost_linux.cpp
+@@ -117,20 +117,6 @@ static FamilyRec* find_family(const SkTypeface* member) {
+ return NULL;
+ }
+
+-static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
+- FamilyRec* curr = gFamilyHead;
+- while (curr != NULL) {
+- for (int i = 0; i < 4; i++) {
+- SkTypeface* face = curr->fFaces[i];
+- if (face != NULL && face->uniqueID() == uniqueID) {
+- return face;
+- }
+- }
+- curr = curr->fNext;
+- }
+- return NULL;
+-}
+-
+ /* Remove reference to this face from its family. If the resulting family
+ is empty (has no faces), return that family, otherwise return NULL
+ */
+--
+1.8.3.1
+
diff --git a/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch b/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch
new file mode 100644
index 0000000000..d396b4ed12
--- /dev/null
+++ b/gfx/skia/patches/archive/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch
@@ -0,0 +1,30 @@
+From f310d7e8b8d9cf6870c739650324bb585b591c0c Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:11:32 -0400
+Subject: [PATCH 02/10] Bug 755869 - [5] Re-apply bug 688366 - Fix Skia
+ marking radial gradients with the same radius as
+ invalid. r=mattwoodrow
+
+---
+ gfx/skia/src/effects/SkGradientShader.cpp | 5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+index 6de820b..59ba48c 100644
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -1911,7 +1911,10 @@ public:
+ SkPMColor* SK_RESTRICT dstC = dstCParam;
+
+ // Zero difference between radii: fill with transparent black.
+- if (fDiffRadius == 0) {
++ // TODO: Is removing this actually correct? Two circles with the
++ // same radius, but different centers doesn't sound like it
++ // should be cleared
++ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
+ sk_bzero(dstC, count * sizeof(*dstC));
+ return;
+ }
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch b/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch
new file mode 100644
index 0000000000..6ac2c9179d
--- /dev/null
+++ b/gfx/skia/patches/archive/0002-Bug-848491-Re-apply-Bug-795549-Move-TileProc-functio.patch
@@ -0,0 +1,50 @@
+From: George Wright <george@mozilla.com>
+Date: Mon, 14 Jan 2013 17:59:09 -0500
+Subject: Bug 848491 - Re-apply Bug 795549 - Move TileProc functions into their own file to ensure they only exist once in a library
+
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+index b9dbf1b..729ce4e 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+@@ -37,34 +37,9 @@ static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
+ }
+ }
+
+-// Clamp
+-
+-static inline SkFixed clamp_tileproc(SkFixed x) {
+- return SkClampMax(x, 0xFFFF);
+-}
+-
+-// Repeat
+-
+-static inline SkFixed repeat_tileproc(SkFixed x) {
+- return x & 0xFFFF;
+-}
+-
+-// Mirror
+-
+-// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
+-// See http://code.google.com/p/skia/issues/detail?id=472
+-#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+-#pragma optimize("", off)
+-#endif
+-
+-static inline SkFixed mirror_tileproc(SkFixed x) {
+- int s = x << 15 >> 31;
+- return (x ^ s) & 0xFFFF;
+-}
+-
+-#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+-#pragma optimize("", on)
+-#endif
++SkFixed clamp_tileproc(SkFixed x);
++SkFixed repeat_tileproc(SkFixed x);
++SkFixed mirror_tileproc(SkFixed x);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch b/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch
new file mode 100644
index 0000000000..dc52a8d3d0
--- /dev/null
+++ b/gfx/skia/patches/archive/0003-SkUserConfig-for-Mozilla.patch
@@ -0,0 +1,39 @@
+From ef53776c06cffc7607c3777702f93e04c0852981 Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:13:49 -0400
+Subject: [PATCH 03/10] Bug 755869 - [6] Re-apply SkUserConfig (no
+ original bug) r=mattwoodrow
+
+---
+ gfx/skia/include/config/SkUserConfig.h | 10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
+index 9fdbd0a..f98ba85 100644
+--- a/gfx/skia/include/config/SkUserConfig.h
++++ b/gfx/skia/include/config/SkUserConfig.h
+@@ -156,6 +156,10 @@
+ //#define SK_SUPPORT_UNITTEST
+ #endif
+
++/* Don't dither 32bit gradients, to match what the canvas test suite expects.
++ */
++#define SK_DISABLE_DITHER_32BIT_GRADIENT
++
+ /* If your system embeds skia and has complex event logging, define this
+ symbol to name a file that maps the following macros to your system's
+ equivalents:
+@@ -177,4 +181,10 @@
+ #define SK_A32_SHIFT 24
+ #endif
+
++/* Don't include stdint.h on windows as it conflicts with our build system.
++ */
++#ifdef SK_BUILD_FOR_WIN32
++ #define SK_IGNORE_STDINT_DOT_H
++#endif
++
+ #endif
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch b/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch
new file mode 100644
index 0000000000..179aeded5d
--- /dev/null
+++ b/gfx/skia/patches/archive/0004-Bug-722011-Fix-trailing-commas-in-enums.patch
@@ -0,0 +1,280 @@
+From 81d61682a94d47be5b47fb7882ea7e7c7e6c3351 Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:15:28 -0400
+Subject: [PATCH 04/10] Bug 755869 - [7] Re-apply bug 722011 - Fix
+ trailing commas at end of enum lists r=mattwoodrow
+
+---
+ gfx/skia/include/core/SkAdvancedTypefaceMetrics.h | 8 ++++----
+ gfx/skia/include/core/SkBlitRow.h | 2 +-
+ gfx/skia/include/core/SkCanvas.h | 2 +-
+ gfx/skia/include/core/SkDevice.h | 2 +-
+ gfx/skia/include/core/SkDeviceProfile.h | 4 ++--
+ gfx/skia/include/core/SkFlattenable.h | 2 +-
+ gfx/skia/include/core/SkFontHost.h | 4 ++--
+ gfx/skia/include/core/SkMaskFilter.h | 2 +-
+ gfx/skia/include/core/SkPaint.h | 4 ++--
+ gfx/skia/include/core/SkScalerContext.h | 9 +++++----
+ gfx/skia/include/core/SkTypes.h | 2 +-
+ gfx/skia/include/effects/SkLayerDrawLooper.h | 2 +-
+ gfx/skia/src/core/SkBitmap.cpp | 2 +-
+ gfx/skia/src/core/SkGlyphCache.cpp | 2 +-
+ 14 files changed, 24 insertions(+), 23 deletions(-)
+
+diff --git a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+index 09fc9a9..5ffdb45 100644
+--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
++++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+@@ -34,7 +34,7 @@ public:
+ kCFF_Font,
+ kTrueType_Font,
+ kOther_Font,
+- kNotEmbeddable_Font,
++ kNotEmbeddable_Font
+ };
+ // The type of the underlying font program. This field determines which
+ // of the following fields are valid. If it is kOther_Font or
+@@ -56,7 +56,7 @@ public:
+ kItalic_Style = 0x00040,
+ kAllCaps_Style = 0x10000,
+ kSmallCaps_Style = 0x20000,
+- kForceBold_Style = 0x40000,
++ kForceBold_Style = 0x40000
+ };
+ uint16_t fStyle; // Font style characteristics.
+ int16_t fItalicAngle; // Counterclockwise degrees from vertical of the
+@@ -75,7 +75,7 @@ public:
+ kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
+ kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
+ kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
+- kToUnicode_PerGlyphInfo = 0x8, // Populate ToUnicode table, ignored
++ kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored
+ // for Type 1 fonts
+ };
+
+@@ -84,7 +84,7 @@ public:
+ enum MetricType {
+ kDefault, // Default advance: fAdvance.count = 1
+ kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
+- kRun, // fStartID-fEndID have same advance: fAdvance.count = 1
++ kRun // fStartID-fEndID have same advance: fAdvance.count = 1
+ };
+ MetricType fType;
+ uint16_t fStartId;
+diff --git a/gfx/skia/include/core/SkBlitRow.h b/gfx/skia/include/core/SkBlitRow.h
+index 973ab4c..febc405 100644
+--- a/gfx/skia/include/core/SkBlitRow.h
++++ b/gfx/skia/include/core/SkBlitRow.h
+@@ -42,7 +42,7 @@ public:
+
+ enum Flags32 {
+ kGlobalAlpha_Flag32 = 1 << 0,
+- kSrcPixelAlpha_Flag32 = 1 << 1,
++ kSrcPixelAlpha_Flag32 = 1 << 1
+ };
+
+ /** Function pointer that blends 32bit colors onto a 32bit destination.
+diff --git a/gfx/skia/include/core/SkCanvas.h b/gfx/skia/include/core/SkCanvas.h
+index 25cc94a..d942783 100644
+--- a/gfx/skia/include/core/SkCanvas.h
++++ b/gfx/skia/include/core/SkCanvas.h
+@@ -148,7 +148,7 @@ public:
+ * low byte to high byte: R, G, B, A.
+ */
+ kRGBA_Premul_Config8888,
+- kRGBA_Unpremul_Config8888,
++ kRGBA_Unpremul_Config8888
+ };
+
+ /**
+diff --git a/gfx/skia/include/core/SkDevice.h b/gfx/skia/include/core/SkDevice.h
+index 1e4e0a3..b4d44bf 100644
+--- a/gfx/skia/include/core/SkDevice.h
++++ b/gfx/skia/include/core/SkDevice.h
+@@ -139,7 +139,7 @@ public:
+ protected:
+ enum Usage {
+ kGeneral_Usage,
+- kSaveLayer_Usage, // <! internal use only
++ kSaveLayer_Usage // <! internal use only
+ };
+
+ struct TextFlags {
+diff --git a/gfx/skia/include/core/SkDeviceProfile.h b/gfx/skia/include/core/SkDeviceProfile.h
+index 46b9781..f6a0bca 100644
+--- a/gfx/skia/include/core/SkDeviceProfile.h
++++ b/gfx/skia/include/core/SkDeviceProfile.h
+@@ -17,7 +17,7 @@ public:
+ kRGB_Horizontal_LCDConfig,
+ kBGR_Horizontal_LCDConfig,
+ kRGB_Vertical_LCDConfig,
+- kBGR_Vertical_LCDConfig,
++ kBGR_Vertical_LCDConfig
+ };
+
+ enum FontHintLevel {
+@@ -25,7 +25,7 @@ public:
+ kSlight_FontHintLevel,
+ kNormal_FontHintLevel,
+ kFull_FontHintLevel,
+- kAuto_FontHintLevel,
++ kAuto_FontHintLevel
+ };
+
+ /**
+diff --git a/gfx/skia/include/core/SkFlattenable.h b/gfx/skia/include/core/SkFlattenable.h
+index 5714f9d..dc115fc 100644
+--- a/gfx/skia/include/core/SkFlattenable.h
++++ b/gfx/skia/include/core/SkFlattenable.h
+@@ -272,7 +272,7 @@ public:
+ * Instructs the writer to inline Factory names as there are seen the
+ * first time (after that we store an index). The pipe code uses this.
+ */
+- kInlineFactoryNames_Flag = 0x02,
++ kInlineFactoryNames_Flag = 0x02
+ };
+ Flags getFlags() const { return (Flags)fFlags; }
+ void setFlags(Flags flags) { fFlags = flags; }
+diff --git a/gfx/skia/include/core/SkFontHost.h b/gfx/skia/include/core/SkFontHost.h
+index 732de5c..10f9bdf 100644
+--- a/gfx/skia/include/core/SkFontHost.h
++++ b/gfx/skia/include/core/SkFontHost.h
+@@ -240,7 +240,7 @@ public:
+ */
+ enum LCDOrientation {
+ kHorizontal_LCDOrientation = 0, //!< this is the default
+- kVertical_LCDOrientation = 1,
++ kVertical_LCDOrientation = 1
+ };
+
+ static void SetSubpixelOrientation(LCDOrientation orientation);
+@@ -259,7 +259,7 @@ public:
+ enum LCDOrder {
+ kRGB_LCDOrder = 0, //!< this is the default
+ kBGR_LCDOrder = 1,
+- kNONE_LCDOrder = 2,
++ kNONE_LCDOrder = 2
+ };
+
+ static void SetSubpixelOrder(LCDOrder order);
+diff --git a/gfx/skia/include/core/SkMaskFilter.h b/gfx/skia/include/core/SkMaskFilter.h
+index 9a470a4..3422e27 100644
+--- a/gfx/skia/include/core/SkMaskFilter.h
++++ b/gfx/skia/include/core/SkMaskFilter.h
+@@ -61,7 +61,7 @@ public:
+ kNormal_BlurType, //!< fuzzy inside and outside
+ kSolid_BlurType, //!< solid inside, fuzzy outside
+ kOuter_BlurType, //!< nothing inside, fuzzy outside
+- kInner_BlurType, //!< fuzzy inside, nothing outside
++ kInner_BlurType //!< fuzzy inside, nothing outside
+ };
+
+ struct BlurInfo {
+diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
+index ff37d77..7c96e193 100644
+--- a/gfx/skia/include/core/SkPaint.h
++++ b/gfx/skia/include/core/SkPaint.h
+@@ -76,7 +76,7 @@ public:
+ kNo_Hinting = 0,
+ kSlight_Hinting = 1,
+ kNormal_Hinting = 2, //!< this is the default
+- kFull_Hinting = 3,
++ kFull_Hinting = 3
+ };
+
+ Hinting getHinting() const {
+@@ -289,7 +289,7 @@ public:
+ kStroke_Style, //!< stroke the geometry
+ kStrokeAndFill_Style, //!< fill and stroke the geometry
+
+- kStyleCount,
++ kStyleCount
+ };
+
+ /** Return the paint's style, used for controlling how primitives'
+diff --git a/gfx/skia/include/core/SkScalerContext.h b/gfx/skia/include/core/SkScalerContext.h
+index 2cb171b..3dbce27 100644
+--- a/gfx/skia/include/core/SkScalerContext.h
++++ b/gfx/skia/include/core/SkScalerContext.h
+@@ -182,21 +182,22 @@ public:
+ kGenA8FromLCD_Flag = 0x0800,
+
+ #ifdef SK_USE_COLOR_LUMINANCE
+- kLuminance_Bits = 3,
++ kLuminance_Bits = 3
+ #else
+ // luminance : 0 for black text, kLuminance_Max for white text
+ kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags
+- kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits
++ kLuminance_Bits = 3 // ensure Flags doesn't exceed 16bits
+ #endif
+ };
+
+ // computed values
+ enum {
+- kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
+ #ifdef SK_USE_COLOR_LUMINANCE
++ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag
+ #else
++ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
+ kLuminance_Max = (1 << kLuminance_Bits) - 1,
+- kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
++ kLuminance_Mask = kLuminance_Max << kLuminance_Shift
+ #endif
+ };
+
+diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h
+index 7963a7d..0c5c2d7 100644
+--- a/gfx/skia/include/core/SkTypes.h
++++ b/gfx/skia/include/core/SkTypes.h
+@@ -438,7 +438,7 @@ public:
+ * current block is dynamically allocated, just return the old
+ * block.
+ */
+- kReuse_OnShrink,
++ kReuse_OnShrink
+ };
+
+ /**
+diff --git a/gfx/skia/include/effects/SkLayerDrawLooper.h b/gfx/skia/include/effects/SkLayerDrawLooper.h
+index 0bc4af2..6cb8ef6 100644
+--- a/gfx/skia/include/effects/SkLayerDrawLooper.h
++++ b/gfx/skia/include/effects/SkLayerDrawLooper.h
+@@ -41,7 +41,7 @@ public:
+ * - Flags and Color are always computed using the LayerInfo's
+ * fFlagsMask and fColorMode.
+ */
+- kEntirePaint_Bits = -1,
++ kEntirePaint_Bits = -1
+
+ };
+ typedef int32_t BitFlags;
+diff --git a/gfx/skia/src/core/SkBitmap.cpp b/gfx/skia/src/core/SkBitmap.cpp
+index 6b99145..aff52fd 100644
+--- a/gfx/skia/src/core/SkBitmap.cpp
++++ b/gfx/skia/src/core/SkBitmap.cpp
+@@ -1376,7 +1376,7 @@ enum {
+ SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE,
+ SERIALIZE_PIXELTYPE_RAW_NO_CTABLE,
+ SERIALIZE_PIXELTYPE_REF_DATA,
+- SERIALIZE_PIXELTYPE_REF_PTR,
++ SERIALIZE_PIXELTYPE_REF_PTR
+ };
+
+ /*
+diff --git a/gfx/skia/src/core/SkGlyphCache.cpp b/gfx/skia/src/core/SkGlyphCache.cpp
+index f3363cd..1fddc9d 100644
+--- a/gfx/skia/src/core/SkGlyphCache.cpp
++++ b/gfx/skia/src/core/SkGlyphCache.cpp
+@@ -417,7 +417,7 @@ class SkGlyphCache_Globals {
+ public:
+ enum UseMutex {
+ kNo_UseMutex, // thread-local cache
+- kYes_UseMutex, // shared cache
++ kYes_UseMutex // shared cache
+ };
+
+ SkGlyphCache_Globals(UseMutex um) {
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch b/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch
new file mode 100644
index 0000000000..ad6e181274
--- /dev/null
+++ b/gfx/skia/patches/archive/0004-Bug-777614-Re-apply-bug-719872-Fix-crash-on-Android-.patch
@@ -0,0 +1,684 @@
+From 0d730a94e9f6676d5cde45f955fe025a4549817e Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 23 Aug 2012 16:45:38 -0400
+Subject: [PATCH 4/9] Bug 777614 - Re-apply bug 719872 - Fix crash on Android
+ by reverting to older FontHost r=nrc
+
+---
+ gfx/skia/src/ports/SkFontHost_android_old.cpp | 664 ++++++++++++++++++++++++++
+ 1 file changed, 664 insertions(+)
+ create mode 100644 gfx/skia/src/ports/SkFontHost_android_old.cpp
+
+diff --git a/gfx/skia/src/ports/SkFontHost_android_old.cpp b/gfx/skia/src/ports/SkFontHost_android_old.cpp
+new file mode 100644
+index 0000000..b5c4f3c
+--- /dev/null
++++ b/gfx/skia/src/ports/SkFontHost_android_old.cpp
+@@ -0,0 +1,664 @@
++
++/*
++ * Copyright 2006 The Android Open Source Project
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++
++#include "SkFontHost.h"
++#include "SkDescriptor.h"
++#include "SkMMapStream.h"
++#include "SkPaint.h"
++#include "SkString.h"
++#include "SkStream.h"
++#include "SkThread.h"
++#include "SkTSearch.h"
++#include <stdio.h>
++
++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
++
++#ifndef SK_FONT_FILE_PREFIX
++ #define SK_FONT_FILE_PREFIX "/fonts/"
++#endif
++
++bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style,
++ bool* isFixedWidth);
++
++static void GetFullPathForSysFonts(SkString* full, const char name[]) {
++ full->set(getenv("ANDROID_ROOT"));
++ full->append(SK_FONT_FILE_PREFIX);
++ full->append(name);
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++struct FamilyRec;
++
++/* This guy holds a mapping of a name -> family, used for looking up fonts.
++ Since it is stored in a stretchy array that doesn't preserve object
++ semantics, we don't use constructor/destructors, but just have explicit
++ helpers to manage our internal bookkeeping.
++*/
++struct NameFamilyPair {
++ const char* fName; // we own this
++ FamilyRec* fFamily; // we don't own this, we just reference it
++
++ void construct(const char name[], FamilyRec* family) {
++ fName = strdup(name);
++ fFamily = family; // we don't own this, so just record the referene
++ }
++
++ void destruct() {
++ free((char*)fName);
++ // we don't own family, so just ignore our reference
++ }
++};
++
++// we use atomic_inc to grow this for each typeface we create
++static int32_t gUniqueFontID;
++
++// this is the mutex that protects these globals
++static SkMutex gFamilyMutex;
++static FamilyRec* gFamilyHead;
++static SkTDArray<NameFamilyPair> gNameList;
++
++struct FamilyRec {
++ FamilyRec* fNext;
++ SkTypeface* fFaces[4];
++
++ FamilyRec()
++ {
++ fNext = gFamilyHead;
++ memset(fFaces, 0, sizeof(fFaces));
++ gFamilyHead = this;
++ }
++};
++
++static SkTypeface* find_best_face(const FamilyRec* family,
++ SkTypeface::Style style) {
++ SkTypeface* const* faces = family->fFaces;
++
++ if (faces[style] != NULL) { // exact match
++ return faces[style];
++ }
++ // look for a matching bold
++ style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
++ if (faces[style] != NULL) {
++ return faces[style];
++ }
++ // look for the plain
++ if (faces[SkTypeface::kNormal] != NULL) {
++ return faces[SkTypeface::kNormal];
++ }
++ // look for anything
++ for (int i = 0; i < 4; i++) {
++ if (faces[i] != NULL) {
++ return faces[i];
++ }
++ }
++ // should never get here, since the faces list should not be empty
++ SkASSERT(!"faces list is empty");
++ return NULL;
++}
++
++static FamilyRec* find_family(const SkTypeface* member) {
++ FamilyRec* curr = gFamilyHead;
++ while (curr != NULL) {
++ for (int i = 0; i < 4; i++) {
++ if (curr->fFaces[i] == member) {
++ return curr;
++ }
++ }
++ curr = curr->fNext;
++ }
++ return NULL;
++}
++
++/* Returns the matching typeface, or NULL. If a typeface is found, its refcnt
++ is not modified.
++ */
++static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
++ FamilyRec* curr = gFamilyHead;
++ while (curr != NULL) {
++ for (int i = 0; i < 4; i++) {
++ SkTypeface* face = curr->fFaces[i];
++ if (face != NULL && face->uniqueID() == uniqueID) {
++ return face;
++ }
++ }
++ curr = curr->fNext;
++ }
++ return NULL;
++}
++
++/* Remove reference to this face from its family. If the resulting family
++ is empty (has no faces), return that family, otherwise return NULL
++*/
++static FamilyRec* remove_from_family(const SkTypeface* face) {
++ FamilyRec* family = find_family(face);
++ SkASSERT(family->fFaces[face->style()] == face);
++ family->fFaces[face->style()] = NULL;
++
++ for (int i = 0; i < 4; i++) {
++ if (family->fFaces[i] != NULL) { // family is non-empty
++ return NULL;
++ }
++ }
++ return family; // return the empty family
++}
++
++// maybe we should make FamilyRec be doubly-linked
++static void detach_and_delete_family(FamilyRec* family) {
++ FamilyRec* curr = gFamilyHead;
++ FamilyRec* prev = NULL;
++
++ while (curr != NULL) {
++ FamilyRec* next = curr->fNext;
++ if (curr == family) {
++ if (prev == NULL) {
++ gFamilyHead = next;
++ } else {
++ prev->fNext = next;
++ }
++ SkDELETE(family);
++ return;
++ }
++ prev = curr;
++ curr = next;
++ }
++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
++}
++
++static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
++ NameFamilyPair* list = gNameList.begin();
++ int count = gNameList.count();
++
++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
++
++ if (index >= 0) {
++ return find_best_face(list[index].fFamily, style);
++ }
++ return NULL;
++}
++
++static SkTypeface* find_typeface(const SkTypeface* familyMember,
++ SkTypeface::Style style) {
++ const FamilyRec* family = find_family(familyMember);
++ return family ? find_best_face(family, style) : NULL;
++}
++
++static void add_name(const char name[], FamilyRec* family) {
++ SkAutoAsciiToLC tolc(name);
++ name = tolc.lc();
++
++ NameFamilyPair* list = gNameList.begin();
++ int count = gNameList.count();
++
++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
++
++ if (index < 0) {
++ list = gNameList.insert(~index);
++ list->construct(name, family);
++ }
++}
++
++static void remove_from_names(FamilyRec* emptyFamily)
++{
++#ifdef SK_DEBUG
++ for (int i = 0; i < 4; i++) {
++ SkASSERT(emptyFamily->fFaces[i] == NULL);
++ }
++#endif
++
++ SkTDArray<NameFamilyPair>& list = gNameList;
++
++ // must go backwards when removing
++ for (int i = list.count() - 1; i >= 0; --i) {
++ NameFamilyPair* pair = &list[i];
++ if (pair->fFamily == emptyFamily) {
++ pair->destruct();
++ list.remove(i);
++ }
++ }
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++class FamilyTypeface : public SkTypeface {
++public:
++ FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ bool isFixedWidth)
++ : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
++ fIsSysFont = sysFont;
++
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyRec* rec = NULL;
++ if (familyMember) {
++ rec = find_family(familyMember);
++ SkASSERT(rec);
++ } else {
++ rec = SkNEW(FamilyRec);
++ }
++ rec->fFaces[style] = this;
++ }
++
++ virtual ~FamilyTypeface() {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ // remove us from our family. If the family is now empty, we return
++ // that and then remove that family from the name list
++ FamilyRec* family = remove_from_family(this);
++ if (NULL != family) {
++ remove_from_names(family);
++ detach_and_delete_family(family);
++ }
++ }
++
++ bool isSysFont() const { return fIsSysFont; }
++
++ virtual SkStream* openStream() = 0;
++ virtual const char* getUniqueString() const = 0;
++ virtual const char* getFilePath() const = 0;
++
++private:
++ bool fIsSysFont;
++
++ typedef SkTypeface INHERITED;
++};
++
++///////////////////////////////////////////////////////////////////////////////
++
++class StreamTypeface : public FamilyTypeface {
++public:
++ StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ SkStream* stream, bool isFixedWidth)
++ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
++ SkASSERT(stream);
++ stream->ref();
++ fStream = stream;
++ }
++ virtual ~StreamTypeface() {
++ fStream->unref();
++ }
++
++ // overrides
++ virtual SkStream* openStream() {
++ // we just ref our existing stream, since the caller will call unref()
++ // when they are through
++ fStream->ref();
++ // must rewind each time, since the caller assumes a "new" stream
++ fStream->rewind();
++ return fStream;
++ }
++ virtual const char* getUniqueString() const { return NULL; }
++ virtual const char* getFilePath() const { return NULL; }
++
++private:
++ SkStream* fStream;
++
++ typedef FamilyTypeface INHERITED;
++};
++
++class FileTypeface : public FamilyTypeface {
++public:
++ FileTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ const char path[], bool isFixedWidth)
++ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
++ SkString fullpath;
++
++ if (sysFont) {
++ GetFullPathForSysFonts(&fullpath, path);
++ path = fullpath.c_str();
++ }
++ fPath.set(path);
++ }
++
++ // overrides
++ virtual SkStream* openStream() {
++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
++
++ // check for failure
++ if (stream->getLength() <= 0) {
++ SkDELETE(stream);
++ // maybe MMAP isn't supported. try FILE
++ stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
++ if (stream->getLength() <= 0) {
++ SkDELETE(stream);
++ stream = NULL;
++ }
++ }
++ return stream;
++ }
++ virtual const char* getUniqueString() const {
++ const char* str = strrchr(fPath.c_str(), '/');
++ if (str) {
++ str += 1; // skip the '/'
++ }
++ return str;
++ }
++ virtual const char* getFilePath() const {
++ return fPath.c_str();
++ }
++
++private:
++ SkString fPath;
++
++ typedef FamilyTypeface INHERITED;
++};
++
++///////////////////////////////////////////////////////////////////////////////
++///////////////////////////////////////////////////////////////////////////////
++
++static bool get_name_and_style(const char path[], SkString* name,
++ SkTypeface::Style* style,
++ bool* isFixedWidth, bool isExpected) {
++ SkString fullpath;
++ GetFullPathForSysFonts(&fullpath, path);
++
++ SkMMAPStream stream(fullpath.c_str());
++ if (stream.getLength() > 0) {
++ find_name_and_attributes(&stream, name, style, isFixedWidth);
++ return true;
++ }
++ else {
++ SkFILEStream stream(fullpath.c_str());
++ if (stream.getLength() > 0) {
++ find_name_and_attributes(&stream, name, style, isFixedWidth);
++ return true;
++ }
++ }
++
++ if (isExpected) {
++ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
++ }
++ return false;
++}
++
++// used to record our notion of the pre-existing fonts
++struct FontInitRec {
++ const char* fFileName;
++ const char* const* fNames; // null-terminated list
++};
++
++static const char* gSansNames[] = {
++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
++};
++
++static const char* gSerifNames[] = {
++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
++};
++
++static const char* gMonoNames[] = {
++ "monospace", "courier", "courier new", "monaco", NULL
++};
++
++// deliberately empty, but we use the address to identify fallback fonts
++static const char* gFBNames[] = { NULL };
++
++/* Fonts must be grouped by family, with the first font in a family having the
++ list of names (even if that list is empty), and the following members having
++ null for the list. The names list must be NULL-terminated
++*/
++static const FontInitRec gSystemFonts[] = {
++ { "DroidSans.ttf", gSansNames },
++ { "DroidSans-Bold.ttf", NULL },
++ { "DroidSerif-Regular.ttf", gSerifNames },
++ { "DroidSerif-Bold.ttf", NULL },
++ { "DroidSerif-Italic.ttf", NULL },
++ { "DroidSerif-BoldItalic.ttf", NULL },
++ { "DroidSansMono.ttf", gMonoNames },
++ /* These are optional, and can be ignored if not found in the file system.
++ These are appended to gFallbackFonts[] as they are seen, so we list
++ them in the order we want them to be accessed by NextLogicalFont().
++ */
++ { "DroidSansArabic.ttf", gFBNames },
++ { "DroidSansHebrew.ttf", gFBNames },
++ { "DroidSansThai.ttf", gFBNames },
++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "DroidSansJapanese.ttf", gFBNames },
++ { "DroidSansFallback.ttf", gFBNames }
++};
++
++#define DEFAULT_NAMES gSansNames
++
++// these globals are assigned (once) by load_system_fonts()
++static FamilyRec* gDefaultFamily;
++static SkTypeface* gDefaultNormal;
++
++/* This is sized conservatively, assuming that it will never be a size issue.
++ It will be initialized in load_system_fonts(), and will be filled with the
++ fontIDs that can be used for fallback consideration, in sorted order (sorted
++ meaning element[0] should be used first, then element[1], etc. When we hit
++ a fontID==0 in the array, the list is done, hence our allocation size is
++ +1 the total number of possible system fonts. Also see NextLogicalFont().
++ */
++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
++
++/* Called once (ensured by the sentinel check at the beginning of our body).
++ Initializes all the globals, and register the system fonts.
++ */
++static void load_system_fonts() {
++ // check if we've already be called
++ if (NULL != gDefaultNormal) {
++ return;
++ }
++
++ const FontInitRec* rec = gSystemFonts;
++ SkTypeface* firstInFamily = NULL;
++ int fallbackCount = 0;
++
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
++ // if we're the first in a new family, clear firstInFamily
++ if (rec[i].fNames != NULL) {
++ firstInFamily = NULL;
++ }
++
++ bool isFixedWidth;
++ SkString name;
++ SkTypeface::Style style;
++
++ // we expect all the fonts, except the "fallback" fonts
++ bool isExpected = (rec[i].fNames != gFBNames);
++ if (!get_name_and_style(rec[i].fFileName, &name, &style,
++ &isFixedWidth, isExpected)) {
++ continue;
++ }
++
++ SkTypeface* tf = SkNEW_ARGS(FileTypeface,
++ (style,
++ true, // system-font (cannot delete)
++ firstInFamily, // what family to join
++ rec[i].fFileName,
++ isFixedWidth) // filename
++ );
++
++ if (rec[i].fNames != NULL) {
++ // see if this is one of our fallback fonts
++ if (rec[i].fNames == gFBNames) {
++ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
++ // rec[i].fFileName, fallbackCount, tf->uniqueID());
++ gFallbackFonts[fallbackCount++] = tf->uniqueID();
++ }
++
++ firstInFamily = tf;
++ FamilyRec* family = find_family(tf);
++ const char* const* names = rec[i].fNames;
++
++ // record the default family if this is it
++ if (names == DEFAULT_NAMES) {
++ gDefaultFamily = family;
++ }
++ // add the names to map to this family
++ while (*names) {
++ add_name(*names, family);
++ names += 1;
++ }
++ }
++ }
++
++ // do this after all fonts are loaded. This is our default font, and it
++ // acts as a sentinel so we only execute load_system_fonts() once
++ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
++ // now terminate our fallback list with the sentinel value
++ gFallbackFonts[fallbackCount] = 0;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
++ const char* name = ((FamilyTypeface*)face)->getUniqueString();
++
++ stream->write8((uint8_t)face->style());
++
++ if (NULL == name || 0 == *name) {
++ stream->writePackedUInt(0);
++// SkDebugf("--- fonthost serialize null\n");
++ } else {
++ uint32_t len = strlen(name);
++ stream->writePackedUInt(len);
++ stream->write(name, len);
++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
++ }
++}
++
++SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
++ load_system_fonts();
++
++ int style = stream->readU8();
++
++ int len = stream->readPackedUInt();
++ if (len > 0) {
++ SkString str;
++ str.resize(len);
++ stream->read(str.writable_str(), len);
++
++ const FontInitRec* rec = gSystemFonts;
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
++ // backup until we hit the fNames
++ for (int j = i; j >= 0; --j) {
++ if (rec[j].fNames != NULL) {
++ return SkFontHost::CreateTypeface(NULL,
++ rec[j].fNames[0], (SkTypeface::Style)style);
++ }
++ }
++ }
++ }
++ }
++ return NULL;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
++ const char familyName[],
++ SkTypeface::Style style) {
++ load_system_fonts();
++
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ // clip to legal style bits
++ style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
++
++ SkTypeface* tf = NULL;
++
++ if (NULL != familyFace) {
++ tf = find_typeface(familyFace, style);
++ } else if (NULL != familyName) {
++// SkDebugf("======= familyName <%s>\n", familyName);
++ tf = find_typeface(familyName, style);
++ }
++
++ if (NULL == tf) {
++ tf = find_best_face(gDefaultFamily, style);
++ }
++
++ // we ref(), since the symantic is to return a new instance
++ tf->ref();
++ return tf;
++}
++
++SkStream* SkFontHost::OpenStream(uint32_t fontID) {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
++ SkStream* stream = tf ? tf->openStream() : NULL;
++
++ if (stream && stream->getLength() == 0) {
++ stream->unref();
++ stream = NULL;
++ }
++ return stream;
++}
++
++size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
++ int32_t* index) {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
++ const char* src = tf ? tf->getFilePath() : NULL;
++
++ if (src) {
++ size_t size = strlen(src);
++ if (path) {
++ memcpy(path, src, SkMin32(size, length));
++ }
++ if (index) {
++ *index = 0; // we don't have collections (yet)
++ }
++ return size;
++ } else {
++ return 0;
++ }
++}
++
++SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
++ load_system_fonts();
++
++ /* First see if fontID is already one of our fallbacks. If so, return
++ its successor. If fontID is not in our list, then return the first one
++ in our list. Note: list is zero-terminated, and returning zero means
++ we have no more fonts to use for fallbacks.
++ */
++ const uint32_t* list = gFallbackFonts;
++ for (int i = 0; list[i] != 0; i++) {
++ if (list[i] == currFontID) {
++ return list[i+1];
++ }
++ }
++ return list[0];
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
++ if (NULL == stream || stream->getLength() <= 0) {
++ return NULL;
++ }
++
++ bool isFixedWidth;
++ SkString name;
++ SkTypeface::Style style;
++ find_name_and_attributes(stream, &name, &style, &isFixedWidth);
++
++ if (!name.isEmpty()) {
++ return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth));
++ } else {
++ return NULL;
++ }
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
++ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
++ // since we created the stream, we let go of our ref() here
++ stream->unref();
++ return face;
++}
++
++///////////////////////////////////////////////////////////////////////////////
+--
+1.7.11.4
+
diff --git a/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch b/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch
new file mode 100644
index 0000000000..e8b5df635b
--- /dev/null
+++ b/gfx/skia/patches/archive/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch
@@ -0,0 +1,36 @@
+From 80350275c72921ed5ac405c029ae33727467d7c5 Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:15:50 -0400
+Subject: [PATCH 05/10] Bug 755869 - [8] Re-apply bug 731384 - Fix compile
+ errors on older versions of clang r=mattwoodrow
+
+---
+ gfx/skia/include/core/SkPostConfig.h | 9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+index 8316f7a..041fe2a 100644
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -288,9 +288,18 @@
+ #if defined(_MSC_VER)
+ #define SK_OVERRIDE override
+ #elif defined(__clang__)
++#if __has_feature(cxx_override_control)
+ // Some documentation suggests we should be using __attribute__((override)),
+ // but it doesn't work.
+ #define SK_OVERRIDE override
++#elif defined(__has_extension)
++#if __has_extension(cxx_override_control)
++#define SK_OVERRIDE override
++#endif
++#endif
++#ifndef SK_OVERRIDE
++#define SK_OVERRIDE
++#endif
+ #else
+ // Linux GCC ignores "__attribute__((override))" and rejects "override".
+ #define SK_OVERRIDE
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch
new file mode 100644
index 0000000000..4b76fcea1d
--- /dev/null
+++ b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch
@@ -0,0 +1,472 @@
+From: George Wright <george@mozilla.com>
+Date: Wed, 1 Aug 2012 16:43:15 -0400
+Subject: Bug 736276 - Add a new SkFontHost that takes a cairo_scaled_font_t r=karl
+
+
+diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in
+index 5ebbd2e..7c8cdbf 100644
+--- a/gfx/skia/Makefile.in
++++ b/gfx/skia/Makefile.in
+@@ -60,15 +60,15 @@ VPATH += \
+ $(NULL)
+
+ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
+-OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
++OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
+ endif
+
+ ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
+-OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
++OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS)
+ endif
+
+ ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
+-OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
++OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS)
+ ifeq (Linux,$(OS_TARGET))
+ DEFINES += -DSK_USE_POSIX_THREADS=1
+ endif
+diff --git a/gfx/skia/include/ports/SkTypeface_cairo.h b/gfx/skia/include/ports/SkTypeface_cairo.h
+new file mode 100644
+index 0000000..7e44f04
+--- /dev/null
++++ b/gfx/skia/include/ports/SkTypeface_cairo.h
+@@ -0,0 +1,11 @@
++#ifndef SkTypeface_cairo_DEFINED
++#define SkTypeface_cairo_DEFINED
++
++#include <cairo.h>
++
++#include "SkTypeface.h"
++
++SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth);
++
++#endif
++
+diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build
+index 9ceba59..66efd52 100644
+--- a/gfx/skia/moz.build
++++ b/gfx/skia/moz.build
+@@ -171,10 +171,12 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ 'SkTime_win.cpp',
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+- 'SkFontHost_linux.cpp',
+ 'SkThread_pthread.cpp',
+ 'SkThreadUtils_pthread.cpp',
+ 'SkThreadUtils_pthread_linux.cpp',
+@@ -183,14 +185,15 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
+ CPP_SOURCES += [
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+ 'SkOSFile.cpp',
+ ]
+ if CONFIG['OS_TARGET'] == 'Linux':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+- 'SkFontHost_linux.cpp',
+- 'SkFontHost_tables.cpp',
+ 'SkThread_pthread.cpp',
+ 'SkThreadUtils_pthread.cpp',
+ 'SkThreadUtils_pthread_linux.cpp',
+@@ -204,11 +207,13 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+ # Separate 'if' from above, since the else below applies to all != 'android'
+ # toolkits.
+ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+ 'ashmem.cpp',
+ 'SkDebug_android.cpp',
+- 'SkFontHost_android_old.cpp',
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+ 'SkImageRef_ashmem.cpp',
+ 'SkTime_Unix.cpp',
+diff --git a/gfx/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/src/ports/SkFontHost_cairo.cpp
+new file mode 100644
+index 0000000..bb5b778
+--- /dev/null
++++ b/gfx/skia/src/ports/SkFontHost_cairo.cpp
+@@ -0,0 +1,364 @@
++
++/*
++ * Copyright 2012 Mozilla Foundation
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include "cairo.h"
++#include "cairo-ft.h"
++
++#include "SkFontHost_FreeType_common.h"
++
++#include "SkAdvancedTypefaceMetrics.h"
++#include "SkFontHost.h"
++#include "SkPath.h"
++#include "SkScalerContext.h"
++#include "SkTypefaceCache.h"
++
++#include <ft2build.h>
++#include FT_FREETYPE_H
++
++static cairo_user_data_key_t kSkTypefaceKey;
++
++class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
++public:
++ SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc);
++ virtual ~SkScalerContext_CairoFT();
++
++protected:
++ virtual unsigned generateGlyphCount() SK_OVERRIDE;
++ virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
++ virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
++ virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
++ virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
++ virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
++ virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
++ SkPaint::FontMetrics* my) SK_OVERRIDE;
++ virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
++private:
++ cairo_scaled_font_t* fScaledFont;
++ uint32_t fLoadGlyphFlags;
++};
++
++class CairoLockedFTFace {
++public:
++ CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
++ : fScaledFont(scaledFont)
++ , fFace(cairo_ft_scaled_font_lock_face(scaledFont))
++ {}
++
++ ~CairoLockedFTFace()
++ {
++ cairo_ft_scaled_font_unlock_face(fScaledFont);
++ }
++
++ FT_Face getFace()
++ {
++ return fFace;
++ }
++
++private:
++ cairo_scaled_font_t* fScaledFont;
++ FT_Face fFace;
++};
++
++class SkCairoFTTypeface : public SkTypeface {
++public:
++ static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
++ SkASSERT(fontFace != NULL);
++ SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
++
++ SkFontID newId = SkTypefaceCache::NewFontID();
++
++ return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
++ }
++
++ cairo_font_face_t* getFontFace() {
++ return fFontFace;
++ }
++
++ virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
++
++ virtual SkAdvancedTypefaceMetrics*
++ onGetAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::PerGlyphInfo,
++ const uint32_t*, uint32_t) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetAdvancedTypefaceMetrics unimplemented\n"));
++ return NULL;
++ }
++
++ virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE
++ {
++ return SkNEW_ARGS(SkScalerContext_CairoFT, (const_cast<SkCairoFTTypeface*>(this), desc));
++ }
++
++ virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onFilterRec unimplemented\n"));
++ }
++
++ virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetFontDescriptor unimplemented\n"));
++ }
++
++
++private:
++
++ SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
++ : SkTypeface(style, id, isFixedWidth)
++ , fFontFace(fontFace)
++ {
++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
++ cairo_font_face_reference(fFontFace);
++ }
++
++ ~SkCairoFTTypeface()
++ {
++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
++ cairo_font_face_destroy(fFontFace);
++ }
++
++ cairo_font_face_t* fFontFace;
++};
++
++SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
++{
++ SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
++
++ if (typeface) {
++ typeface->ref();
++ } else {
++ typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
++ SkTypefaceCache::Add(typeface, style);
++ }
++
++ return typeface;
++}
++
++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
++ const char famillyName[],
++ SkTypeface::Style style)
++{
++ SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
++ return NULL;
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
++{
++ SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
++ return NULL;
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
++{
++ SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
++ return NULL;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++static bool isLCD(const SkScalerContext::Rec& rec) {
++ switch (rec.fMaskFormat) {
++ case SkMask::kLCD16_Format:
++ case SkMask::kLCD32_Format:
++ return true;
++ default:
++ return false;
++ }
++}
++
++///////////////////////////////////////////////////////////////////////////////
++SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc)
++ : SkScalerContext_FreeType_Base(typeface, desc)
++{
++ SkMatrix matrix;
++ fRec.getSingleMatrix(&matrix);
++
++ cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace();
++
++ cairo_matrix_t fontMatrix, ctMatrix;
++ cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
++ cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
++
++ // We need to ensure that the font options match for hinting, as generateMetrics()
++ // uses the fScaledFont which uses these font options
++ cairo_font_options_t *fontOptions = cairo_font_options_create();
++
++ FT_Int32 loadFlags = FT_LOAD_DEFAULT;
++
++ if (SkMask::kBW_Format == fRec.fMaskFormat) {
++ // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
++ loadFlags = FT_LOAD_TARGET_MONO;
++ if (fRec.getHinting() == SkPaint::kNo_Hinting) {
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
++ loadFlags = FT_LOAD_NO_HINTING;
++ }
++ } else {
++ switch (fRec.getHinting()) {
++ case SkPaint::kNo_Hinting:
++ loadFlags = FT_LOAD_NO_HINTING;
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
++ break;
++ case SkPaint::kSlight_Hinting:
++ loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
++ break;
++ case SkPaint::kNormal_Hinting:
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
++ loadFlags = FT_LOAD_FORCE_AUTOHINT;
++ }
++ break;
++ case SkPaint::kFull_Hinting:
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
++ loadFlags = FT_LOAD_FORCE_AUTOHINT;
++ }
++ if (isLCD(fRec)) {
++ if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
++ loadFlags = FT_LOAD_TARGET_LCD_V;
++ } else {
++ loadFlags = FT_LOAD_TARGET_LCD;
++ }
++ }
++ break;
++ default:
++ SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
++ break;
++ }
++ }
++
++ fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
++
++ if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
++ loadFlags |= FT_LOAD_NO_BITMAP;
++ }
++
++ // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
++ // advances, as fontconfig and cairo do.
++ // See http://code.google.com/p/skia/issues/detail?id=222.
++ loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
++
++ fLoadGlyphFlags = loadFlags;
++}
++
++SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
++{
++ cairo_scaled_font_destroy(fScaledFont);
++}
++
++unsigned SkScalerContext_CairoFT::generateGlyphCount()
++{
++ CairoLockedFTFace faceLock(fScaledFont);
++ return faceLock.getFace()->num_glyphs;
++}
++
++uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
++{
++ CairoLockedFTFace faceLock(fScaledFont);
++ return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
++}
++
++void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
++{
++ generateMetrics(glyph);
++}
++
++void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ cairo_text_extents_t extents;
++ cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
++ cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
++
++ glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
++ glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
++ glyph->fWidth = SkToU16(SkScalarCeil(extents.width));
++ glyph->fHeight = SkToU16(SkScalarCeil(extents.height));
++ glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing));
++ glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing));
++ glyph->fLsbDelta = 0;
++ glyph->fRsbDelta = 0;
++}
++
++void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
++
++ if (err != 0) {
++ memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
++ return;
++ }
++
++ generateGlyphImage(face, glyph);
++}
++
++void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ SkASSERT(&glyph && path);
++
++ uint32_t flags = fLoadGlyphFlags;
++ flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
++ flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
++
++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
++
++ if (err != 0) {
++ path->reset();
++ return;
++ }
++
++ generateGlyphPath(face, path);
++}
++
++void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
++ SkPaint::FontMetrics* my)
++{
++ SkDEBUGCODE(SkDebugf("SkScalerContext_CairoFT::generateFontMetrics unimplemented\n"));
++}
++
++SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ FT_UInt glyphIndex;
++ SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
++ while (glyphIndex != 0) {
++ if (glyphIndex == glyph) {
++ return charCode;
++ }
++ charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
++ }
++
++ return 0;
++}
++
++#ifdef SK_BUILD_FOR_ANDROID
++SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
++ SkFontID origFontID) {
++ return NULL;
++}
++#endif
++
++///////////////////////////////////////////////////////////////////////////////
++
++#include "SkFontMgr.h"
++
++SkFontMgr* SkFontMgr::Factory() {
++ // todo
++ return NULL;
++}
++
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch b/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch
new file mode 100644
index 0000000000..cfcb40b9d7
--- /dev/null
+++ b/gfx/skia/patches/archive/0005-Bug-777614-Re-apply-bug-687188-Expand-the-gradient-c.patch
@@ -0,0 +1,198 @@
+From 1ab13a923399aa638388231baca784ba89f2c82b Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Wed, 12 Sep 2012 12:30:29 -0400
+Subject: [PATCH 5/9] Bug 777614 - Re-apply bug 687188 - Expand the gradient
+ cache by 2 to store 0/1 colour stop values for
+ clamping. r=nrc
+
+---
+ .../src/effects/gradients/SkGradientShader.cpp | 22 +++++++++++----
+ .../src/effects/gradients/SkGradientShaderPriv.h | 5 +++-
+ .../src/effects/gradients/SkLinearGradient.cpp | 32 ++++++++++++++++------
+ .../gradients/SkTwoPointConicalGradient.cpp | 11 ++++++--
+ .../effects/gradients/SkTwoPointRadialGradient.cpp | 11 ++++++--
+ 5 files changed, 61 insertions(+), 20 deletions(-)
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+index f0dac4d..79e7202 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+@@ -426,15 +426,15 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) {
+
+ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ if (fCache32 == NULL) {
+- // double the count for dither entries
+- const int entryCount = kCache32Count * 2;
++ // double the count for dither entries, and have an extra two entries for clamp values
++ const int entryCount = kCache32Count * 2 + 2;
+ const size_t allocSize = sizeof(SkPMColor) * entryCount;
+
+ if (NULL == fCache32PixelRef) {
+ fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ }
+- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
+ if (fColorCount == 2) {
+ Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
+ kGradient32Length, fCacheAlpha);
+@@ -458,7 +458,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ SkPMColor* linear = fCache32; // just computed linear data
+- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
+ SkUnitMapper* map = fMapper;
+ for (int i = 0; i < kGradient32Length; i++) {
+ int index = map->mapUnit16((i << 8) | i) >> 8;
+@@ -467,10 +467,22 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ }
+ fCache32PixelRef->unref();
+ fCache32PixelRef = newPR;
+- fCache32 = (SkPMColor*)newPR->getAddr();
++ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
+ }
+ complete_32bit_cache(fCache32, kCache32Count);
+ }
++
++ // Write the clamp colours into the first and last entries of fCache32
++ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha,
++ SkColorGetR(fOrigColors[0]),
++ SkColorGetG(fOrigColors[0]),
++ SkColorGetB(fOrigColors[0]));
++
++ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha,
++ SkColorGetR(fOrigColors[fColorCount - 1]),
++ SkColorGetG(fOrigColors[fColorCount - 1]),
++ SkColorGetB(fOrigColors[fColorCount - 1]));
++
+ return fCache32;
+ }
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+index 0e7c2fc..7427935 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+@@ -133,7 +133,10 @@ public:
+ kDitherStride32 = 0,
+ #endif
+ kDitherStride16 = kCache16Count,
+- kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1
++ kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1,
++
++ kCache32ClampLower = -1,
++ kCache32ClampUpper = kCache32Count * 2
+ };
+
+
+diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+index bcebc26..d400b4d 100644
+--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+@@ -126,6 +126,17 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
++ if (proc == clamp_tileproc) {
++ // No need to lerp or dither for clamp values
++ if (fx < 0) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
++ return;
++ } else if (fx > 0xffff) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
++ return;
++ }
++ }
++
+ // We're a vertical gradient, so no change in a span.
+ // If colors change sharply across the gradient, dithering is
+ // insufficient (it subsamples the color space) and we need to lerp.
+@@ -144,6 +155,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
++ if (proc == clamp_tileproc) {
++ // No need to lerp or dither for clamp values
++ if (fx < 0) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
++ return;
++ } else if (fx > 0xffff) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
++ return;
++ }
++ }
++
+ // We're a vertical gradient, so no change in a span.
+ // If colors change sharply across the gradient, dithering is
+ // insufficient (it subsamples the color space) and we need to lerp.
+@@ -169,10 +191,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient32Length);
+
+ if ((count = range.fCount0) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV0],
+- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV0],
+- count);
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
+ dstC += count;
+ }
+ if ((count = range.fCount1) > 0) {
+@@ -191,10 +210,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ }
+ }
+ if ((count = range.fCount2) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV1],
+- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV1],
+- count);
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
+ }
+ }
+
+diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+index 3466d2c..764a444 100644
+--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+@@ -123,9 +123,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
+ if (TwoPtRadial::DontDrawT(t)) {
+ *dstC++ = 0;
+ } else {
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
++ if (t < 0) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
++ }
+ }
+ }
+ }
+diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
+index 9362ded..22b028e 100644
+--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
+@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+ fOneOverTwoA, posRoot);
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
++ if (t < 0) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
++ }
+ fx += dx;
+ fy += dy;
+ b += db;
+--
+1.7.11.4
+
diff --git a/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch b/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch
new file mode 100644
index 0000000000..eb75691ad7
--- /dev/null
+++ b/gfx/skia/patches/archive/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch
@@ -0,0 +1,147 @@
+From 94916fbbc7865c6fe23a57d6edc48c6daf93dda8 Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:16:08 -0400
+Subject: [PATCH 06/10] Bug 755869 - [9] Re-apply bug 751814 - Various
+ Skia fixes for ARM without EDSP and ARMv6+
+ r=mattwoodrow
+
+---
+ gfx/skia/include/core/SkMath.h | 5 +--
+ gfx/skia/include/core/SkPostConfig.h | 45 ++++++++++++++++++++++
+ gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp | 6 +-
+ gfx/skia/src/opts/SkBlitRow_opts_arm.cpp | 9 ++++
+ 4 files changed, 58 insertions(+), 7 deletions(-)
+
+diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h
+index 5889103..7a4b707 100644
+--- a/gfx/skia/include/core/SkMath.h
++++ b/gfx/skia/include/core/SkMath.h
+@@ -153,10 +153,7 @@ static inline bool SkIsPow2(int value) {
+ With this requirement, we can generate faster instructions on some
+ architectures.
+ */
+-#if defined(__arm__) \
+- && !defined(__thumb__) \
+- && !defined(__ARM_ARCH_4T__) \
+- && !defined(__ARM_ARCH_5T__)
++#ifdef SK_ARM_HAS_EDSP
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+index 041fe2a..03105e4 100644
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -311,3 +311,48 @@
+ #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+ #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
+ #endif
++
++//////////////////////////////////////////////////////////////////////
++// ARM defines
++
++#if defined(__GNUC__) && defined(__arm__)
++
++# define SK_ARM_ARCH 3
++
++# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
++ || defined(_ARM_ARCH_4)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 4
++# endif
++
++# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
++ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
++ || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 5
++# endif
++
++# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
++ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
++ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
++ || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 6
++# endif
++
++# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
++ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
++ || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 7
++# endif
++
++# undef SK_ARM_HAS_EDSP
++# if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
++ || !defined(__thumb__) \
++ && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
++ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
++# define SK_ARM_HAS_EDSP 1
++# endif
++
++#endif
+diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
+index 20d62e1..deb1bfe 100644
+--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
+@@ -11,7 +11,7 @@
+ #include "SkColorPriv.h"
+ #include "SkUtils.h"
+
+-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+ void SI8_D16_nofilter_DX_arm(
+ const SkBitmapProcState& s,
+ const uint32_t* SK_RESTRICT xy,
+@@ -182,7 +182,7 @@ void SI8_opaque_D32_nofilter_DX_arm(const SkBitmapProcState& s,
+
+ s.fBitmap->getColorTable()->unlockColors(false);
+ }
+-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+@@ -200,7 +200,7 @@ void SkBitmapProcState::platformProcs() {
+
+ switch (fBitmap->config()) {
+ case SkBitmap::kIndex8_Config:
+-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+ if (justDx && !doFilter) {
+ #if 0 /* crashing on android device */
+ fSampleProc16 = SI8_D16_nofilter_DX_arm;
+diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+index 2490371..c928888 100644
+--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+@@ -675,8 +675,13 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_
+ /* dst1_scale and dst2_scale*/
+ "lsr r9, r5, #24 \n\t" /* src >> 24 */
+ "lsr r10, r6, #24 \n\t" /* src >> 24 */
++#ifdef SK_ARM_HAS_EDSP
+ "smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
+ "smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
++#else
++ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
++ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
++#endif
+ "lsr r9, r9, #8 \n\t" /* r9 >> 8 */
+ "lsr r10, r10, #8 \n\t" /* r10 >> 8 */
+ "rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */
+@@ -745,7 +750,11 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_
+
+ "lsr r6, r5, #24 \n\t" /* src >> 24 */
+ "and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */
++#ifdef SK_ARM_HAS_EDSP
+ "smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
++#else
++ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
++#endif
+ "and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */
+ "lsr r6, r6, #8 \n\t" /* r6 >> 8 */
+ "mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch b/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch
new file mode 100644
index 0000000000..2850000ace
--- /dev/null
+++ b/gfx/skia/patches/archive/0006-Bug-848491-Re-apply-Bug-777614-Add-our-SkUserConfig..patch
@@ -0,0 +1,27 @@
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 25 Apr 2013 20:40:12 -0400
+Subject: Bug 848491 - Re-apply Bug 777614 - Add our SkUserConfig.h
+
+
+diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
+index 63fc90d..c965e91 100644
+--- a/gfx/skia/include/config/SkUserConfig.h
++++ b/gfx/skia/include/config/SkUserConfig.h
+@@ -201,4 +201,14 @@
+ */
+ //#define SK_SUPPORT_GPU 1
+
++/* Don't dither 32bit gradients, to match what the canvas test suite expects.
++ */
++#define SK_DISABLE_DITHER_32BIT_GRADIENT
++
++/* Don't include stdint.h on windows as it conflicts with our build system.
++ */
++#ifdef SK_BUILD_FOR_WIN32
++ #define SK_IGNORE_STDINT_DOT_H
++#endif
++
+ #endif
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch b/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch
new file mode 100644
index 0000000000..ca34e1a457
--- /dev/null
+++ b/gfx/skia/patches/archive/0007-Bug-719872-Old-Android-FontHost.patch
@@ -0,0 +1,702 @@
+From 6982ad469adcdfa2b7bdbf8bbd843bc22d3832fc Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Fri, 18 May 2012 14:52:40 -0400
+Subject: [PATCH 07/10] Bug 755869 - [10] Re-apply bug 719872 - Fix crash
+ on Android by reverting to older FontHost impl
+ r=mattwoodrow
+
+---
+ gfx/skia/Makefile.in | 5 +-
+ gfx/skia/src/ports/SkFontHost_android_old.cpp | 664 +++++++++++++++++++++++++
+ 2 files changed, 668 insertions(+), 1 deletions(-)
+ create mode 100644 gfx/skia/src/ports/SkFontHost_android_old.cpp
+
+diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in
+index 9da098a..8184f1c 100644
+--- a/gfx/skia/Makefile.in
++++ b/gfx/skia/Makefile.in
+@@ -327,7 +327,10 @@ endif
+ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
+ CPPSRCS += \
+ SkDebug_android.cpp \
+- SkFontHost_none.cpp \
++ SkFontHost_android_old.cpp \
++ SkFontHost_gamma.cpp \
++ SkFontHost_FreeType.cpp \
++ SkFontHost_tables.cpp \
+ SkMMapStream.cpp \
+ SkTime_Unix.cpp \
+ SkThread_pthread.cpp \
+diff --git a/gfx/skia/src/ports/SkFontHost_android_old.cpp b/gfx/skia/src/ports/SkFontHost_android_old.cpp
+new file mode 100644
+index 0000000..b5c4f3c
+--- /dev/null
++++ b/gfx/skia/src/ports/SkFontHost_android_old.cpp
+@@ -0,0 +1,664 @@
++
++/*
++ * Copyright 2006 The Android Open Source Project
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++
++#include "SkFontHost.h"
++#include "SkDescriptor.h"
++#include "SkMMapStream.h"
++#include "SkPaint.h"
++#include "SkString.h"
++#include "SkStream.h"
++#include "SkThread.h"
++#include "SkTSearch.h"
++#include <stdio.h>
++
++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
++
++#ifndef SK_FONT_FILE_PREFIX
++ #define SK_FONT_FILE_PREFIX "/fonts/"
++#endif
++
++bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style,
++ bool* isFixedWidth);
++
++static void GetFullPathForSysFonts(SkString* full, const char name[]) {
++ full->set(getenv("ANDROID_ROOT"));
++ full->append(SK_FONT_FILE_PREFIX);
++ full->append(name);
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++struct FamilyRec;
++
++/* This guy holds a mapping of a name -> family, used for looking up fonts.
++ Since it is stored in a stretchy array that doesn't preserve object
++ semantics, we don't use constructor/destructors, but just have explicit
++ helpers to manage our internal bookkeeping.
++*/
++struct NameFamilyPair {
++ const char* fName; // we own this
++ FamilyRec* fFamily; // we don't own this, we just reference it
++
++ void construct(const char name[], FamilyRec* family) {
++ fName = strdup(name);
++ fFamily = family; // we don't own this, so just record the referene
++ }
++
++ void destruct() {
++ free((char*)fName);
++ // we don't own family, so just ignore our reference
++ }
++};
++
++// we use atomic_inc to grow this for each typeface we create
++static int32_t gUniqueFontID;
++
++// this is the mutex that protects these globals
++static SkMutex gFamilyMutex;
++static FamilyRec* gFamilyHead;
++static SkTDArray<NameFamilyPair> gNameList;
++
++struct FamilyRec {
++ FamilyRec* fNext;
++ SkTypeface* fFaces[4];
++
++ FamilyRec()
++ {
++ fNext = gFamilyHead;
++ memset(fFaces, 0, sizeof(fFaces));
++ gFamilyHead = this;
++ }
++};
++
++static SkTypeface* find_best_face(const FamilyRec* family,
++ SkTypeface::Style style) {
++ SkTypeface* const* faces = family->fFaces;
++
++ if (faces[style] != NULL) { // exact match
++ return faces[style];
++ }
++ // look for a matching bold
++ style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
++ if (faces[style] != NULL) {
++ return faces[style];
++ }
++ // look for the plain
++ if (faces[SkTypeface::kNormal] != NULL) {
++ return faces[SkTypeface::kNormal];
++ }
++ // look for anything
++ for (int i = 0; i < 4; i++) {
++ if (faces[i] != NULL) {
++ return faces[i];
++ }
++ }
++ // should never get here, since the faces list should not be empty
++ SkASSERT(!"faces list is empty");
++ return NULL;
++}
++
++static FamilyRec* find_family(const SkTypeface* member) {
++ FamilyRec* curr = gFamilyHead;
++ while (curr != NULL) {
++ for (int i = 0; i < 4; i++) {
++ if (curr->fFaces[i] == member) {
++ return curr;
++ }
++ }
++ curr = curr->fNext;
++ }
++ return NULL;
++}
++
++/* Returns the matching typeface, or NULL. If a typeface is found, its refcnt
++ is not modified.
++ */
++static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
++ FamilyRec* curr = gFamilyHead;
++ while (curr != NULL) {
++ for (int i = 0; i < 4; i++) {
++ SkTypeface* face = curr->fFaces[i];
++ if (face != NULL && face->uniqueID() == uniqueID) {
++ return face;
++ }
++ }
++ curr = curr->fNext;
++ }
++ return NULL;
++}
++
++/* Remove reference to this face from its family. If the resulting family
++ is empty (has no faces), return that family, otherwise return NULL
++*/
++static FamilyRec* remove_from_family(const SkTypeface* face) {
++ FamilyRec* family = find_family(face);
++ SkASSERT(family->fFaces[face->style()] == face);
++ family->fFaces[face->style()] = NULL;
++
++ for (int i = 0; i < 4; i++) {
++ if (family->fFaces[i] != NULL) { // family is non-empty
++ return NULL;
++ }
++ }
++ return family; // return the empty family
++}
++
++// maybe we should make FamilyRec be doubly-linked
++static void detach_and_delete_family(FamilyRec* family) {
++ FamilyRec* curr = gFamilyHead;
++ FamilyRec* prev = NULL;
++
++ while (curr != NULL) {
++ FamilyRec* next = curr->fNext;
++ if (curr == family) {
++ if (prev == NULL) {
++ gFamilyHead = next;
++ } else {
++ prev->fNext = next;
++ }
++ SkDELETE(family);
++ return;
++ }
++ prev = curr;
++ curr = next;
++ }
++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
++}
++
++static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
++ NameFamilyPair* list = gNameList.begin();
++ int count = gNameList.count();
++
++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
++
++ if (index >= 0) {
++ return find_best_face(list[index].fFamily, style);
++ }
++ return NULL;
++}
++
++static SkTypeface* find_typeface(const SkTypeface* familyMember,
++ SkTypeface::Style style) {
++ const FamilyRec* family = find_family(familyMember);
++ return family ? find_best_face(family, style) : NULL;
++}
++
++static void add_name(const char name[], FamilyRec* family) {
++ SkAutoAsciiToLC tolc(name);
++ name = tolc.lc();
++
++ NameFamilyPair* list = gNameList.begin();
++ int count = gNameList.count();
++
++ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
++
++ if (index < 0) {
++ list = gNameList.insert(~index);
++ list->construct(name, family);
++ }
++}
++
++static void remove_from_names(FamilyRec* emptyFamily)
++{
++#ifdef SK_DEBUG
++ for (int i = 0; i < 4; i++) {
++ SkASSERT(emptyFamily->fFaces[i] == NULL);
++ }
++#endif
++
++ SkTDArray<NameFamilyPair>& list = gNameList;
++
++ // must go backwards when removing
++ for (int i = list.count() - 1; i >= 0; --i) {
++ NameFamilyPair* pair = &list[i];
++ if (pair->fFamily == emptyFamily) {
++ pair->destruct();
++ list.remove(i);
++ }
++ }
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++class FamilyTypeface : public SkTypeface {
++public:
++ FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ bool isFixedWidth)
++ : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
++ fIsSysFont = sysFont;
++
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyRec* rec = NULL;
++ if (familyMember) {
++ rec = find_family(familyMember);
++ SkASSERT(rec);
++ } else {
++ rec = SkNEW(FamilyRec);
++ }
++ rec->fFaces[style] = this;
++ }
++
++ virtual ~FamilyTypeface() {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ // remove us from our family. If the family is now empty, we return
++ // that and then remove that family from the name list
++ FamilyRec* family = remove_from_family(this);
++ if (NULL != family) {
++ remove_from_names(family);
++ detach_and_delete_family(family);
++ }
++ }
++
++ bool isSysFont() const { return fIsSysFont; }
++
++ virtual SkStream* openStream() = 0;
++ virtual const char* getUniqueString() const = 0;
++ virtual const char* getFilePath() const = 0;
++
++private:
++ bool fIsSysFont;
++
++ typedef SkTypeface INHERITED;
++};
++
++///////////////////////////////////////////////////////////////////////////////
++
++class StreamTypeface : public FamilyTypeface {
++public:
++ StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ SkStream* stream, bool isFixedWidth)
++ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
++ SkASSERT(stream);
++ stream->ref();
++ fStream = stream;
++ }
++ virtual ~StreamTypeface() {
++ fStream->unref();
++ }
++
++ // overrides
++ virtual SkStream* openStream() {
++ // we just ref our existing stream, since the caller will call unref()
++ // when they are through
++ fStream->ref();
++ // must rewind each time, since the caller assumes a "new" stream
++ fStream->rewind();
++ return fStream;
++ }
++ virtual const char* getUniqueString() const { return NULL; }
++ virtual const char* getFilePath() const { return NULL; }
++
++private:
++ SkStream* fStream;
++
++ typedef FamilyTypeface INHERITED;
++};
++
++class FileTypeface : public FamilyTypeface {
++public:
++ FileTypeface(Style style, bool sysFont, SkTypeface* familyMember,
++ const char path[], bool isFixedWidth)
++ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
++ SkString fullpath;
++
++ if (sysFont) {
++ GetFullPathForSysFonts(&fullpath, path);
++ path = fullpath.c_str();
++ }
++ fPath.set(path);
++ }
++
++ // overrides
++ virtual SkStream* openStream() {
++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
++
++ // check for failure
++ if (stream->getLength() <= 0) {
++ SkDELETE(stream);
++ // maybe MMAP isn't supported. try FILE
++ stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
++ if (stream->getLength() <= 0) {
++ SkDELETE(stream);
++ stream = NULL;
++ }
++ }
++ return stream;
++ }
++ virtual const char* getUniqueString() const {
++ const char* str = strrchr(fPath.c_str(), '/');
++ if (str) {
++ str += 1; // skip the '/'
++ }
++ return str;
++ }
++ virtual const char* getFilePath() const {
++ return fPath.c_str();
++ }
++
++private:
++ SkString fPath;
++
++ typedef FamilyTypeface INHERITED;
++};
++
++///////////////////////////////////////////////////////////////////////////////
++///////////////////////////////////////////////////////////////////////////////
++
++static bool get_name_and_style(const char path[], SkString* name,
++ SkTypeface::Style* style,
++ bool* isFixedWidth, bool isExpected) {
++ SkString fullpath;
++ GetFullPathForSysFonts(&fullpath, path);
++
++ SkMMAPStream stream(fullpath.c_str());
++ if (stream.getLength() > 0) {
++ find_name_and_attributes(&stream, name, style, isFixedWidth);
++ return true;
++ }
++ else {
++ SkFILEStream stream(fullpath.c_str());
++ if (stream.getLength() > 0) {
++ find_name_and_attributes(&stream, name, style, isFixedWidth);
++ return true;
++ }
++ }
++
++ if (isExpected) {
++ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
++ }
++ return false;
++}
++
++// used to record our notion of the pre-existing fonts
++struct FontInitRec {
++ const char* fFileName;
++ const char* const* fNames; // null-terminated list
++};
++
++static const char* gSansNames[] = {
++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
++};
++
++static const char* gSerifNames[] = {
++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
++};
++
++static const char* gMonoNames[] = {
++ "monospace", "courier", "courier new", "monaco", NULL
++};
++
++// deliberately empty, but we use the address to identify fallback fonts
++static const char* gFBNames[] = { NULL };
++
++/* Fonts must be grouped by family, with the first font in a family having the
++ list of names (even if that list is empty), and the following members having
++ null for the list. The names list must be NULL-terminated
++*/
++static const FontInitRec gSystemFonts[] = {
++ { "DroidSans.ttf", gSansNames },
++ { "DroidSans-Bold.ttf", NULL },
++ { "DroidSerif-Regular.ttf", gSerifNames },
++ { "DroidSerif-Bold.ttf", NULL },
++ { "DroidSerif-Italic.ttf", NULL },
++ { "DroidSerif-BoldItalic.ttf", NULL },
++ { "DroidSansMono.ttf", gMonoNames },
++ /* These are optional, and can be ignored if not found in the file system.
++ These are appended to gFallbackFonts[] as they are seen, so we list
++ them in the order we want them to be accessed by NextLogicalFont().
++ */
++ { "DroidSansArabic.ttf", gFBNames },
++ { "DroidSansHebrew.ttf", gFBNames },
++ { "DroidSansThai.ttf", gFBNames },
++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "DroidSansJapanese.ttf", gFBNames },
++ { "DroidSansFallback.ttf", gFBNames }
++};
++
++#define DEFAULT_NAMES gSansNames
++
++// these globals are assigned (once) by load_system_fonts()
++static FamilyRec* gDefaultFamily;
++static SkTypeface* gDefaultNormal;
++
++/* This is sized conservatively, assuming that it will never be a size issue.
++ It will be initialized in load_system_fonts(), and will be filled with the
++ fontIDs that can be used for fallback consideration, in sorted order (sorted
++ meaning element[0] should be used first, then element[1], etc. When we hit
++ a fontID==0 in the array, the list is done, hence our allocation size is
++ +1 the total number of possible system fonts. Also see NextLogicalFont().
++ */
++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
++
++/* Called once (ensured by the sentinel check at the beginning of our body).
++ Initializes all the globals, and register the system fonts.
++ */
++static void load_system_fonts() {
++ // check if we've already be called
++ if (NULL != gDefaultNormal) {
++ return;
++ }
++
++ const FontInitRec* rec = gSystemFonts;
++ SkTypeface* firstInFamily = NULL;
++ int fallbackCount = 0;
++
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
++ // if we're the first in a new family, clear firstInFamily
++ if (rec[i].fNames != NULL) {
++ firstInFamily = NULL;
++ }
++
++ bool isFixedWidth;
++ SkString name;
++ SkTypeface::Style style;
++
++ // we expect all the fonts, except the "fallback" fonts
++ bool isExpected = (rec[i].fNames != gFBNames);
++ if (!get_name_and_style(rec[i].fFileName, &name, &style,
++ &isFixedWidth, isExpected)) {
++ continue;
++ }
++
++ SkTypeface* tf = SkNEW_ARGS(FileTypeface,
++ (style,
++ true, // system-font (cannot delete)
++ firstInFamily, // what family to join
++ rec[i].fFileName,
++ isFixedWidth) // filename
++ );
++
++ if (rec[i].fNames != NULL) {
++ // see if this is one of our fallback fonts
++ if (rec[i].fNames == gFBNames) {
++ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
++ // rec[i].fFileName, fallbackCount, tf->uniqueID());
++ gFallbackFonts[fallbackCount++] = tf->uniqueID();
++ }
++
++ firstInFamily = tf;
++ FamilyRec* family = find_family(tf);
++ const char* const* names = rec[i].fNames;
++
++ // record the default family if this is it
++ if (names == DEFAULT_NAMES) {
++ gDefaultFamily = family;
++ }
++ // add the names to map to this family
++ while (*names) {
++ add_name(*names, family);
++ names += 1;
++ }
++ }
++ }
++
++ // do this after all fonts are loaded. This is our default font, and it
++ // acts as a sentinel so we only execute load_system_fonts() once
++ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
++ // now terminate our fallback list with the sentinel value
++ gFallbackFonts[fallbackCount] = 0;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
++ const char* name = ((FamilyTypeface*)face)->getUniqueString();
++
++ stream->write8((uint8_t)face->style());
++
++ if (NULL == name || 0 == *name) {
++ stream->writePackedUInt(0);
++// SkDebugf("--- fonthost serialize null\n");
++ } else {
++ uint32_t len = strlen(name);
++ stream->writePackedUInt(len);
++ stream->write(name, len);
++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
++ }
++}
++
++SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
++ load_system_fonts();
++
++ int style = stream->readU8();
++
++ int len = stream->readPackedUInt();
++ if (len > 0) {
++ SkString str;
++ str.resize(len);
++ stream->read(str.writable_str(), len);
++
++ const FontInitRec* rec = gSystemFonts;
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
++ // backup until we hit the fNames
++ for (int j = i; j >= 0; --j) {
++ if (rec[j].fNames != NULL) {
++ return SkFontHost::CreateTypeface(NULL,
++ rec[j].fNames[0], (SkTypeface::Style)style);
++ }
++ }
++ }
++ }
++ }
++ return NULL;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
++ const char familyName[],
++ SkTypeface::Style style) {
++ load_system_fonts();
++
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ // clip to legal style bits
++ style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
++
++ SkTypeface* tf = NULL;
++
++ if (NULL != familyFace) {
++ tf = find_typeface(familyFace, style);
++ } else if (NULL != familyName) {
++// SkDebugf("======= familyName <%s>\n", familyName);
++ tf = find_typeface(familyName, style);
++ }
++
++ if (NULL == tf) {
++ tf = find_best_face(gDefaultFamily, style);
++ }
++
++ // we ref(), since the symantic is to return a new instance
++ tf->ref();
++ return tf;
++}
++
++SkStream* SkFontHost::OpenStream(uint32_t fontID) {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
++ SkStream* stream = tf ? tf->openStream() : NULL;
++
++ if (stream && stream->getLength() == 0) {
++ stream->unref();
++ stream = NULL;
++ }
++ return stream;
++}
++
++size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
++ int32_t* index) {
++ SkAutoMutexAcquire ac(gFamilyMutex);
++
++ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
++ const char* src = tf ? tf->getFilePath() : NULL;
++
++ if (src) {
++ size_t size = strlen(src);
++ if (path) {
++ memcpy(path, src, SkMin32(size, length));
++ }
++ if (index) {
++ *index = 0; // we don't have collections (yet)
++ }
++ return size;
++ } else {
++ return 0;
++ }
++}
++
++SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
++ load_system_fonts();
++
++ /* First see if fontID is already one of our fallbacks. If so, return
++ its successor. If fontID is not in our list, then return the first one
++ in our list. Note: list is zero-terminated, and returning zero means
++ we have no more fonts to use for fallbacks.
++ */
++ const uint32_t* list = gFallbackFonts;
++ for (int i = 0; list[i] != 0; i++) {
++ if (list[i] == currFontID) {
++ return list[i+1];
++ }
++ }
++ return list[0];
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
++ if (NULL == stream || stream->getLength() <= 0) {
++ return NULL;
++ }
++
++ bool isFixedWidth;
++ SkString name;
++ SkTypeface::Style style;
++ find_name_and_attributes(stream, &name, &style, &isFixedWidth);
++
++ if (!name.isEmpty()) {
++ return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth));
++ } else {
++ return NULL;
++ }
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
++ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
++ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
++ // since we created the stream, we let go of our ref() here
++ stream->unref();
++ return face;
++}
++
++///////////////////////////////////////////////////////////////////////////////
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch b/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch
new file mode 100644
index 0000000000..73bca9a48d
--- /dev/null
+++ b/gfx/skia/patches/archive/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch
@@ -0,0 +1,168 @@
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 25 Apr 2013 20:47:06 -0400
+Subject: Bug 848491 - Re-apply bug 687188 - Expand the gradient cache by 2 to store 0/1 colour stop values for clamping.
+
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+index 684355d..27a9c46 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+@@ -453,15 +453,15 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
+
+ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ if (fCache32 == NULL) {
+- // double the count for dither entries
+- const int entryCount = kCache32Count * 4;
++ // double the count for dither entries, and have an extra two entries for clamp values
++ const int entryCount = kCache32Count * 4 + 2;
+ const size_t allocSize = sizeof(SkPMColor) * entryCount;
+
+ if (NULL == fCache32PixelRef) {
+ fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ }
+- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
+ if (fColorCount == 2) {
+ Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
+ kCache32Count, fCacheAlpha);
+@@ -484,7 +484,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ SkPMColor* linear = fCache32; // just computed linear data
+- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
+ SkUnitMapper* map = fMapper;
+ for (int i = 0; i < kCache32Count; i++) {
+ int index = map->mapUnit16((i << 8) | i) >> 8;
+@@ -495,9 +495,21 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ }
+ fCache32PixelRef->unref();
+ fCache32PixelRef = newPR;
+- fCache32 = (SkPMColor*)newPR->getAddr();
++ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
+ }
+ }
++
++ // Write the clamp colours into the first and last entries of fCache32
++ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha,
++ SkColorGetR(fOrigColors[0]),
++ SkColorGetG(fOrigColors[0]),
++ SkColorGetB(fOrigColors[0]));
++
++ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha,
++ SkColorGetR(fOrigColors[fColorCount - 1]),
++ SkColorGetG(fOrigColors[fColorCount - 1]),
++ SkColorGetB(fOrigColors[fColorCount - 1]));
++
+ return fCache32;
+ }
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+index 729ce4e..2cb6a9d 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+@@ -86,6 +86,9 @@ public:
+ /// if dithering is disabled.
+ kDitherStride32 = kCache32Count,
+ kDitherStride16 = kCache16Count,
++
++ kCache32ClampLower = -1,
++ kCache32ClampUpper = kCache32Count * 4
+ };
+
+
+diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+index e0f216c..40ab918 100644
+--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+@@ -127,6 +127,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
++ if (proc == clamp_tileproc) {
++ // No need to lerp or dither for clamp values
++ if (fx < 0) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
++ return;
++ } else if (fx > 0xffff) {
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
++ return;
++ }
++ }
++
+ // We're a vertical gradient, so no change in a span.
+ // If colors change sharply across the gradient, dithering is
+ // insufficient (it subsamples the color space) and we need to lerp.
+@@ -154,10 +165,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
+
+ if ((count = range.fCount0) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV0],
+- cache[next_dither_toggle(toggle) + range.fV0],
+- count);
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
+ dstC += count;
+ }
+ if ((count = range.fCount1) > 0) {
+@@ -176,10 +184,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ }
+ }
+ if ((count = range.fCount2) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV1],
+- cache[next_dither_toggle(toggle) + range.fV1],
+- count);
++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
+ }
+ }
+
+diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+index abd974b..601fff4 100644
+--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+@@ -124,10 +124,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
+ if (TwoPtRadial::DontDrawT(t)) {
+ *dstC++ = 0;
+ } else {
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[toggle +
+- (index >> SkGradientShaderBase::kCache32Shift)];
++ if (t < 0) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
++ }
+ }
+ toggle = next_dither_toggle(toggle);
+ }
+diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
+index f70b67d..ec2ae75 100644
+--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
++++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
+@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+ fOneOverTwoA, posRoot);
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
++ if (t < 0) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
++ }
+ fx += dx;
+ fy += dy;
+ b += db;
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch b/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch
new file mode 100644
index 0000000000..0f60dbd8ea
--- /dev/null
+++ b/gfx/skia/patches/archive/0008-Bug-687188-Skia-radial-gradients.patch
@@ -0,0 +1,173 @@
+From f941ea32e44a2436d235e83ef1a434289a9d9c1e Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Wed, 23 May 2012 11:40:25 -0400
+Subject: [PATCH 08/10] Bug 755869 - [11] Re-apply bug 687188 - Skia
+ radial gradients should use the 0/1 color stop values
+ for clamping. r=mattwoodrow
+
+---
+ gfx/skia/src/effects/SkGradientShader.cpp | 76 +++++++++++++++++++++++------
+ 1 files changed, 61 insertions(+), 15 deletions(-)
+
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+index 59ba48c..ea05a39 100644
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -204,6 +204,7 @@ private:
+ mutable SkMallocPixelRef* fCache32PixelRef;
+ mutable unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value
+
++ static SkPMColor PremultiplyColor(SkColor c0, U8CPU alpha);
+ static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
+ static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
+ U8CPU alpha);
+@@ -507,6 +508,21 @@ static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) {
+ return ((n << 1) - (n | (n >> 8))) >> 8;
+ }
+
++SkPMColor Gradient_Shader::PremultiplyColor(SkColor c0, U8CPU paintAlpha)
++{
++ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
++ SkFixed r = SkColorGetR(c0);
++ SkFixed g = SkColorGetG(c0);
++ SkFixed b = SkColorGetB(c0);
++
++ a = SkIntToFixed(a) + 0x8000;
++ r = SkIntToFixed(r) + 0x8000;
++ g = SkIntToFixed(g) + 0x8000;
++ b = SkIntToFixed(b) + 0x8000;
++
++ return SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16);
++}
++
+ void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
+ int count, U8CPU paintAlpha) {
+ SkASSERT(count > 1);
+@@ -628,14 +644,14 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) {
+ const SkPMColor* Gradient_Shader::getCache32() const {
+ if (fCache32 == NULL) {
+ // double the count for dither entries
+- const int entryCount = kCache32Count * 2;
++ const int entryCount = kCache32Count * 2 + 2;
+ const size_t allocSize = sizeof(SkPMColor) * entryCount;
+
+ if (NULL == fCache32PixelRef) {
+ fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ }
+- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
+ if (fColorCount == 2) {
+ Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
+ kGradient32Length, fCacheAlpha);
+@@ -659,7 +675,7 @@ const SkPMColor* Gradient_Shader::getCache32() const {
+ SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ SkPMColor* linear = fCache32; // just computed linear data
+- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
+ SkUnitMapper* map = fMapper;
+ for (int i = 0; i < kGradient32Length; i++) {
+ int index = map->mapUnit16((i << 8) | i) >> 8;
+@@ -668,10 +684,13 @@ const SkPMColor* Gradient_Shader::getCache32() const {
+ }
+ fCache32PixelRef->unref();
+ fCache32PixelRef = newPR;
+- fCache32 = (SkPMColor*)newPR->getAddr();
++ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
+ }
+ complete_32bit_cache(fCache32, kCache32Count);
+ }
++ //Write the clamp colours into the first and last entries of fCache32
++ fCache32[-1] = PremultiplyColor(fOrigColors[0], fCacheAlpha);
++ fCache32[kCache32Count * 2] = PremultiplyColor(fOrigColors[fColorCount - 1], fCacheAlpha);
+ return fCache32;
+ }
+
+@@ -857,6 +876,18 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
++ if (proc == clamp_tileproc) {
++ // Read out clamp values from beginning/end of the cache. No need to lerp
++ // or dither
++ if (fx < 0) {
++ sk_memset32(dstC, cache[-1], count);
++ return;
++ } else if (fx > 0xFFFF) {
++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
++ return;
++ }
++ }
++
+ // We're a vertical gradient, so no change in a span.
+ // If colors change sharply across the gradient, dithering is
+ // insufficient (it subsamples the color space) and we need to lerp.
+@@ -875,6 +906,18 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
++ if (proc == clamp_tileproc) {
++ // Read out clamp values from beginning/end of the cache. No need to lerp
++ // or dither
++ if (fx < 0) {
++ sk_memset32(dstC, cache[-1], count);
++ return;
++ } else if (fx > 0xFFFF) {
++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
++ return;
++ }
++ }
++
+ // We're a vertical gradient, so no change in a span.
+ // If colors change sharply across the gradient, dithering is
+ // insufficient (it subsamples the color space) and we need to lerp.
+@@ -900,10 +943,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ range.init(fx, dx, count, 0, Gradient_Shader::kGradient32Length);
+
+ if ((count = range.fCount0) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV0],
+- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV0],
+- count);
++ // Shouldn't be any need to dither for clamping?
++ sk_memset32(dstC, cache[-1], count);
+ dstC += count;
+ }
+ if ((count = range.fCount1) > 0) {
+@@ -922,10 +963,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
+ }
+ }
+ if ((count = range.fCount2) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV1],
+- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV1],
+- count);
++ // Shouldn't be any need to dither for clamping?
++ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
+ }
+ }
+
+@@ -1796,9 +1835,16 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+ fOneOverTwoA, posRoot);
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
++
++ if (t < 0) {
++ *dstC++ = cache[-1];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[Gradient_Shader::kCache32Count * 2];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> Gradient_Shader::kCache32Shift];
++ }
++
+ fx += dx;
+ fy += dy;
+ b += db;
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch b/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch
new file mode 100644
index 0000000000..58961d6e06
--- /dev/null
+++ b/gfx/skia/patches/archive/0008-Bug-848491-Re-apply-759683-Handle-compilers-that-don.patch
@@ -0,0 +1,35 @@
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 25 Apr 2013 20:49:45 -0400
+Subject: Bug 848491 - Re-apply 759683 - Handle compilers that don't support SSSE3 intrinsics
+
+
+diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp
+index 6370058..18f68d6 100644
+--- a/gfx/skia/src/opts/opts_check_SSE2.cpp
++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp
+@@ -86,9 +86,13 @@ static inline bool hasSSSE3() {
+ #else
+
+ static inline bool hasSSSE3() {
++#if defined(SK_BUILD_SSSE3)
+ int cpu_info[4] = { 0 };
+ getcpuid(1, cpu_info);
+ return (cpu_info[2] & 0x200) != 0;
++#else
++ return false;
++#endif
+ }
+ #endif
+
+@@ -104,7 +108,7 @@ static bool cachedHasSSSE3() {
+
+ void SkBitmapProcState::platformProcs() {
+ if (cachedHasSSSE3()) {
+-#if !defined(SK_BUILD_FOR_ANDROID)
++#if !defined(SK_BUILD_FOR_ANDROID) && defined(SK_BUILD_SSSE3)
+ // Disable SSSE3 optimization for Android x86
+ if (fSampleProc32 == S32_opaque_D32_filter_DX) {
+ fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch b/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch
new file mode 100644
index 0000000000..1e9a93f20a
--- /dev/null
+++ b/gfx/skia/patches/archive/0009-Bug-755869-FreeBSD-Hurd.patch
@@ -0,0 +1,28 @@
+From df3be24040f7cb2f9c7ed86ad3e47206630e885f Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Wed, 23 May 2012 14:49:57 -0400
+Subject: [PATCH 09/10] Bug 755869 - [12] Re-apply bug 749533 - Add
+ support for GNU/kFreeBSD and Hurd in Skia.
+ r=mattwoodrow
+
+---
+ gfx/skia/include/core/SkPreConfig.h | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/gfx/skia/include/core/SkPreConfig.h b/gfx/skia/include/core/SkPreConfig.h
+index 46c6929..16c4d6c 100644
+--- a/gfx/skia/include/core/SkPreConfig.h
++++ b/gfx/skia/include/core/SkPreConfig.h
+@@ -35,7 +35,8 @@
+ #elif defined(ANDROID)
+ #define SK_BUILD_FOR_ANDROID
+ #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+- defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
++ defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \
++ defined(__GLIBC__) || defined(__GNU__)
+ #define SK_BUILD_FOR_UNIX
+ #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ #define SK_BUILD_FOR_IOS
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch b/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch
new file mode 100644
index 0000000000..1da208ed18
--- /dev/null
+++ b/gfx/skia/patches/archive/0009-Bug-777614-Re-apply-759683-Handle-compilers-that-don.patch
@@ -0,0 +1,40 @@
+From 2c5a8cebc806ed287ce7c3723ea64a233266cd9e Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 13 Sep 2012 14:55:33 -0400
+Subject: [PATCH 9/9] Bug 777614 - Re-apply 759683 - Handle compilers that
+ don't support SSSE3 intrinsics r=nrc
+
+---
+ gfx/skia/src/opts/opts_check_SSE2.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp
+index 96d0dea..add6d5f 100644
+--- a/gfx/skia/src/opts/opts_check_SSE2.cpp
++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp
+@@ -86,9 +86,13 @@ static inline bool hasSSSE3() {
+ #else
+
+ static inline bool hasSSSE3() {
++#if defined(SK_BUILD_SSSE3)
+ int cpu_info[4] = { 0 };
+ getcpuid(1, cpu_info);
+ return (cpu_info[2] & 0x200) != 0;
++#else
++ return false;
++#endif
+ }
+ #endif
+
+@@ -104,7 +108,7 @@ static bool cachedHasSSSE3() {
+
+ void SkBitmapProcState::platformProcs() {
+ if (cachedHasSSSE3()) {
+-#if !defined(SK_BUILD_FOR_ANDROID)
++#if !defined(SK_BUILD_FOR_ANDROID) && defined(SK_BUILD_SSSE3)
+ // Disable SSSE3 optimization for Android x86
+ if (fSampleProc32 == S32_opaque_D32_filter_DX) {
+ fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
+--
+1.7.11.4
+
diff --git a/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch b/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch
new file mode 100644
index 0000000000..9778015c4f
--- /dev/null
+++ b/gfx/skia/patches/archive/0009-Bug-848491-Re-apply-bug-751418-Add-our-own-GrUserCon.patch
@@ -0,0 +1,23 @@
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 25 Apr 2013 20:52:32 -0400
+Subject: Bug 848491 - Re-apply bug 751418 - Add our own GrUserConfig
+
+
+diff --git a/gfx/skia/include/gpu/GrUserConfig.h b/gfx/skia/include/gpu/GrUserConfig.h
+index 11d4feb..77ab850 100644
+--- a/gfx/skia/include/gpu/GrUserConfig.h
++++ b/gfx/skia/include/gpu/GrUserConfig.h
+@@ -43,6 +43,10 @@
+ */
+ //#define GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT 96
+
++/*
++ * This allows us to set a callback to be called before each GL call to ensure
++ * that our context is set correctly
++ */
+ #define GR_GL_PER_GL_FUNC_CALLBACK 1
+
+ #endif
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch b/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch
new file mode 100644
index 0000000000..bd6604b4bd
--- /dev/null
+++ b/gfx/skia/patches/archive/0010-Bug-689069-ARM-Opts.patch
@@ -0,0 +1,36 @@
+From dc1292fc8c2b9da900ebcac953120eaffd0d329e Mon Sep 17 00:00:00 2001
+From: George Wright <gwright@mozilla.com>
+Date: Wed, 23 May 2012 14:52:36 -0400
+Subject: [PATCH 10/10] Bug 755869 - [13] Re-apply bug 750733 - Use
+ handles in API object hooks where possible
+ r=mattwoodrow
+
+---
+ gfx/skia/src/xml/SkJS.cpp | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gfx/skia/src/xml/SkJS.cpp b/gfx/skia/src/xml/SkJS.cpp
+index f2e7a83..b2717d7 100644
+--- a/gfx/skia/src/xml/SkJS.cpp
++++ b/gfx/skia/src/xml/SkJS.cpp
+@@ -74,7 +74,7 @@ extern "C" {
+ #endif
+
+ static bool
+-global_enumerate(JSContext *cx, JSObject *obj)
++global_enumerate(JSContext *cx, JSHandleObject *obj)
+ {
+ #ifdef LAZY_STANDARD_CLASSES
+ return JS_EnumerateStandardClasses(cx, obj);
+@@ -84,7 +84,7 @@ global_enumerate(JSContext *cx, JSObject *obj)
+ }
+
+ static bool
+-global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
++global_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSObject **objp)
+ {
+ #ifdef LAZY_STANDARD_CLASSES
+ if ((flags & JSRESOLVE_ASSIGNING) == 0) {
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch b/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch
new file mode 100644
index 0000000000..a446037de0
--- /dev/null
+++ b/gfx/skia/patches/archive/0010-Bug-836892-Add-new-blending-modes-to-SkXfermode.patch
@@ -0,0 +1,698 @@
+# HG changeset patch
+# User Rik Cabanier <cabanier@adobe.com>
+# Date 1360273929 -46800
+# Node ID 3ac8edca3a03b3d22240b5a5b95ae3b5ada9877d
+# Parent cbb67fe70b864b36165061e1fd3b083cd09af087
+Bug 836892 - Add new blending modes to SkXfermode. r=gw280
+
+diff --git a/gfx/skia/include/core/SkXfermode.h b/gfx/skia/include/core/SkXfermode.h
+--- a/gfx/skia/include/core/SkXfermode.h
++++ b/gfx/skia/include/core/SkXfermode.h
+@@ -96,33 +96,37 @@ public:
+ kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
+ kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
+ kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
+ kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
+
+ // all remaining modes are defined in the SVG Compositing standard
+ // http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
+ kPlus_Mode,
+- kMultiply_Mode,
+
+ // all above modes can be expressed as pair of src/dst Coeffs
+ kCoeffModesCnt,
+
+- kScreen_Mode = kCoeffModesCnt,
++ kMultiply_Mode = kCoeffModesCnt,
++ kScreen_Mode,
+ kOverlay_Mode,
+ kDarken_Mode,
+ kLighten_Mode,
+ kColorDodge_Mode,
+ kColorBurn_Mode,
+ kHardLight_Mode,
+ kSoftLight_Mode,
+ kDifference_Mode,
+ kExclusion_Mode,
++ kHue_Mode,
++ kSaturation_Mode,
++ kColor_Mode,
++ kLuminosity_Mode,
+
+- kLastMode = kExclusion_Mode
++ kLastMode = kLuminosity_Mode
+ };
+
+ /**
+ * If the xfermode is one of the modes in the Mode enum, then asMode()
+ * returns true and sets (if not null) mode accordingly. Otherwise it
+ * returns false and ignores the mode parameter.
+ */
+ virtual bool asMode(Mode* mode);
+diff --git a/gfx/skia/src/core/SkXfermode.cpp b/gfx/skia/src/core/SkXfermode.cpp
+--- a/gfx/skia/src/core/SkXfermode.cpp
++++ b/gfx/skia/src/core/SkXfermode.cpp
+@@ -7,16 +7,18 @@
+ */
+
+
+ #include "SkXfermode.h"
+ #include "SkColorPriv.h"
+ #include "SkFlattenableBuffers.h"
+ #include "SkMathPriv.h"
+
++#include <algorithm>
++
+ SK_DEFINE_INST_COUNT(SkXfermode)
+
+ #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b)
+
+ #if 0
+ // idea for higher precision blends in xfer procs (and slightly faster)
+ // see DstATop as a probable caller
+ static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) {
+@@ -176,244 +178,439 @@ static SkPMColor xor_modeproc(SkPMColor
+ static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) {
+ unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst));
+ unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst));
+ unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst));
+ unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst));
+ return SkPackARGB32(a, r, g, b);
+ }
+
++static inline int srcover_byte(int a, int b) {
++ return a + b - SkAlphaMulAlpha(a, b);
++}
++
++#define blendfunc_byte(sc, dc, sa, da, blendfunc) \
++ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendfunc(sc, dc, sa, da))
++
+ // kMultiply_Mode
++static inline int multiply_byte(int sc, int dc, int sa, int da) {
++ return sc * dc;
++}
+ static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) {
+- int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst));
+- int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst));
+- int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst));
+- int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst));
++ int sa = SkGetPackedA32(src);
++ int da = SkGetPackedA32(dst);
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, multiply_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, multiply_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, multiply_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kScreen_Mode
+-static inline int srcover_byte(int a, int b) {
+- return a + b - SkAlphaMulAlpha(a, b);
++static inline int screen_byte(int sc, int dc, int sa, int da) {
++ return sc * da + sa * dc - sc * dc;
+ }
+ static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) {
+- int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst));
+- int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst));
+- int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst));
+- int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst));
++ int sa = SkGetPackedA32(src);
++ int da = SkGetPackedA32(dst);
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, screen_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, screen_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, screen_byte);
++ return SkPackARGB32(a, r, g, b);
++}
++
++// kHardLight_Mode
++static inline int hardlight_byte(int sc, int dc, int sa, int da) {
++ if(!sa || !da)
++ return sc * da;
++ float Sc = (float)sc/sa;
++ float Dc = (float)dc/da;
++ if(Sc <= 0.5)
++ Sc *= 2 * Dc;
++ else
++ Sc = -1 + 2 * Sc + 2 * Dc - 2 * Sc * Dc;
++
++ return Sc * sa * da;
++}
++static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
++ int sa = SkGetPackedA32(src);
++ int da = SkGetPackedA32(dst);
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, hardlight_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, hardlight_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, hardlight_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kOverlay_Mode
+ static inline int overlay_byte(int sc, int dc, int sa, int da) {
+- int tmp = sc * (255 - da) + dc * (255 - sa);
+- int rc;
+- if (2 * dc <= da) {
+- rc = 2 * sc * dc;
+- } else {
+- rc = sa * da - 2 * (da - dc) * (sa - sc);
+- }
+- return clamp_div255round(rc + tmp);
++ return hardlight_byte(dc, sc, da, sa);
+ }
+ static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, overlay_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, overlay_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, overlay_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kDarken_Mode
+ static inline int darken_byte(int sc, int dc, int sa, int da) {
+- int sd = sc * da;
+- int ds = dc * sa;
+- if (sd < ds) {
+- // srcover
+- return sc + dc - SkDiv255Round(ds);
+- } else {
+- // dstover
+- return dc + sc - SkDiv255Round(sd);
+- }
++ return SkMin32(sc * da, sa * dc);
+ }
+ static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, darken_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, darken_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, darken_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kLighten_Mode
+ static inline int lighten_byte(int sc, int dc, int sa, int da) {
+- int sd = sc * da;
+- int ds = dc * sa;
+- if (sd > ds) {
+- // srcover
+- return sc + dc - SkDiv255Round(ds);
+- } else {
+- // dstover
+- return dc + sc - SkDiv255Round(sd);
+- }
++ return SkMax32(sc * da, sa * dc);
+ }
+ static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, lighten_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, lighten_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, lighten_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kColorDodge_Mode
+ static inline int colordodge_byte(int sc, int dc, int sa, int da) {
+- int diff = sa - sc;
+- int rc;
+- if (0 == diff) {
+- rc = sa * da + sc * (255 - da) + dc * (255 - sa);
+- rc = SkDiv255Round(rc);
+- } else {
+- int tmp = (dc * sa << 15) / (da * diff);
+- rc = SkDiv255Round(sa * da) * tmp >> 15;
+- // don't clamp here, since we'll do it in our modeproc
+- }
+- return rc;
++ if (dc == 0)
++ return 0;
++ // Avoid division by 0
++ if (sc == sa)
++ return da * sa;
++
++ return SkMin32(sa * da, sa * sa * dc / (sa - sc));
+ }
+ static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) {
+- // added to avoid div-by-zero in colordodge_byte
+- if (0 == dst) {
+- return src;
+- }
+-
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
+- r = clamp_max(r, a);
+- g = clamp_max(g, a);
+- b = clamp_max(b, a);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colordodge_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colordodge_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colordodge_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kColorBurn_Mode
+ static inline int colorburn_byte(int sc, int dc, int sa, int da) {
+- int rc;
+- if (dc == da && 0 == sc) {
+- rc = sa * da + dc * (255 - sa);
+- } else if (0 == sc) {
+- return SkAlphaMulAlpha(dc, 255 - sa);
+- } else {
+- int tmp = (sa * (da - dc) * 256) / (sc * da);
+- if (tmp > 256) {
+- tmp = 256;
+- }
+- int tmp2 = sa * da;
+- rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa);
+- }
+- return SkDiv255Round(rc);
++ // Avoid division by 0
++ if(dc == da)
++ return sa * da;
++ if(sc == 0)
++ return 0;
++
++ return sa * da - SkMin32(sa * da, sa * sa * (da - dc) / sc);
+ }
+ static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
+- // added to avoid div-by-zero in colorburn_byte
+- if (0 == dst) {
+- return src;
+- }
+-
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
+- return SkPackARGB32(a, r, g, b);
+-}
+-
+-// kHardLight_Mode
+-static inline int hardlight_byte(int sc, int dc, int sa, int da) {
+- int rc;
+- if (2 * sc <= sa) {
+- rc = 2 * sc * dc;
+- } else {
+- rc = sa * da - 2 * (da - dc) * (sa - sc);
+- }
+- return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
+-}
+-static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
+- int sa = SkGetPackedA32(src);
+- int da = SkGetPackedA32(dst);
+- int a = srcover_byte(sa, da);
+- int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, colorburn_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, colorburn_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, colorburn_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // returns 255 * sqrt(n/255)
+ static U8CPU sqrt_unit_byte(U8CPU n) {
+ return SkSqrtBits(n, 15+4);
+ }
+
+ // kSoftLight_Mode
+ static inline int softlight_byte(int sc, int dc, int sa, int da) {
+ int m = da ? dc * 256 / da : 0;
+ int rc;
+- if (2 * sc <= sa) {
+- rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8));
+- } else if (4 * dc <= da) {
++ if (2 * sc <= sa)
++ return dc * (sa + ((2 * sc - sa) * (256 - m) >> 8));
++
++ if (4 * dc <= da) {
+ int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m;
+- rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
+- } else {
+- int tmp = sqrt_unit_byte(m) - m;
+- rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
++ return dc * sa + (da * (2 * sc - sa) * tmp >> 8);
+ }
+- return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
++ int tmp = sqrt_unit_byte(m) - m;
++ return rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
+ }
+ static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, softlight_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, softlight_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, softlight_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kDifference_Mode
+ static inline int difference_byte(int sc, int dc, int sa, int da) {
+- int tmp = SkMin32(sc * da, dc * sa);
+- return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp));
++ int tmp = dc * sa - sc * da;
++ if(tmp<0)
++ return - tmp;
++
++ return tmp;
+ }
+ static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, difference_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, difference_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, difference_byte);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ // kExclusion_Mode
+ static inline int exclusion_byte(int sc, int dc, int sa, int da) {
+- // this equations is wacky, wait for SVG to confirm it
+- int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa);
+- return clamp_div255round(r);
++ return sc * da + dc * sa - 2 * dc * sc;
+ }
+ static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) {
+ int sa = SkGetPackedA32(src);
+ int da = SkGetPackedA32(dst);
+ int a = srcover_byte(sa, da);
+- int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
+- int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
+- int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
++ int r = blendfunc_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da, exclusion_byte);
++ int g = blendfunc_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da, exclusion_byte);
++ int b = blendfunc_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da, exclusion_byte);
++ return SkPackARGB32(a, r, g, b);
++}
++
++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++struct BlendColor {
++ float r;
++ float g;
++ float b;
++
++ BlendColor(): r(0), g(0), b(0)
++ {}
++};
++
++static inline float Lum(BlendColor C)
++{
++ return C.r * 0.3 + C.g * 0.59 + C.b* 0.11;
++}
++
++static inline float SkMinFloat(float a, float b)
++{
++ if (a > b)
++ a = b;
++ return a;
++}
++
++static inline float SkMaxFloat(float a, float b)
++{
++ if (a < b)
++ a = b;
++ return a;
++}
++
++#define minimum(C) SkMinFloat(SkMinFloat(C.r, C.g), C.b)
++#define maximum(C) SkMaxFloat(SkMaxFloat(C.r, C.g), C.b)
++
++static inline float Sat(BlendColor c) {
++ return maximum(c) - minimum(c);
++}
++
++static inline void setSaturationComponents(float& Cmin, float& Cmid, float& Cmax, float s) {
++ if(Cmax > Cmin) {
++ Cmid = (((Cmid - Cmin) * s ) / (Cmax - Cmin));
++ Cmax = s;
++ } else {
++ Cmax = 0;
++ Cmid = 0;
++ }
++ Cmin = 0;
++}
++
++static inline BlendColor SetSat(BlendColor C, float s) {
++ if(C.r <= C.g) {
++ if(C.g <= C.b)
++ setSaturationComponents(C.r, C.g, C.b, s);
++ else
++ if(C.r <= C.b)
++ setSaturationComponents(C.r, C.b, C.g, s);
++ else
++ setSaturationComponents(C.b, C.r, C.g, s);
++ } else if(C.r <= C.b)
++ setSaturationComponents(C.g, C.r, C.b, s);
++ else
++ if(C.g <= C.b)
++ setSaturationComponents(C.g, C.b, C.r, s);
++ else
++ setSaturationComponents(C.b, C.g, C.r, s);
++
++ return C;
++}
++
++static inline BlendColor clipColor(BlendColor C) {
++ float L = Lum(C);
++ float n = minimum(C);
++ float x = maximum(C);
++ if(n < 0) {
++ C.r = L + (((C.r - L) * L) / (L - n));
++ C.g = L + (((C.g - L) * L) / (L - n));
++ C.b = L + (((C.b - L) * L) / (L - n));
++ }
++
++ if(x > 1) {
++ C.r = L + (((C.r - L) * (1 - L)) / (x - L));
++ C.g = L + (((C.g - L) * (1 - L)) / (x - L));
++ C.b = L + (((C.b - L) * (1 - L)) / (x - L));
++ }
++ return C;
++}
++
++static inline BlendColor SetLum(BlendColor C, float l) {
++ float d = l - Lum(C);
++ C.r += d;
++ C.g += d;
++ C.b += d;
++
++ return clipColor(C);
++}
++
++#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \
++ clamp_div255round(sc * (255 - da) + dc * (255 - sa) + (int)(sa * da * blendval))
++
++static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) {
++ int sr = SkGetPackedR32(src);
++ int sg = SkGetPackedG32(src);
++ int sb = SkGetPackedB32(src);
++ int sa = SkGetPackedA32(src);
++
++ int dr = SkGetPackedR32(dst);
++ int dg = SkGetPackedG32(dst);
++ int db = SkGetPackedB32(dst);
++ int da = SkGetPackedA32(dst);
++
++ BlendColor Cs;
++ if(sa) {
++ Cs.r = (float)sr / sa;
++ Cs.g = (float)sg / sa;
++ Cs.b = (float)sb / sa;
++ BlendColor Cd;
++ if(da) {
++ Cd.r = (float)dr / da;
++ Cd.g = (float)dg / da;
++ Cd.b = (float)db / da;
++ Cs = SetLum(SetSat(Cs, Sat(Cd)), Lum(Cd));
++ }
++ }
++
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
++ return SkPackARGB32(a, r, g, b);
++}
++
++static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) {
++ int sr = SkGetPackedR32(src);
++ int sg = SkGetPackedG32(src);
++ int sb = SkGetPackedB32(src);
++ int sa = SkGetPackedA32(src);
++
++ int dr = SkGetPackedR32(dst);
++ int dg = SkGetPackedG32(dst);
++ int db = SkGetPackedB32(dst);
++ int da = SkGetPackedA32(dst);
++
++ BlendColor Cs;
++ if(sa) {
++ Cs.r = (float)sr / sa;
++ Cs.g = (float)sg / sa;
++ Cs.b = (float)sb / sa;
++ BlendColor Cd;
++ if(da) {
++ Cd.r = (float)dr / da;
++ Cd.g = (float)dg / da;
++ Cd.b = (float)db / da;
++ Cs = SetLum(SetSat(Cd, Sat(Cs)), Lum(Cd));
++ }
++ }
++
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
++ return SkPackARGB32(a, r, g, b);
++}
++
++static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) {
++ int sr = SkGetPackedR32(src);
++ int sg = SkGetPackedG32(src);
++ int sb = SkGetPackedB32(src);
++ int sa = SkGetPackedA32(src);
++
++ int dr = SkGetPackedR32(dst);
++ int dg = SkGetPackedG32(dst);
++ int db = SkGetPackedB32(dst);
++ int da = SkGetPackedA32(dst);
++
++ BlendColor Cs;
++ if(sa) {
++ Cs.r = (float)sr / sa;
++ Cs.g = (float)sg / sa;
++ Cs.b = (float)sb / sa;
++ BlendColor Cd;
++ if(da) {
++ Cd.r = (float)dr / da;
++ Cd.g = (float)dg / da;
++ Cd.b = (float)db / da;
++ Cs = SetLum(Cs, Lum(Cd));
++ }
++ }
++
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
++ return SkPackARGB32(a, r, g, b);
++}
++
++static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) {
++ int sr = SkGetPackedR32(src);
++ int sg = SkGetPackedG32(src);
++ int sb = SkGetPackedB32(src);
++ int sa = SkGetPackedA32(src);
++
++ int dr = SkGetPackedR32(dst);
++ int dg = SkGetPackedG32(dst);
++ int db = SkGetPackedB32(dst);
++ int da = SkGetPackedA32(dst);
++
++ BlendColor Cs;
++ if(sa) {
++ Cs.r = (float)sr / sa;
++ Cs.g = (float)sg / sa;
++ Cs.b = (float)sb / sa;
++ BlendColor Cd;
++ if(da) {
++ Cd.r = (float)dr / da;
++ Cd.g = (float)dg / da;
++ Cd.b = (float)db / da;
++ Cs = SetLum(Cd, Lum(Cs));
++ }
++ }
++
++ int a = srcover_byte(sa, da);
++ int r = blendfunc_nonsep_byte(sr, dr, sa, da, Cs.r);
++ int g = blendfunc_nonsep_byte(sg, dg, sa, da, Cs.g);
++ int b = blendfunc_nonsep_byte(sb, db, sa, da, Cs.b);
+ return SkPackARGB32(a, r, g, b);
+ }
+
+ struct ProcCoeff {
+ SkXfermodeProc fProc;
+ SkXfermode::Coeff fSC;
+ SkXfermode::Coeff fDC;
+ };
+@@ -430,27 +627,31 @@ static const ProcCoeff gProcCoeffs[] = {
+ { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
+ { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
+ { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
+ { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
+ { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
+ { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
+
+ { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff },
+- { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
++ { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_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 },
+ { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
++ { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
++ { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
++ { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
++ { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) {
+ return false;
+ }
+
+@@ -1172,16 +1373,20 @@ static const Proc16Rec gModeProcs16[] =
+ { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken
+ { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten
+ { NULL, NULL, NULL }, // colordodge
+ { NULL, NULL, NULL }, // colorburn
+ { NULL, NULL, NULL }, // hardlight
+ { NULL, NULL, NULL }, // softlight
+ { NULL, NULL, NULL }, // difference
+ { NULL, NULL, NULL }, // exclusion
++ { NULL, NULL, NULL }, // hue
++ { NULL, NULL, NULL }, // saturation
++ { NULL, NULL, NULL }, // color
++ { NULL, NULL, NULL }, // luminosity
+ };
+
+ SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
+ SkXfermodeProc16 proc16 = NULL;
+ if ((unsigned)mode < kModeCount) {
+ const Proc16Rec& rec = gModeProcs16[mode];
+ unsigned a = SkColorGetA(srcColor);
+
diff --git a/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch b/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch
new file mode 100644
index 0000000000..0d44b008d6
--- /dev/null
+++ b/gfx/skia/patches/archive/0010-Bug-848491-Re-apply-bug-817356-Patch-Skia-to-recogni.patch
@@ -0,0 +1,22 @@
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 25 Apr 2013 20:55:02 -0400
+Subject: Bug 848491 - Re-apply bug 817356 - Patch Skia to recognize uppercase PPC/PPC64.
+
+
+diff --git a/gfx/skia/include/core/SkPreConfig.h b/gfx/skia/include/core/SkPreConfig.h
+index 11cb223..7e95b99 100644
+--- a/gfx/skia/include/core/SkPreConfig.h
++++ b/gfx/skia/include/core/SkPreConfig.h
+@@ -99,7 +99,8 @@
+ //////////////////////////////////////////////////////////////////////
+
+ #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+- #if defined (__ppc__) || defined(__ppc64__)
++ #if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \
++ || defined(__PPC64__)
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch b/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch
new file mode 100644
index 0000000000..95cb08a36f
--- /dev/null
+++ b/gfx/skia/patches/archive/0011-Bug-719575-Fix-clang-build.patch
@@ -0,0 +1,28 @@
+From cf855f31194ff071f2c787a7413d70a43f15f204 Mon Sep 17 00:00:00 2001
+From: Ehsan Akhgari <ehsan@mozilla.com>
+Date: Tue, 29 May 2012 15:39:55 -0400
+Subject: [PATCH] Bug 755869 - Re-apply patch from bug 719575 to fix clang
+ builds for the new Skia r=gw280
+
+---
+ gfx/skia/src/ports/SkFontHost_mac_coretext.cpp | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+index c43d1a6..ce5f409 100644
+--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
++++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+@@ -807,8 +807,8 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
+ void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkIPoint* offset) const {
+ CGSize vertOffset;
+ CTFontGetVerticalTranslationsForGlyphs(fCTVerticalFont, &glyphID, &vertOffset, 1);
+- const SkPoint trans = {SkFloatToScalar(vertOffset.width),
+- SkFloatToScalar(vertOffset.height)};
++ const SkPoint trans = {SkScalar(SkFloatToScalar(vertOffset.width)),
++ SkScalar(SkFloatToScalar(vertOffset.height))};
+ SkPoint floatOffset;
+ fVerticalMatrix.mapPoints(&floatOffset, &trans, 1);
+ if (!isSnowLeopard()) {
+--
+1.7.5.4
+
diff --git a/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch b/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch
new file mode 100644
index 0000000000..854f0b1afe
--- /dev/null
+++ b/gfx/skia/patches/archive/0011-Bug-839347-no-anon-namespace-around-SkNO_RETURN_HINT.patch
@@ -0,0 +1,31 @@
+# HG changeset patch
+# Parent 2c6da9f02606f7a02f635d99ef8cf669d3bc5c4b
+# User Daniel Holbert <dholbert@cs.stanford.edu>
+Bug 839347: Move SkNO_RETURN_HINT out of anonymous namespace so that clang won't warn about it being unused. r=mattwoodrow
+
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -63,20 +63,18 @@
+ * The clang static analyzer likes to know that when the program is not
+ * expected to continue (crash, assertion failure, etc). It will notice that
+ * some combination of parameters lead to a function call that does not return.
+ * It can then make appropriate assumptions about the parameters in code
+ * executed only if the non-returning function was *not* called.
+ */
+ #if !defined(SkNO_RETURN_HINT)
+ #if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
+- namespace {
+- inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
+- inline void SkNO_RETURN_HINT() {}
+- }
++ inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
++ inline void SkNO_RETURN_HINT() {}
+ #else
+ #define SkNO_RETURN_HINT() do {} while (false)
+ #endif
+ #endif
+
+ #if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
+ #error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
+ #elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
diff --git a/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch b/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch
new file mode 100644
index 0000000000..cde2940950
--- /dev/null
+++ b/gfx/skia/patches/archive/0012-Bug-751418-Add-our-own-GrUserConfig-r-mattwoodrow.patch
@@ -0,0 +1,29 @@
+From 4c25387e6e6cdb55f19e51631a78c3fa9b4a3c73 Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Thu, 1 Nov 2012 17:29:50 -0400
+Subject: [PATCH 2/8] Bug 751418 - Add our own GrUserConfig r=mattwoodrow
+
+---
+ gfx/skia/include/gpu/GrUserConfig.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/gfx/skia/include/gpu/GrUserConfig.h b/gfx/skia/include/gpu/GrUserConfig.h
+index d514486..b729ab3 100644
+--- a/gfx/skia/include/gpu/GrUserConfig.h
++++ b/gfx/skia/include/gpu/GrUserConfig.h
+@@ -64,6 +64,12 @@
+ #define GR_TEXT_SCALAR_IS_FIXED 0
+ #define GR_TEXT_SCALAR_IS_FLOAT 1
+
++/*
++ * This allows us to set a callback to be called before each GL call to ensure
++ * that our context is set correctly
++ */
++#define GR_GL_PER_GL_FUNC_CALLBACK 1
++
+ #endif
+
+
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch b/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch
new file mode 100644
index 0000000000..dc780c5ec6
--- /dev/null
+++ b/gfx/skia/patches/archive/0012-Bug-759683-make-ssse3-conditional.patch
@@ -0,0 +1,22 @@
+diff --git a/gfx/skia/src/opts/opts_check_SSE2.cpp b/gfx/skia/src/opts/opts_check_SSE2.cpp
+--- a/gfx/skia/src/opts/opts_check_SSE2.cpp
++++ b/gfx/skia/src/opts/opts_check_SSE2.cpp
+@@ -91,17 +91,17 @@ static bool cachedHasSSE2() {
+
+ static bool cachedHasSSSE3() {
+ static bool gHasSSSE3 = hasSSSE3();
+ return gHasSSSE3;
+ }
+
+ void SkBitmapProcState::platformProcs() {
+ if (cachedHasSSSE3()) {
+-#if !defined(SK_BUILD_FOR_ANDROID)
++#if defined(SK_BUILD_SSSE3)
+ // Disable SSSE3 optimization for Android x86
+ if (fSampleProc32 == S32_opaque_D32_filter_DX) {
+ fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
+ } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
+ fSampleProc32 = S32_alpha_D32_filter_DX_SSSE3;
+ }
+
+ if (fSampleProc32 == S32_opaque_D32_filter_DXDY) {
diff --git a/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch b/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch
new file mode 100644
index 0000000000..167e22184d
--- /dev/null
+++ b/gfx/skia/patches/archive/0013-Bug-751418-Fix-compile-error-on-gcc-in-Skia-GL-r-mat.patch
@@ -0,0 +1,26 @@
+From 3d786b1f0c040205ad9ef6d4216ce06b41f7359f Mon Sep 17 00:00:00 2001
+From: George Wright <gw@gwright.org.uk>
+Date: Mon, 5 Nov 2012 15:49:42 +0000
+Subject: [PATCH 3/8] Bug 751418 - Fix compile error on gcc in Skia/GL
+ r=mattwoodrow
+
+---
+ gfx/skia/src/gpu/gl/GrGLProgram.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gfx/skia/src/gpu/gl/GrGLProgram.cpp b/gfx/skia/src/gpu/gl/GrGLProgram.cpp
+index 2703110..40cadc3 100644
+--- a/gfx/skia/src/gpu/gl/GrGLProgram.cpp
++++ b/gfx/skia/src/gpu/gl/GrGLProgram.cpp
+@@ -575,7 +575,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
+ POS_ATTR_NAME);
+
+ builder.fVSCode.appendf("void main() {\n"
+- "\tvec3 pos3 = %s * vec3("POS_ATTR_NAME", 1);\n"
++ "\tvec3 pos3 = %s * vec3(" POS_ATTR_NAME ", 1);\n"
+ "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
+ viewMName);
+
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch b/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch
new file mode 100644
index 0000000000..f20293d4cc
--- /dev/null
+++ b/gfx/skia/patches/archive/0013-Bug-761890-fonts.patch
@@ -0,0 +1,162 @@
+# HG changeset patch
+# User Nicholas Cameron <ncameron@mozilla.com>
+# Date 1337146927 -43200
+# Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821
+# Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8
+Bug 746883; changes to the Skia library. r=gw280
+
+diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h
+--- a/gfx/skia/include/core/SkDraw.h
++++ b/gfx/skia/include/core/SkDraw.h
+@@ -125,23 +125,24 @@ public:
+ #endif
+ };
+
+ class SkGlyphCache;
+
+ class SkTextToPathIter {
+ public:
+ SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
+- bool applyStrokeAndPathEffects);
++ bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true);
+ ~SkTextToPathIter();
+
+ const SkPaint& getPaint() const { return fPaint; }
+ SkScalar getPathScale() const { return fScale; }
+
+ const SkPath* next(SkScalar* xpos); //!< returns nil when there are no more paths
++ bool nextWithWhitespace(const SkPath** path, SkScalar* xpos); //!< returns false when there are no more paths
+
+ private:
+ SkGlyphCache* fCache;
+ SkPaint fPaint;
+ SkScalar fScale;
+ SkFixed fPrevAdvance;
+ const char* fText;
+ const char* fStop;
+diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
+--- a/gfx/skia/src/core/SkPaint.cpp
++++ b/gfx/skia/src/core/SkPaint.cpp
+@@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void*
+ const SkPoint pos[], SkPath* path) const {
+ SkASSERT(length == 0 || textData != NULL);
+
+ const char* text = (const char*)textData;
+ if (text == NULL || length == 0 || path == NULL) {
+ return;
+ }
+
+- SkTextToPathIter iter(text, length, *this, false);
++ SkTextToPathIter iter(text, length, *this, false, false);
+ SkMatrix matrix;
+ SkPoint prevPos;
+ prevPos.set(0, 0);
+
+ matrix.setScale(iter.getPathScale(), iter.getPathScale());
+ path->reset();
+
+ unsigned int i = 0;
+ const SkPath* iterPath;
+- while ((iterPath = iter.next(NULL)) != NULL) {
+- matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
+- path->addPath(*iterPath, matrix);
+- prevPos = pos[i];
++ while (iter.nextWithWhitespace(&iterPath, NULL)) {
++ if (iterPath) {
++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
++ path->addPath(*iterPath, matrix);
++ prevPos = pos[i];
++ }
+ i++;
+ }
+ }
+
+ static void add_flattenable(SkDescriptor* desc, uint32_t tag,
+ SkFlattenableWriteBuffer* buffer) {
+ buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
+ }
+@@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun
+
+ static bool has_thick_frame(const SkPaint& paint) {
+ return paint.getStrokeWidth() > 0 &&
+ paint.getStyle() != SkPaint::kFill_Style;
+ }
+
+ SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
+ const SkPaint& paint,
+- bool applyStrokeAndPathEffects)
++ bool applyStrokeAndPathEffects,
++ bool useCanonicalTextSize)
+ : fPaint(paint) {
+ fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
+ true);
+
+ fPaint.setLinearText(true);
+ fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup
+
+ if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
+ applyStrokeAndPathEffects = false;
+ }
+
+ // can't use our canonical size if we need to apply patheffects
+- if (fPaint.getPathEffect() == NULL) {
++ if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) {
+ fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
+ fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
+ if (has_thick_frame(fPaint)) {
+ fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
+ }
+ } else {
+ fScale = SK_Scalar1;
+ }
+@@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons
+ fXYIndex = paint.isVerticalText() ? 1 : 0;
+ }
+
+ SkTextToPathIter::~SkTextToPathIter() {
+ SkGlyphCache::AttachCache(fCache);
+ }
+
+ const SkPath* SkTextToPathIter::next(SkScalar* xpos) {
+- while (fText < fStop) {
++ const SkPath* result;
++ while (nextWithWhitespace(&result, xpos)) {
++ if (result) {
++ if (xpos) {
++ *xpos = fXPos;
++ }
++ return result;
++ }
++ }
++ return NULL;
++}
++
++bool SkTextToPathIter::nextWithWhitespace(const SkPath** path, SkScalar* xpos) {
++ if (fText < fStop) {
+ const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
+
+ fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
+ fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking();
+
+ if (glyph.fWidth) {
+ if (xpos) {
+ *xpos = fXPos;
+ }
+- return fCache->findPath(glyph);
++ *path = fCache->findPath(glyph);
++ return true;
++ } else {
++ *path = NULL;
++ return true;
+ }
+ }
+- return NULL;
++ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ bool SkPaint::nothingToDraw() const {
+ if (fLooper) {
+ return false;
+ }
diff --git a/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch b/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch
new file mode 100644
index 0000000000..6cc74914d2
--- /dev/null
+++ b/gfx/skia/patches/archive/0014-Bug-765038-Fix-clang-build.patch
@@ -0,0 +1,29 @@
+# HG changeset patch
+# Parent 9ded7a9f94a863dfa1f3227d3013367f51b8b522
+# User Nicholas Cameron <ncameron@mozilla.com>
+Bug 765038; fix a Clang compilation bug in Skia; r=jwatt
+
+diff --git a/gfx/skia/src/sfnt/SkOTTable_head.h b/gfx/skia/src/sfnt/SkOTTable_head.h
+--- a/gfx/skia/src/sfnt/SkOTTable_head.h
++++ b/gfx/skia/src/sfnt/SkOTTable_head.h
+@@ -109,18 +109,18 @@ struct SkOTTableHead {
+ } raw;
+ } macStyle;
+ SK_OT_USHORT lowestRecPPEM;
+ struct FontDirectionHint {
+ SK_TYPED_ENUM(Value, SK_OT_SHORT,
+ ((FullyMixedDirectionalGlyphs, SkTEndian_SwapBE16(0)))
+ ((OnlyStronglyLTR, SkTEndian_SwapBE16(1)))
+ ((StronglyLTR, SkTEndian_SwapBE16(2)))
+- ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-1))))
+- ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-2))))
++ ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-1)))))
++ ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-2)))))
+ SK_SEQ_END,
+ (value)SK_SEQ_END)
+ } fontDirectionHint;
+ struct IndexToLocFormat {
+ SK_TYPED_ENUM(Value, SK_OT_SHORT,
+ ((ShortOffsets, SkTEndian_SwapBE16(0)))
+ ((LongOffsets, SkTEndian_SwapBE16(1)))
+ SK_SEQ_END,
diff --git a/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch b/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch
new file mode 100644
index 0000000000..174dcb9bce
--- /dev/null
+++ b/gfx/skia/patches/archive/0015-Bug-766017-warnings.patch
@@ -0,0 +1,865 @@
+From: David Zbarsky <dzbarsky@gmail.com>
+Bug 766017 - Fix some skia warnings r=gw280
+
+diff --git a/gfx/skia/include/utils/mac/SkCGUtils.h b/gfx/skia/include/utils/mac/SkCGUtils.h
+--- a/gfx/skia/include/utils/mac/SkCGUtils.h
++++ b/gfx/skia/include/utils/mac/SkCGUtils.h
+@@ -39,18 +39,16 @@ static inline CGImageRef SkCreateCGImage
+ /**
+ * Draw the bitmap into the specified CG context. The bitmap will be converted
+ * to a CGImage using the generic RGB colorspace. (x,y) specifies the position
+ * of the top-left corner of the bitmap. The bitmap is converted using the
+ * colorspace returned by CGColorSpaceCreateDeviceRGB()
+ */
+ void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y);
+
+-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output);
+-
+ /**
+ * Return a provider that wraps the specified stream. It will become an
+ * owner of the stream, so the caller must still manage its ownership.
+ *
+ * To hand-off ownership of the stream to the provider, the caller must do
+ * something like the following:
+ *
+ * SkStream* stream = new ...;
+diff --git a/gfx/skia/src/core/SkAAClip.cpp b/gfx/skia/src/core/SkAAClip.cpp
+--- a/gfx/skia/src/core/SkAAClip.cpp
++++ b/gfx/skia/src/core/SkAAClip.cpp
+@@ -246,17 +246,17 @@ static void count_left_right_zeros(const
+ zeros = 0;
+ }
+ row += 2;
+ width -= n;
+ }
+ *riteZ = zeros;
+ }
+
+-#ifdef SK_DEBUG
++#if 0
+ static void test_count_left_right_zeros() {
+ static bool gOnce;
+ if (gOnce) {
+ return;
+ }
+ gOnce = true;
+
+ const uint8_t data0[] = { 0, 0, 10, 0xFF };
+@@ -1319,22 +1319,16 @@ bool SkAAClip::setPath(const SkPath& pat
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ typedef void (*RowProc)(SkAAClip::Builder&, int bottom,
+ const uint8_t* rowA, const SkIRect& rectA,
+ const uint8_t* rowB, const SkIRect& rectB);
+
+-static void sectRowProc(SkAAClip::Builder& builder, int bottom,
+- const uint8_t* rowA, const SkIRect& rectA,
+- const uint8_t* rowB, const SkIRect& rectB) {
+-
+-}
+-
+ typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB);
+
+ static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) {
+ // Multiply
+ return SkMulDiv255Round(alphaA, alphaB);
+ }
+
+ static U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) {
+@@ -1429,31 +1423,16 @@ private:
+ static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) {
+ if (rite == riteA) {
+ iter.next();
+ leftA = iter.left();
+ riteA = iter.right();
+ }
+ }
+
+-static bool intersect(int& min, int& max, int boundsMin, int boundsMax) {
+- SkASSERT(min < max);
+- SkASSERT(boundsMin < boundsMax);
+- if (min >= boundsMax || max <= boundsMin) {
+- return false;
+- }
+- if (min < boundsMin) {
+- min = boundsMin;
+- }
+- if (max > boundsMax) {
+- max = boundsMax;
+- }
+- return true;
+-}
+-
+ static void operatorX(SkAAClip::Builder& builder, int lastY,
+ RowIter& iterA, RowIter& iterB,
+ AlphaProc proc, const SkIRect& bounds) {
+ int leftA = iterA.left();
+ int riteA = iterA.right();
+ int leftB = iterB.left();
+ int riteB = iterB.right();
+
+@@ -1970,34 +1949,33 @@ static void small_bzero(void* dst, size_
+ static inline uint8_t mergeOne(uint8_t value, unsigned alpha) {
+ return SkMulDiv255Round(value, alpha);
+ }
+ static inline uint16_t mergeOne(uint16_t value, unsigned alpha) {
+ unsigned r = SkGetPackedR16(value);
+ unsigned g = SkGetPackedG16(value);
+ unsigned b = SkGetPackedB16(value);
+ return SkPackRGB16(SkMulDiv255Round(r, alpha),
+- SkMulDiv255Round(r, alpha),
+- SkMulDiv255Round(r, alpha));
++ SkMulDiv255Round(g, alpha),
++ SkMulDiv255Round(b, alpha));
+ }
+ static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) {
+ unsigned a = SkGetPackedA32(value);
+ unsigned r = SkGetPackedR32(value);
+ unsigned g = SkGetPackedG32(value);
+ unsigned b = SkGetPackedB32(value);
+ return SkPackARGB32(SkMulDiv255Round(a, alpha),
+ SkMulDiv255Round(r, alpha),
+ SkMulDiv255Round(g, alpha),
+ SkMulDiv255Round(b, alpha));
+ }
+
+ template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN,
+ const uint8_t* SK_RESTRICT row, int rowN,
+ T* SK_RESTRICT dst) {
+- SkDEBUGCODE(int accumulated = 0;)
+ for (;;) {
+ SkASSERT(rowN > 0);
+ SkASSERT(srcN > 0);
+
+ int n = SkMin32(rowN, srcN);
+ unsigned rowA = row[1];
+ if (0xFF == rowA) {
+ small_memcpy(dst, src, n * sizeof(T));
+diff --git a/gfx/skia/src/core/SkBlitMask_D32.cpp b/gfx/skia/src/core/SkBlitMask_D32.cpp
+--- a/gfx/skia/src/core/SkBlitMask_D32.cpp
++++ b/gfx/skia/src/core/SkBlitMask_D32.cpp
+@@ -268,107 +268,49 @@ bool SkBlitMask::BlitColor(const SkBitma
+ return true;
+ }
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////
+
+-static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
+- const uint8_t* SK_RESTRICT mask,
+- const SkPMColor* SK_RESTRICT src, int count) {
+- int i, octuple = (count + 7) >> 3;
+- for (i = 0; i < octuple; ++i) {
+- int m = *mask++;
+- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
+- if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
+- if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
+- if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
+- if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
+- if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
+- if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
+- if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
+- src += 8;
+- dst += 8;
+- }
+- count &= 7;
+- if (count > 0) {
+- int m = *mask;
+- do {
+- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
+- m <<= 1;
+- src += 1;
+- dst += 1;
+- } while (--count > 0);
+- }
+-}
+-
+-static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
+- const uint8_t* SK_RESTRICT mask,
+- const SkPMColor* SK_RESTRICT src, int count) {
+- int i, octuple = (count + 7) >> 3;
+- for (i = 0; i < octuple; ++i) {
+- int m = *mask++;
+- if (m & 0x80) { dst[0] = src[0]; }
+- if (m & 0x40) { dst[1] = src[1]; }
+- if (m & 0x20) { dst[2] = src[2]; }
+- if (m & 0x10) { dst[3] = src[3]; }
+- if (m & 0x08) { dst[4] = src[4]; }
+- if (m & 0x04) { dst[5] = src[5]; }
+- if (m & 0x02) { dst[6] = src[6]; }
+- if (m & 0x01) { dst[7] = src[7]; }
+- src += 8;
+- dst += 8;
+- }
+- count &= 7;
+- if (count > 0) {
+- int m = *mask;
+- do {
+- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
+- m <<= 1;
+- src += 1;
+- dst += 1;
+- } while (--count > 0);
+- }
+-}
+-
+ static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
+ const uint8_t* SK_RESTRICT mask,
+ const SkPMColor* SK_RESTRICT src, int count) {
+ for (int i = 0; i < count; ++i) {
+ if (mask[i]) {
+ dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
+ }
+ }
+ }
+
+ // expand the steps that SkAlphaMulQ performs, but this way we can
+-// exand.. add.. combine
++// expand.. add.. combine
+ // instead of
+ // expand..combine add expand..combine
+ //
+ #define EXPAND0(v, m, s) ((v) & (m)) * (s)
+ #define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s)
+ #define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m)))
+
+ static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
+ const uint8_t* SK_RESTRICT mask,
+ const SkPMColor* SK_RESTRICT src, int count) {
+- const uint32_t rbmask = gMask_00FF00FF;
+ for (int i = 0; i < count; ++i) {
+ int m = mask[i];
+ if (m) {
+ m += (m >> 7);
+ #if 1
+ // this is slightly slower than the expand/combine version, but it
+ // is much closer to the old results, so we use it for now to reduce
+ // rebaselining.
+ dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
+ #else
++ const uint32_t rbmask = gMask_00FF00FF;
+ uint32_t v = src[i];
+ uint32_t s0 = EXPAND0(v, rbmask, m);
+ uint32_t s1 = EXPAND1(v, rbmask, m);
+ v = dst[i];
+ uint32_t d0 = EXPAND0(v, rbmask, m);
+ uint32_t d1 = EXPAND1(v, rbmask, m);
+ dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask);
+ #endif
+@@ -559,17 +501,17 @@ SkBlitMask::RowProc SkBlitMask::RowFacto
+ // make this opt-in until chrome can rebaseline
+ RowProc proc = PlatformRowProcs(config, format, flags);
+ if (proc) {
+ return proc;
+ }
+
+ static const RowProc gProcs[] = {
+ // need X coordinate to handle BW
+- NULL, NULL, //(RowProc)BW_RowProc_Blend, (RowProc)BW_RowProc_Opaque,
++ NULL, NULL,
+ (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque,
+ (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque,
+ (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque,
+ };
+
+ int index;
+ switch (config) {
+ case SkBitmap::kARGB_8888_Config:
+diff --git a/gfx/skia/src/core/SkConcaveToTriangles.cpp b/gfx/skia/src/core/SkConcaveToTriangles.cpp
+--- a/gfx/skia/src/core/SkConcaveToTriangles.cpp
++++ b/gfx/skia/src/core/SkConcaveToTriangles.cpp
+@@ -37,17 +37,16 @@
+ #include "SkTDArray.h"
+ #include "SkGeometry.h"
+ #include "SkTSort.h"
+
+ // This is used to prevent runaway code bugs, and can probably be removed after
+ // the code has been proven robust.
+ #define kMaxCount 1000
+
+-#define DEBUG
+ #ifdef DEBUG
+ //------------------------------------------------------------------------------
+ // Debugging support
+ //------------------------------------------------------------------------------
+
+ #include <cstdio>
+ #include <stdarg.h>
+
+diff --git a/gfx/skia/src/core/SkPath.cpp b/gfx/skia/src/core/SkPath.cpp
+--- a/gfx/skia/src/core/SkPath.cpp
++++ b/gfx/skia/src/core/SkPath.cpp
+@@ -469,17 +469,16 @@ void SkPath::incReserve(U16CPU inc) {
+ fPts.setReserve(fPts.count() + inc);
+
+ SkDEBUGCODE(this->validate();)
+ }
+
+ void SkPath::moveTo(SkScalar x, SkScalar y) {
+ SkDEBUGCODE(this->validate();)
+
+- int vc = fVerbs.count();
+ SkPoint* pt;
+
+ // remember our index
+ fLastMoveToIndex = fPts.count();
+
+ pt = fPts.append();
+ *fVerbs.append() = kMove_Verb;
+ pt->set(x, y);
+@@ -1163,17 +1162,16 @@ void SkPath::reversePathTo(const SkPath&
+ }
+ pts -= gPtsInVerb[verbs[i]];
+ }
+ }
+
+ void SkPath::reverseAddPath(const SkPath& src) {
+ this->incReserve(src.fPts.count());
+
+- const SkPoint* startPts = src.fPts.begin();
+ const SkPoint* pts = src.fPts.end();
+ const uint8_t* startVerbs = src.fVerbs.begin();
+ const uint8_t* verbs = src.fVerbs.end();
+
+ fIsOval = false;
+
+ bool needMove = true;
+ bool needClose = false;
+diff --git a/gfx/skia/src/core/SkRegion.cpp b/gfx/skia/src/core/SkRegion.cpp
+--- a/gfx/skia/src/core/SkRegion.cpp
++++ b/gfx/skia/src/core/SkRegion.cpp
+@@ -920,20 +920,16 @@ static int operate(const SkRegion::RunTy
+ /* Given count RunTypes in a complex region, return the worst case number of
+ logical intervals that represents (i.e. number of rects that would be
+ returned from the iterator).
+
+ We could just return count/2, since there must be at least 2 values per
+ interval, but we can first trim off the const overhead of the initial TOP
+ value, plus the final BOTTOM + 2 sentinels.
+ */
+-static int count_to_intervals(int count) {
+- SkASSERT(count >= 6); // a single rect is 6 values
+- return (count - 4) >> 1;
+-}
+
+ /* Given a number of intervals, what is the worst case representation of that
+ many intervals?
+
+ Worst case (from a storage perspective), is a vertical stack of single
+ intervals: TOP + N * (BOTTOM INTERVALCOUNT LEFT RIGHT SENTINEL) + SENTINEL
+ */
+ static int intervals_to_count(int intervals) {
+diff --git a/gfx/skia/src/core/SkScalerContext.cpp b/gfx/skia/src/core/SkScalerContext.cpp
+--- a/gfx/skia/src/core/SkScalerContext.cpp
++++ b/gfx/skia/src/core/SkScalerContext.cpp
+@@ -336,44 +336,16 @@ SK_ERROR:
+ glyph->fTop = 0;
+ glyph->fWidth = 0;
+ glyph->fHeight = 0;
+ // put a valid value here, in case it was earlier set to
+ // MASK_FORMAT_JUST_ADVANCE
+ glyph->fMaskFormat = fRec.fMaskFormat;
+ }
+
+-static bool isLCD(const SkScalerContext::Rec& rec) {
+- return SkMask::kLCD16_Format == rec.fMaskFormat ||
+- SkMask::kLCD32_Format == rec.fMaskFormat;
+-}
+-
+-static uint16_t a8_to_rgb565(unsigned a8) {
+- return SkPackRGB16(a8 >> 3, a8 >> 2, a8 >> 3);
+-}
+-
+-static void copyToLCD16(const SkBitmap& src, const SkMask& dst) {
+- SkASSERT(SkBitmap::kA8_Config == src.config());
+- SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
+-
+- const int width = dst.fBounds.width();
+- const int height = dst.fBounds.height();
+- const uint8_t* srcP = src.getAddr8(0, 0);
+- size_t srcRB = src.rowBytes();
+- uint16_t* dstP = (uint16_t*)dst.fImage;
+- size_t dstRB = dst.fRowBytes;
+- for (int y = 0; y < height; ++y) {
+- for (int x = 0; x < width; ++x) {
+- dstP[x] = a8_to_rgb565(srcP[x]);
+- }
+- srcP += srcRB;
+- dstP = (uint16_t*)((char*)dstP + dstRB);
+- }
+-}
+-
+ #define SK_FREETYPE_LCD_LERP 160
+
+ static int lerp(int start, int end) {
+ SkASSERT((unsigned)SK_FREETYPE_LCD_LERP <= 256);
+ return start + ((end - start) * (SK_FREETYPE_LCD_LERP) >> 8);
+ }
+
+ static uint16_t packLCD16(unsigned r, unsigned g, unsigned b) {
+diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp
+--- a/gfx/skia/src/core/SkScan_AntiPath.cpp
++++ b/gfx/skia/src/core/SkScan_AntiPath.cpp
+@@ -230,52 +230,16 @@ void SuperBlitter::blitH(int x, int y, i
+ fOffsetX);
+
+ #ifdef SK_DEBUG
+ fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
+ fCurrX = x + width;
+ #endif
+ }
+
+-static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
+- int n, U8CPU riteA) {
+- SkASSERT(leftA <= 0xFF);
+- SkASSERT(riteA <= 0xFF);
+-
+- int16_t* run = runs.fRuns;
+- uint8_t* aa = runs.fAlpha;
+-
+- if (ileft > 0) {
+- run[0] = ileft;
+- aa[0] = 0;
+- run += ileft;
+- aa += ileft;
+- }
+-
+- SkASSERT(leftA < 0xFF);
+- if (leftA > 0) {
+- *run++ = 1;
+- *aa++ = leftA;
+- }
+-
+- if (n > 0) {
+- run[0] = n;
+- aa[0] = 0xFF;
+- run += n;
+- aa += n;
+- }
+-
+- SkASSERT(riteA < 0xFF);
+- if (riteA > 0) {
+- *run++ = 1;
+- *aa++ = riteA;
+- }
+- run[0] = 0;
+-}
+-
+ void SuperBlitter::blitRect(int x, int y, int width, int height) {
+ SkASSERT(width > 0);
+ SkASSERT(height > 0);
+
+ // blit leading rows
+ while ((y & MASK)) {
+ this->blitH(x, y++, width);
+ if (--height <= 0) {
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -865,45 +865,16 @@ bool Linear_Gradient::setContext(const S
+ } while (0)
+
+ namespace {
+
+ typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* dstC, const SkPMColor* cache,
+ int toggle, int count);
+
+-// This function is deprecated, and will be replaced by
+-// shadeSpan_linear_vertical_lerp() once Chrome has been weaned off of it.
+-void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
+- SkPMColor* SK_RESTRICT dstC,
+- const SkPMColor* SK_RESTRICT cache,
+- int toggle, int count) {
+- if (proc == clamp_tileproc) {
+- // Read out clamp values from beginning/end of the cache. No need to lerp
+- // or dither
+- if (fx < 0) {
+- sk_memset32(dstC, cache[-1], count);
+- return;
+- } else if (fx > 0xFFFF) {
+- sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
+- return;
+- }
+- }
+-
+- // We're a vertical gradient, so no change in a span.
+- // If colors change sharply across the gradient, dithering is
+- // insufficient (it subsamples the color space) and we need to lerp.
+- unsigned fullIndex = proc(fx);
+- unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits);
+- sk_memset32_dither(dstC,
+- cache[toggle + fi],
+- cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi],
+- count);
+-}
+-
+ // Linear interpolation (lerp) is unnecessary if there are no sharp
+ // discontinuities in the gradient - which must be true if there are
+ // only 2 colors - but it's cheap.
+ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
+ SkPMColor* SK_RESTRICT dstC,
+ const SkPMColor* SK_RESTRICT cache,
+ int toggle, int count) {
+ if (proc == clamp_tileproc) {
+@@ -2131,16 +2102,18 @@ protected:
+ buffer.writePoint(fCenter);
+ }
+
+ private:
+ typedef Gradient_Shader INHERITED;
+ const SkPoint fCenter;
+ };
+
++#ifndef SK_SCALAR_IS_FLOAT
++
+ #ifdef COMPUTE_SWEEP_TABLE
+ #define PI 3.14159265
+ static bool gSweepTableReady;
+ static uint8_t gSweepTable[65];
+
+ /* Our table stores precomputed values for atan: [0...1] -> [0..PI/4]
+ We scale the results to [0..32]
+ */
+@@ -2168,20 +2141,23 @@ static const uint8_t gSweepTable[] = {
+ 10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18,
+ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26,
+ 26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32,
+ 32
+ };
+ static const uint8_t* build_sweep_table() { return gSweepTable; }
+ #endif
+
++#endif
++
+ // divide numer/denom, with a bias of 6bits. Assumes numer <= denom
+ // and denom != 0. Since our table is 6bits big (+1), this is a nice fit.
+ // Same as (but faster than) SkFixedDiv(numer, denom) >> 10
+
++#ifndef SK_SCALAR_IS_FLOAT
+ //unsigned div_64(int numer, int denom);
+ static unsigned div_64(int numer, int denom) {
+ SkASSERT(numer <= denom);
+ SkASSERT(numer > 0);
+ SkASSERT(denom > 0);
+
+ int nbits = SkCLZ(numer);
+ int dbits = SkCLZ(denom);
+@@ -2294,16 +2270,17 @@ static unsigned atan_0_90(SkFixed y, SkF
+ result = 64 - result;
+ // pin to 63
+ result -= result >> 6;
+ }
+
+ SkASSERT(result <= 63);
+ return result;
+ }
++#endif
+
+ // returns angle in a circle [0..2PI) -> [0..255]
+ #ifdef SK_SCALAR_IS_FLOAT
+ static unsigned SkATan2_255(float y, float x) {
+ // static const float g255Over2PI = 255 / (2 * SK_ScalarPI);
+ static const float g255Over2PI = 40.584510488433314f;
+
+ float result = sk_float_atan2(y, x);
+diff --git a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
+--- a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
++++ b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
+@@ -112,17 +112,17 @@ void BlitRect32_OpaqueWide_SSE2(SkPMColo
+ }
+
+ void ColorRect32_SSE2(SkPMColor* destination,
+ int width, int height,
+ size_t rowBytes, uint32_t color) {
+ if (0 == height || 0 == width || 0 == color) {
+ return;
+ }
+- unsigned colorA = SkGetPackedA32(color);
++ //unsigned colorA = SkGetPackedA32(color);
+ //if (255 == colorA) {
+ //if (width < 31) {
+ //BlitRect32_OpaqueNarrow_SSE2(destination, width, height,
+ //rowBytes, color);
+ //} else {
+ //BlitRect32_OpaqueWide_SSE2(destination, width, height,
+ //rowBytes, color);
+ //}
+diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
++++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+@@ -75,20 +75,16 @@ static CGFloat CGRectGetMinY_inline(cons
+ static CGFloat CGRectGetMaxY_inline(const CGRect& rect) {
+ return rect.origin.y + rect.size.height;
+ }
+
+ static CGFloat CGRectGetWidth_inline(const CGRect& rect) {
+ return rect.size.width;
+ }
+
+-static CGFloat CGRectGetHeight(const CGRect& rect) {
+- return rect.size.height;
+-}
+-
+ ///////////////////////////////////////////////////////////////////////////////
+
+ static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width,
+ size_t height, size_t rowBytes) {
+ SkASSERT(width);
+ SkASSERT(width * sizeof(uint32_t) <= rowBytes);
+
+ if (width >= 32) {
+@@ -125,28 +121,30 @@ static void sk_memset_rect32(uint32_t* p
+ *ptr++ = value;
+ } while (--w > 0);
+ ptr = (uint32_t*)((char*)ptr + rowBytes);
+ height -= 1;
+ }
+ }
+ }
+
++#if 0
+ // Potentially this should be made (1) public (2) optimized when width is small.
+ // Also might want 16 and 32 bit version
+ //
+ static void sk_memset_rect(void* ptr, U8CPU byte, size_t width, size_t height,
+ size_t rowBytes) {
+ uint8_t* dst = (uint8_t*)ptr;
+ while (height) {
+ memset(dst, byte, width);
+ dst += rowBytes;
+ height -= 1;
+ }
+ }
++#endif
+
+ #include <sys/utsname.h>
+
+ typedef uint32_t CGRGBPixel;
+
+ static unsigned CGRGBPixel_getAlpha(CGRGBPixel pixel) {
+ return pixel & 0xFF;
+ }
+@@ -250,23 +248,16 @@ static CGAffineTransform MatrixToCGAffin
+ return CGAffineTransformMake(ScalarToCG(matrix[SkMatrix::kMScaleX]) * sx,
+ -ScalarToCG(matrix[SkMatrix::kMSkewY]) * sy,
+ -ScalarToCG(matrix[SkMatrix::kMSkewX]) * sx,
+ ScalarToCG(matrix[SkMatrix::kMScaleY]) * sy,
+ ScalarToCG(matrix[SkMatrix::kMTransX]) * sx,
+ ScalarToCG(matrix[SkMatrix::kMTransY]) * sy);
+ }
+
+-static void CGAffineTransformToMatrix(const CGAffineTransform& xform, SkMatrix* matrix) {
+- matrix->setAll(
+- CGToScalar(xform.a), CGToScalar(xform.c), CGToScalar(xform.tx),
+- CGToScalar(xform.b), CGToScalar(xform.d), CGToScalar(xform.ty),
+- 0, 0, SK_Scalar1);
+-}
+-
+ static SkScalar getFontScale(CGFontRef cgFont) {
+ int unitsPerEm = CGFontGetUnitsPerEm(cgFont);
+ return SkScalarInvert(SkIntToScalar(unitsPerEm));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ #define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
+@@ -1075,16 +1066,17 @@ static const uint8_t* getInverseTable(bo
+ if (!gInited) {
+ build_power_table(gWhiteTable, 1.5f);
+ build_power_table(gTable, 2.2f);
+ gInited = true;
+ }
+ return isWhite ? gWhiteTable : gTable;
+ }
+
++#ifdef SK_USE_COLOR_LUMINANCE
+ static const uint8_t* getGammaTable(U8CPU luminance) {
+ static uint8_t gGammaTables[4][256];
+ static bool gInited;
+ if (!gInited) {
+ #if 1
+ float start = 1.1;
+ float stop = 2.1;
+ for (int i = 0; i < 4; ++i) {
+@@ -1097,45 +1089,49 @@ static const uint8_t* getGammaTable(U8CP
+ build_power_table(gGammaTables[2], 1);
+ build_power_table(gGammaTables[3], 1);
+ #endif
+ gInited = true;
+ }
+ SkASSERT(0 == (luminance >> 8));
+ return gGammaTables[luminance >> 6];
+ }
++#endif
+
++#ifndef SK_USE_COLOR_LUMINANCE
+ static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width,
+ int height, size_t rb) {
+ const uint8_t* table = getInverseTable(isWhite);
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ uint32_t c = rgb[x];
+ int r = (c >> 16) & 0xFF;
+ int g = (c >> 8) & 0xFF;
+ int b = (c >> 0) & 0xFF;
+ rgb[x] = (table[r] << 16) | (table[g] << 8) | table[b];
+ }
+ rgb = (CGRGBPixel*)((char*)rgb + rb);
+ }
+ }
++#endif
+
+ static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
+ while (count > 0) {
+ uint8_t mask = 0;
+ for (int i = 7; i >= 0; --i) {
+ mask |= (CGRGBPixel_getAlpha(*src++) >> 7) << i;
+ if (0 == --count) {
+ break;
+ }
+ }
+ *dst++ = mask;
+ }
+ }
+
++#ifdef SK_USE_COLOR_LUMINANCE
+ static int lerpScale(int dst, int src, int scale) {
+ return dst + (scale * (src - dst) >> 23);
+ }
+
+ static CGRGBPixel lerpPixel(CGRGBPixel dst, CGRGBPixel src,
+ int scaleR, int scaleG, int scaleB) {
+ int sr = (src >> 16) & 0xFF;
+ int sg = (src >> 8) & 0xFF;
+@@ -1147,37 +1143,31 @@ static CGRGBPixel lerpPixel(CGRGBPixel d
+ int rr = lerpScale(dr, sr, scaleR);
+ int rg = lerpScale(dg, sg, scaleG);
+ int rb = lerpScale(db, sb, scaleB);
+ return (rr << 16) | (rg << 8) | rb;
+ }
+
+ static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width,
+ int height, int rowBytes, int lumBits) {
+-#ifdef SK_USE_COLOR_LUMINANCE
+ int scaleR = (1 << 23) * SkColorGetR(lumBits) / 0xFF;
+ int scaleG = (1 << 23) * SkColorGetG(lumBits) / 0xFF;
+ int scaleB = (1 << 23) * SkColorGetB(lumBits) / 0xFF;
+-#else
+- int scale = (1 << 23) * lumBits / SkScalerContext::kLuminance_Max;
+- int scaleR = scale;
+- int scaleG = scale;
+- int scaleB = scale;
+-#endif
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ // bit-not the src, since it was drawn from black, so we need the
+ // compliment of those bits
+ dst[x] = lerpPixel(dst[x], ~src[x], scaleR, scaleG, scaleB);
+ }
+ src = (CGRGBPixel*)((char*)src + rowBytes);
+ dst = (CGRGBPixel*)((char*)dst + rowBytes);
+ }
+ }
++#endif
+
+ #if 1
+ static inline int r32_to_16(int x) { return SkR32ToR16(x); }
+ static inline int g32_to_16(int x) { return SkG32ToG16(x); }
+ static inline int b32_to_16(int x) { return SkB32ToB16(x); }
+ #else
+ static inline int round8to5(int x) {
+ return (x + 3 - (x >> 5) + (x >> 7)) >> 3;
+@@ -1212,22 +1202,21 @@ static inline uint32_t rgb_to_lcd32(CGRG
+ return SkPackARGB32(0xFF, r, g, b);
+ }
+
+ #define BLACK_LUMINANCE_LIMIT 0x40
+ #define WHITE_LUMINANCE_LIMIT 0xA0
+
+ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
+ CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
+-
+ const bool isLCD = isLCDFormat(glyph.fMaskFormat);
++#ifdef SK_USE_COLOR_LUMINANCE
+ const bool isBW = SkMask::kBW_Format == glyph.fMaskFormat;
+ const bool isA8 = !isLCD && !isBW;
+-
+-#ifdef SK_USE_COLOR_LUMINANCE
++
+ unsigned lumBits = fRec.getLuminanceColor();
+ uint32_t xorMask = 0;
+
+ if (isA8) {
+ // for A8, we just want a component (they're all the same)
+ lumBits = SkColorGetR(lumBits);
+ }
+ #else
+diff --git a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
+--- a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
++++ b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
+@@ -163,59 +163,8 @@ private:
+ CGPDFDocumentRef fDoc;
+ };
+
+ static void CGDataProviderReleaseData_FromMalloc(void*, const void* data,
+ size_t size) {
+ sk_free((void*)data);
+ }
+
+-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
+- size_t size = stream->getLength();
+- void* ptr = sk_malloc_throw(size);
+- stream->read(ptr, size);
+- CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size,
+- CGDataProviderReleaseData_FromMalloc);
+- if (NULL == data) {
+- return false;
+- }
+-
+- CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
+- CGDataProviderRelease(data);
+- if (NULL == pdf) {
+- return false;
+- }
+- SkAutoPDFRelease releaseMe(pdf);
+-
+- CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
+- if (NULL == page) {
+- return false;
+- }
+-
+- CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
+-
+- int w = (int)CGRectGetWidth(bounds);
+- int h = (int)CGRectGetHeight(bounds);
+-
+- SkBitmap bitmap;
+- bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
+- bitmap.allocPixels();
+- bitmap.eraseColor(SK_ColorWHITE);
+-
+- size_t bitsPerComponent;
+- CGBitmapInfo info;
+- getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);
+-
+- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+- CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
+- bitsPerComponent, bitmap.rowBytes(),
+- cs, info);
+- CGColorSpaceRelease(cs);
+-
+- if (ctx) {
+- CGContextDrawPDFPage(ctx, page);
+- CGContextRelease(ctx);
+- }
+-
+- output->swap(bitmap);
+- return true;
+-}
+-
diff --git a/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch b/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch
new file mode 100644
index 0000000000..e00fd8602e
--- /dev/null
+++ b/gfx/skia/patches/archive/0016-Bug-718849-Radial-gradients.patch
@@ -0,0 +1,400 @@
+# HG changeset patch
+# User Matt Woodrow <mwoodrow@mozilla.com>
+# Date 1339988782 -43200
+# Node ID 1e9dae659ee6c992f719fd4136efbcc5410ded37
+# Parent 946750f6d95febd199fb7b748e9d2c48fd01c8a6
+[mq]: skia-windows-gradients
+
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -847,16 +847,19 @@ bool Linear_Gradient::setContext(const S
+ fFlags |= SkShader::kConstInY32_Flag;
+ if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) {
+ // only claim this if we do have a 16bit mode (i.e. none of our
+ // colors have alpha), and if we are not dithering (which obviously
+ // is not const in Y).
+ fFlags |= SkShader::kConstInY16_Flag;
+ }
+ }
++ if (fStart == fEnd) {
++ fFlags &= ~kOpaqueAlpha_Flag;
++ }
+ return true;
+ }
+
+ #define NO_CHECK_ITER \
+ do { \
+ unsigned fi = fx >> Gradient_Shader::kCache32Shift; \
+ SkASSERT(fi <= 0xFF); \
+ fx += dx; \
+@@ -976,16 +979,21 @@ void Linear_Gradient::shadeSpan(int x, i
+ TileProc proc = fTileProc;
+ const SkPMColor* SK_RESTRICT cache = this->getCache32();
+ #ifdef USE_DITHER_32BIT_GRADIENT
+ int toggle = ((x ^ y) & 1) * kDitherStride32;
+ #else
+ int toggle = 0;
+ #endif
+
++ if (fStart == fEnd) {
++ sk_bzero(dstC, count * sizeof(*dstC));
++ return;
++ }
++
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+ SkFixed dxStorage[1];
+ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
+@@ -1169,16 +1177,21 @@ void Linear_Gradient::shadeSpan16(int x,
+ SkASSERT(count > 0);
+
+ SkPoint srcPt;
+ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+ TileProc proc = fTileProc;
+ const uint16_t* SK_RESTRICT cache = this->getCache16();
+ int toggle = ((x ^ y) & 1) * kDitherStride16;
+
++ if (fStart == fEnd) {
++ sk_bzero(dstC, count * sizeof(*dstC));
++ return;
++ }
++
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+ SkFixed dxStorage[1];
+ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
+@@ -1739,21 +1752,25 @@ void Radial_Gradient::shadeSpan(int x, i
+ possible circles on which the point may fall. Solving for t yields
+ the gradient value to use.
+
+ If a<0, the start circle is entirely contained in the
+ end circle, and one of the roots will be <0 or >1 (off the line
+ segment). If a>0, the start circle falls at least partially
+ outside the end circle (or vice versa), and the gradient
+ defines a "tube" where a point may be on one circle (on the
+- inside of the tube) or the other (outside of the tube). We choose
+- one arbitrarily.
++ inside of the tube) or the other (outside of the tube). We choose
++ the one with the highest t value, as long as the radius that it
++ corresponds to is >=0. In the case where neither root has a positive
++ radius, we don't draw anything.
+
++ XXXmattwoodrow: I've removed this for now since it breaks
++ down when Dr == 0. Is there something else we can do instead?
+ In order to keep the math to within the limits of fixed point,
+- we divide the entire quadratic by Dr^2, and replace
++ we divide the entire quadratic by Dr, and replace
+ (x - Sx)/Dr with x' and (y - Sy)/Dr with y', giving
+
+ [Dx^2 / Dr^2 + Dy^2 / Dr^2 - 1)] * t^2
+ + 2 * [x' * Dx / Dr + y' * Dy / Dr - Sr / Dr] * t
+ + [x'^2 + y'^2 - Sr^2/Dr^2] = 0
+
+ (x' and y' are computed by appending the subtract and scale to the
+ fDstToIndex matrix in the constructor).
+@@ -1763,99 +1780,122 @@ void Radial_Gradient::shadeSpan(int x, i
+ x' and y', if x and y are linear in the span, 'B' can be computed
+ incrementally with a simple delta (db below). If it is not (e.g.,
+ a perspective projection), it must be computed in the loop.
+
+ */
+
+ namespace {
+
+-inline SkFixed two_point_radial(SkScalar b, SkScalar fx, SkScalar fy,
+- SkScalar sr2d2, SkScalar foura,
+- SkScalar oneOverTwoA, bool posRoot) {
++inline bool two_point_radial(SkScalar b, SkScalar fx, SkScalar fy,
++ SkScalar sr2d2, SkScalar foura,
++ SkScalar oneOverTwoA, SkScalar diffRadius,
++ SkScalar startRadius, SkFixed& t) {
+ SkScalar c = SkScalarSquare(fx) + SkScalarSquare(fy) - sr2d2;
+ if (0 == foura) {
+- return SkScalarToFixed(SkScalarDiv(-c, b));
++ SkScalar result = SkScalarDiv(-c, b);
++ if (result * diffRadius + startRadius >= 0) {
++ t = SkScalarToFixed(result);
++ return true;
++ }
++ return false;
+ }
+
+ SkScalar discrim = SkScalarSquare(b) - SkScalarMul(foura, c);
+ if (discrim < 0) {
+- discrim = -discrim;
++ return false;
+ }
+ SkScalar rootDiscrim = SkScalarSqrt(discrim);
+- SkScalar result;
+- if (posRoot) {
+- result = SkScalarMul(-b + rootDiscrim, oneOverTwoA);
+- } else {
+- result = SkScalarMul(-b - rootDiscrim, oneOverTwoA);
++
++ // Make sure the results corresponds to a positive radius.
++ SkScalar result = SkScalarMul(-b + rootDiscrim, oneOverTwoA);
++ if (result * diffRadius + startRadius >= 0) {
++ t = SkScalarToFixed(result);
++ return true;
+ }
+- return SkScalarToFixed(result);
++ result = SkScalarMul(-b - rootDiscrim, oneOverTwoA);
++ if (result * diffRadius + startRadius >= 0) {
++ t = SkScalarToFixed(result);
++ return true;
++ }
++
++ return false;
+ }
+
+ typedef void (* TwoPointRadialShadeProc)(SkScalar fx, SkScalar dx,
+ SkScalar fy, SkScalar dy,
+ SkScalar b, SkScalar db,
+- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA,
++ SkScalar fDiffRadius, SkScalar fRadius1,
+ SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
+ int count);
+
+ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
+ SkScalar fy, SkScalar dy,
+ SkScalar b, SkScalar db,
+- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA,
++ SkScalar fDiffRadius, SkScalar fRadius1,
+ SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
+ int count) {
+ for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+- fOneOverTwoA, posRoot);
+-
+- if (t < 0) {
++ SkFixed t;
++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) {
++ *(dstC++) = 0;
++ } else if (t < 0) {
+ *dstC++ = cache[-1];
+ } else if (t > 0xFFFF) {
+ *dstC++ = cache[Gradient_Shader::kCache32Count * 2];
+ } else {
+ SkASSERT(t <= 0xFFFF);
+ *dstC++ = cache[t >> Gradient_Shader::kCache32Shift];
+ }
+
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ }
+ void shadeSpan_twopoint_mirror(SkScalar fx, SkScalar dx,
+ SkScalar fy, SkScalar dy,
+ SkScalar b, SkScalar db,
+- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA,
++ SkScalar fDiffRadius, SkScalar fRadius1,
+ SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
+ int count) {
+ for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+- fOneOverTwoA, posRoot);
+- SkFixed index = mirror_tileproc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
++ SkFixed t;
++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) {
++ *(dstC++) = 0;
++ } else {
++ SkFixed index = mirror_tileproc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - Gradient_Shader::kCache32Shift)];
++ }
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ }
+
+ void shadeSpan_twopoint_repeat(SkScalar fx, SkScalar dx,
+ SkScalar fy, SkScalar dy,
+ SkScalar b, SkScalar db,
+- SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
++ SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA,
++ SkScalar fDiffRadius, SkScalar fRadius1,
+ SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
+ int count) {
+ for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+- fOneOverTwoA, posRoot);
+- SkFixed index = repeat_tileproc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
++ SkFixed t;
++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) {
++ *(dstC++) = 0;
++ } else {
++ SkFixed index = repeat_tileproc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - Gradient_Shader::kCache32Shift)];
++ }
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ }
+
+
+
+@@ -1935,17 +1975,16 @@ public:
+ sk_bzero(dstC, count * sizeof(*dstC));
+ return;
+ }
+ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+ TileProc proc = fTileProc;
+ const SkPMColor* SK_RESTRICT cache = this->getCache32();
+
+ SkScalar foura = fA * 4;
+- bool posRoot = fDiffRadius < 0;
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
+ SkPoint srcPt;
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkScalar dx, fx = srcPt.fX;
+ SkScalar dy, fy = srcPt.fY;
+
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+@@ -1954,60 +1993,69 @@ public:
+ dx = SkFixedToScalar(fixedX);
+ dy = SkFixedToScalar(fixedY);
+ } else {
+ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+ dx = fDstToIndex.getScaleX();
+ dy = fDstToIndex.getSkewY();
+ }
+ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
++ SkScalarMul(fDiff.fY, fy) - fStartRadius * fDiffRadius) * 2;
+ SkScalar db = (SkScalarMul(fDiff.fX, dx) +
+ SkScalarMul(fDiff.fY, dy)) * 2;
+
+ TwoPointRadialShadeProc shadeProc = shadeSpan_twopoint_repeat;
+ if (proc == clamp_tileproc) {
+ shadeProc = shadeSpan_twopoint_clamp;
+ } else if (proc == mirror_tileproc) {
+ shadeProc = shadeSpan_twopoint_mirror;
+ } else {
+ SkASSERT(proc == repeat_tileproc);
+ }
+ (*shadeProc)(fx, dx, fy, dy, b, db,
+- fSr2D2, foura, fOneOverTwoA, posRoot,
++ fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1,
+ dstC, cache, count);
+ } else { // perspective case
+ SkScalar dstX = SkIntToScalar(x);
+ SkScalar dstY = SkIntToScalar(y);
+ for (; count > 0; --count) {
+ SkPoint srcPt;
+ dstProc(fDstToIndex, dstX, dstY, &srcPt);
+ SkScalar fx = srcPt.fX;
+ SkScalar fy = srcPt.fY;
+ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
+- fOneOverTwoA, posRoot);
+- SkFixed index = proc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
++ SkFixed t;
++ if (!two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, fDiffRadius, fRadius1, t)) {
++ *(dstC++) = 0;
++ } else {
++ SkFixed index = proc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - kCache32Bits)];
++ }
+ dstX += SK_Scalar1;
+ }
+ }
+ }
+
+ virtual bool setContext(const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix) SK_OVERRIDE {
+ if (!this->INHERITED::setContext(device, paint, matrix)) {
+ return false;
+ }
+
+ // we don't have a span16 proc
+ fFlags &= ~kHasSpan16_Flag;
++
++ // If we might end up wanting to draw nothing as part of the gradient
++ // then we should mark ourselves as not being opaque.
++ if (fA >= 0 || (fDiffRadius == 0 && fCenter1 == fCenter2)) {
++ fFlags &= ~kOpaqueAlpha_Flag;
++ }
+ return true;
+ }
+
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Two_Point_Radial_Gradient)
+
+ protected:
+ Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
+ : INHERITED(buffer),
+@@ -2033,26 +2081,22 @@ private:
+ const SkScalar fRadius1;
+ const SkScalar fRadius2;
+ SkPoint fDiff;
+ SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
+
+ void init() {
+ fDiff = fCenter1 - fCenter2;
+ fDiffRadius = fRadius2 - fRadius1;
+- SkScalar inv = SkScalarInvert(fDiffRadius);
+- fDiff.fX = SkScalarMul(fDiff.fX, inv);
+- fDiff.fY = SkScalarMul(fDiff.fY, inv);
+- fStartRadius = SkScalarMul(fRadius1, inv);
++ fStartRadius = fRadius1;
+ fSr2D2 = SkScalarSquare(fStartRadius);
+- fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
++ fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SkScalarSquare(fDiffRadius);
+ fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
+
+ fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
+- fPtsToUnit.postScale(inv, inv);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ class Sweep_Gradient : public Gradient_Shader {
+ public:
+ Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[],
+@@ -2488,16 +2532,20 @@ SkShader* SkGradientShader::CreateTwoPoi
+ int colorCount,
+ SkShader::TileMode mode,
+ SkUnitMapper* mapper) {
+ if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) {
+ return NULL;
+ }
+ EXPAND_1_COLOR(colorCount);
+
++ if (start == end && startRadius == 0) {
++ return CreateRadial(start, endRadius, colors, pos, colorCount, mode, mapper);
++ }
++
+ return SkNEW_ARGS(Two_Point_Radial_Gradient,
+ (start, startRadius, end, endRadius, colors, pos,
+ colorCount, mode, mapper));
+ }
+
+ SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy,
+ const SkColor colors[],
+ const SkScalar pos[],
diff --git a/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch b/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch
new file mode 100644
index 0000000000..719fda1650
--- /dev/null
+++ b/gfx/skia/patches/archive/0017-Bug-740194-SkMemory-mozalloc.patch
@@ -0,0 +1,73 @@
+commit 5786f516119bcb677510f3c9256b870c3b5616c8
+Author: George Wright <gwright@mozilla.com>
+Date: Wed Aug 15 23:51:34 2012 -0400
+
+ Bug 740194 - [Skia] Implement a version of SkMemory for Mozilla that uses the infallible mozalloc allocators r=cjones
+
+diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
+index f98ba85..17be191 100644
+--- a/gfx/skia/include/config/SkUserConfig.h
++++ b/gfx/skia/include/config/SkUserConfig.h
+@@ -35,6 +35,16 @@
+ commented out, so including it will have no effect.
+ */
+
++/*
++ Override new/delete with Mozilla's allocator, mozalloc
++
++ Ideally we shouldn't need to do this here, but until
++ http://code.google.com/p/skia/issues/detail?id=598 is fixed
++ we need to include this here to override operator new and delete
++*/
++
++#include "mozilla/mozalloc.h"
++
+ ///////////////////////////////////////////////////////////////////////////////
+
+ /* Scalars (the fractional value type in skia) can be implemented either as
+diff --git a/gfx/skia/src/ports/SkMemory_mozalloc.cpp b/gfx/skia/src/ports/SkMemory_mozalloc.cpp
+new file mode 100644
+index 0000000..1f16ee5
+--- /dev/null
++++ b/gfx/skia/src/ports/SkMemory_mozalloc.cpp
+@@ -0,0 +1,40 @@
++/*
++ * Copyright 2011 Google Inc.
++ * Copyright 2012 Mozilla Foundation
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include "SkTypes.h"
++
++#include "mozilla/mozalloc.h"
++#include "mozilla/mozalloc_abort.h"
++#include "mozilla/mozalloc_oom.h"
++
++void sk_throw() {
++ SkDEBUGFAIL("sk_throw");
++ mozalloc_abort("Abort from sk_throw");
++}
++
++void sk_out_of_memory(void) {
++ SkDEBUGFAIL("sk_out_of_memory");
++ mozalloc_handle_oom(0);
++}
++
++void* sk_malloc_throw(size_t size) {
++ return sk_malloc_flags(size, SK_MALLOC_THROW);
++}
++
++void* sk_realloc_throw(void* addr, size_t size) {
++ return moz_xrealloc(addr, size);
++}
++
++void sk_free(void* p) {
++ free(p);
++}
++
++void* sk_malloc_flags(size_t size, unsigned flags) {
++ return (flags & SK_MALLOC_THROW) ? moz_xmalloc(size) : malloc(size);
++}
++
diff --git a/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch b/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch
new file mode 100644
index 0000000000..d16ec4b3b4
--- /dev/null
+++ b/gfx/skia/patches/archive/0018-Bug-817356-PPC-defines.patch
@@ -0,0 +1,14 @@
+Index: gfx/skia/include/core/SkPreConfig.h
+===================================================================
+--- gfx/skia/include/core/SkPreConfig.h (revision 6724)
++++ gfx/skia/include/core/SkPreConfig.h (working copy)
+@@ -94,7 +94,8 @@
+ //////////////////////////////////////////////////////////////////////
+
+ #if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
+- #if defined (__ppc__) || defined(__ppc64__)
++ #if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \
++ || defined(__PPC64__)
+ #define SK_CPU_BENDIAN
+ #else
+ #define SK_CPU_LENDIAN
diff --git a/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch b/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch
new file mode 100644
index 0000000000..97404c431b
--- /dev/null
+++ b/gfx/skia/patches/archive/0022-Bug-848491-Re-apply-bug-795538-Ensure-we-use-the-cor.patch
@@ -0,0 +1,39 @@
+From: George Wright <gwright@mozilla.com>
+Date: Thu, 20 Jun 2013 09:21:21 -0400
+Subject: Bug 848491 - Re-apply bug 795538 - Ensure we use the correct colour (and alpha) for the clamp values r=mattwoodrow
+
+
+diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+index 27a9c46..ce077b5 100644
+--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+@@ -500,15 +500,17 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
+ }
+
+ // Write the clamp colours into the first and last entries of fCache32
+- fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha,
+- SkColorGetR(fOrigColors[0]),
+- SkColorGetG(fOrigColors[0]),
+- SkColorGetB(fOrigColors[0]));
+-
+- fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha,
+- SkColorGetR(fOrigColors[fColorCount - 1]),
+- SkColorGetG(fOrigColors[fColorCount - 1]),
+- SkColorGetB(fOrigColors[fColorCount - 1]));
++ fCache32[kCache32ClampLower] = SkPremultiplyARGBInline(SkMulDiv255Round(SkColorGetA(fOrigColors[0]),
++ fCacheAlpha),
++ SkColorGetR(fOrigColors[0]),
++ SkColorGetG(fOrigColors[0]),
++ SkColorGetB(fOrigColors[0]));
++
++ fCache32[kCache32ClampUpper] = SkPremultiplyARGBInline(SkMulDiv255Round(SkColorGetA(fOrigColors[fColorCount - 1]),
++ fCacheAlpha),
++ SkColorGetR(fOrigColors[fColorCount - 1]),
++ SkColorGetG(fOrigColors[fColorCount - 1]),
++ SkColorGetB(fOrigColors[fColorCount - 1]));
+
+ return fCache32;
+ }
+--
+1.7.11.7
+
diff --git a/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch b/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch
new file mode 100644
index 0000000000..9bc7ddec46
--- /dev/null
+++ b/gfx/skia/patches/archive/0023-Bug-890539-Fix-SK_COMPILE_ASSERT-build-warning.patch
@@ -0,0 +1,39 @@
+# HG changeset patch
+# Parent e378875000890099fffcdb4cbc4ab12828ac34ee
+# User Daniel Holbert <dholbert@cs.stanford.edu>
+Bug 890539: Annotate SK_COMPILE_ASSERT's typedef as permissibly unused, to fix GCC 4.8 build warning. r=gw280
+
+diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h
+--- a/gfx/skia/include/core/SkTypes.h
++++ b/gfx/skia/include/core/SkTypes.h
+@@ -121,18 +121,29 @@ inline void operator delete(void* p) {
+ #define SkDEVCODE(code)
+ #define SK_DEVELOPER_TO_STRING()
+ #endif
+
+ template <bool>
+ struct SkCompileAssert {
+ };
+
++/*
++ * The SK_COMPILE_ASSERT definition creates an otherwise-unused typedef. This
++ * triggers compiler warnings with some versions of gcc, so mark the typedef
++ * as permissibly-unused to disable the warnings.
++ */
++# if defined(__GNUC__)
++# define SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
++# else
++# define SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE /* nothing */
++# endif
++
+ #define SK_COMPILE_ASSERT(expr, msg) \
+- typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
++ typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] SK_COMPILE_ASSERT_UNUSED_ATTRIBUTE
+
+ /*
+ * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab
+ *
+ * SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
+ *
+ */
+ #define SK_MACRO_CONCAT(X, Y) SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
diff --git a/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch b/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch
new file mode 100644
index 0000000000..864a0af7a9
--- /dev/null
+++ b/gfx/skia/patches/archive/0024-Bug-887318-fix-bgra-readback.patch
@@ -0,0 +1,217 @@
+diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp
+--- a/gfx/gl/GLContextSkia.cpp
++++ b/gfx/gl/GLContextSkia.cpp
+@@ -303,39 +303,47 @@ const GLubyte* glGetString_mozilla(GrGLe
+ if (name == LOCAL_GL_VERSION) {
+ if (sGLContext.get()->IsGLES2()) {
+ return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0");
+ } else {
+ return reinterpret_cast<const GLubyte*>("2.0");
+ }
+ } else if (name == LOCAL_GL_EXTENSIONS) {
+ // Only expose the bare minimum extensions we want to support to ensure a functional Ganesh
+ // as GLContext only exposes certain extensions
+ static bool extensionsStringBuilt = false;
+- static char extensionsString[120];
++ static char extensionsString[256];
+
+ if (!extensionsStringBuilt) {
+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) {
+ strcpy(extensionsString, "GL_EXT_texture_format_BGRA8888 ");
+ }
+
+ if (sGLContext.get()->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) {
+ strcat(extensionsString, "GL_OES_packed_depth_stencil ");
+ }
+
+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) {
+ strcat(extensionsString, "GL_EXT_packed_depth_stencil ");
+ }
+
+ if (sGLContext.get()->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) {
+ strcat(extensionsString, "GL_OES_rgb8_rgba8 ");
+ }
+
++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_bgra)) {
++ strcat(extensionsString, "GL_EXT_bgra ");
++ }
++
++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_read_format_bgra)) {
++ strcat(extensionsString, "GL_EXT_read_format_bgra ");
++ }
++
+ extensionsStringBuilt = true;
+ }
+
+ return reinterpret_cast<const GLubyte*>(extensionsString);
+
+ } else if (name == LOCAL_GL_SHADING_LANGUAGE_VERSION) {
+ if (sGLContext.get()->IsGLES2()) {
+ return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0");
+ } else {
+ return reinterpret_cast<const GLubyte*>("1.10");
+diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/src/gpu/gl/GrGpuGL.cpp
+--- a/gfx/skia/src/gpu/gl/GrGpuGL.cpp
++++ b/gfx/skia/src/gpu/gl/GrGpuGL.cpp
+@@ -1,18 +1,18 @@
+ /*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+-
++#include <algorithm>
+ #include "GrGpuGL.h"
+ #include "GrGLStencilBuffer.h"
+ #include "GrGLPath.h"
+ #include "GrGLShaderBuilder.h"
+ #include "GrTemplates.h"
+ #include "GrTypes.h"
+ #include "SkTemplates.h"
+
+ static const GrGLuint GR_MAX_GLUINT = ~0U;
+ static const GrGLint GR_INVAL_GLINT = ~0;
+@@ -1381,29 +1381,67 @@ bool GrGpuGL::readPixelsWillPayForYFlip(
+ // Note the rowBytes might be tight to the passed in data, but if data
+ // gets clipped in x to the target the rowBytes will no longer be tight.
+ if (left >= 0 && (left + width) < renderTarget->width()) {
+ return 0 == rowBytes ||
+ GrBytesPerPixel(config) * width == rowBytes;
+ } else {
+ return false;
+ }
+ }
+
++static void swizzleRow(void* buffer, int byteLen) {
++ uint8_t* src = (uint8_t*)buffer;
++ uint8_t* end = src + byteLen;
++
++ GrAssert((end - src) % 4 == 0);
++
++ for (; src != end; src += 4) {
++ std::swap(src[0], src[2]);
++ }
++}
++
++bool GrGpuGL::canReadBGRA() const
++{
++ if (kDesktop_GrGLBinding == this->glBinding() ||
++ this->hasExtension("GL_EXT_bgra"))
++ return true;
++
++ if (this->hasExtension("GL_EXT_read_format_bgra")) {
++ GrGLint readFormat = 0;
++ GrGLint readType = 0;
++
++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat));
++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType));
++
++ return readFormat == GR_GL_BGRA && readType == GR_GL_UNSIGNED_BYTE;
++ }
++
++ return false;
++}
++
+ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
+ int left, int top,
+ int width, int height,
+ GrPixelConfig config,
+ void* buffer,
+ size_t rowBytes) {
+ GrGLenum format;
+ GrGLenum type;
+ bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin();
++ bool needSwizzle = false;
++
++ if (kBGRA_8888_GrPixelConfig == config && !this->canReadBGRA()) {
++ // Read RGBA and swizzle after
++ config = kRGBA_8888_GrPixelConfig;
++ needSwizzle = true;
++ }
++
+ if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
+ return false;
+ }
+ size_t bpp = GrBytesPerPixel(config);
+ if (!adjust_pixel_ops_params(target->width(), target->height(), bpp,
+ &left, &top, &width, &height,
+ const_cast<const void**>(&buffer),
+ &rowBytes)) {
+ return false;
+ }
+@@ -1478,35 +1516,46 @@ bool GrGpuGL::onReadPixels(GrRenderTarge
+ scratch.reset(tightRowBytes);
+ void* tmpRow = scratch.get();
+ // flip y in-place by rows
+ const int halfY = height >> 1;
+ char* top = reinterpret_cast<char*>(buffer);
+ char* bottom = top + (height - 1) * rowBytes;
+ for (int y = 0; y < halfY; y++) {
+ memcpy(tmpRow, top, tightRowBytes);
+ memcpy(top, bottom, tightRowBytes);
+ memcpy(bottom, tmpRow, tightRowBytes);
++
++ if (needSwizzle) {
++ swizzleRow(top, tightRowBytes);
++ swizzleRow(bottom, tightRowBytes);
++ }
++
+ top += rowBytes;
+ bottom -= rowBytes;
+ }
+ }
+ } else {
+- GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes);
++ GrAssert(readDst != buffer);
++ GrAssert(rowBytes != tightRowBytes);
+ // copy from readDst to buffer while flipping y
+ // const int halfY = height >> 1;
+ const char* src = reinterpret_cast<const char*>(readDst);
+ char* dst = reinterpret_cast<char*>(buffer);
+ if (flipY) {
+ dst += (height-1) * rowBytes;
+ }
+ for (int y = 0; y < height; y++) {
+ memcpy(dst, src, tightRowBytes);
++ if (needSwizzle) {
++ swizzleRow(dst, tightRowBytes);
++ }
++
+ src += readDstRowBytes;
+ if (!flipY) {
+ dst += rowBytes;
+ } else {
+ dst -= rowBytes;
+ }
+ }
+ }
+ return true;
+ }
+diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.h b/gfx/skia/src/gpu/gl/GrGpuGL.h
+--- a/gfx/skia/src/gpu/gl/GrGpuGL.h
++++ b/gfx/skia/src/gpu/gl/GrGpuGL.h
+@@ -243,20 +243,22 @@ private:
+ GrPixelConfig dataConfig,
+ const void* data,
+ size_t rowBytes);
+
+ bool createRenderTargetObjects(int width, int height,
+ GrGLuint texID,
+ GrGLRenderTarget::Desc* desc);
+
+ void fillInConfigRenderableTable();
+
++ bool canReadBGRA() const;
++
+ GrGLContext fGLContext;
+
+ // GL program-related state
+ ProgramCache* fProgramCache;
+ SkAutoTUnref<GrGLProgram> fCurrentProgram;
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///@name Caching of GL State
+ ///@{
+ int fHWActiveTextureUnitIdx;
diff --git a/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch b/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch
new file mode 100644
index 0000000000..aff99f75f1
--- /dev/null
+++ b/gfx/skia/patches/archive/0025-Bug-896049-Add-default-Value-SK_OVERRIDE.patch
@@ -0,0 +1,26 @@
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -325,19 +325,19 @@
+ // Some documentation suggests we should be using __attribute__((override)),
+ // but it doesn't work.
+ #define SK_OVERRIDE override
+ #elif defined(__has_extension)
+ #if __has_extension(cxx_override_control)
+ #define SK_OVERRIDE override
+ #endif
+ #endif
+- #else
+- // Linux GCC ignores "__attribute__((override))" and rejects "override".
+- #define SK_OVERRIDE
++ #endif
++ #ifndef SK_OVERRIDE
++ #define SK_OVERRIDE
+ #endif
+ #endif
+
+ //////////////////////////////////////////////////////////////////////
+
+ #ifndef SK_PRINTF_LIKE
+ #if defined(__clang__) || defined(__GNUC__)
+ #define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
diff --git a/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch b/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch
new file mode 100644
index 0000000000..5c95b54014
--- /dev/null
+++ b/gfx/skia/patches/archive/0026-Bug-901208-Fix-ARM-v4t.patch
@@ -0,0 +1,83 @@
+diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+@@ -26,66 +26,78 @@ static void S32A_D565_Opaque(uint16_t* S
+ asm volatile (
+ "1: \n\t"
+ "ldr r3, [%[src]], #4 \n\t"
+ "cmp r3, #0xff000000 \n\t"
+ "blo 2f \n\t"
+ "and r4, r3, #0x0000f8 \n\t"
+ "and r5, r3, #0x00fc00 \n\t"
+ "and r6, r3, #0xf80000 \n\t"
++#ifdef SK_ARM_HAS_EDSP
+ "pld [r1, #32] \n\t"
++#endif
+ "lsl r3, r4, #8 \n\t"
+ "orr r3, r3, r5, lsr #5 \n\t"
+ "orr r3, r3, r6, lsr #19 \n\t"
+ "subs %[count], %[count], #1 \n\t"
+ "strh r3, [%[dst]], #2 \n\t"
+ "bne 1b \n\t"
+ "b 4f \n\t"
+ "2: \n\t"
+ "lsrs r7, r3, #24 \n\t"
+ "beq 3f \n\t"
+ "ldrh r4, [%[dst]] \n\t"
+ "rsb r7, r7, #255 \n\t"
+ "and r6, r4, #0x001f \n\t"
+-#if SK_ARM_ARCH == 6
++#if SK_ARM_ARCH <= 6
+ "lsl r5, r4, #21 \n\t"
+ "lsr r5, r5, #26 \n\t"
+ #else
+ "ubfx r5, r4, #5, #6 \n\t"
+ #endif
++#ifdef SK_ARM_HAS_EDSP
+ "pld [r0, #16] \n\t"
++#endif
+ "lsr r4, r4, #11 \n\t"
+ #ifdef SK_ARM_HAS_EDSP
+ "smulbb r6, r6, r7 \n\t"
+ "smulbb r5, r5, r7 \n\t"
+ "smulbb r4, r4, r7 \n\t"
+ #else
+ "mul r6, r6, r7 \n\t"
+ "mul r5, r5, r7 \n\t"
+ "mul r4, r4, r7 \n\t"
+ #endif
++#if SK_ARM_ARCH >= 6
+ "uxtb r7, r3, ROR #16 \n\t"
+ "uxtb ip, r3, ROR #8 \n\t"
++#else
++ "mov ip, #0xff \n\t"
++ "and r7, ip, r3, ROR #16 \n\t"
++ "and ip, ip, r3, ROR #8 \n\t"
++#endif
+ "and r3, r3, #0xff \n\t"
+ "add r6, r6, #16 \n\t"
+ "add r5, r5, #32 \n\t"
+ "add r4, r4, #16 \n\t"
+ "add r6, r6, r6, lsr #5 \n\t"
+ "add r5, r5, r5, lsr #6 \n\t"
+ "add r4, r4, r4, lsr #5 \n\t"
+ "add r6, r7, r6, lsr #5 \n\t"
+ "add r5, ip, r5, lsr #6 \n\t"
+ "add r4, r3, r4, lsr #5 \n\t"
+ "lsr r6, r6, #3 \n\t"
+ "and r5, r5, #0xfc \n\t"
+ "and r4, r4, #0xf8 \n\t"
+ "orr r6, r6, r5, lsl #3 \n\t"
+ "orr r4, r6, r4, lsl #8 \n\t"
+ "strh r4, [%[dst]], #2 \n\t"
++#ifdef SK_ARM_HAS_EDSP
+ "pld [r1, #32] \n\t"
++#endif
+ "subs %[count], %[count], #1 \n\t"
+ "bne 1b \n\t"
+ "b 4f \n\t"
+ "3: \n\t"
+ "subs %[count], %[count], #1 \n\t"
+ "add %[dst], %[dst], #2 \n\t"
+ "bne 1b \n\t"
+ "4: \n\t"
diff --git a/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch b/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch
new file mode 100644
index 0000000000..c92bf2aaeb
--- /dev/null
+++ b/gfx/skia/patches/archive/0030-Bug-939629-Add-missing-include-guards.patch
@@ -0,0 +1,94 @@
+# HG changeset patch
+# Parent 979e60d9c09f22eb139643da6de7568b603e1aa1
+
+diff --git a/gfx/skia/include/images/SkImages.h b/gfx/skia/include/images/SkImages.h
+--- a/gfx/skia/include/images/SkImages.h
++++ b/gfx/skia/include/images/SkImages.h
+@@ -1,14 +1,19 @@
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef SkImages_DEFINED
++#define SkImages_DEFINED
++
+ class SkImages {
+ public:
+ /**
+ * Initializes flattenables in the images project.
+ */
+ static void InitializeFlattenables();
+ };
++
++#endif
+diff --git a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
+--- a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
++++ b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
+@@ -1,16 +1,19 @@
+
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef GrAAConvexPathRenderer_DEFINED
++#define GrAAConvexPathRenderer_DEFINED
++
+ #include "GrPathRenderer.h"
+
+
+ class GrAAConvexPathRenderer : public GrPathRenderer {
+ public:
+ GrAAConvexPathRenderer();
+
+ virtual bool canDrawPath(const SkPath& path,
+@@ -19,8 +22,10 @@ public:
+ bool antiAlias) const SK_OVERRIDE;
+
+ protected:
+ virtual bool onDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ GrDrawTarget* target,
+ bool antiAlias) SK_OVERRIDE;
+ };
++
++#endif
+diff --git a/gfx/skia/src/gpu/GrReducedClip.h b/gfx/skia/src/gpu/GrReducedClip.h
+--- a/gfx/skia/src/gpu/GrReducedClip.h
++++ b/gfx/skia/src/gpu/GrReducedClip.h
+@@ -1,16 +1,19 @@
+
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef GrReducedClip_DEFINED
++#define GrReducedClip_DEFINED
++
+ #include "SkClipStack.h"
+ #include "SkTLList.h"
+
+ namespace GrReducedClip {
+
+ typedef SkTLList<SkClipStack::Element> ElementList;
+
+ enum InitialState {
+@@ -33,8 +36,10 @@ enum InitialState {
+ void ReduceClipStack(const SkClipStack& stack,
+ const SkIRect& queryBounds,
+ ElementList* result,
+ InitialState* initialState,
+ SkIRect* tighterBounds = NULL,
+ bool* requiresAA = NULL);
+
+ } // namespace GrReducedClip
++
++#endif
diff --git a/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch b/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch
new file mode 100644
index 0000000000..f58e7e1659
--- /dev/null
+++ b/gfx/skia/patches/archive/0031-Bug-945588-Add-include-guard.patch
@@ -0,0 +1,39 @@
+# HG changeset patch
+# User Ehsan Akhgari <ehsan@mozilla.com>
+
+Bug 945588 - Add include guards to SkConfig8888.h
+
+diff --git a/gfx/skia/src/core/SkConfig8888.h b/gfx/skia/src/core/SkConfig8888.h
+index 96eaef2..36bc9b4 100644
+--- a/gfx/skia/src/core/SkConfig8888.h
++++ b/gfx/skia/src/core/SkConfig8888.h
+@@ -1,16 +1,18 @@
+
+ /*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef SkConfig8888_DEFINED
++#define SkConfig8888_DEFINED
+
+ #include "SkCanvas.h"
+ #include "SkColorPriv.h"
+
+ /**
+ * Converts pixels from one Config8888 to another Config8888
+ */
+ void SkConvertConfig8888Pixels(uint32_t* dstPixels,
+@@ -69,8 +71,10 @@ static inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp,
+ int h = dstBmp.height();
+ size_t dstRowBytes = dstBmp.rowBytes();
+ uint32_t* dstPixels = reinterpret_cast<uint32_t*>(dstBmp.getPixels());
+
+ SkConvertConfig8888Pixels(dstPixels, dstRowBytes, SkCanvas::kNative_Premul_Config8888, srcPixels, srcRowBytes, srcConfig8888, w, h);
+ }
+
+ }
++
++#endif
diff --git a/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch b/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch
new file mode 100644
index 0000000000..b6b8461213
--- /dev/null
+++ b/gfx/skia/patches/archive/0032-Bug-974900-More-missing-include-guards.patch
@@ -0,0 +1,148 @@
+# HG changeset patch
+# Parent c8288d0c7a1544a590a0cac9c39397ac10c8a45b
+Bug 974900 - Add missing include guards to Skia headers - r=gw280
+
+diff --git a/gfx/skia/trunk/include/images/SkImages.h b/gfx/skia/trunk/include/images/SkImages.h
+--- a/gfx/skia/trunk/include/images/SkImages.h
++++ b/gfx/skia/trunk/include/images/SkImages.h
+@@ -1,14 +1,19 @@
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef SkImages_DEFINED
++#define SkImages_DEFINED
++
+ class SkImages {
+ public:
+ /**
+ * Initializes flattenables in the images project.
+ */
+ static void InitializeFlattenables();
+ };
++
++#endif
+diff --git a/gfx/skia/trunk/src/core/SkConvolver.h b/gfx/skia/trunk/src/core/SkConvolver.h
+--- a/gfx/skia/trunk/src/core/SkConvolver.h
++++ b/gfx/skia/trunk/src/core/SkConvolver.h
+@@ -8,16 +8,18 @@
+ #include "SkSize.h"
+ #include "SkTypes.h"
+ #include "SkTArray.h"
+
+ // avoid confusion with Mac OS X's math library (Carbon)
+ #if defined(__APPLE__)
+ #undef FloatToConvolutionFixed
+ #undef ConvolutionFixedToFloat
++#undef FloatToFixed
++#undef FixedToFloat
+ #endif
+
+ // Represents a filter in one dimension. Each output pixel has one entry in this
+ // object for the filter values contributing to it. You build up the filter
+ // list by calling AddFilter for each output pixel (in order).
+ //
+ // We do 2-dimensional convolution by first convolving each row by one
+ // SkConvolutionFilter1D, then convolving each column by another one.
+diff --git a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
+--- a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
++++ b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
+@@ -3,24 +3,28 @@
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+ #include "GrPathRenderer.h"
+
++#ifndef GrAAConvexPathRenderer_DEFINED
++#define GrAAConvexPathRenderer_DEFINED
+
+ class GrAAConvexPathRenderer : public GrPathRenderer {
+ public:
+ GrAAConvexPathRenderer();
+
+ virtual bool canDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
+
+ protected:
+ virtual bool onDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ GrDrawTarget* target,
+ bool antiAlias) SK_OVERRIDE;
+ };
++
++#endif
+diff --git a/gfx/skia/trunk/src/gpu/GrReducedClip.h b/gfx/skia/trunk/src/gpu/GrReducedClip.h
+--- a/gfx/skia/trunk/src/gpu/GrReducedClip.h
++++ b/gfx/skia/trunk/src/gpu/GrReducedClip.h
+@@ -1,16 +1,19 @@
+
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
++#ifndef GrReducedClip_DEFINED
++#define GrReducedClip_DEFINED
++
+ #include "SkClipStack.h"
+ #include "SkTLList.h"
+
+ namespace GrReducedClip {
+
+ typedef SkTLList<SkClipStack::Element> ElementList;
+
+ enum InitialState {
+@@ -36,8 +39,10 @@ SK_API void ReduceClipStack(const SkClip
+ const SkIRect& queryBounds,
+ ElementList* result,
+ int32_t* resultGenID,
+ InitialState* initialState,
+ SkIRect* tighterBounds = NULL,
+ bool* requiresAA = NULL);
+
+ } // namespace GrReducedClip
++
++#endif
+diff --git a/gfx/skia/trunk/src/pathops/SkLineParameters.h b/gfx/skia/trunk/src/pathops/SkLineParameters.h
+--- a/gfx/skia/trunk/src/pathops/SkLineParameters.h
++++ b/gfx/skia/trunk/src/pathops/SkLineParameters.h
+@@ -1,14 +1,18 @@
+ /*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
++
++#ifndef SkLineParameters_DEFINED
++#define SkLineParameters_DEFINED
++
+ #include "SkPathOpsCubic.h"
+ #include "SkPathOpsLine.h"
+ #include "SkPathOpsQuad.h"
+
+ // Sources
+ // computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
+ // online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
+
+@@ -164,8 +168,10 @@ public:
+ return -a;
+ }
+
+ private:
+ double a;
+ double b;
+ double c;
+ };
++
++#endif
diff --git a/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch b/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch
new file mode 100644
index 0000000000..05f17000a0
--- /dev/null
+++ b/gfx/skia/patches/archive/0033-Bug-974900-undef-interface-windows.patch
@@ -0,0 +1,27 @@
+# HG changeset patch
+# Parent b12f9a408740aa5fd93c296a7d41e1b5f54c1b20
+Bug 974900 - #undef interface defined by windows headers - r=gw280
+
+diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
+--- a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
++++ b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
+@@ -9,16 +9,19 @@
+ #ifndef GrGLCaps_DEFINED
+ #define GrGLCaps_DEFINED
+
+ #include "GrDrawTargetCaps.h"
+ #include "GrGLStencilBuffer.h"
+ #include "SkTArray.h"
+ #include "SkTDArray.h"
+
++// defined in Windows headers
++#undef interface
++
+ class GrGLContextInfo;
+
+ /**
+ * Stores some capabilities of a GL context. Most are determined by the GL
+ * version and the extensions string. It also tracks formats that have passed
+ * the FBO completeness test.
+ */
+ class GrGLCaps : public GrDrawTargetCaps {
diff --git a/gfx/skia/patches/archive/SkPostConfig.patch b/gfx/skia/patches/archive/SkPostConfig.patch
new file mode 100644
index 0000000000..d32341f4ea
--- /dev/null
+++ b/gfx/skia/patches/archive/SkPostConfig.patch
@@ -0,0 +1,32 @@
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -277,19 +277,28 @@
+ #endif
+
+ //////////////////////////////////////////////////////////////////////
+
+ #ifndef SK_OVERRIDE
+ #if defined(_MSC_VER)
+ #define SK_OVERRIDE override
+ #elif defined(__clang__)
++#if __has_feature(cxx_override_control)
+ // Some documentation suggests we should be using __attribute__((override)),
+ // but it doesn't work.
+ #define SK_OVERRIDE override
++#elif defined(__has_extension)
++#if __has_extension(cxx_override_control)
++#define SK_OVERRIDE override
++#endif
++#endif
++#ifndef SK_OVERRIDE
++#define SK_OVERRIDE
++#endif
+ #else
+ // Linux GCC ignores "__attribute__((override))" and rejects "override".
+ #define SK_OVERRIDE
+ #endif
+ #endif
+
+ //////////////////////////////////////////////////////////////////////
+
diff --git a/gfx/skia/patches/archive/arm-fixes.patch b/gfx/skia/patches/archive/arm-fixes.patch
new file mode 100644
index 0000000000..d9fa430df0
--- /dev/null
+++ b/gfx/skia/patches/archive/arm-fixes.patch
@@ -0,0 +1,191 @@
+diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h
+--- a/gfx/skia/include/core/SkMath.h
++++ b/gfx/skia/include/core/SkMath.h
+@@ -148,20 +148,17 @@ static inline bool SkIsPow2(int value) {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ /** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
+ With this requirement, we can generate faster instructions on some
+ architectures.
+ */
+-#if defined(__arm__) \
+- && !defined(__thumb__) \
+- && !defined(__ARM_ARCH_4T__) \
+- && !defined(__ARM_ARCH_5T__)
++#ifdef SK_ARM_HAS_EDSP
+ static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
+ SkASSERT((int16_t)x == x);
+ SkASSERT((int16_t)y == y);
+ int32_t product;
+ asm("smulbb %0, %1, %2 \n"
+ : "=r"(product)
+ : "r"(x), "r"(y)
+ );
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -300,8 +300,53 @@
+ #endif
+ #endif
+
+ //////////////////////////////////////////////////////////////////////
+
+ #ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+ #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
+ #endif
++
++//////////////////////////////////////////////////////////////////////
++// ARM defines
++
++#if defined(__GNUC__) && defined(__arm__)
++
++# define SK_ARM_ARCH 3
++
++# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
++ || defined(_ARM_ARCH_4)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 4
++# endif
++
++# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
++ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
++ || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 5
++# endif
++
++# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
++ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
++ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
++ || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 6
++# endif
++
++# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
++ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
++ || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
++# undef SK_ARM_ARCH
++# define SK_ARM_ARCH 7
++# endif
++
++# undef SK_ARM_HAS_EDSP
++# if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
++ || !defined(__thumb__) \
++ && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
++ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
++# define SK_ARM_HAS_EDSP 1
++# endif
++
++#endif
+diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
+--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
+@@ -6,17 +6,17 @@
+ * found in the LICENSE file.
+ */
+
+
+ #include "SkBitmapProcState.h"
+ #include "SkColorPriv.h"
+ #include "SkUtils.h"
+
+-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+ void SI8_D16_nofilter_DX_arm(
+ const SkBitmapProcState& s,
+ const uint32_t* SK_RESTRICT xy,
+ int count,
+ uint16_t* SK_RESTRICT colors) __attribute__((optimize("O1")));
+
+ void SI8_D16_nofilter_DX_arm(const SkBitmapProcState& s,
+ const uint32_t* SK_RESTRICT xy,
+@@ -177,17 +177,17 @@ void SI8_opaque_D32_nofilter_DX_arm(cons
+ : [xx] "+r" (xx), [count] "+r" (count), [colors] "+r" (colors)
+ : [table] "r" (table), [srcAddr] "r" (srcAddr)
+ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11"
+ );
+ }
+
+ s.fBitmap->getColorTable()->unlockColors(false);
+ }
+-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ /* If we replace a sampleproc, then we null-out the associated shaderproc,
+ otherwise the shader won't even look at the matrix/sampler
+ */
+ void SkBitmapProcState::platformProcs() {
+ bool doFilter = fDoFilter;
+@@ -195,17 +195,17 @@ void SkBitmapProcState::platformProcs()
+ bool justDx = false;
+
+ if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
+ justDx = true;
+ }
+
+ switch (fBitmap->config()) {
+ case SkBitmap::kIndex8_Config:
+-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
++#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
+ if (justDx && !doFilter) {
+ #if 0 /* crashing on android device */
+ fSampleProc16 = SI8_D16_nofilter_DX_arm;
+ fShaderProc16 = NULL;
+ #endif
+ if (isOpaque) {
+ // this one is only very slighty faster than the C version
+ fSampleProc32 = SI8_opaque_D32_nofilter_DX_arm;
+diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+@@ -669,18 +669,23 @@ static void __attribute((noinline,optimi
+ /* Double Loop */
+ "1: \n\t" /* <double loop> */
+ "ldm %[src]!, {r5, r6} \n\t" /* loading src pointers into r5 and r6 */
+ "ldm %[dst], {r7, r8} \n\t" /* loading dst pointers into r7 and r8 */
+
+ /* dst1_scale and dst2_scale*/
+ "lsr r9, r5, #24 \n\t" /* src >> 24 */
+ "lsr r10, r6, #24 \n\t" /* src >> 24 */
++#ifdef SK_ARM_HAS_EDSP
+ "smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
+ "smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
++#else
++ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
++ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
++#endif
+ "lsr r9, r9, #8 \n\t" /* r9 >> 8 */
+ "lsr r10, r10, #8 \n\t" /* r10 >> 8 */
+ "rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */
+ "rsb r10, r10, #256 \n\t" /* dst2_scale = r10 = 255 - r10 + 1 */
+
+ /* ---------------------- */
+
+ /* src1, src1_scale */
+@@ -739,17 +744,21 @@ static void __attribute((noinline,optimi
+ /* else get into the single loop */
+ /* Single Loop */
+ "2: \n\t" /* <single loop> */
+ "ldr r5, [%[src]], #4 \n\t" /* loading src pointer into r5: r5=src */
+ "ldr r7, [%[dst]] \n\t" /* loading dst pointer into r7: r7=dst */
+
+ "lsr r6, r5, #24 \n\t" /* src >> 24 */
+ "and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */
++#ifdef SK_ARM_HAS_EDSP
+ "smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
++#else
++ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
++#endif
+ "and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */
+ "lsr r6, r6, #8 \n\t" /* r6 >> 8 */
+ "mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */
+ "rsb r6, r6, #256 \n\t" /* r6 = 255 - r6 + 1 */
+
+ /* src, src_scale */
+ "mul r9, r9, %[alpha] \n\t" /* rb = r9 times scale */
+ "and r8, r8, r12, lsl #8 \n\t" /* ag masked by reverse mask (r12) */
diff --git a/gfx/skia/patches/archive/arm-opts.patch b/gfx/skia/patches/archive/arm-opts.patch
new file mode 100644
index 0000000000..02ad85c9a7
--- /dev/null
+++ b/gfx/skia/patches/archive/arm-opts.patch
@@ -0,0 +1,41 @@
+diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
++++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+@@ -549,17 +549,17 @@ static void S32A_Opaque_BlitRow32_neon(S
+ #define S32A_Opaque_BlitRow32_PROC S32A_Opaque_BlitRow32_neon
+
+ #else
+
+ #ifdef TEST_SRC_ALPHA
+ #error The ARM asm version of S32A_Opaque_BlitRow32 does not support TEST_SRC_ALPHA
+ #endif
+
+-static void S32A_Opaque_BlitRow32_arm(SkPMColor* SK_RESTRICT dst,
++static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Opaque_BlitRow32_arm(SkPMColor* SK_RESTRICT dst,
+ const SkPMColor* SK_RESTRICT src,
+ int count, U8CPU alpha) {
+
+ SkASSERT(255 == alpha);
+
+ /* Does not support the TEST_SRC_ALPHA case */
+ asm volatile (
+ "cmp %[count], #0 \n\t" /* comparing count with 0 */
+@@ -646,17 +646,17 @@ static void S32A_Opaque_BlitRow32_arm(Sk
+ );
+ }
+ #define S32A_Opaque_BlitRow32_PROC S32A_Opaque_BlitRow32_arm
+ #endif
+
+ /*
+ * ARM asm version of S32A_Blend_BlitRow32
+ */
+-static void S32A_Blend_BlitRow32_arm(SkPMColor* SK_RESTRICT dst,
++static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_BlitRow32_arm(SkPMColor* SK_RESTRICT dst,
+ const SkPMColor* SK_RESTRICT src,
+ int count, U8CPU alpha) {
+ asm volatile (
+ "cmp %[count], #0 \n\t" /* comparing count with 0 */
+ "beq 3f \n\t" /* if zero exit */
+
+ "mov r12, #0xff \n\t" /* load the 0xff mask in r12 */
+ "orr r12, r12, r12, lsl #16 \n\t" /* convert it to 0xff00ff in r12 */
diff --git a/gfx/skia/patches/archive/fix-comma-end-enum-list.patch b/gfx/skia/patches/archive/fix-comma-end-enum-list.patch
new file mode 100644
index 0000000000..dea36377e8
--- /dev/null
+++ b/gfx/skia/patches/archive/fix-comma-end-enum-list.patch
@@ -0,0 +1,380 @@
+diff --git a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
++++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+@@ -29,17 +29,17 @@ public:
+ SkString fFontName;
+
+ enum FontType {
+ kType1_Font,
+ kType1CID_Font,
+ kCFF_Font,
+ kTrueType_Font,
+ kOther_Font,
+- kNotEmbeddable_Font,
++ kNotEmbeddable_Font
+ };
+ // The type of the underlying font program. This field determines which
+ // of the following fields are valid. If it is kOther_Font or
+ // kNotEmbeddable_Font, the per glyph information will never be populated.
+ FontType fType;
+
+ // fMultiMaster may be true for Type1_Font or CFF_Font.
+ bool fMultiMaster;
+@@ -51,17 +51,17 @@ public:
+ kFixedPitch_Style = 0x00001,
+ kSerif_Style = 0x00002,
+ kSymbolic_Style = 0x00004,
+ kScript_Style = 0x00008,
+ kNonsymbolic_Style = 0x00020,
+ kItalic_Style = 0x00040,
+ kAllCaps_Style = 0x10000,
+ kSmallCaps_Style = 0x20000,
+- kForceBold_Style = 0x40000,
++ kForceBold_Style = 0x40000
+ };
+ uint16_t fStyle; // Font style characteristics.
+ int16_t fItalicAngle; // Counterclockwise degrees from vertical of the
+ // dominant vertical stroke for an Italic face.
+ // The following fields are all in font units.
+ int16_t fAscent; // Max height above baseline, not including accents.
+ int16_t fDescent; // Max depth below baseline (negative).
+ int16_t fStemV; // Thickness of dominant vertical stem.
+@@ -70,26 +70,26 @@ public:
+ SkIRect fBBox; // The bounding box of all glyphs (in font units).
+
+ // The type of advance data wanted.
+ enum PerGlyphInfo {
+ kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info.
+ kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
+ kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
+ kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
+- kToUnicode_PerGlyphInfo = 0x8, // Populate ToUnicode table, ignored
++ kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored
+ // for Type 1 fonts
+ };
+
+ template <typename Data>
+ struct AdvanceMetric {
+ enum MetricType {
+ kDefault, // Default advance: fAdvance.count = 1
+ kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
+- kRun, // fStartID-fEndID have same advance: fAdvance.count = 1
++ kRun // fStartID-fEndID have same advance: fAdvance.count = 1
+ };
+ MetricType fType;
+ uint16_t fStartId;
+ uint16_t fEndId;
+ SkTDArray<Data> fAdvance;
+ SkTScopedPtr<AdvanceMetric<Data> > fNext;
+ };
+
+diff --git a/gfx/skia/include/core/SkBlitRow.h b/gfx/skia/include/core/SkBlitRow.h
+--- a/gfx/skia/include/core/SkBlitRow.h
++++ b/gfx/skia/include/core/SkBlitRow.h
+@@ -44,17 +44,17 @@ public:
+
+ //! Public entry-point to return a blit function ptr
+ static Proc Factory(unsigned flags, SkBitmap::Config);
+
+ ///////////// D32 version
+
+ enum Flags32 {
+ kGlobalAlpha_Flag32 = 1 << 0,
+- kSrcPixelAlpha_Flag32 = 1 << 1,
++ kSrcPixelAlpha_Flag32 = 1 << 1
+ };
+
+ /** Function pointer that blends 32bit colors onto a 32bit destination.
+ @param dst array of dst 32bit colors
+ @param src array of src 32bit colors (w/ or w/o alpha)
+ @param count number of colors to blend
+ @param alpha global alpha to be applied to all src colors
+ */
+diff --git a/gfx/skia/include/core/SkCanvas.h b/gfx/skia/include/core/SkCanvas.h
+--- a/gfx/skia/include/core/SkCanvas.h
++++ b/gfx/skia/include/core/SkCanvas.h
+@@ -132,17 +132,17 @@ public:
+ * low byte to high byte: B, G, R, A.
+ */
+ kBGRA_Premul_Config8888,
+ kBGRA_Unpremul_Config8888,
+ /**
+ * low byte to high byte: R, G, B, A.
+ */
+ kRGBA_Premul_Config8888,
+- kRGBA_Unpremul_Config8888,
++ kRGBA_Unpremul_Config8888
+ };
+
+ /**
+ * On success (returns true), copy the canvas pixels into the bitmap.
+ * On failure, the bitmap parameter is left unchanged and false is
+ * returned.
+ *
+ * The canvas' pixels are converted to the bitmap's config. The only
+diff --git a/gfx/skia/include/core/SkDevice.h b/gfx/skia/include/core/SkDevice.h
+--- a/gfx/skia/include/core/SkDevice.h
++++ b/gfx/skia/include/core/SkDevice.h
+@@ -134,17 +134,17 @@ public:
+ * Return the device's origin: its offset in device coordinates from
+ * the default origin in its canvas' matrix/clip
+ */
+ const SkIPoint& getOrigin() const { return fOrigin; }
+
+ protected:
+ enum Usage {
+ kGeneral_Usage,
+- kSaveLayer_Usage, // <! internal use only
++ kSaveLayer_Usage // <! internal use only
+ };
+
+ struct TextFlags {
+ uint32_t fFlags; // SkPaint::getFlags()
+ SkPaint::Hinting fHinting;
+ };
+
+ /**
+diff --git a/gfx/skia/include/core/SkFlattenable.h b/gfx/skia/include/core/SkFlattenable.h
+--- a/gfx/skia/include/core/SkFlattenable.h
++++ b/gfx/skia/include/core/SkFlattenable.h
+@@ -216,17 +216,17 @@ public:
+ SkFactorySet* setFactoryRecorder(SkFactorySet*);
+
+ enum Flags {
+ kCrossProcess_Flag = 0x01,
+ /**
+ * Instructs the writer to inline Factory names as there are seen the
+ * first time (after that we store an index). The pipe code uses this.
+ */
+- kInlineFactoryNames_Flag = 0x02,
++ kInlineFactoryNames_Flag = 0x02
+ };
+ Flags getFlags() const { return (Flags)fFlags; }
+ void setFlags(Flags flags) { fFlags = flags; }
+
+ bool isCrossProcess() const {
+ return SkToBool(fFlags & kCrossProcess_Flag);
+ }
+ bool inlineFactoryNames() const {
+diff --git a/gfx/skia/include/core/SkFontHost.h b/gfx/skia/include/core/SkFontHost.h
+--- a/gfx/skia/include/core/SkFontHost.h
++++ b/gfx/skia/include/core/SkFontHost.h
+@@ -245,17 +245,17 @@ public:
+ vertically. When rendering subpixel glyphs we need to know which way
+ round they are.
+
+ Note, if you change this after startup, you'll need to flush the glyph
+ cache because it'll have the wrong type of masks cached.
+ */
+ enum LCDOrientation {
+ kHorizontal_LCDOrientation = 0, //!< this is the default
+- kVertical_LCDOrientation = 1,
++ kVertical_LCDOrientation = 1
+ };
+
+ static void SetSubpixelOrientation(LCDOrientation orientation);
+ static LCDOrientation GetSubpixelOrientation();
+
+ /** LCD color elements can vary in order. For subpixel text we need to know
+ the order which the LCDs uses so that the color fringes are in the
+ correct place.
+@@ -264,17 +264,17 @@ public:
+ cache because it'll have the wrong type of masks cached.
+
+ kNONE_LCDOrder means that the subpixel elements are not spatially
+ separated in any usable fashion.
+ */
+ enum LCDOrder {
+ kRGB_LCDOrder = 0, //!< this is the default
+ kBGR_LCDOrder = 1,
+- kNONE_LCDOrder = 2,
++ kNONE_LCDOrder = 2
+ };
+
+ static void SetSubpixelOrder(LCDOrder order);
+ static LCDOrder GetSubpixelOrder();
+
+ #ifdef SK_BUILD_FOR_ANDROID
+ ///////////////////////////////////////////////////////////////////////////
+
+diff --git a/gfx/skia/include/core/SkMaskFilter.h b/gfx/skia/include/core/SkMaskFilter.h
+--- a/gfx/skia/include/core/SkMaskFilter.h
++++ b/gfx/skia/include/core/SkMaskFilter.h
+@@ -57,17 +57,17 @@ public:
+
+ virtual void flatten(SkFlattenableWriteBuffer& ) {}
+
+ enum BlurType {
+ kNone_BlurType, //!< this maskfilter is not a blur
+ kNormal_BlurType, //!< fuzzy inside and outside
+ kSolid_BlurType, //!< solid inside, fuzzy outside
+ kOuter_BlurType, //!< nothing inside, fuzzy outside
+- kInner_BlurType, //!< fuzzy inside, nothing outside
++ kInner_BlurType //!< fuzzy inside, nothing outside
+ };
+
+ struct BlurInfo {
+ SkScalar fRadius;
+ bool fIgnoreTransform;
+ bool fHighQuality;
+ };
+
+diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
+--- a/gfx/skia/include/core/SkPaint.h
++++ b/gfx/skia/include/core/SkPaint.h
+@@ -70,17 +70,17 @@ public:
+ kFull_Hinting -> <same as kNormalHinting, unless we are rendering
+ subpixel glyphs, in which case TARGET_LCD or
+ TARGET_LCD_V is used>
+ */
+ enum Hinting {
+ kNo_Hinting = 0,
+ kSlight_Hinting = 1,
+ kNormal_Hinting = 2, //!< this is the default
+- kFull_Hinting = 3,
++ kFull_Hinting = 3
+ };
+
+ Hinting getHinting() const {
+ return static_cast<Hinting>(fHinting);
+ }
+
+ void setHinting(Hinting hintingLevel);
+
+@@ -282,17 +282,17 @@ public:
+ results may not appear the same as if it was drawn twice, filled and
+ then stroked.
+ */
+ enum Style {
+ kFill_Style, //!< fill the geometry
+ kStroke_Style, //!< stroke the geometry
+ kStrokeAndFill_Style, //!< fill and stroke the geometry
+
+- kStyleCount,
++ kStyleCount
+ };
+
+ /** Return the paint's style, used for controlling how primitives'
+ geometries are interpreted (except for drawBitmap, which always assumes
+ kFill_Style).
+ @return the paint's Style
+ */
+ Style getStyle() const { return (Style)fStyle; }
+diff --git a/gfx/skia/include/core/SkScalerContext.h b/gfx/skia/include/core/SkScalerContext.h
+--- a/gfx/skia/include/core/SkScalerContext.h
++++ b/gfx/skia/include/core/SkScalerContext.h
+@@ -172,24 +172,24 @@ public:
+ kHintingBit2_Flag = 0x0100,
+
+ // these should only ever be set if fMaskFormat is LCD16 or LCD32
+ kLCD_Vertical_Flag = 0x0200, // else Horizontal
+ kLCD_BGROrder_Flag = 0x0400, // else RGB order
+
+ // luminance : 0 for black text, kLuminance_Max for white text
+ kLuminance_Shift = 11, // to shift into the other flags above
+- kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits
++ kLuminance_Bits = 3 // ensure Flags doesn't exceed 16bits
+ };
+
+ // computed values
+ enum {
+ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
+ kLuminance_Max = (1 << kLuminance_Bits) - 1,
+- kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
++ kLuminance_Mask = kLuminance_Max << kLuminance_Shift
+ };
+
+ struct Rec {
+ uint32_t fOrigFontID;
+ uint32_t fFontID;
+ SkScalar fTextSize, fPreScaleX, fPreSkewX;
+ SkScalar fPost2x2[2][2];
+ SkScalar fFrameWidth, fMiterLimit;
+diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h
+--- a/gfx/skia/include/core/SkTypes.h
++++ b/gfx/skia/include/core/SkTypes.h
+@@ -433,17 +433,17 @@ public:
+ */
+ kAlloc_OnShrink,
+
+ /**
+ * If the requested size is smaller than the current size, and the
+ * current block is dynamically allocated, just return the old
+ * block.
+ */
+- kReuse_OnShrink,
++ kReuse_OnShrink
+ };
+
+ /**
+ * Reallocates the block to a new size. The ptr may or may not change.
+ */
+ void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink) {
+ if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) {
+ return fPtr;
+diff --git a/gfx/skia/include/effects/SkLayerDrawLooper.h b/gfx/skia/include/effects/SkLayerDrawLooper.h
+--- a/gfx/skia/include/effects/SkLayerDrawLooper.h
++++ b/gfx/skia/include/effects/SkLayerDrawLooper.h
+@@ -36,17 +36,17 @@ public:
+
+ /**
+ * Use the layer's paint entirely, with these exceptions:
+ * - We never override the draw's paint's text_encoding, since that is
+ * used to interpret the text/len parameters in draw[Pos]Text.
+ * - Flags and Color are always computed using the LayerInfo's
+ * fFlagsMask and fColorMode.
+ */
+- kEntirePaint_Bits = -1,
++ kEntirePaint_Bits = -1
+
+ };
+ typedef int32_t BitFlags;
+
+ /**
+ * Info for how to apply the layer's paint and offset.
+ *
+ * fFlagsMask selects which flags in the layer's paint should be applied.
+diff --git a/gfx/skia/src/core/SkBitmap.cpp b/gfx/skia/src/core/SkBitmap.cpp
+--- a/gfx/skia/src/core/SkBitmap.cpp
++++ b/gfx/skia/src/core/SkBitmap.cpp
+@@ -1357,17 +1357,17 @@ bool SkBitmap::extractAlpha(SkBitmap* ds
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ enum {
+ SERIALIZE_PIXELTYPE_NONE,
+ SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE,
+ SERIALIZE_PIXELTYPE_RAW_NO_CTABLE,
+ SERIALIZE_PIXELTYPE_REF_DATA,
+- SERIALIZE_PIXELTYPE_REF_PTR,
++ SERIALIZE_PIXELTYPE_REF_PTR
+ };
+
+ static void writeString(SkFlattenableWriteBuffer& buffer, const char str[]) {
+ size_t len = strlen(str);
+ buffer.write32(len);
+ buffer.writePad(str, len);
+ }
+
+diff --git a/gfx/skia/src/core/SkMatrix.cpp b/gfx/skia/src/core/SkMatrix.cpp
+--- a/gfx/skia/src/core/SkMatrix.cpp
++++ b/gfx/skia/src/core/SkMatrix.cpp
+@@ -1715,17 +1715,17 @@ SkScalar SkMatrix::getMaxStretch() const
+ const SkMatrix& SkMatrix::I() {
+ static SkMatrix gIdentity;
+ static bool gOnce;
+ if (!gOnce) {
+ gIdentity.reset();
+ gOnce = true;
+ }
+ return gIdentity;
+-};
++}
+
+ const SkMatrix& SkMatrix::InvalidMatrix() {
+ static SkMatrix gInvalid;
+ static bool gOnce;
+ if (!gOnce) {
+ gInvalid.setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax,
+ SK_ScalarMax, SK_ScalarMax, SK_ScalarMax,
+ SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
diff --git a/gfx/skia/patches/archive/fix-gradient-clamp.patch b/gfx/skia/patches/archive/fix-gradient-clamp.patch
new file mode 100644
index 0000000000..91481c2c12
--- /dev/null
+++ b/gfx/skia/patches/archive/fix-gradient-clamp.patch
@@ -0,0 +1,211 @@
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -167,16 +167,17 @@ private:
+
+ mutable uint16_t* fCache16; // working ptr. If this is NULL, we need to recompute the cache values
+ mutable SkPMColor* fCache32; // working ptr. If this is NULL, we need to recompute the cache values
+
+ mutable uint16_t* fCache16Storage; // storage for fCache16, allocated on demand
+ mutable SkMallocPixelRef* fCache32PixelRef;
+ mutable unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value
+
++ static SkPMColor PremultiplyColor(SkColor c0, U8CPU alpha);
+ static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
+ static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
+ U8CPU alpha);
+ void setCacheAlpha(U8CPU alpha) const;
+ void initCommon();
+
+ typedef SkShader INHERITED;
+ };
+@@ -512,16 +513,31 @@ static inline U8CPU dither_fixed_to_8(Sk
+ * For dithering with premultiply, we want to ceiling the alpha component,
+ * to ensure that it is always >= any color component.
+ */
+ static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) {
+ n >>= 8;
+ return ((n << 1) - (n | (n >> 8))) >> 8;
+ }
+
++SkPMColor Gradient_Shader::PremultiplyColor(SkColor c0, U8CPU paintAlpha)
++{
++ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
++ SkFixed r = SkColorGetR(c0);
++ SkFixed g = SkColorGetG(c0);
++ SkFixed b = SkColorGetB(c0);
++
++ a = SkIntToFixed(a) + 0x8000;
++ r = SkIntToFixed(r) + 0x8000;
++ g = SkIntToFixed(g) + 0x8000;
++ b = SkIntToFixed(b) + 0x8000;
++
++ return SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16);
++}
++
+ void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
+ int count, U8CPU paintAlpha) {
+ SkASSERT(count > 1);
+
+ // need to apply paintAlpha to our two endpoints
+ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
+ SkFixed da;
+ {
+@@ -613,24 +629,24 @@ const uint16_t* Gradient_Shader::getCach
+ }
+ }
+ return fCache16;
+ }
+
+ const SkPMColor* Gradient_Shader::getCache32() const {
+ if (fCache32 == NULL) {
+ // double the count for dither entries
+- const int entryCount = kCache32Count * 2;
++ const int entryCount = kCache32Count * 2 + 2;
+ const size_t allocSize = sizeof(SkPMColor) * entryCount;
+
+ if (NULL == fCache32PixelRef) {
+ fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ }
+- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
+ if (fColorCount == 2) {
+ Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
+ kCache32Count, fCacheAlpha);
+ } else {
+ Rec* rec = fRecs;
+ int prevIndex = 0;
+ for (int i = 1; i < fColorCount; i++) {
+ int nextIndex = SkFixedToFFFF(rec[i].fPos) >> (16 - kCache32Bits);
+@@ -644,28 +660,31 @@ const SkPMColor* Gradient_Shader::getCac
+ }
+ SkASSERT(prevIndex == kCache32Count - 1);
+ }
+
+ if (fMapper) {
+ SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
+ (NULL, allocSize, NULL));
+ SkPMColor* linear = fCache32; // just computed linear data
+- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
+ SkUnitMapper* map = fMapper;
+ for (int i = 0; i < kCache32Count; i++) {
+ int index = map->mapUnit16((i << 8) | i) >> 8;
+ mapped[i] = linear[index];
+ mapped[i + kCache32Count] = linear[index + kCache32Count];
+ }
+ fCache32PixelRef->unref();
+ fCache32PixelRef = newPR;
+- fCache32 = (SkPMColor*)newPR->getAddr();
++ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
+ }
+ }
++ //Write the clamp colours into the first and last entries of fCache32
++ fCache32[-1] = PremultiplyColor(fOrigColors[0], fCacheAlpha);
++ fCache32[kCache32Count * 2] = PremultiplyColor(fOrigColors[fColorCount - 1], fCacheAlpha);
+ return fCache32;
+ }
+
+ /*
+ * Because our caller might rebuild the same (logically the same) gradient
+ * over and over, we'd like to return exactly the same "bitmap" if possible,
+ * allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
+ * To do that, we maintain a private cache of built-bitmaps, based on our
+@@ -875,28 +894,38 @@ void Linear_Gradient::shadeSpan(int x, i
+ dx = dxStorage[0];
+ } else {
+ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+ dx = SkScalarToFixed(fDstToIndex.getScaleX());
+ }
+
+ if (SkFixedNearlyZero(dx)) {
+ // we're a vertical gradient, so no change in a span
+- unsigned fi = proc(fx) >> (16 - kCache32Bits);
+- sk_memset32_dither(dstC, cache[toggle + fi],
+- cache[(toggle ^ TOGGLE_MASK) + fi], count);
++ if (proc == clamp_tileproc) {
++ if (fx < 0) {
++ sk_memset32(dstC, cache[-1], count);
++ } else if (fx > 0xFFFF) {
++ sk_memset32(dstC, cache[kCache32Count * 2], count);
++ } else {
++ unsigned fi = proc(fx) >> (16 - kCache32Bits);
++ sk_memset32_dither(dstC, cache[toggle + fi],
++ cache[(toggle ^ TOGGLE_MASK) + fi], count);
++ }
++ } else {
++ unsigned fi = proc(fx) >> (16 - kCache32Bits);
++ sk_memset32_dither(dstC, cache[toggle + fi],
++ cache[(toggle ^ TOGGLE_MASK) + fi], count);
++ }
+ } else if (proc == clamp_tileproc) {
+ SkClampRange range;
+- range.init(fx, dx, count, 0, 0xFF);
++ range.init(fx, dx, count, cache[-1], cache[kCache32Count * 2]);
+
+ if ((count = range.fCount0) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV0],
+- cache[(toggle ^ TOGGLE_MASK) + range.fV0],
+- count);
++ // Do we really want to dither the clamp values?
++ sk_memset32(dstC, range.fV0, count);
+ dstC += count;
+ }
+ if ((count = range.fCount1) > 0) {
+ int unroll = count >> 3;
+ fx = range.fFx1;
+ for (int i = 0; i < unroll; i++) {
+ NO_CHECK_ITER; NO_CHECK_ITER;
+ NO_CHECK_ITER; NO_CHECK_ITER;
+@@ -905,20 +934,17 @@ void Linear_Gradient::shadeSpan(int x, i
+ }
+ if ((count &= 7) > 0) {
+ do {
+ NO_CHECK_ITER;
+ } while (--count != 0);
+ }
+ }
+ if ((count = range.fCount2) > 0) {
+- sk_memset32_dither(dstC,
+- cache[toggle + range.fV1],
+- cache[(toggle ^ TOGGLE_MASK) + range.fV1],
+- count);
++ sk_memset32(dstC, range.fV1, count);
+ }
+ } else if (proc == mirror_tileproc) {
+ do {
+ unsigned fi = mirror_8bits(fx >> 8);
+ SkASSERT(fi <= 0xFF);
+ fx += dx;
+ *dstC++ = cache[toggle + fi];
+ toggle ^= TOGGLE_MASK;
+@@ -1670,19 +1699,24 @@ public:
+ }
+ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+ SkScalar db = (SkScalarMul(fDiff.fX, dx) +
+ SkScalarMul(fDiff.fY, dy)) * 2;
+ if (proc == clamp_tileproc) {
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+- SkFixed index = SkClampMax(t, 0xFFFF);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> (16 - kCache32Bits)];
++ if (t < 0) {
++ *dstC++ = cache[-1];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[kCache32Count * 2];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> (16 - kCache32Bits)];
++ }
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ } else if (proc == mirror_tileproc) {
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+ SkFixed index = mirror_tileproc(t);
diff --git a/gfx/skia/patches/archive/getpostextpath.patch b/gfx/skia/patches/archive/getpostextpath.patch
new file mode 100644
index 0000000000..7181411ec8
--- /dev/null
+++ b/gfx/skia/patches/archive/getpostextpath.patch
@@ -0,0 +1,70 @@
+diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
+--- a/gfx/skia/include/core/SkPaint.h
++++ b/gfx/skia/include/core/SkPaint.h
+@@ -836,16 +836,19 @@ public:
+
+ /** Return the path (outline) for the specified text.
+ Note: just like SkCanvas::drawText, this will respect the Align setting
+ in the paint.
+ */
+ void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
+ SkPath* path) const;
+
++ void getPosTextPath(const void* text, size_t length,
++ const SkPoint pos[], SkPath* path) const;
++
+ #ifdef SK_BUILD_FOR_ANDROID
+ const SkGlyph& getUnicharMetrics(SkUnichar);
+ const void* findImage(const SkGlyph&);
+
+ uint32_t getGenerationID() const;
+ #endif
+
+ // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
+diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
+--- a/gfx/skia/src/core/SkPaint.cpp
++++ b/gfx/skia/src/core/SkPaint.cpp
+@@ -1242,16 +1242,43 @@ void SkPaint::getTextPath(const void* te
+ const SkPath* iterPath;
+ while ((iterPath = iter.next(&xpos)) != NULL) {
+ matrix.postTranslate(xpos - prevXPos, 0);
+ path->addPath(*iterPath, matrix);
+ prevXPos = xpos;
+ }
+ }
+
++void SkPaint::getPosTextPath(const void* textData, size_t length,
++ const SkPoint pos[], SkPath* path) const {
++ SkASSERT(length == 0 || textData != NULL);
++
++ const char* text = (const char*)textData;
++ if (text == NULL || length == 0 || path == NULL) {
++ return;
++ }
++
++ SkTextToPathIter iter(text, length, *this, false, true);
++ SkMatrix matrix;
++ SkPoint prevPos;
++ prevPos.set(0, 0);
++
++ matrix.setScale(iter.getPathScale(), iter.getPathScale());
++ path->reset();
++
++ unsigned int i = 0;
++ const SkPath* iterPath;
++ while ((iterPath = iter.next(NULL)) != NULL) {
++ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
++ path->addPath(*iterPath, matrix);
++ prevPos = pos[i];
++ i++;
++ }
++}
++
+ static void add_flattenable(SkDescriptor* desc, uint32_t tag,
+ SkFlattenableWriteBuffer* buffer) {
+ buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
+ }
+
+ // SkFontHost can override this choice in FilterRec()
+ static SkMask::Format computeMaskFormat(const SkPaint& paint) {
+ uint32_t flags = paint.getFlags();
diff --git a/gfx/skia/patches/archive/mingw-fix.patch b/gfx/skia/patches/archive/mingw-fix.patch
new file mode 100644
index 0000000000..d91a16aa70
--- /dev/null
+++ b/gfx/skia/patches/archive/mingw-fix.patch
@@ -0,0 +1,57 @@
+diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
+index 0135b85..bb108f8 100644
+--- a/gfx/skia/include/core/SkPostConfig.h
++++ b/gfx/skia/include/core/SkPostConfig.h
+@@ -253,7 +253,7 @@
+ //////////////////////////////////////////////////////////////////////
+
+ #ifndef SK_OVERRIDE
+-#if defined(SK_BUILD_FOR_WIN)
++#if defined(_MSC_VER)
+ #define SK_OVERRIDE override
+ #elif defined(__clang__)
+ // Some documentation suggests we should be using __attribute__((override)),
+diff --git a/gfx/skia/src/ports/SkFontHost_win.cpp b/gfx/skia/src/ports/SkFontHost_win.cpp
+index dd9c5dc..ca2c3dc 100644
+--- a/gfx/skia/src/ports/SkFontHost_win.cpp
++++ b/gfx/skia/src/ports/SkFontHost_win.cpp
+@@ -22,7 +22,7 @@
+ #ifdef WIN32
+ #include "windows.h"
+ #include "tchar.h"
+-#include "Usp10.h"
++#include "usp10.h"
+
+ // always packed xxRRGGBB
+ typedef uint32_t SkGdiRGB;
+@@ -1033,6 +1033,10 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+ HFONT designFont = NULL;
+
++ const char stem_chars[] = {'i', 'I', '!', '1'};
++ int16_t min_width;
++ unsigned glyphCount;
++
+ // To request design units, create a logical font whose height is specified
+ // as unitsPerEm.
+ OUTLINETEXTMETRIC otm;
+@@ -1046,7 +1050,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
+ if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
+ goto Error;
+ }
+- const unsigned glyphCount = calculateGlyphCount(hdc);
++ glyphCount = calculateGlyphCount(hdc);
+
+ info = new SkAdvancedTypefaceMetrics;
+ info->fEmSize = otm.otmEMSquare;
+@@ -1115,9 +1119,8 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
+
+ // Figure out a good guess for StemV - Min width of i, I, !, 1.
+ // This probably isn't very good with an italic font.
+- int16_t min_width = SHRT_MAX;
++ min_width = SHRT_MAX;
+ info->fStemV = 0;
+- char stem_chars[] = {'i', 'I', '!', '1'};
+ for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
+ ABC abcWidths;
+ if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
diff --git a/gfx/skia/patches/archive/new-aa.patch b/gfx/skia/patches/archive/new-aa.patch
new file mode 100644
index 0000000000..d5e6fbf73d
--- /dev/null
+++ b/gfx/skia/patches/archive/new-aa.patch
@@ -0,0 +1,22 @@
+diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp
+--- a/gfx/skia/src/core/SkScan_AntiPath.cpp
++++ b/gfx/skia/src/core/SkScan_AntiPath.cpp
+@@ -31,17 +31,17 @@
+ - supersampled coordinates, scale equal to the output * SCALE
+
+ NEW_AA is a set of code-changes to try to make both paths produce identical
+ results. Its not quite there yet, though the remaining differences may be
+ in the subsequent blits, and not in the different masks/runs...
+ */
+ //#define FORCE_SUPERMASK
+ //#define FORCE_RLE
+-//#define SK_SUPPORT_NEW_AA
++#define SK_SUPPORT_NEW_AA
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ /// Base class for a single-pass supersampled blitter.
+ class BaseSuperBlitter : public SkBlitter {
+ public:
+ BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
+ const SkRegion& clip);
diff --git a/gfx/skia/patches/archive/old-android-fonthost.patch b/gfx/skia/patches/archive/old-android-fonthost.patch
new file mode 100644
index 0000000000..1c64ace7dd
--- /dev/null
+++ b/gfx/skia/patches/archive/old-android-fonthost.patch
@@ -0,0 +1,530 @@
+# HG changeset patch
+# Parent 9ee29e4aace683ddf6cf8ddb2893cd34fcfc772c
+# User James Willcox <jwillcox@mozilla.com>
+diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in
+--- a/gfx/skia/Makefile.in
++++ b/gfx/skia/Makefile.in
+@@ -305,21 +305,20 @@ CPPSRCS += \
+ SkFontHost_mac_coretext.cpp \
+ SkTime_Unix.cpp \
+ $(NULL)
+ endif
+
+ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
+ CPPSRCS += \
+ SkFontHost_FreeType.cpp \
+ SkFontHost_android.cpp \
+ SkFontHost_gamma.cpp \
+- FontHostConfiguration_android.cpp \
+ SkMMapStream.cpp \
+ SkTime_Unix.cpp \
+ $(NULL)
+
+ DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
+ OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
+ endif
+
+ ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
+ CPPSRCS += \
+diff --git a/gfx/skia/src/ports/SkFontHost_android.cpp b/gfx/skia/src/ports/SkFontHost_android.cpp
+--- a/gfx/skia/src/ports/SkFontHost_android.cpp
++++ b/gfx/skia/src/ports/SkFontHost_android.cpp
+@@ -1,38 +1,31 @@
++
+ /*
+-**
+-** 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.
+-*/
++ * Copyright 2006 The Android Open Source Project
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
+
+ #include "SkFontHost.h"
+ #include "SkDescriptor.h"
+ #include "SkMMapStream.h"
+ #include "SkPaint.h"
+ #include "SkString.h"
+ #include "SkStream.h"
+ #include "SkThread.h"
+ #include "SkTSearch.h"
+-#include "FontHostConfiguration_android.h"
+ #include <stdio.h>
+
++#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
++
+ #ifndef SK_FONT_FILE_PREFIX
+ #define SK_FONT_FILE_PREFIX "/fonts/"
+ #endif
+
+ SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
+ bool* isFixedWidth);
+
+ static void GetFullPathForSysFonts(SkString* full, const char name[]) {
+ full->set(getenv("ANDROID_ROOT"));
+ full->append(SK_FONT_FILE_PREFIX);
+@@ -99,21 +92,21 @@ static SkTypeface* find_best_face(const
+ if (faces[SkTypeface::kNormal] != NULL) {
+ return faces[SkTypeface::kNormal];
+ }
+ // look for anything
+ for (int i = 0; i < 4; i++) {
+ if (faces[i] != NULL) {
+ return faces[i];
+ }
+ }
+ // should never get here, since the faces list should not be empty
+- SkDEBUGFAIL("faces list is empty");
++ SkASSERT(!"faces list is empty");
+ return NULL;
+ }
+
+ static FamilyRec* find_family(const SkTypeface* member) {
+ FamilyRec* curr = gFamilyHead;
+ while (curr != NULL) {
+ for (int i = 0; i < 4; i++) {
+ if (curr->fFaces[i] == member) {
+ return curr;
+ }
+@@ -138,31 +131,27 @@ static SkTypeface* find_from_uniqueID(ui
+ curr = curr->fNext;
+ }
+ return NULL;
+ }
+
+ /* Remove reference to this face from its family. If the resulting family
+ is empty (has no faces), return that family, otherwise return NULL
+ */
+ static FamilyRec* remove_from_family(const SkTypeface* face) {
+ FamilyRec* family = find_family(face);
+- if (family) {
+- SkASSERT(family->fFaces[face->style()] == face);
+- family->fFaces[face->style()] = NULL;
++ SkASSERT(family->fFaces[face->style()] == face);
++ family->fFaces[face->style()] = NULL;
+
+- for (int i = 0; i < 4; i++) {
+- if (family->fFaces[i] != NULL) { // family is non-empty
+- return NULL;
+- }
++ for (int i = 0; i < 4; i++) {
++ if (family->fFaces[i] != NULL) { // family is non-empty
++ return NULL;
+ }
+- } else {
+-// SkDebugf("remove_from_family(%p) face not found", face);
+ }
+ return family; // return the empty family
+ }
+
+ // maybe we should make FamilyRec be doubly-linked
+ static void detach_and_delete_family(FamilyRec* family) {
+ FamilyRec* curr = gFamilyHead;
+ FamilyRec* prev = NULL;
+
+ while (curr != NULL) {
+@@ -172,21 +161,21 @@ static void detach_and_delete_family(Fam
+ gFamilyHead = next;
+ } else {
+ prev->fNext = next;
+ }
+ SkDELETE(family);
+ return;
+ }
+ prev = curr;
+ curr = next;
+ }
+- SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete");
++ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
+ }
+
+ static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
+ NameFamilyPair* list = gNameList.begin();
+ int count = gNameList.count();
+
+ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
+
+ if (index >= 0) {
+ return find_best_face(list[index].fFamily, style);
+@@ -387,111 +376,90 @@ static bool get_name_and_style(const cha
+ }
+ return false;
+ }
+
+ // used to record our notion of the pre-existing fonts
+ struct FontInitRec {
+ const char* fFileName;
+ const char* const* fNames; // null-terminated list
+ };
+
++static const char* gSansNames[] = {
++ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
++};
++
++static const char* gSerifNames[] = {
++ "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
++ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
++};
++
++static const char* gMonoNames[] = {
++ "monospace", "courier", "courier new", "monaco", NULL
++};
++
+ // deliberately empty, but we use the address to identify fallback fonts
+ static const char* gFBNames[] = { NULL };
+
++/* Fonts must be grouped by family, with the first font in a family having the
++ list of names (even if that list is empty), and the following members having
++ null for the list. The names list must be NULL-terminated
++*/
++static const FontInitRec gSystemFonts[] = {
++ { "DroidSans.ttf", gSansNames },
++ { "DroidSans-Bold.ttf", NULL },
++ { "DroidSerif-Regular.ttf", gSerifNames },
++ { "DroidSerif-Bold.ttf", NULL },
++ { "DroidSerif-Italic.ttf", NULL },
++ { "DroidSerif-BoldItalic.ttf", NULL },
++ { "DroidSansMono.ttf", gMonoNames },
++ /* These are optional, and can be ignored if not found in the file system.
++ These are appended to gFallbackFonts[] as they are seen, so we list
++ them in the order we want them to be accessed by NextLogicalFont().
++ */
++ { "DroidSansArabic.ttf", gFBNames },
++ { "DroidSansHebrew.ttf", gFBNames },
++ { "DroidSansThai.ttf", gFBNames },
++ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
++ { "DroidSansJapanese.ttf", gFBNames },
++ { "DroidSansFallback.ttf", gFBNames }
++};
+
+-/* Fonts are grouped by family, with the first font in a family having the
+- list of names (even if that list is empty), and the following members having
+- null for the list. The names list must be NULL-terminated.
+-*/
+-static FontInitRec *gSystemFonts;
+-static size_t gNumSystemFonts = 0;
+-
+-#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.cfg"
++#define DEFAULT_NAMES gSansNames
+
+ // these globals are assigned (once) by load_system_fonts()
+ static FamilyRec* gDefaultFamily;
+ static SkTypeface* gDefaultNormal;
+-static char** gDefaultNames = NULL;
+-static uint32_t *gFallbackFonts;
+
+-/* Load info from a configuration file that populates the system/fallback font structures
+-*/
+-static void load_font_info() {
+-// load_font_info_xml("/system/etc/system_fonts.xml");
+- SkTDArray<FontFamily*> fontFamilies;
+- getFontFamilies(fontFamilies);
+-
+- SkTDArray<FontInitRec> fontInfo;
+- bool firstInFamily = false;
+- for (int i = 0; i < fontFamilies.count(); ++i) {
+- FontFamily *family = fontFamilies[i];
+- firstInFamily = true;
+- for (int j = 0; j < family->fFileNames.count(); ++j) {
+- FontInitRec fontInfoRecord;
+- fontInfoRecord.fFileName = family->fFileNames[j];
+- if (j == 0) {
+- if (family->fNames.count() == 0) {
+- // Fallback font
+- fontInfoRecord.fNames = (char **)gFBNames;
+- } else {
+- SkTDArray<const char*> names = family->fNames;
+- const char **nameList = (const char**)
+- malloc((names.count() + 1) * sizeof(char*));
+- if (nameList == NULL) {
+- // shouldn't get here
+- break;
+- }
+- if (gDefaultNames == NULL) {
+- gDefaultNames = (char**) nameList;
+- }
+- for (int i = 0; i < names.count(); ++i) {
+- nameList[i] = names[i];
+- }
+- nameList[names.count()] = NULL;
+- fontInfoRecord.fNames = nameList;
+- }
+- } else {
+- fontInfoRecord.fNames = NULL;
+- }
+- *fontInfo.append() = fontInfoRecord;
+- }
+- }
+- gNumSystemFonts = fontInfo.count();
+- gSystemFonts = (FontInitRec*) malloc(gNumSystemFonts * sizeof(FontInitRec));
+- gFallbackFonts = (uint32_t*) malloc((gNumSystemFonts + 1) * sizeof(uint32_t));
+- if (gSystemFonts == NULL) {
+- // shouldn't get here
+- gNumSystemFonts = 0;
+- }
+- for (size_t i = 0; i < gNumSystemFonts; ++i) {
+- gSystemFonts[i].fFileName = fontInfo[i].fFileName;
+- gSystemFonts[i].fNames = fontInfo[i].fNames;
+- }
+- fontFamilies.deleteAll();
+-}
++/* This is sized conservatively, assuming that it will never be a size issue.
++ It will be initialized in load_system_fonts(), and will be filled with the
++ fontIDs that can be used for fallback consideration, in sorted order (sorted
++ meaning element[0] should be used first, then element[1], etc. When we hit
++ a fontID==0 in the array, the list is done, hence our allocation size is
++ +1 the total number of possible system fonts. Also see NextLogicalFont().
++ */
++static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
+
+ /* Called once (ensured by the sentinel check at the beginning of our body).
+ Initializes all the globals, and register the system fonts.
+ */
+ static void load_system_fonts() {
+ // check if we've already be called
+ if (NULL != gDefaultNormal) {
+ return;
+ }
+
+- load_font_info();
+-
+ const FontInitRec* rec = gSystemFonts;
+ SkTypeface* firstInFamily = NULL;
+ int fallbackCount = 0;
+
+- for (size_t i = 0; i < gNumSystemFonts; i++) {
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
+ // if we're the first in a new family, clear firstInFamily
+ if (rec[i].fNames != NULL) {
+ firstInFamily = NULL;
+ }
+
+ bool isFixedWidth;
+ SkString name;
+ SkTypeface::Style style;
+
+ // we expect all the fonts, except the "fallback" fonts
+@@ -515,120 +483,75 @@ static void load_system_fonts() {
+ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
+ // rec[i].fFileName, fallbackCount, tf->uniqueID());
+ gFallbackFonts[fallbackCount++] = tf->uniqueID();
+ }
+
+ firstInFamily = tf;
+ FamilyRec* family = find_family(tf);
+ const char* const* names = rec[i].fNames;
+
+ // record the default family if this is it
+- if (names == gDefaultNames) {
++ if (names == DEFAULT_NAMES) {
+ gDefaultFamily = family;
+ }
+ // add the names to map to this family
+ while (*names) {
+ add_name(*names, family);
+ names += 1;
+ }
+ }
+ }
+
+ // do this after all fonts are loaded. This is our default font, and it
+ // acts as a sentinel so we only execute load_system_fonts() once
+ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
+ // now terminate our fallback list with the sentinel value
+ gFallbackFonts[fallbackCount] = 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
+- // lookup and record if the font is custom (i.e. not a system font)
+- bool isCustomFont = !((FamilyTypeface*)face)->isSysFont();
+- stream->writeBool(isCustomFont);
++ const char* name = ((FamilyTypeface*)face)->getUniqueString();
+
+- if (isCustomFont) {
+- SkStream* fontStream = ((FamilyTypeface*)face)->openStream();
++ stream->write8((uint8_t)face->style());
+
+- // store the length of the custom font
+- uint32_t len = fontStream->getLength();
+- stream->write32(len);
+-
+- // store the entire font in the serialized stream
+- void* fontData = malloc(len);
+-
+- fontStream->read(fontData, len);
+- stream->write(fontData, len);
+-
+- fontStream->unref();
+- free(fontData);
+-// SkDebugf("--- fonthost custom serialize %d %d\n", face->style(), len);
+-
++ if (NULL == name || 0 == *name) {
++ stream->writePackedUInt(0);
++// SkDebugf("--- fonthost serialize null\n");
+ } else {
+- const char* name = ((FamilyTypeface*)face)->getUniqueString();
+-
+- stream->write8((uint8_t)face->style());
+-
+- if (NULL == name || 0 == *name) {
+- stream->writePackedUInt(0);
+-// SkDebugf("--- fonthost serialize null\n");
+- } else {
+- uint32_t len = strlen(name);
+- stream->writePackedUInt(len);
+- stream->write(name, len);
+-// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
+- }
++ uint32_t len = strlen(name);
++ stream->writePackedUInt(len);
++ stream->write(name, len);
++// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
+ }
+ }
+
+ SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
+ load_system_fonts();
+
+- // check if the font is a custom or system font
+- bool isCustomFont = stream->readBool();
++ int style = stream->readU8();
+
+- if (isCustomFont) {
++ int len = stream->readPackedUInt();
++ if (len > 0) {
++ SkString str;
++ str.resize(len);
++ stream->read(str.writable_str(), len);
+
+- // read the length of the custom font from the stream
+- uint32_t len = stream->readU32();
+-
+- // generate a new stream to store the custom typeface
+- SkMemoryStream* fontStream = new SkMemoryStream(len);
+- stream->read((void*)fontStream->getMemoryBase(), len);
+-
+- SkTypeface* face = CreateTypefaceFromStream(fontStream);
+-
+- fontStream->unref();
+-
+-// SkDebugf("--- fonthost custom deserialize %d %d\n", face->style(), len);
+- return face;
+-
+- } else {
+- int style = stream->readU8();
+-
+- int len = stream->readPackedUInt();
+- if (len > 0) {
+- SkString str;
+- str.resize(len);
+- stream->read(str.writable_str(), len);
+-
+- const FontInitRec* rec = gSystemFonts;
+- for (size_t i = 0; i < gNumSystemFonts; i++) {
+- if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
+- // backup until we hit the fNames
+- for (int j = i; j >= 0; --j) {
+- if (rec[j].fNames != NULL) {
+- return SkFontHost::CreateTypeface(NULL,
+- rec[j].fNames[0], NULL, 0,
+- (SkTypeface::Style)style);
+- }
++ const FontInitRec* rec = gSystemFonts;
++ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
++ if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
++ // backup until we hit the fNames
++ for (int j = i; j >= 0; --j) {
++ if (rec[j].fNames != NULL) {
++ return SkFontHost::CreateTypeface(NULL,
++ rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style);
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+@@ -697,49 +620,32 @@ size_t SkFontHost::GetFileName(SkFontID
+ }
+ return size;
+ } else {
+ return 0;
+ }
+ }
+
+ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+ load_system_fonts();
+
+- const SkTypeface* origTypeface = find_from_uniqueID(origFontID);
+- const SkTypeface* currTypeface = find_from_uniqueID(currFontID);
+-
+- SkASSERT(origTypeface != 0);
+- SkASSERT(currTypeface != 0);
+-
+- // Our fallback list always stores the id of the plain in each fallback
+- // family, so we transform currFontID to its plain equivalent.
+- currFontID = find_typeface(currTypeface, SkTypeface::kNormal)->uniqueID();
+-
+ /* First see if fontID is already one of our fallbacks. If so, return
+ its successor. If fontID is not in our list, then return the first one
+ in our list. Note: list is zero-terminated, and returning zero means
+ we have no more fonts to use for fallbacks.
+ */
+ const uint32_t* list = gFallbackFonts;
+ for (int i = 0; list[i] != 0; i++) {
+ if (list[i] == currFontID) {
+- if (list[i+1] == 0)
+- return 0;
+- const SkTypeface* nextTypeface = find_from_uniqueID(list[i+1]);
+- return find_typeface(nextTypeface, origTypeface->style())->uniqueID();
++ return list[i+1];
+ }
+ }
+-
+- // If we get here, currFontID was not a fallback, so we start at the
+- // beginning of our list.
+- const SkTypeface* firstTypeface = find_from_uniqueID(list[0]);
+- return find_typeface(firstTypeface, origTypeface->style())->uniqueID();
++ return list[0];
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ if (NULL == stream || stream->getLength() <= 0) {
+ return NULL;
+ }
+
+ bool isFixedWidth;
+@@ -754,10 +660,11 @@ SkTypeface* SkFontHost::CreateTypefaceFr
+ }
+
+ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
+ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
+ // since we created the stream, we let go of our ref() here
+ stream->unref();
+ return face;
+ }
+
++///////////////////////////////////////////////////////////////////////////////
diff --git a/gfx/skia/patches/archive/radial-gradients.patch b/gfx/skia/patches/archive/radial-gradients.patch
new file mode 100644
index 0000000000..183923e83e
--- /dev/null
+++ b/gfx/skia/patches/archive/radial-gradients.patch
@@ -0,0 +1,25 @@
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -1665,17 +1665,20 @@ public:
+ }
+ return kRadial2_GradientType;
+ }
+
+ virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) SK_OVERRIDE {
+ SkASSERT(count > 0);
+
+ // Zero difference between radii: fill with transparent black.
+- if (fDiffRadius == 0) {
++ // TODO: Is removing this actually correct? Two circles with the
++ // same radius, but different centers doesn't sound like it
++ // should be cleared
++ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
+ sk_bzero(dstC, count * sizeof(*dstC));
+ return;
+ }
+ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+ TileProc proc = fTileProc;
+ const SkPMColor* SK_RESTRICT cache = this->getCache32();
+
+ SkScalar foura = fA * 4;
diff --git a/gfx/skia/patches/archive/skia_restrict_problem.patch b/gfx/skia/patches/archive/skia_restrict_problem.patch
new file mode 100644
index 0000000000..c7639ca2ce
--- /dev/null
+++ b/gfx/skia/patches/archive/skia_restrict_problem.patch
@@ -0,0 +1,461 @@
+diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
+--- a/gfx/skia/src/effects/SkGradientShader.cpp
++++ b/gfx/skia/src/effects/SkGradientShader.cpp
+@@ -1184,116 +1184,17 @@ public:
+ {
+ // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
+ SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
+
+ rad_to_unit_matrix(center, radius, &fPtsToUnit);
+ }
+
+ virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE;
+- virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) SK_OVERRIDE {
+- SkASSERT(count > 0);
+-
+- SkPoint srcPt;
+- SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+- TileProc proc = fTileProc;
+- const uint16_t* SK_RESTRICT cache = this->getCache16();
+- int toggle = ((x ^ y) & 1) << kCache16Bits;
+-
+- if (fDstToIndexClass != kPerspective_MatrixClass) {
+- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+- SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+- SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
+-
+- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+- SkFixed storage[2];
+- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
+- dx = storage[0];
+- dy = storage[1];
+- } else {
+- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+- dx = SkScalarToFixed(fDstToIndex.getScaleX());
+- dy = SkScalarToFixed(fDstToIndex.getSkewY());
+- }
+-
+- if (proc == clamp_tileproc) {
+- const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
+-
+- /* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
+- rather than 0xFFFF which is slower. This is a compromise, since it reduces our
+- precision, but that appears to be visually OK. If we decide this is OK for
+- all of our cases, we could (it seems) put this scale-down into fDstToIndex,
+- to avoid having to do these extra shifts each time.
+- */
+- fx >>= 1;
+- dx >>= 1;
+- fy >>= 1;
+- dy >>= 1;
+- if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
+- fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
+- fy *= fy;
+- do {
+- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
+- unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
+- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
+- fx += dx;
+- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
+- toggle ^= (1 << kCache16Bits);
+- } while (--count != 0);
+- } else {
+- do {
+- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
+- unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
+- fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
+- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
+- fx += dx;
+- fy += dy;
+- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
+- toggle ^= (1 << kCache16Bits);
+- } while (--count != 0);
+- }
+- } else if (proc == mirror_tileproc) {
+- do {
+- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+- unsigned fi = mirror_tileproc(dist);
+- SkASSERT(fi <= 0xFFFF);
+- fx += dx;
+- fy += dy;
+- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
+- toggle ^= (1 << kCache16Bits);
+- } while (--count != 0);
+- } else {
+- SkASSERT(proc == repeat_tileproc);
+- do {
+- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+- unsigned fi = repeat_tileproc(dist);
+- SkASSERT(fi <= 0xFFFF);
+- fx += dx;
+- fy += dy;
+- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
+- toggle ^= (1 << kCache16Bits);
+- } while (--count != 0);
+- }
+- } else { // perspective case
+- SkScalar dstX = SkIntToScalar(x);
+- SkScalar dstY = SkIntToScalar(y);
+- do {
+- dstProc(fDstToIndex, dstX, dstY, &srcPt);
+- unsigned fi = proc(SkScalarToFixed(srcPt.length()));
+- SkASSERT(fi <= 0xFFFF);
+-
+- int index = fi >> (16 - kCache16Bits);
+- *dstC++ = cache[toggle + index];
+- toggle ^= (1 << kCache16Bits);
+-
+- dstX += SK_Scalar1;
+- } while (--count != 0);
+- }
+- }
++ virtual void shadeSpan16(int x, int y, uint16_t* dstC, int count) SK_OVERRIDE;
+
+ virtual BitmapType asABitmap(SkBitmap* bitmap,
+ SkMatrix* matrix,
+ TileMode* xy,
+ SkScalar* twoPointRadialParams) const SK_OVERRIDE {
+ if (bitmap) {
+ this->commonAsABitmap(bitmap);
+ }
+@@ -1507,16 +1408,117 @@ void Radial_Gradient::shadeSpan(int x, i
+ unsigned fi = proc(SkScalarToFixed(srcPt.length()));
+ SkASSERT(fi <= 0xFFFF);
+ *dstC++ = cache[fi >> (16 - kCache32Bits)];
+ dstX += SK_Scalar1;
+ } while (--count != 0);
+ }
+ }
+
++void Radial_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) {
++ SkASSERT(count > 0);
++
++ SkPoint srcPt;
++ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
++ TileProc proc = fTileProc;
++ const uint16_t* SK_RESTRICT cache = this->getCache16();
++ int toggle = ((x ^ y) & 1) << kCache16Bits;
++
++ if (fDstToIndexClass != kPerspective_MatrixClass) {
++ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
++ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
++ SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
++ SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
++
++ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
++ SkFixed storage[2];
++ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
++ dx = storage[0];
++ dy = storage[1];
++ } else {
++ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
++ dx = SkScalarToFixed(fDstToIndex.getScaleX());
++ dy = SkScalarToFixed(fDstToIndex.getSkewY());
++ }
++
++ if (proc == clamp_tileproc) {
++ const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
++
++ /* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
++ rather than 0xFFFF which is slower. This is a compromise, since it reduces our
++ precision, but that appears to be visually OK. If we decide this is OK for
++ all of our cases, we could (it seems) put this scale-down into fDstToIndex,
++ to avoid having to do these extra shifts each time.
++ */
++ fx >>= 1;
++ dx >>= 1;
++ fy >>= 1;
++ dy >>= 1;
++ if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
++ fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
++ fy *= fy;
++ do {
++ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
++ unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
++ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
++ fx += dx;
++ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
++ toggle ^= (1 << kCache16Bits);
++ } while (--count != 0);
++ } else {
++ do {
++ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
++ unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
++ fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
++ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
++ fx += dx;
++ fy += dy;
++ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
++ toggle ^= (1 << kCache16Bits);
++ } while (--count != 0);
++ }
++ } else if (proc == mirror_tileproc) {
++ do {
++ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
++ unsigned fi = mirror_tileproc(dist);
++ SkASSERT(fi <= 0xFFFF);
++ fx += dx;
++ fy += dy;
++ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
++ toggle ^= (1 << kCache16Bits);
++ } while (--count != 0);
++ } else {
++ SkASSERT(proc == repeat_tileproc);
++ do {
++ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
++ unsigned fi = repeat_tileproc(dist);
++ SkASSERT(fi <= 0xFFFF);
++ fx += dx;
++ fy += dy;
++ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
++ toggle ^= (1 << kCache16Bits);
++ } while (--count != 0);
++ }
++ } else { // perspective case
++ SkScalar dstX = SkIntToScalar(x);
++ SkScalar dstY = SkIntToScalar(y);
++ do {
++ dstProc(fDstToIndex, dstX, dstY, &srcPt);
++ unsigned fi = proc(SkScalarToFixed(srcPt.length()));
++ SkASSERT(fi <= 0xFFFF);
++
++ int index = fi >> (16 - kCache16Bits);
++ *dstC++ = cache[toggle + index];
++ toggle ^= (1 << kCache16Bits);
++
++ dstX += SK_Scalar1;
++ } while (--count != 0);
++ }
++}
++
+ /* Two-point radial gradients are specified by two circles, each with a center
+ point and radius. The gradient can be considered to be a series of
+ concentric circles, with the color interpolated from the start circle
+ (at t=0) to the end circle (at t=1).
+
+ For each point (x, y) in the span, we want to find the
+ interpolated circle that intersects that point. The center
+ of the desired circle (Cx, Cy) falls at some distance t
+@@ -1661,109 +1663,17 @@ public:
+ info->fPoint[0] = fCenter1;
+ info->fPoint[1] = fCenter2;
+ info->fRadius[0] = fRadius1;
+ info->fRadius[1] = fRadius2;
+ }
+ return kRadial2_GradientType;
+ }
+
+- virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) SK_OVERRIDE {
+- SkASSERT(count > 0);
+-
+- // Zero difference between radii: fill with transparent black.
+- // TODO: Is removing this actually correct? Two circles with the
+- // same radius, but different centers doesn't sound like it
+- // should be cleared
+- if (fDiffRadius == 0 && fCenter1 == fCenter2) {
+- sk_bzero(dstC, count * sizeof(*dstC));
+- return;
+- }
+- SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+- TileProc proc = fTileProc;
+- const SkPMColor* SK_RESTRICT cache = this->getCache32();
+-
+- SkScalar foura = fA * 4;
+- bool posRoot = fDiffRadius < 0;
+- if (fDstToIndexClass != kPerspective_MatrixClass) {
+- SkPoint srcPt;
+- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+- SkScalar dx, fx = srcPt.fX;
+- SkScalar dy, fy = srcPt.fY;
+-
+- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+- SkFixed fixedX, fixedY;
+- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
+- dx = SkFixedToScalar(fixedX);
+- dy = SkFixedToScalar(fixedY);
+- } else {
+- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+- dx = fDstToIndex.getScaleX();
+- dy = fDstToIndex.getSkewY();
+- }
+- SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+- SkScalar db = (SkScalarMul(fDiff.fX, dx) +
+- SkScalarMul(fDiff.fY, dy)) * 2;
+- if (proc == clamp_tileproc) {
+- for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+- if (t < 0) {
+- *dstC++ = cache[-1];
+- } else if (t > 0xFFFF) {
+- *dstC++ = cache[kCache32Count * 2];
+- } else {
+- SkASSERT(t <= 0xFFFF);
+- *dstC++ = cache[t >> (16 - kCache32Bits)];
+- }
+- fx += dx;
+- fy += dy;
+- b += db;
+- }
+- } else if (proc == mirror_tileproc) {
+- for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+- SkFixed index = mirror_tileproc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> (16 - kCache32Bits)];
+- fx += dx;
+- fy += dy;
+- b += db;
+- }
+- } else {
+- SkASSERT(proc == repeat_tileproc);
+- for (; count > 0; --count) {
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+- SkFixed index = repeat_tileproc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> (16 - kCache32Bits)];
+- fx += dx;
+- fy += dy;
+- b += db;
+- }
+- }
+- } else { // perspective case
+- SkScalar dstX = SkIntToScalar(x);
+- SkScalar dstY = SkIntToScalar(y);
+- for (; count > 0; --count) {
+- SkPoint srcPt;
+- dstProc(fDstToIndex, dstX, dstY, &srcPt);
+- SkScalar fx = srcPt.fX;
+- SkScalar fy = srcPt.fY;
+- SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+- SkFixed index = proc(t);
+- SkASSERT(index <= 0xFFFF);
+- *dstC++ = cache[index >> (16 - kCache32Bits)];
+- dstX += SK_Scalar1;
+- }
+- }
+- }
++ virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count) SK_OVERRIDE;
+
+ virtual bool setContext(const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix) SK_OVERRIDE {
+ if (!this->INHERITED::setContext(device, paint, matrix)) {
+ return false;
+ }
+
+@@ -1817,16 +1727,110 @@ private:
+ fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
+ fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
+
+ fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
+ fPtsToUnit.postScale(inv, inv);
+ }
+ };
+
++void Two_Point_Radial_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
++ SkASSERT(count > 0);
++
++ // Zero difference between radii: fill with transparent black.
++ // TODO: Is removing this actually correct? Two circles with the
++ // same radius, but different centers doesn't sound like it
++ // should be cleared
++ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
++ sk_bzero(dstC, count * sizeof(*dstC));
++ return;
++ }
++ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
++ TileProc proc = fTileProc;
++ const SkPMColor* SK_RESTRICT cache = this->getCache32();
++
++ SkScalar foura = fA * 4;
++ bool posRoot = fDiffRadius < 0;
++ if (fDstToIndexClass != kPerspective_MatrixClass) {
++ SkPoint srcPt;
++ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
++ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
++ SkScalar dx, fx = srcPt.fX;
++ SkScalar dy, fy = srcPt.fY;
++
++ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
++ SkFixed fixedX, fixedY;
++ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
++ dx = SkFixedToScalar(fixedX);
++ dy = SkFixedToScalar(fixedY);
++ } else {
++ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
++ dx = fDstToIndex.getScaleX();
++ dy = fDstToIndex.getSkewY();
++ }
++ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
++ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
++ SkScalar db = (SkScalarMul(fDiff.fX, dx) +
++ SkScalarMul(fDiff.fY, dy)) * 2;
++ if (proc == clamp_tileproc) {
++ for (; count > 0; --count) {
++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
++ if (t < 0) {
++ *dstC++ = cache[-1];
++ } else if (t > 0xFFFF) {
++ *dstC++ = cache[kCache32Count * 2];
++ } else {
++ SkASSERT(t <= 0xFFFF);
++ *dstC++ = cache[t >> (16 - kCache32Bits)];
++ }
++ fx += dx;
++ fy += dy;
++ b += db;
++ }
++ } else if (proc == mirror_tileproc) {
++ for (; count > 0; --count) {
++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
++ SkFixed index = mirror_tileproc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - kCache32Bits)];
++ fx += dx;
++ fy += dy;
++ b += db;
++ }
++ } else {
++ SkASSERT(proc == repeat_tileproc);
++ for (; count > 0; --count) {
++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
++ SkFixed index = repeat_tileproc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - kCache32Bits)];
++ fx += dx;
++ fy += dy;
++ b += db;
++ }
++ }
++ } else { // perspective case
++ SkScalar dstX = SkIntToScalar(x);
++ SkScalar dstY = SkIntToScalar(y);
++ for (; count > 0; --count) {
++ SkPoint srcPt;
++ dstProc(fDstToIndex, dstX, dstY, &srcPt);
++ SkScalar fx = srcPt.fX;
++ SkScalar fy = srcPt.fY;
++ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
++ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
++ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
++ SkFixed index = proc(t);
++ SkASSERT(index <= 0xFFFF);
++ *dstC++ = cache[index >> (16 - kCache32Bits)];
++ dstX += SK_Scalar1;
++ }
++ }
++}
++
+ ///////////////////////////////////////////////////////////////////////////////
+
+ class Sweep_Gradient : public Gradient_Shader {
+ public:
+ Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[],
+ const SkScalar pos[], int count, SkUnitMapper* mapper)
+ : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper),
+ fCenter(SkPoint::Make(cx, cy))
diff --git a/gfx/skia/patches/archive/uninitialized-margin.patch b/gfx/skia/patches/archive/uninitialized-margin.patch
new file mode 100644
index 0000000000..b8ab213e7b
--- /dev/null
+++ b/gfx/skia/patches/archive/uninitialized-margin.patch
@@ -0,0 +1,22 @@
+diff --git a/gfx/skia/src/core/SkDraw.cpp b/gfx/skia/src/core/SkDraw.cpp
+--- a/gfx/skia/src/core/SkDraw.cpp
++++ b/gfx/skia/src/core/SkDraw.cpp
+@@ -2529,17 +2529,17 @@ static bool compute_bounds(const SkPath&
+
+ // init our bounds from the path
+ {
+ SkRect pathBounds = devPath.getBounds();
+ pathBounds.inset(-SK_ScalarHalf, -SK_ScalarHalf);
+ pathBounds.roundOut(bounds);
+ }
+
+- SkIPoint margin;
++ SkIPoint margin = SkIPoint::Make(0, 0);
+ if (filter) {
+ SkASSERT(filterMatrix);
+
+ SkMask srcM, dstM;
+
+ srcM.fBounds = *bounds;
+ srcM.fFormat = SkMask::kA8_Format;
+ srcM.fImage = NULL;
diff --git a/gfx/skia/patches/archive/user-config.patch b/gfx/skia/patches/archive/user-config.patch
new file mode 100644
index 0000000000..11c6f1f638
--- /dev/null
+++ b/gfx/skia/patches/archive/user-config.patch
@@ -0,0 +1,40 @@
+diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
+--- a/gfx/skia/include/config/SkUserConfig.h
++++ b/gfx/skia/include/config/SkUserConfig.h
+@@ -140,16 +140,20 @@
+ /* If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST
+ which will run additional self-tests at startup. These can take a long time,
+ so this flag is optional.
+ */
+ #ifdef SK_DEBUG
+ //#define SK_SUPPORT_UNITTEST
+ #endif
+
++/* Don't dither 32bit gradients, to match what the canvas test suite expects.
++ */
++#define SK_DISABLE_DITHER_32BIT_GRADIENT
++
+ /* If your system embeds skia and has complex event logging, define this
+ symbol to name a file that maps the following macros to your system's
+ equivalents:
+ SK_TRACE_EVENT0(event)
+ SK_TRACE_EVENT1(event, name1, value1)
+ SK_TRACE_EVENT2(event, name1, value1, name2, value2)
+ src/utils/SkDebugTrace.h has a trivial implementation that writes to
+ the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined,
+@@ -161,9 +165,15 @@
+ */
+ #ifdef SK_SAMPLES_FOR_X
+ #define SK_R32_SHIFT 16
+ #define SK_G32_SHIFT 8
+ #define SK_B32_SHIFT 0
+ #define SK_A32_SHIFT 24
+ #endif
+
++/* Don't include stdint.h on windows as it conflicts with our build system.
++ */
++#ifdef SK_BUILD_FOR_WIN32
++ #define SK_IGNORE_STDINT_DOT_H
++#endif
++
+ #endif