Move configuration to new YGConfig and pass them down to CalculateLayout

Summary:
Move configuration to new ```YGConfig``` and pass them down to CalculateLayout. See #418 .

Adds ```YGConfigNew()``` + ```YGConfigFree```, and changed ```YGSetExperimentalFeatureEnabled``` to use the config.

New function for calculation is ```YGNodeCalculateLayoutWithConfig```.
Closes https://github.com/facebook/yoga/pull/432

Reviewed By: astreet

Differential Revision: D4611359

Pulled By: emilsjolander

fbshipit-source-id: a1332f0e1b21cec02129dd021ee57408449e10b0
This commit is contained in:
Lukas Wöhrl 2017-03-01 09:19:55 -08:00 committed by Facebook Github Bot
parent 4d69f4b2d1
commit bdd9aed909
5 changed files with 177 additions and 57 deletions

View File

@ -0,0 +1,49 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
@DoNotStrip
public class YogaConfig {
static {
SoLoader.loadLibrary("yoga");
}
long mNativePointer;
private native long jni_YGConfigNew();
public YogaConfig() {
mNativePointer = jni_YGConfigNew();
if (mNativePointer == 0) {
throw new IllegalStateException("Failed to allocate native memory");
}
}
private native void jni_YGConfigFree(long nativePointer);
@Override
protected void finalize() throws Throwable {
try {
jni_YGConfigFree(mNativePointer);
} finally {
super.finalize();
}
}
private native void jni_YGConfigSetExperimentalFeatureEnabled(
long nativePointer,
int feature,
boolean enabled);
public void setExperimentalFeatureEnabled(YogaExperimentalFeature feature, boolean enabled) {
jni_YGConfigSetExperimentalFeatureEnabled(mNativePointer, feature.intValue(), enabled);
}
}

View File

