Changed pointScaleFactor usage to avoid accumulating error

Summary: Previously pointScaleFactor was stored as a divider that opened way to accumulating difference. For instance in ScreenScale=3, pointScaleFactor = 0.3333343 (0.000001 error). When used for width = 300 that error was multiplied by the number of times pointScale contained in width (300 *3 = 900) and we had almost 0.001 error accumulated. With this change Yoga will avoid such issue

Reviewed By: shergin

Differential Revision: D5137923

fbshipit-source-id: 652b59bc3da3f35ee93ffa3695936f623298a023
This commit is contained in:
Georgiy Kassabli
2017-05-26 10:56:33 -07:00
committed by Facebook Github Bot
parent fa50f048f1
commit b378a685a4

View File

@@ -3148,19 +3148,19 @@ static float YGRoundValueToPixelGrid(const float value,
const float pointScaleFactor, const float pointScaleFactor,
const bool forceCeil, const bool forceCeil,
const bool forceFloor) { const bool forceFloor) {
float fractial = fmodf(value, pointScaleFactor); float scaledValue = value * pointScaleFactor;
float fractial = fmodf(scaledValue, 1.0);
if (YGFloatsEqual(fractial, 0)) { if (YGFloatsEqual(fractial, 0)) {
// Still remove fractial as fractial could be extremely small. // Still remove fractial as fractial could be extremely small.
return value - fractial; scaledValue = scaledValue - fractial;
} } else if (forceCeil) {
scaledValue = scaledValue - fractial + 1.0;
if (forceCeil) {
return value - fractial + pointScaleFactor;
} else if (forceFloor) { } else if (forceFloor) {
return value - fractial; scaledValue = scaledValue - fractial;
} else { } else {
return value - fractial + (fractial >= pointScaleFactor / 2.0f ? pointScaleFactor : 0); scaledValue = scaledValue - fractial + (fractial >= 0.5f ? 1.0 : 0);
} }
return scaledValue / pointScaleFactor;
} }
bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode, bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
@@ -3427,7 +3427,7 @@ void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInP
// Zero is used to skip rounding // Zero is used to skip rounding
config->pointScaleFactor = 0.0f; config->pointScaleFactor = 0.0f;
} else { } else {
config->pointScaleFactor = 1.0f / pixelsInPoint; config->pointScaleFactor = pixelsInPoint;
} }
} }