aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Lee Salzman <lsalzman@mozilla.com>2017-03-14 14:52:51 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-22 19:30:30 +0000
commitb8e752198dde333e71cb1a9578cd3dfd404dd06c (patch)
tree4189b99fd65494b29665fa72e9e94a56829a008f /src
parentce425510a07632f14b7b779ec3864f719cb4326b (diff)
fix round_asymmetric_to_int to also bias bottom and right
BUG=skia:6294 Change-Id: I1ee1031f1fb7cb035916e8945ce5396759955885 Reviewed-on: https://skia-review.googlesource.com/9700 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkScan_Path.cpp46
1 files changed, 24 insertions, 22 deletions
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index 11f9c403c8..0415b2f99a 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -562,28 +562,35 @@ static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) {
}
/**
- * Variant of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
- * is 0.5. In this case only, round the value down. This is used to round the top and left
- * of a rectangle, and corresponds to the way the scan converter treats the top and left edges.
+ * Variants of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
+ * is 0.5. When SK_RASTERIZE_EVEN_ROUNDING is enabled, we must bias the result before rounding to
+ * account for potential FDot6 rounding edge-cases.
+ */
+#ifdef SK_RASTERIZE_EVEN_ROUNDING
+static const double kRoundBias = 0.5 / SK_FDot6One;
+#else
+static const double kRoundBias = 0.0;
+#endif
+
+/**
+ * Round the value down. This is used to round the top and left of a rectangle,
+ * and corresponds to the way the scan converter treats the top and left edges.
*/
static inline int round_down_to_int(SkScalar x) {
double xx = x;
- xx -= 0.5;
+ xx -= 0.5 + kRoundBias;
return (int)ceil(xx);
}
-#ifdef SK_RASTERIZE_EVEN_ROUNDING
/**
- * Variant of SkDScalarRoundToInt that biases the input up by a half an FDot6 unit to account
- * for potential FDot6 rounding in downstream FDot6 calculations.
+ * Round the value up. This is used to round the bottom and right of a rectangle,
+ * and corresponds to the way the scan converter treats the bottom and right edges.
*/
-static inline int round_biased_to_int(SkScalar x) {
- const double bias = 0.5 / SK_FDot6One;
+static inline int round_up_to_int(SkScalar x) {
double xx = x;
- xx += 0.5 + bias;
+ xx += 0.5 + kRoundBias;
return (int)floor(xx);
}
-#endif
/**
* Variant of SkRect::round() that explicitly performs the rounding step (i.e. floor(x + 0.5))
@@ -604,26 +611,21 @@ static inline int round_biased_to_int(SkScalar x) {
* SkASSERT(0 == iright); // <--- succeeds
*
*
- * If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure that bottom and right account for
- * edges bounded by this rect being rounded to FDot6 format before being later rounded to an
- * integer. For example, a value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which
- * would finally round to the integer 1, instead of just rounding to 0.
+ * If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure we account for edges bounded by this
+ * rect being rounded to FDot6 format before being later rounded to an integer. For example, a
+ * value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which would finally round to
+ * the integer 1, instead of just rounding to 0.
*
* To handle this, a small bias of half an FDot6 increment is added before actually rounding to
* an integer value. This simulates the rounding of SkScalarRoundToFDot6 without incurring the
* range loss of converting to FDot6 format first, preserving the integer range for the SkIRect.
* Thus, bottom and right are rounded in this manner (biased up), ensuring the rect is large
- * enough. Top and left can round as normal since they will round (biased down) to values less
- * or equal to the desired rect origin.
+ * enough.
*/
static void round_asymmetric_to_int(const SkRect& src, SkIRect* dst) {
SkASSERT(dst);
dst->set(round_down_to_int(src.fLeft), round_down_to_int(src.fTop),
-#ifdef SK_RASTERIZE_EVEN_ROUNDING
- round_biased_to_int(src.fRight), round_biased_to_int(src.fBottom));
-#else
- SkDScalarRoundToInt(src.fRight), SkDScalarRoundToInt(src.fBottom));
-#endif
+ round_up_to_int(src.fRight), round_up_to_int(src.fBottom));
}
void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,