mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 22:27:31 +09:00
Backport some upstream Skia patches.
Backport of: https://skia.googlesource.com/skia/+/1e259cda4fb7f12e98dd611bd651f40ebef2d14a https://skia.googlesource.com/skia/+/73be50da2a1fe8944f2623a511fda1957eed708a
This commit is contained in:
parent
d4db378b5a
commit
031102b1ca
2 changed files with 38 additions and 12 deletions
|
|
@ -62,6 +62,15 @@ static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Just returns its argument, but makes it easy to set a break-point to know when
|
||||||
|
// SkFindUnitQuadRoots is going to return 0 (an error).
|
||||||
|
static int return_check_zero(int value) {
|
||||||
|
if (value == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/** From Numerical Recipes in C.
|
/** From Numerical Recipes in C.
|
||||||
|
|
||||||
Q = -1/2 (B + sign(B) sqrt[B*B - 4*A*C])
|
Q = -1/2 (B + sign(B) sqrt[B*B - 4*A*C])
|
||||||
|
|
@ -72,22 +81,21 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) {
|
||||||
SkASSERT(roots);
|
SkASSERT(roots);
|
||||||
|
|
||||||
if (A == 0) {
|
if (A == 0) {
|
||||||
return valid_unit_divide(-C, B, roots);
|
return return_check_zero(valid_unit_divide(-C, B, roots));
|
||||||
}
|
}
|
||||||
|
|
||||||
SkScalar* r = roots;
|
SkScalar* r = roots;
|
||||||
|
|
||||||
SkScalar R = B*B - 4*A*C;
|
// use doubles so we don't overflow temporarily trying to compute R
|
||||||
if (R < 0 || !SkScalarIsFinite(R)) { // complex roots
|
double dr = (double)B * B - 4 * (double)A * C;
|
||||||
// if R is infinite, it's possible that it may still produce
|
if (dr < 0) {
|
||||||
// useful results if the operation was repeated in doubles
|
return return_check_zero(0);
|
||||||
// the flipside is determining if the more precise answer
|
}
|
||||||
// isn't useful because surrounding machinery (e.g., subtracting
|
dr = sqrt(dr);
|
||||||
// the axis offset from C) already discards the extra precision
|
SkScalar R = SkDoubleToScalar(dr);
|
||||||
// more investigation and unit tests required...
|
if (!SkScalarIsFinite(R)) {
|
||||||
return 0;
|
return return_check_zero(0);
|
||||||
}
|
}
|
||||||
R = SkScalarSqrt(R);
|
|
||||||
|
|
||||||
SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2;
|
SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2;
|
||||||
r += valid_unit_divide(Q, A, r);
|
r += valid_unit_divide(Q, A, r);
|
||||||
|
|
@ -98,7 +106,7 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) {
|
||||||
else if (roots[0] == roots[1]) // nearly-equal?
|
else if (roots[0] == roots[1]) // nearly-equal?
|
||||||
r -= 1; // skip the double root
|
r -= 1; // skip the double root
|
||||||
}
|
}
|
||||||
return (int)(r - roots);
|
return return_check_zero((int)(r - roots));
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,19 @@ void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
|
||||||
this->scaleRadii();
|
this->scaleRadii();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we can't distinguish one of the radii relative to the other, force it to zero so it
|
||||||
|
// doesn't confuse us later. See crbug.com/850350
|
||||||
|
//
|
||||||
|
static void flush_to_zero(SkScalar& a, SkScalar& b) {
|
||||||
|
SkASSERT(a >= 0);
|
||||||
|
SkASSERT(b >= 0);
|
||||||
|
if (a + b == a) {
|
||||||
|
b = 0;
|
||||||
|
} else if (a + b == b) {
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SkRRect::scaleRadii() {
|
void SkRRect::scaleRadii() {
|
||||||
|
|
||||||
// Proportionally scale down all radii to fit. Find the minimum ratio
|
// Proportionally scale down all radii to fit. Find the minimum ratio
|
||||||
|
|
@ -183,6 +196,11 @@ void SkRRect::scaleRadii() {
|
||||||
scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, width, scale);
|
scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, width, scale);
|
||||||
scale = compute_min_scale(fRadii[3].fY, fRadii[0].fY, height, scale);
|
scale = compute_min_scale(fRadii[3].fY, fRadii[0].fY, height, scale);
|
||||||
|
|
||||||
|
flush_to_zero(fRadii[0].fX, fRadii[1].fX);
|
||||||
|
flush_to_zero(fRadii[1].fY, fRadii[2].fY);
|
||||||
|
flush_to_zero(fRadii[2].fX, fRadii[3].fX);
|
||||||
|
flush_to_zero(fRadii[3].fY, fRadii[0].fY);
|
||||||
|
|
||||||
if (scale < 1.0) {
|
if (scale < 1.0) {
|
||||||
SkScaleToSides::AdjustRadii(width, scale, &fRadii[0].fX, &fRadii[1].fX);
|
SkScaleToSides::AdjustRadii(width, scale, &fRadii[0].fX, &fRadii[1].fX);
|
||||||
SkScaleToSides::AdjustRadii(height, scale, &fRadii[1].fY, &fRadii[2].fY);
|
SkScaleToSides::AdjustRadii(height, scale, &fRadii[1].fY, &fRadii[2].fY);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue