Add rounding to the pixel grid to Yoga
Reviewed By: emilsjolander Differential Revision: D4565980 fbshipit-source-id: 9700f6d6ed147f82b19f230fbff2e9ccbd625b25
This commit is contained in:
parent
7f6f964e18
commit
387ec8ce37
|
@ -3216,18 +3216,58 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
|
||||||
return (needToVisitNode || cachedResults == NULL);
|
return (needToVisitNode || cachedResults == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGRoundToPixelGrid(const YGNodeRef node) {
|
static float gPointScaleFactor = 1.0;
|
||||||
const float fractialLeft =
|
|
||||||
node->layout.position[YGEdgeLeft] - floorf(node->layout.position[YGEdgeLeft]);
|
|
||||||
const float fractialTop =
|
|
||||||
node->layout.position[YGEdgeTop] - floorf(node->layout.position[YGEdgeTop]);
|
|
||||||
node->layout.dimensions[YGDimensionWidth] =
|
|
||||||
roundf(fractialLeft + node->layout.dimensions[YGDimensionWidth]) - roundf(fractialLeft);
|
|
||||||
node->layout.dimensions[YGDimensionHeight] =
|
|
||||||
roundf(fractialTop + node->layout.dimensions[YGDimensionHeight]) - roundf(fractialTop);
|
|
||||||
|
|
||||||
node->layout.position[YGEdgeLeft] = roundf(node->layout.position[YGEdgeLeft]);
|
void YGSetPointScaleFactor(float pixelsInPoint) {
|
||||||
node->layout.position[YGEdgeTop] = roundf(node->layout.position[YGEdgeTop]);
|
YG_ASSERT(pixelsInPoint >= 0.0, "Scale factor should not be less than zero");
|
||||||
|
// We store points for Pixel as we will use it for rounding
|
||||||
|
if (pixelsInPoint == 0.0) {
|
||||||
|
// Zero is used to skip rounding
|
||||||
|
gPointScaleFactor = 0.0;
|
||||||
|
} else {
|
||||||
|
gPointScaleFactor = 1.0 / pixelsInPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void YGRoundToPixelGrid(const YGNodeRef node) {
|
||||||
|
if (gPointScaleFactor == 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const float nodeLeft = node->layout.position[YGEdgeLeft];
|
||||||
|
const float nodeTop = node->layout.position[YGEdgeTop];
|
||||||
|
|
||||||
|
// To round correctly to the pixel grid, first we calculate left and top coordinates
|
||||||
|
float fractialLeft = fmodf(nodeLeft, gPointScaleFactor);
|
||||||
|
float fractialTop = fmodf(nodeTop, gPointScaleFactor);
|
||||||
|
float roundedLeft = nodeLeft - fractialLeft;
|
||||||
|
float roundedTop = nodeTop - fractialTop;
|
||||||
|
|
||||||
|
// To do the actual rounding we check if leftover fraction is bigger or equal than half of the grid step
|
||||||
|
if (fractialLeft >= gPointScaleFactor / 2.0) {
|
||||||
|
roundedLeft += gPointScaleFactor;
|
||||||
|
fractialLeft -= gPointScaleFactor;
|
||||||
|
}
|
||||||
|
if (fractialTop >= gPointScaleFactor / 2.0) {
|
||||||
|
roundedTop += gPointScaleFactor;
|
||||||
|
fractialTop -= gPointScaleFactor;
|
||||||
|
}
|
||||||
|
node->layout.position[YGEdgeLeft] = roundedLeft;
|
||||||
|
node->layout.position[YGEdgeTop] = roundedTop;
|
||||||
|
|
||||||
|
// Now we round width and height in the same way accounting for fractial leftovers from rounding position
|
||||||
|
const float adjustedWidth = fractialLeft + node->layout.dimensions[YGDimensionWidth];
|
||||||
|
const float adjustedHeight = fractialTop + node->layout.dimensions[YGDimensionHeight];
|
||||||
|
float roundedWidth = adjustedWidth - fmodf(adjustedWidth, gPointScaleFactor);
|
||||||
|
float roundedHeight = adjustedHeight - fmodf(adjustedHeight, gPointScaleFactor);
|
||||||
|
|
||||||
|
if (adjustedWidth - roundedWidth >= gPointScaleFactor / 2.0) {
|
||||||
|
roundedWidth += gPointScaleFactor;
|
||||||
|
}
|
||||||
|
if (adjustedHeight - roundedHeight >= gPointScaleFactor / 2.0) {
|
||||||
|
roundedHeight += gPointScaleFactor;
|
||||||
|
}
|
||||||
|
node->layout.dimensions[YGDimensionWidth] = roundedWidth;
|
||||||
|
node->layout.dimensions[YGDimensionHeight] = roundedHeight;
|
||||||
|
|
||||||
const uint32_t childCount = YGNodeListCount(node->children);
|
const uint32_t childCount = YGNodeListCount(node->children);
|
||||||
for (uint32_t i = 0; i < childCount; i++) {
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
|
|
|
@ -219,6 +219,10 @@ YG_NODE_LAYOUT_EDGE_PROPERTY(float, Padding);
|
||||||
WIN_EXPORT void YGSetLogger(YGLogger logger);
|
WIN_EXPORT void YGSetLogger(YGLogger logger);
|
||||||
WIN_EXPORT void YGLog(YGLogLevel level, const char *message, ...);
|
WIN_EXPORT void YGLog(YGLogLevel level, const char *message, ...);
|
||||||
|
|
||||||
|
// Set this to number of pixels in 1 point to round calculation results
|
||||||
|
// If you want to avoid rounding - set PointScaleFactor to 0
|
||||||
|
WIN_EXPORT void YGSetPointScaleFactor(float pixelsInPoint);
|
||||||
|
|
||||||
WIN_EXPORT void YGSetExperimentalFeatureEnabled(YGExperimentalFeature feature, bool enabled);
|
WIN_EXPORT void YGSetExperimentalFeatureEnabled(YGExperimentalFeature feature, bool enabled);
|
||||||
WIN_EXPORT bool YGIsExperimentalFeatureEnabled(YGExperimentalFeature feature);
|
WIN_EXPORT bool YGIsExperimentalFeatureEnabled(YGExperimentalFeature feature);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue