AI 144443: Change how skia handles gradient stops that are missing either pos=0 or pos=1. Instead of ignoring the first and last pos, and assuming they were 0,1, now we insert in the missing values. This matches webkit's expectations, and seems fine for skia clients as well.
  On the webkit side, call Gradient::getColor() before we sniff the stops-array. This has the side-effect of sorting the stops, which we need for skia.
  BUG=1688373

Automated import of CL 144443
diff --git a/WebCore/platform/graphics/android/GradientAndroid.cpp b/WebCore/platform/graphics/android/GradientAndroid.cpp
index 71b7f73..718c49b 100644
--- a/WebCore/platform/graphics/android/GradientAndroid.cpp
+++ b/WebCore/platform/graphics/android/GradientAndroid.cpp
@@ -42,6 +42,7 @@
 
     SkShader*           m_shader;
     SkShader::TileMode  m_tileMode;
+    int                 m_colorCountWhenShaderWasBuilt;
 };
 
 namespace WebCore {
@@ -57,42 +58,49 @@
     return (int)(x * 255);
 }
 
-SkShader* Gradient::getShader(SkShader::TileMode mode) {
-    if (NULL == m_gradient) {
+SkShader* Gradient::getShader(SkShader::TileMode mode)
+{
+    if (NULL == m_gradient)
         m_gradient = new PlatformGradientRec;
-    } else if (m_gradient->m_tileMode == mode) {
+    else if (mode == m_gradient->m_tileMode)
         return m_gradient->m_shader;
+
+    // need to ensure that the m_stops array is sorted. We call getColor()
+    // which, as a side effect, does the sort.
+    // TODO: refactor Gradient.h to formally expose a sort method
+    {
+        float r, g, b, a;
+        this->getColor(0, &r, &g, &b, &a);
     }
 
     SkPoint pts[2];
-
     android_setpt(&pts[0], m_p0);
     android_setpt(&pts[1], m_p1);
-    size_t count = m_stops.size();
+
+    const size_t count = m_stops.size();
     SkAutoMalloc    storage(count * (sizeof(SkColor) + sizeof(SkScalar)));
     SkColor*        colors = (SkColor*)storage.get();
     SkScalar*       pos = (SkScalar*)(colors + count);
 
     Vector<ColorStop>::iterator iter = m_stops.begin();
-    int i = -1;
-    while (i++, iter != m_stops.end()) {
+    for (int i = 0; iter != m_stops.end(); i++) {
         pos[i] = SkFloatToScalar(iter->stop);
         colors[i] = SkColorSetARGB(F2B(iter->alpha), F2B(iter->red),
-            F2B(iter->green), F2B(iter->blue));
+                                   F2B(iter->green), F2B(iter->blue));
         ++iter;
     }
 
     SkShader* s;
-    if (0 == count) {
-        // it seems the spec says a zero-size gradient draws transparent
-        s = new SkColorShader(0);
-    } else if (m_radial) {
+    if (m_radial)
         s = SkGradientShader::CreateRadial(pts[0], SkFloatToScalar(m_r0),
                                            colors, pos, count, mode);
-    } else {
+    else
         s = SkGradientShader::CreateLinear(pts, colors, pos, count, mode);
-    }
 
+    if (NULL == s)
+        s = new SkColorShader(0);
+
+    // zap our previous shader, if present
     m_gradient->m_shader->safeUnref();
     m_gradient->m_shader = s;
     m_gradient->m_tileMode = mode;