Fixed color bleeding issue when drawing a sub region of a bitmap with filtering enabled.
Problem was resolved by adding the notion of a custom texture domain in generated shaders, when necessary.




git-svn-id: http://skia.googlecode.com/svn/trunk@1337 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index a015347..360fa34 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -984,11 +984,36 @@
     GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
                                     GrIntToScalar(srcRect.height()));
     GrRect paintRect;
-    paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16)   / bitmap.width()),
-                      GrFixedToScalar((srcRect.fTop << 16)    / bitmap.height()),
-                      GrFixedToScalar((srcRect.fRight << 16)  / bitmap.width()),
+    paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16) / bitmap.width()),
+                      GrFixedToScalar((srcRect.fTop << 16) / bitmap.height()),
+                      GrFixedToScalar((srcRect.fRight << 16) / bitmap.width()),
                       GrFixedToScalar((srcRect.fBottom << 16) / bitmap.height()));
 
+    if (GrSamplerState::kNearest_Filter != grPaint->fSampler.getFilter() &&
+        (srcRect.width() < bitmap.width() || 
+        srcRect.height() < bitmap.height())) {
+        // If drawing a subrect of the bitmap and filtering is enabled,
+        // use a constrained texture domain to avoid color bleeding
+        GrScalar left, top, right, bottom;
+        if (srcRect.width() > 1) {
+            GrScalar border = GR_ScalarHalf / bitmap.width();
+            left = paintRect.left() + border;
+            right = paintRect.right() - border;
+        } else {
+            left = right = GrScalarHalf(paintRect.left() + paintRect.right());
+        }
+        if (srcRect.height() > 1) {
+            GrScalar border = GR_ScalarHalf / bitmap.height();
+            top = paintRect.top() + border;
+            bottom = paintRect.bottom() - border;
+        } else {
+            top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
+        }
+        GrRect textureDomain;
+        textureDomain.setLTRB(left, top, right, bottom);
+        grPaint->fSampler.setTextureDomain(textureDomain);
+    }
+
     fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
 }