@ -35,20 +35,6 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
jni_YGSetLogger(logger); jni_YGSetLogger(logger);
} }
private static native void jni_YGSetExperimentalFeatureEnabled(
int feature,
boolean enabled);
public static void setExperimentalFeatureEnabled(
YogaExperimentalFeature feature,
boolean enabled) {
jni_YGSetExperimentalFeatureEnabled(feature.intValue(), enabled);
}
private static native boolean jni_YGIsExperimentalFeatureEnabled(int feature);
public static boolean isExperimentalFeatureEnabled(YogaExperimentalFeature feature) {
return jni_YGIsExperimentalFeatureEnabled(feature.intValue());
}
private YogaNode mParent; private YogaNode mParent;
private List<YogaNode> mChildren; private List<YogaNode> mChildren;
private YogaMeasureFunction mMeasureFunction; private YogaMeasureFunction mMeasureFunction;
@ -104,6 +90,14 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
} }
} }
private native long jni_YGNodeNewWithConfig(long configPointer);
public YogaNode(YogaConfig config) {
mNativePointer = jni_YGNodeNewWithConfig(config.mNativePointer);
if (mNativePointer == 0) {
throw new IllegalStateException("Failed to allocate native memory");
}
}
private native void jni_YGNodeFree(long nativePointer); private native void jni_YGNodeFree(long nativePointer);
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {

View File

@ -150,6 +150,10 @@ static inline YGNodeRef _jlong2YGNodeRef(jlong addr) {
return reinterpret_cast<YGNodeRef>(static_cast<intptr_t>(addr)); return reinterpret_cast<YGNodeRef>(static_cast<intptr_t>(addr));
} }
static inline YGConfigRef _jlong2YGConfigRef(jlong addr) {
return reinterpret_cast<YGConfigRef>(static_cast<intptr_t>(addr));
}
void jni_YGSetLogger(alias_ref<jclass> clazz, alias_ref<jobject> logger) { void jni_YGSetLogger(alias_ref<jclass> clazz, alias_ref<jobject> logger) {
if (jLogger) { if (jLogger) {
jLogger->releaseAlias(); jLogger->releaseAlias();
@ -171,18 +175,6 @@ void jni_YGLog(alias_ref<jclass> clazz, jint level, jstring message) {
Environment::current()->ReleaseStringUTFChars(message, nMessage); Environment::current()->ReleaseStringUTFChars(message, nMessage);
} }
void jni_YGSetExperimentalFeatureEnabled(alias_ref<jclass> clazz, jint feature, jboolean enabled) {
YGSetExperimentalFeatureEnabled(static_cast<YGExperimentalFeature>(feature), enabled);
}
jboolean jni_YGIsExperimentalFeatureEnabled(alias_ref<jclass> clazz, jint feature) {
return YGIsExperimentalFeatureEnabled(static_cast<YGExperimentalFeature>(feature));
}
jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
return YGNodeGetInstanceCount();
}
jlong jni_YGNodeNew(alias_ref<jobject> thiz) { jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
const YGNodeRef node = YGNodeNew(); const YGNodeRef node = YGNodeNew();
YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz))); YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz)));
@ -190,6 +182,13 @@ jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
return reinterpret_cast<jlong>(node); return reinterpret_cast<jlong>(node);
} }
jlong jni_YGNodeNewWithConfig(alias_ref<jobject> thiz, jlong configPointer) {
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz)));
YGNodeSetPrintFunc(node, YGPrint);
return reinterpret_cast<jlong>(node);
}
void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) { void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer); const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
delete YGNodeJobject(node); delete YGNodeJobject(node);
@ -368,6 +367,24 @@ YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight);
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification
YG_NODE_JNI_STYLE_PROP(jfloat, float, AspectRatio); YG_NODE_JNI_STYLE_PROP(jfloat, float, AspectRatio);
jlong jni_YGConfigNew(alias_ref<jobject>) {
return reinterpret_cast<jlong>(YGConfigNew());
}
void jni_YGConfigFree(alias_ref<jobject>, jlong nativePointer) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigFree(config);
}
void jni_YGConfigSetExperimentalFeatureEnabled(alias_ref<jobject>, jlong nativePointer, jint feature, jboolean enabled) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetExperimentalFeatureEnabled(config, static_cast<YGExperimentalFeature>(feature), enabled);
}
jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
return YGNodeGetInstanceCount();
}
#define YGMakeNativeMethod(name) makeNativeMethod(#name, name) #define YGMakeNativeMethod(name) makeNativeMethod(#name, name)
jint JNI_OnLoad(JavaVM *vm, void *) { jint JNI_OnLoad(JavaVM *vm, void *) {
@ -375,6 +392,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
registerNatives("com/facebook/yoga/YogaNode", registerNatives("com/facebook/yoga/YogaNode",
{ {
YGMakeNativeMethod(jni_YGNodeNew), YGMakeNativeMethod(jni_YGNodeNew),
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
YGMakeNativeMethod(jni_YGNodeFree), YGMakeNativeMethod(jni_YGNodeFree),
YGMakeNativeMethod(jni_YGNodeReset), YGMakeNativeMethod(jni_YGNodeReset),
YGMakeNativeMethod(jni_YGNodeInsertChild), YGMakeNativeMethod(jni_YGNodeInsertChild),
@ -452,8 +470,12 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGNodeGetInstanceCount), YGMakeNativeMethod(jni_YGNodeGetInstanceCount),
YGMakeNativeMethod(jni_YGSetLogger), YGMakeNativeMethod(jni_YGSetLogger),
YGMakeNativeMethod(jni_YGLog), YGMakeNativeMethod(jni_YGLog),
YGMakeNativeMethod(jni_YGSetExperimentalFeatureEnabled), });
YGMakeNativeMethod(jni_YGIsExperimentalFeatureEnabled), registerNatives("com/facebook/yoga/YogaConfig",
{
YGMakeNativeMethod(jni_YGConfigNew),
YGMakeNativeMethod(jni_YGConfigFree),
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled),
}); });
}); });
} }

View File

@ -94,6 +94,8 @@ typedef struct YGStyle {
float aspectRatio; float aspectRatio;
} YGStyle; } YGStyle;
typedef struct YGConfig { bool experimentalFeatures[YGExperimentalFeatureCount + 1]; } YGConfig;
typedef struct YGNode { typedef struct YGNode {
YGStyle style; YGStyle style;
YGLayout layout; YGLayout layout;
@ -107,6 +109,7 @@ typedef struct YGNode {
YGMeasureFunc measure; YGMeasureFunc measure;
YGBaselineFunc baseline; YGBaselineFunc baseline;
YGPrintFunc print; YGPrintFunc print;
YGConfigRef config;
void *context; void *context;
bool isDirty; bool isDirty;
@ -191,6 +194,14 @@ static YGNode gYGNodeDefaults = {
}, },
}; };
static YGConfig gYGConfigDefaults = {
.experimentalFeatures =
{
[YGExperimentalFeatureRounding] = false,
[YGExperimentalFeatureWebFlexBasis] = false,
},
};
static void YGNodeMarkDirtyInternal(const YGNodeRef node); static void YGNodeMarkDirtyInternal(const YGNodeRef node);
YGMalloc gYGMalloc = &malloc; YGMalloc gYGMalloc = &malloc;
@ -290,15 +301,21 @@ static inline float YGValueResolveMargin(const YGValue *const value, const float
int32_t gNodeInstanceCount = 0; int32_t gNodeInstanceCount = 0;
YGNodeRef YGNodeNew(void) {
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
const YGNodeRef node = gYGMalloc(sizeof(YGNode)); const YGNodeRef node = gYGMalloc(sizeof(YGNode));
YG_ASSERT(node, "Could not allocate memory for node"); YG_ASSERT(node, "Could not allocate memory for node");
gNodeInstanceCount++; gNodeInstanceCount++;
memcpy(node, &gYGNodeDefaults, sizeof(YGNode)); memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
node->config = config;
return node; return node;
} }
YGNodeRef YGNodeNew(void) {
return YGNodeNewWithConfig(&gYGConfigDefaults);
}
void YGNodeFree(const YGNodeRef node) { void YGNodeFree(const YGNodeRef node) {
if (node->parent) { if (node->parent) {
YGNodeListDelete(node->parent->children, node); YGNodeListDelete(node->parent->children, node);
@ -331,13 +348,27 @@ void YGNodeReset(const YGNodeRef node) {
YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent"); YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent");
YGNodeListFree(node->children); YGNodeListFree(node->children);
const YGConfigRef config = node->config;
memcpy(node, &gYGNodeDefaults, sizeof(YGNode)); memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
node->config = config;
} }
int32_t YGNodeGetInstanceCount(void) { int32_t YGNodeGetInstanceCount(void) {
return gNodeInstanceCount; return gNodeInstanceCount;
} }
YGConfigRef YGConfigNew(void) {
const YGConfigRef config = gYGMalloc(sizeof(YGConfig));
YG_ASSERT(config, "Could not allocate memory for config");
memcpy(config, &gYGConfigDefaults, sizeof(YGConfig));
return config;
}
void YGConfigFree(const YGConfigRef config) {
gYGFree(config);
}
static void YGNodeMarkDirtyInternal(const YGNodeRef node) { static void YGNodeMarkDirtyInternal(const YGNodeRef node) {
if (!node->isDirty) { if (!node->isDirty) {
node->isDirty = true; node->isDirty = true;
@ -678,7 +709,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
const float parentWidth, const float parentWidth,
const float parentHeight, const float parentHeight,
const bool performLayout, const bool performLayout,
const char *reason); const char *reason,
const YGConfigRef config);
inline bool YGFloatIsUndefined(const float value) { inline bool YGFloatIsUndefined(const float value) {
return isnan(value); return isnan(value);
@ -1335,7 +1367,8 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
const float parentWidth, const float parentWidth,
const float parentHeight, const float parentHeight,
const YGMeasureMode heightMode, const YGMeasureMode heightMode,
const YGDirection direction) { const YGDirection direction,
const YGConfigRef config) {
const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction); const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const float mainAxisSize = isMainAxisRow ? width : height; const float mainAxisSize = isMainAxisRow ? width : height;
@ -1354,7 +1387,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (!YGFloatIsUndefined(resolvedFlexBasis) && !YGFloatIsUndefined(mainAxisSize)) { if (!YGFloatIsUndefined(resolvedFlexBasis) && !YGFloatIsUndefined(mainAxisSize)) {
if (YGFloatIsUndefined(child->layout.computedFlexBasis) || if (YGFloatIsUndefined(child->layout.computedFlexBasis) ||
(YGIsExperimentalFeatureEnabled(YGExperimentalFeatureWebFlexBasis) && (YGConfigIsExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis) &&
child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) { child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(resolvedFlexBasis, YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)); fmaxf(resolvedFlexBasis, YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth));
@ -1456,7 +1489,8 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
parentWidth, parentWidth,
parentHeight, parentHeight,
false, false,
"measure"); "measure",
config);
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(child->layout.measuredDimensions[dim[mainAxis]], fmaxf(child->layout.measuredDimensions[dim[mainAxis]],
@ -1471,7 +1505,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
const float width, const float width,
const YGMeasureMode widthMode, const YGMeasureMode widthMode,
const float height, const float height,
const YGDirection direction) { const YGDirection direction,
const YGConfigRef config) {
const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction); const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction);
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
@ -1560,7 +1595,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
childWidth, childWidth,
childHeight, childHeight,
false, false,
"abs-measure"); "abs-measure",
config);
childWidth = child->layout.measuredDimensions[YGDimensionWidth] + childWidth = child->layout.measuredDimensions[YGDimensionWidth] +
YGNodeMarginForAxis(child, YGFlexDirectionRow, width); YGNodeMarginForAxis(child, YGFlexDirectionRow, width);
childHeight = child->layout.measuredDimensions[YGDimensionHeight] + childHeight = child->layout.measuredDimensions[YGDimensionHeight] +
@ -1576,7 +1612,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
childWidth, childWidth,
childHeight, childHeight,
true, true,
"abs-layout"); "abs-layout",
config);
if (YGNodeIsTrailingPosDefined(child, mainAxis) && !YGNodeIsLeadingPosDefined(child, mainAxis)) { if (YGNodeIsTrailingPosDefined(child, mainAxis) && !YGNodeIsLeadingPosDefined(child, mainAxis)) {
child->layout.position[leading[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] - child->layout.position[leading[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] -
@ -1854,7 +1891,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const YGMeasureMode heightMeasureMode, const YGMeasureMode heightMeasureMode,
const float parentWidth, const float parentWidth,
const float parentHeight, const float parentHeight,
const bool performLayout) { const bool performLayout,
const YGConfigRef config) {
YG_ASSERT(YGFloatIsUndefined(availableWidth) ? widthMeasureMode == YGMeasureModeUndefined : true, YG_ASSERT(YGFloatIsUndefined(availableWidth) ? widthMeasureMode == YGMeasureModeUndefined : true,
"availableWidth is indefinite so widthMeasureMode must be " "availableWidth is indefinite so widthMeasureMode must be "
"YGMeasureModeUndefined"); "YGMeasureModeUndefined");
@ -2056,7 +2094,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
availableInnerHeight, availableInnerHeight,
heightMeasureMode, heightMeasureMode,
direction); direction,
config);
} }
} }
@ -2173,7 +2212,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerMainDim = minInnerMainDim; availableInnerMainDim = minInnerMainDim;
} else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) { } else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) {
availableInnerMainDim = maxInnerMainDim; availableInnerMainDim = maxInnerMainDim;
} else if (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix)) { } else if (YGConfigIsExperimentalFeatureEnabled(config, YGExperimentalFeatureMinFlexFix)) {
// TODO: this needs to be moved out of experimental feature, as this is legitimate fix // TODO: this needs to be moved out of experimental feature, as this is legitimate fix
// If the measurement isn't exact, we want to use as little space as possible // If the measurement isn't exact, we want to use as little space as possible
availableInnerMainDim = sizeConsumedOnCurrentLine; availableInnerMainDim = sizeConsumedOnCurrentLine;
@ -2422,7 +2461,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
availableInnerHeight, availableInnerHeight,
performLayout && !requiresStretchLayout, performLayout && !requiresStretchLayout,
"flex"); "flex",
config);
currentRelativeChild = currentRelativeChild->nextChild; currentRelativeChild = currentRelativeChild->nextChild;
} }
@ -2660,7 +2700,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
availableInnerHeight, availableInnerHeight,
true, true,
"stretch"); "stretch",
config);
} }
} else { } else {
const float remainingCrossDim = const float remainingCrossDim =
@ -2827,7 +2868,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
availableInnerHeight, availableInnerHeight,
true, true,
"stretch"); "stretch",
config);
} }
} }
break; break;
@ -2915,7 +2957,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
isMainAxisRow ? measureModeMainDim : measureModeCrossDim, isMainAxisRow ? measureModeMainDim : measureModeCrossDim,
availableInnerHeight, availableInnerHeight,
direction); direction,
config);
} }
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
@ -3057,7 +3100,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
const float parentWidth, const float parentWidth,
const float parentHeight, const float parentHeight,
const bool performLayout, const bool performLayout,
const char *reason) { const char *reason,
const YGConfigRef config) {
YGLayout *layout = &node->layout; YGLayout *layout = &node->layout;
gDepth++; gDepth++;
@ -3186,7 +3230,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
heightMeasureMode, heightMeasureMode,
parentWidth, parentWidth,
parentHeight, parentHeight,
performLayout); performLayout,
config);
if (gPrintChanges) { if (gPrintChanges) {
printf("%s%d.}%s", YGSpacer(gDepth), gDepth, needToVisitNode ? "*" : ""); printf("%s%d.}%s", YGSpacer(gDepth), gDepth, needToVisitNode ? "*" : "");
@ -3352,11 +3397,11 @@ void YGNodeCalculateLayout(const YGNodeRef node,
parentWidth, parentWidth,
parentHeight, parentHeight,
true, true,
"initia" "initial",
"l")) { node->config)) {
YGNodeSetPosition(node, node->layout.direction, node->layout.dimensions[YGDimensionWidth], node->layout.dimensions[YGDimensionHeight], parentWidth); YGNodeSetPosition(node, node->layout.direction, parentWidth, parentHeight, parentWidth);
if (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureRounding)) { if (YGConfigIsExperimentalFeatureEnabled(node->config, YGExperimentalFeatureRounding)) {
YGRoundToPixelGrid(node); YGRoundToPixelGrid(node);
} }
@ -3377,14 +3422,15 @@ void YGLog(YGLogLevel level, const char *format, ...) {
va_end(args); va_end(args);
} }
static bool experimentalFeatures[YGExperimentalFeatureCount + 1]; void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config,
const YGExperimentalFeature feature,
void YGSetExperimentalFeatureEnabled(YGExperimentalFeature feature, bool enabled) { const bool enabled) {
experimentalFeatures[feature] = enabled; config->experimentalFeatures[feature] = enabled;
} }
inline bool YGIsExperimentalFeatureEnabled(YGExperimentalFeature feature) { inline bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
return experimentalFeatures[feature]; const YGExperimentalFeature feature) {
return config->experimentalFeatures[feature];
} }
void YGSetMemoryFuncs(YGMalloc ygmalloc, YGCalloc yccalloc, YGRealloc ygrealloc, YGFree ygfree) { void YGSetMemoryFuncs(YGMalloc ygmalloc, YGCalloc yccalloc, YGRealloc ygrealloc, YGFree ygfree) {

View File

@ -46,6 +46,7 @@ typedef struct YGValue {
static const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; static const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined};
static const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; static const YGValue YGValueAuto = {YGUndefined, YGUnitAuto};
typedef struct YGConfig *YGConfigRef;
typedef struct YGNode *YGNodeRef; typedef struct YGNode *YGNodeRef;
typedef YGSize (*YGMeasureFunc)(YGNodeRef node, typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
float width, float width,
@ -63,6 +64,7 @@ typedef void (*YGFree)(void *ptr);
// YGNode // YGNode
WIN_EXPORT YGNodeRef YGNodeNew(void); WIN_EXPORT YGNodeRef YGNodeNew(void);
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config);
WIN_EXPORT void YGNodeFree(const YGNodeRef node); WIN_EXPORT void YGNodeFree(const YGNodeRef node);
WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node); WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node);
WIN_EXPORT void YGNodeReset(const YGNodeRef node); WIN_EXPORT void YGNodeReset(const YGNodeRef node);
@ -223,8 +225,15 @@ WIN_EXPORT void YGLog(YGLogLevel level, const char *message, ...);
// If you want to avoid rounding - set PointScaleFactor to 0 // If you want to avoid rounding - set PointScaleFactor to 0
WIN_EXPORT void YGSetPointScaleFactor(float pixelsInPoint); WIN_EXPORT void YGSetPointScaleFactor(float pixelsInPoint);
WIN_EXPORT void YGSetExperimentalFeatureEnabled(YGExperimentalFeature feature, bool enabled); // YGConfig
WIN_EXPORT bool YGIsExperimentalFeatureEnabled(YGExperimentalFeature feature); WIN_EXPORT YGConfigRef YGConfigNew(void);
WIN_EXPORT void YGConfigFree(const YGConfigRef config);
WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(const YGConfigRef config,
const YGExperimentalFeature feature,
const bool enabled);
WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
const YGExperimentalFeature feature);
WIN_EXPORT void WIN_EXPORT void
YGSetMemoryFuncs(YGMalloc ygmalloc, YGCalloc yccalloc, YGRealloc ygrealloc, YGFree ygfree); YGSetMemoryFuncs(YGMalloc ygmalloc, YGCalloc yccalloc, YGRealloc ygrealloc, YGFree ygfree);