diff --git a/.gitignore b/.gitignore index a344606..0e86cf6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ /buck-out/ /.buckconfig.local /.buckd -/lib/gtest/googletest-*/ /gentest/test.html # Visual studio code diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..16b40a6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/gtest/googletest"] + path = lib/gtest/googletest + url = https://github.com/google/googletest.git diff --git a/.hgignore b/.hgignore index 875f1d7..5b34676 100644 --- a/.hgignore +++ b/.hgignore @@ -4,8 +4,7 @@ /buck-out/ /.buckconfig.local /.buckd -/lib/gtest/googletest-*/ /gentest/test.html # Visual studio code -.vscode \ No newline at end of file +.vscode diff --git a/.travis.yml b/.travis.yml index 5e20510..f74b3aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,12 +14,17 @@ before_install: - brew update - brew tap facebook/fb - brew install buck + - brew cask install java - brew outdated xctool || brew upgrade xctool + - brew install mono + - export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) + - export PATH=$JAVA_HOME/bin:$PATH script: - buck test //:CSSLayout - buck test //java:java - - buck test //uikit/CSSLayout:CSSLayout - - buck run //benchmark:benchmark + - buck test //CSSLayoutKit:CSSLayoutKit --config cxx.default_platform=iphonesimulator-x86_64 --config cxx.cflags=-DTRAVIS_CI + - sh csharp/tests/Facebook.CSSLayout/test_macos.sh + - buck run //benchmark:benchmark - git checkout HEAD^ - - buck run //benchmark:benchmark + - buck run //benchmark:benchmark diff --git a/CSSLAYOUT_DEFS b/CSSLAYOUT_DEFS index c73f54f..91d372a 100644 --- a/CSSLAYOUT_DEFS +++ b/CSSLAYOUT_DEFS @@ -6,8 +6,8 @@ JUNIT_TARGET = '//lib/junit:junit' PROGRUARD_ANNOTATIONS_TARGET = '//java/com/facebook/proguard/annotations:annotations' SOLOADER_TARGET = '//lib/soloader:soloader' GTEST_TARGET = '//lib/gtest:gtest' -GTEST_DL_URL = 'https://github.com/google/googletest/archive/release-1.7.0.zip' -JNI_DEPS = ['//lib/fb:fbjni'] +JNI_TARGET = '//lib/jni:jni' +FBJNI_TARGET = '//lib/fb:fbjni' CXX_LIBRARY_WHITELIST = [ '//lib/fb:fbjni', diff --git a/CSSLayout/CSSEnums.h b/CSSLayout/CSSEnums.h new file mode 100644 index 0000000..8f9979f --- /dev/null +++ b/CSSLayout/CSSEnums.h @@ -0,0 +1,106 @@ +/** + * 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. + */ + +typedef enum CSSOverflow { + CSSOverflowVisible, + CSSOverflowHidden, + CSSOverflowScroll, + CSSOverflowCount, +} CSSOverflow; + +typedef enum CSSJustify { + CSSJustifyFlexStart, + CSSJustifyCenter, + CSSJustifyFlexEnd, + CSSJustifySpaceBetween, + CSSJustifySpaceAround, + CSSJustifyCount, +} CSSJustify; + +typedef enum CSSFlexDirection { + CSSFlexDirectionColumn, + CSSFlexDirectionColumnReverse, + CSSFlexDirectionRow, + CSSFlexDirectionRowReverse, + CSSFlexDirectionCount, +} CSSFlexDirection; + +typedef enum CSSAlign { + CSSAlignAuto, + CSSAlignFlexStart, + CSSAlignCenter, + CSSAlignFlexEnd, + CSSAlignStretch, + CSSAlignCount, +} CSSAlign; + +typedef enum CSSEdge { + CSSEdgeLeft, + CSSEdgeTop, + CSSEdgeRight, + CSSEdgeBottom, + CSSEdgeStart, + CSSEdgeEnd, + CSSEdgeHorizontal, + CSSEdgeVertical, + CSSEdgeAll, + CSSEdgeCount, +} CSSEdge; + +typedef enum CSSWrap { + CSSWrapNoWrap, + CSSWrapWrap, + CSSWrapCount, +} CSSWrap; + +typedef enum CSSDirection { + CSSDirectionInherit, + CSSDirectionLTR, + CSSDirectionRTL, + CSSDirectionCount, +} CSSDirection; + +typedef enum CSSExperimentalFeature { + CSSExperimentalFeatureCount, +} CSSExperimentalFeature; + +typedef enum CSSLogLevel { + CSSLogLevelError, + CSSLogLevelWarn, + CSSLogLevelInfo, + CSSLogLevelDebug, + CSSLogLevelVerbose, + CSSLogLevelCount, +} CSSLogLevel; + +typedef enum CSSDimension { + CSSDimensionWidth, + CSSDimensionHeight, + CSSDimensionCount, +} CSSDimension; + +typedef enum CSSMeasureMode { + CSSMeasureModeUndefined, + CSSMeasureModeExactly, + CSSMeasureModeAtMost, + CSSMeasureModeCount, +} CSSMeasureMode; + +typedef enum CSSPositionType { + CSSPositionTypeRelative, + CSSPositionTypeAbsolute, + CSSPositionTypeCount, +} CSSPositionType; + +typedef enum CSSPrintOptions { + CSSPrintOptionsLayout = 1, + CSSPrintOptionsStyle = 2, + CSSPrintOptionsChildren = 4, + CSSPrintOptionsCount, +} CSSPrintOptions; diff --git a/CSSLayout/CSSLayout.cpp b/CSSLayout/CSSLayout.cpp index c71ac40..2f9a1ae 100644 --- a/CSSLayout/CSSLayout.cpp +++ b/CSSLayout/CSSLayout.cpp @@ -14,7 +14,9 @@ #ifdef _MSC_VER #include +#ifndef isnan #define isnan _isnan +#endif #ifndef __cplusplus #define inline __inline @@ -29,7 +31,6 @@ __forceinline const float fmaxf(const float a, const float b) { return (a > b) ? a : b; } - // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 __forceinline const float fminf(const float a, const float b) { return (a < b) ? a : b; @@ -45,7 +46,6 @@ __forceinline const float fminf(const float a, const float b) { #include #define isnan std::isnan #endif -// END_UNITY typedef struct CSSCachedMeasurement { float availableWidth; @@ -66,6 +66,7 @@ typedef struct CSSLayout { float dimensions[2]; CSSDirection direction; + uint32_t computedFlexBasisGeneration; float computedFlexBasis; // Instead of recomputing the entire layout every single time, we @@ -88,10 +89,7 @@ typedef struct CSSStyle { CSSAlign alignItems; CSSAlign alignSelf; CSSPositionType positionType; - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSWrapType flexWrap; CSSWrap flexWrap; -// END_UNITY CSSOverflow overflow; float flex; float flexGrow; @@ -124,12 +122,17 @@ typedef struct CSSNode { static void _CSSNodeMarkDirty(const CSSNodeRef node); +CSSMalloc gCSSMalloc = &malloc; +CSSCalloc gCSSCalloc = &calloc; +CSSRealloc gCSSRealloc = &realloc; +CSSFree gCSSFree = &free; + #ifdef ANDROID #include static int _csslayoutAndroidLog(CSSLogLevel level, const char *format, va_list args) { int androidLevel = CSSLogLevelDebug; switch (level) { - case CSSLogLevelError: + case CSSLogLevelError: androidLevel = ANDROID_LOG_ERROR; break; case CSSLogLevelWarn: @@ -138,12 +141,14 @@ static int _csslayoutAndroidLog(CSSLogLevel level, const char *format, va_list a case CSSLogLevelInfo: androidLevel = ANDROID_LOG_INFO; break; - case CSSLogLevelDebug: + case CSSLogLevelDebug: androidLevel = ANDROID_LOG_DEBUG; break; case CSSLogLevelVerbose: androidLevel = ANDROID_LOG_VERBOSE; break; + case CSSLogLevelCount: + break; } const int result = __android_log_vprint(androidLevel, "css-layout", format, args); return result; @@ -152,11 +157,11 @@ static CSSLogger gLogger = &_csslayoutAndroidLog; #else static int _csslayoutDefaultLog(CSSLogLevel level, const char *format, va_list args) { switch (level) { - case CSSLogLevelError: + case CSSLogLevelError: return vfprintf(stderr, format, args); case CSSLogLevelWarn: case CSSLogLevelInfo: - case CSSLogLevelDebug: + case CSSLogLevelDebug: case CSSLogLevelVerbose: default: return vprintf(format, args); @@ -195,12 +200,12 @@ static inline float computedEdgeValue(const float edges[CSSEdgeCount], return defaultValue; } -static int32_t gNodeInstanceCount = 0; +int32_t gNodeInstanceCount = 0; CSSNodeRef CSSNodeNew(void) { // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 -// const CSSNodeRef node = calloc(1, sizeof(CSSNode)); - const CSSNodeRef node = (CSSNodeRef)calloc(1, sizeof(CSSNode)); +// const CSSNodeRef node = gCSSCalloc(1, sizeof(CSSNode)); + const CSSNodeRef node = (CSSNodeRef)gCSSCalloc(1, sizeof(CSSNode)); // END_UNITY CSS_ASSERT(node, "Could not allocate memory for node"); gNodeInstanceCount++; @@ -222,7 +227,7 @@ void CSSNodeFree(const CSSNodeRef node) { } CSSNodeListFree(node->children); - free(node); + gCSSFree(node); gNodeInstanceCount--; } @@ -314,11 +319,11 @@ static void _CSSNodeMarkDirty(const CSSNodeRef node) { } void CSSNodeSetMeasureFunc(const CSSNodeRef node, CSSMeasureFunc measureFunc) { - // You can always NULLify the measure function of a node. if (measureFunc == NULL) { node->measure = NULL; } else { - CSS_ASSERT(CSSNodeChildCount(node) == 0, "Cannot set measure function: Nodes with measure functions cannot have children."); + CSS_ASSERT(CSSNodeChildCount(node) == 0, + "Cannot set measure function: Nodes with measure functions cannot have children."); node->measure = measureFunc; } } @@ -329,7 +334,8 @@ CSSMeasureFunc CSSNodeGetMeasureFunc(const CSSNodeRef node) { void CSSNodeInsertChild(const CSSNodeRef node, const CSSNodeRef child, const uint32_t index) { CSS_ASSERT(child->parent == NULL, "Child already has a parent, it must be removed first."); - CSS_ASSERT(node->measure == NULL, "Cannot add child: Nodes with measure functions cannot have children."); + CSS_ASSERT(node->measure == NULL, + "Cannot add child: Nodes with measure functions cannot have children."); CSSNodeListInsert(&node->children, child, index); child->parent = node; _CSSNodeMarkDirty(node); @@ -364,9 +370,16 @@ bool CSSNodeIsDirty(const CSSNodeRef node) { return node->isDirty; } +void CSSNodeCopyStyle(const CSSNodeRef dstNode, const CSSNodeRef srcNode) { + if (memcmp(&dstNode->style, &srcNode->style, sizeof(CSSStyle)) != 0) { + memcpy(&dstNode->style, &srcNode->style, sizeof(CSSStyle)); + _CSSNodeMarkDirty(dstNode); + } +} + // BEGIN_UNITY @antoine 11-14-2016 CompileForVS2010 -// inline float CSSNodeStyleGetFlexGrow(CSSNodeRef node) { -float CSSNodeStyleGetFlexGrow(CSSNodeRef node) { +// inline float CSSNodeStyleGetFlexGrow(const CSSNodeRef node) { +float CSSNodeStyleGetFlexGrow(const CSSNodeRef node) { // END_UNITY if (!CSSValueIsUndefined(node->style.flexGrow)) { return node->style.flexGrow; @@ -378,8 +391,8 @@ float CSSNodeStyleGetFlexGrow(CSSNodeRef node) { } // BEGIN_UNITY @antoine 11-14-2016 CompileForVS2010 -// inline float CSSNodeStyleGetFlexShrink(CSSNodeRef node) { -float CSSNodeStyleGetFlexShrink(CSSNodeRef node) { +// inline float CSSNodeStyleGetFlexShrink(const CSSNodeRef node) { +float CSSNodeStyleGetFlexShrink(const CSSNodeRef node) { // END_UNITY if (!CSSValueIsUndefined(node->style.flexShrink)) { return node->style.flexShrink; @@ -391,8 +404,8 @@ float CSSNodeStyleGetFlexShrink(CSSNodeRef node) { } // BEGIN_UNITY @antoine 11-14-2016 CompileForVS2010 -// inline float CSSNodeStyleGetFlexBasis(CSSNodeRef node) { -float CSSNodeStyleGetFlexBasis(CSSNodeRef node) { +// inline float CSSNodeStyleGetFlexBasis(const CSSNodeRef node) { +float CSSNodeStyleGetFlexBasis(const CSSNodeRef node) { // END_UNITY if (!CSSValueIsUndefined(node->style.flexBasis)) { return node->style.flexBasis; @@ -462,10 +475,7 @@ CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignContent, alignContent, alignContent) CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignItems, alignItems, alignItems); CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignSelf, alignSelf, alignSelf); CSS_NODE_STYLE_PROPERTY_IMPL(CSSPositionType, PositionType, positionType, positionType); -// BEGIN_UNITY @joce 11-01-2016 CompileForC# -//CSS_NODE_STYLE_PROPERTY_IMPL(CSSWrapType, FlexWrap, flexWrap, flexWrap); CSS_NODE_STYLE_PROPERTY_IMPL(CSSWrap, FlexWrap, flexWrap, flexWrap); -// END_UNITY CSS_NODE_STYLE_PROPERTY_IMPL(CSSOverflow, Overflow, overflow, overflow); CSS_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexGrow, flexGrow, flexGrow); @@ -701,7 +711,7 @@ static void _CSSNodePrint(const CSSNodeRef node, //void CSSNodePrint(const CSSNodeRef node, const CSSPrintOptions options) { void CSSNodePrint(const CSSNodeRef node, const int options) { // END_UNITY - _CSSNodePrint(node, options, 0); + _CSSNodePrint(node, options, 0); } static const CSSEdge leading[4] = { @@ -978,6 +988,23 @@ static float getRelativePosition(const CSSNodeRef node, const CSSFlexDirection a : -getTrailingPosition(node, axis); } +static void constrainMaxSizeForMode(const float maxSize, CSSMeasureMode *mode, float *size) { + switch (*mode) { + case CSSMeasureModeExactly: + case CSSMeasureModeAtMost: + *size = (CSSValueIsUndefined(maxSize) || *size < maxSize) ? *size : maxSize; + break; + case CSSMeasureModeUndefined: + if (!CSSValueIsUndefined(maxSize)) { + *mode = CSSMeasureModeAtMost; + *size = maxSize; + } + break; + case CSSMeasureModeCount: + break; + } +} + static void setPosition(const CSSNodeRef node, const CSSDirection direction) { const CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction); const CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); @@ -1014,7 +1041,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, if (!CSSValueIsUndefined(CSSNodeStyleGetFlexBasis(child)) && !CSSValueIsUndefined(isMainAxisRow ? width : height)) { - if (CSSValueIsUndefined(child->layout.computedFlexBasis)) { + if (CSSValueIsUndefined(child->layout.computedFlexBasis) || + child->layout.computedFlexBasisGeneration != gCurrentGenerationCount) { child->layout.computedFlexBasis = fmaxf(CSSNodeStyleGetFlexBasis(child), getPaddingAndBorderAxis(child, mainAxis)); } @@ -1077,15 +1105,12 @@ static void computeChildFlexBasis(const CSSNodeRef node, childHeightMeasureMode = CSSMeasureModeExactly; } - if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionWidth])) { - childWidth = child->style.maxDimensions[CSSDimensionWidth]; - childWidthMeasureMode = CSSMeasureModeAtMost; - } - - if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionHeight])) { - childHeight = child->style.maxDimensions[CSSDimensionHeight]; - childHeightMeasureMode = CSSMeasureModeAtMost; - } + constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth], + &childWidthMeasureMode, + &childWidth); + constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionHeight], + &childHeightMeasureMode, + &childHeight); // Measure the child layoutNodeInternal(child, @@ -1102,6 +1127,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, : child->layout.measuredDimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, mainAxis)); } + + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; } static void absoluteLayoutChild(const CSSNodeRef node, @@ -1196,12 +1223,14 @@ static void absoluteLayoutChild(const CSSNodeRef node, if (isTrailingPosDefined(child, mainAxis) && !isLeadingPosDefined(child, mainAxis)) { child->layout.position[leading[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] - child->layout.measuredDimensions[dim[mainAxis]] - + getTrailingBorder(node, mainAxis) - getTrailingPosition(child, mainAxis); } if (isTrailingPosDefined(child, crossAxis) && !isLeadingPosDefined(child, crossAxis)) { child->layout.position[leading[crossAxis]] = node->layout.measuredDimensions[dim[crossAxis]] - child->layout.measuredDimensions[dim[crossAxis]] - + getTrailingBorder(node, crossAxis) - getTrailingPosition(child, crossAxis); } } @@ -1459,10 +1488,7 @@ static void layoutNodeImpl(const CSSNodeRef node, const CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); const bool isMainAxisRow = isRowDirection(mainAxis); const CSSJustify justifyContent = node->style.justifyContent; - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// const bool isNodeFlexWrap = node->style.flexWrap == CSSWrapTypeWrap; const bool isNodeFlexWrap = node->style.flexWrap == CSSWrapWrap; - // END_UNITY CSSNodeRef firstAbsoluteChild = NULL; CSSNodeRef currentAbsoluteChild = NULL; @@ -1483,6 +1509,26 @@ static void layoutNodeImpl(const CSSNodeRef node, const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; + // If there is only one child with flexGrow + flexShrink it means we can set the + // computedFlexBasis to 0 instead of measuring and shrinking / flexing the child to exactly + // match the remaining space + CSSNodeRef singleFlexChild = NULL; + if ((isMainAxisRow && widthMeasureMode == CSSMeasureModeExactly) || + (!isMainAxisRow && heightMeasureMode == CSSMeasureModeExactly)) { + for (uint32_t i = 0; i < childCount; i++) { + const CSSNodeRef child = CSSNodeGetChild(node, i); + if (singleFlexChild) { + if (isFlex(child)) { + // There is already a flexible child, abort. + singleFlexChild = NULL; + break; + } + } else if (CSSNodeStyleGetFlexGrow(child) > 0 && CSSNodeStyleGetFlexShrink(child) > 0) { + singleFlexChild = child; + } + } + } + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM for (uint32_t i = 0; i < childCount; i++) { const CSSNodeRef child = CSSNodeListGet(node->children, i); @@ -1507,13 +1553,18 @@ static void layoutNodeImpl(const CSSNodeRef node, currentAbsoluteChild = child; child->nextChild = NULL; } else { - computeChildFlexBasis(node, - child, - availableInnerWidth, - widthMeasureMode, - availableInnerHeight, - heightMeasureMode, - direction); + if (child == singleFlexChild) { + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; + child->layout.computedFlexBasis = 0; + } else { + computeChildFlexBasis(node, + child, + availableInnerWidth, + widthMeasureMode, + availableInnerHeight, + heightMeasureMode, + direction); + } } } @@ -1796,15 +1847,12 @@ static void layoutNodeImpl(const CSSNodeRef node, } } - if (!CSSValueIsUndefined(currentRelativeChild->style.maxDimensions[CSSDimensionWidth])) { - childWidth = currentRelativeChild->style.maxDimensions[CSSDimensionWidth]; - childWidthMeasureMode = CSSMeasureModeAtMost; - } - - if (!CSSValueIsUndefined(currentRelativeChild->style.maxDimensions[CSSDimensionHeight])) { - childHeight = currentRelativeChild->style.maxDimensions[CSSDimensionHeight]; - childHeightMeasureMode = CSSMeasureModeAtMost; - } + constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionWidth], + &childWidthMeasureMode, + &childWidth); + constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionHeight], + &childHeightMeasureMode, + &childHeight); const bool requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && @@ -1842,14 +1890,9 @@ static void layoutNodeImpl(const CSSNodeRef node, if (measureModeMainDim == CSSMeasureModeAtMost && remainingFreeSpace > 0) { if (!CSSValueIsUndefined(node->style.minDimensions[dim[mainAxis]]) && node->style.minDimensions[dim[mainAxis]] >= 0) { - // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 -// remainingFreeSpace = fmax(0, -// node->style.minDimensions[dim[mainAxis]] - -// (availableInnerMainDim - remainingFreeSpace)); remainingFreeSpace = fmaxf(0, - node->style.minDimensions[dim[mainAxis]] - - (availableInnerMainDim - remainingFreeSpace)); - // END_UNITY + node->style.minDimensions[dim[mainAxis]] - + (availableInnerMainDim - remainingFreeSpace)); } else { remainingFreeSpace = 0; } @@ -1875,6 +1918,7 @@ static void layoutNodeImpl(const CSSNodeRef node, leadingMainDim = betweenMainDim / 2; break; case CSSJustifyFlexStart: + case CSSJustifyCount: break; } @@ -1895,16 +1939,14 @@ static void layoutNodeImpl(const CSSNodeRef node, getLeadingMargin(child, mainAxis); } } else { - if (performLayout) { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child->layout.position[pos[mainAxis]] += mainDim; - } - // Now that we placed the element, we need to update the variables. // We need to do that only for relative elements. Absolute elements // do not take part in that phase. if (child->style.positionType == CSSPositionTypeRelative) { + if (performLayout) { + child->layout.position[pos[mainAxis]] += mainDim; + } + if (canSkipFlex) { // If we skipped the flex step, then we can't rely on the // measuredDims because @@ -1922,6 +1964,9 @@ static void layoutNodeImpl(const CSSNodeRef node, // can only be one element in that cross dimension. crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis)); } + } else if (performLayout) { + child->layout.position[pos[mainAxis]] += + getLeadingBorder(node, mainAxis) + leadingMainDim; } } } @@ -1966,7 +2011,7 @@ static void layoutNodeImpl(const CSSNodeRef node, getLeadingMargin(child, crossAxis); } else { child->layout.position[pos[crossAxis]] = - leadingPaddingAndBorderCross + getLeadingMargin(child, crossAxis); + getLeadingBorder(node, crossAxis) + getLeadingMargin(child, crossAxis); } } else { float leadingCrossDim = leadingPaddingAndBorderCross; @@ -1987,8 +2032,8 @@ static void layoutNodeImpl(const CSSNodeRef node, float childWidth; float childHeight; - CSSMeasureMode childWidthMeasureMode; - CSSMeasureMode childHeightMeasureMode; + CSSMeasureMode childWidthMeasureMode = CSSMeasureModeExactly; + CSSMeasureMode childHeightMeasureMode = CSSMeasureModeExactly; if (isMainAxisRow) { childHeight = crossDim; @@ -2000,15 +2045,12 @@ static void layoutNodeImpl(const CSSNodeRef node, getMarginAxis(child, CSSFlexDirectionColumn); } - if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionWidth])) { - childWidth = child->style.maxDimensions[CSSDimensionWidth]; - childWidthMeasureMode = CSSMeasureModeAtMost; - } - - if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionHeight])) { - childHeight = child->style.maxDimensions[CSSDimensionHeight]; - childHeightMeasureMode = CSSMeasureModeAtMost; - } + constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth], + &childWidthMeasureMode, + &childWidth); + constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionHeight], + &childHeightMeasureMode, + &childHeight); // If the child defines a definite size for its cross axis, there's // no need to stretch. @@ -2017,6 +2059,7 @@ static void layoutNodeImpl(const CSSNodeRef node, CSSValueIsUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; childHeightMeasureMode = CSSValueIsUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; + layoutNodeInternal(child, childWidth, childHeight, @@ -2067,6 +2110,7 @@ static void layoutNodeImpl(const CSSNodeRef node, break; case CSSAlignAuto: case CSSAlignFlexStart: + case CSSAlignCount: break; } @@ -2126,6 +2170,7 @@ static void layoutNodeImpl(const CSSNodeRef node, break; } case CSSAlignAuto: + case CSSAlignCount: break; } } @@ -2208,7 +2253,7 @@ bool gPrintSkips = false; static const char *spacer = " "; static const char *getSpacer(const unsigned long level) { - const unsigned long spacerLen = strlen(spacer); + const size_t spacerLen = strlen(spacer); if (level > spacerLen) { return &spacer[0]; } else { @@ -2254,17 +2299,17 @@ static inline bool newMeasureSizeIsStricterAndStillValid(CSSMeasureMode sizeMode } bool CSSNodeCanUseCachedMeasurement(const CSSMeasureMode widthMode, - const float width, - const CSSMeasureMode heightMode, - const float height, - const CSSMeasureMode lastWidthMode, - const float lastWidth, - const CSSMeasureMode lastHeightMode, - const float lastHeight, - const float lastComputedWidth, - const float lastComputedHeight, - const float marginRow, - const float marginColumn) { + const float width, + const CSSMeasureMode heightMode, + const float height, + const CSSMeasureMode lastWidthMode, + const float lastWidth, + const CSSMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn) { if (lastComputedHeight < 0 || lastComputedWidth < 0) { return false; } @@ -2282,19 +2327,16 @@ bool CSSNodeCanUseCachedMeasurement(const CSSMeasureMode widthMode, newMeasureSizeIsStricterAndStillValid( widthMode, width - marginRow, lastWidthMode, lastWidth, lastComputedWidth); - const bool heightIsCompatible = hasSameHeightSpec || - newSizeIsExactAndMatchesOldMeasuredSize(heightMode, - height - marginColumn, - lastComputedHeight) || - oldSizeIsUnspecifiedAndStillFits(heightMode, + const bool heightIsCompatible = + hasSameHeightSpec || newSizeIsExactAndMatchesOldMeasuredSize(heightMode, height - marginColumn, - lastHeightMode, lastComputedHeight) || - newMeasureSizeIsStricterAndStillValid(heightMode, - height - marginColumn, - lastHeightMode, - lastHeight, - lastComputedHeight); + oldSizeIsUnspecifiedAndStillFits(heightMode, + height - marginColumn, + lastHeightMode, + lastComputedHeight) || + newMeasureSizeIsStricterAndStillValid( + heightMode, height - marginColumn, lastHeightMode, lastHeight, lastComputedHeight); return widthIsCompatible && heightIsCompatible; } @@ -2564,16 +2606,34 @@ void CSSLog(CSSLogLevel level, const char *format, ...) { va_end(args); } -#ifdef CSS_ASSERT_FAIL_ENABLED -static CSSAssertFailFunc gAssertFailFunc; +static bool experimentalFeatures[CSSExperimentalFeatureCount + 1]; -void CSSAssertSetFailFunc(CSSAssertFailFunc func) { - gAssertFailFunc = func; +void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, bool enabled) { + experimentalFeatures[feature] = enabled; } -void CSSAssertFail(const char *message) { - if (gAssertFailFunc) { - (*gAssertFailFunc)(message); +bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature) { + return experimentalFeatures[feature]; +} + +void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc, + CSSCalloc cssCalloc, + CSSRealloc cssRealloc, + CSSFree cssFree) { + CSS_ASSERT(gNodeInstanceCount == 0, "Cannot set memory functions: all node must be freed first"); + CSS_ASSERT((cssMalloc == NULL && cssCalloc == NULL && cssRealloc == NULL && cssFree == NULL) || + (cssMalloc != NULL && cssCalloc != NULL && cssRealloc != NULL && cssFree != NULL), + "Cannot set memory functions: functions must be all NULL or Non-NULL"); + + if (cssMalloc == NULL || cssCalloc == NULL || cssRealloc == NULL || cssFree == NULL) { + gCSSMalloc = &malloc; + gCSSCalloc = &calloc; + gCSSRealloc = &realloc; + gCSSFree = &free; + } else { + gCSSMalloc = cssMalloc; + gCSSCalloc = cssCalloc; + gCSSRealloc = cssRealloc; + gCSSFree = cssFree; } } -#endif diff --git a/CSSLayout/CSSLayout.h b/CSSLayout/CSSLayout.h index 2a21afb..831c804 100644 --- a/CSSLayout/CSSLayout.h +++ b/CSSLayout/CSSLayout.h @@ -28,107 +28,16 @@ static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define CSSUndefined NAN +#include "CSSEnums.h" #include "CSSMacros.h" CSS_EXTERN_C_BEGIN -typedef enum CSSDirection { - CSSDirectionInherit, - CSSDirectionLTR, - CSSDirectionRTL, -} CSSDirection; - -typedef enum CSSFlexDirection { - CSSFlexDirectionColumn, - CSSFlexDirectionColumnReverse, - CSSFlexDirectionRow, - CSSFlexDirectionRowReverse, -} CSSFlexDirection; - -typedef enum CSSJustify { - CSSJustifyFlexStart, - CSSJustifyCenter, - CSSJustifyFlexEnd, - CSSJustifySpaceBetween, - CSSJustifySpaceAround, -} CSSJustify; - -typedef enum CSSOverflow { - CSSOverflowVisible, - CSSOverflowHidden, - CSSOverflowScroll, -} CSSOverflow; - -// Note: auto is only a valid value for alignSelf. It is NOT a valid value for -// alignItems. -typedef enum CSSAlign { - CSSAlignAuto, - CSSAlignFlexStart, - CSSAlignCenter, - CSSAlignFlexEnd, - CSSAlignStretch, -} CSSAlign; - -typedef enum CSSPositionType { - CSSPositionTypeRelative, - CSSPositionTypeAbsolute, -} CSSPositionType; - -// BEGIN_UNITY @joce 11-01-2016 CompileForC# -// typedef enum CSSWrapType { -// CSSWrapTypeNoWrap, -// CSSWrapTypeWrap, -// } CSSWrapType; -typedef enum CSSWrap { - CSSWrapNoWrap, - CSSWrapWrap, -} CSSWrap; -// END_UNITY - -typedef enum CSSMeasureMode { - CSSMeasureModeUndefined, - CSSMeasureModeExactly, - CSSMeasureModeAtMost, - CSSMeasureModeCount, -} CSSMeasureMode; - -typedef enum CSSDimension { - CSSDimensionWidth, - CSSDimensionHeight, -} CSSDimension; - -typedef enum CSSEdge { - CSSEdgeLeft, - CSSEdgeTop, - CSSEdgeRight, - CSSEdgeBottom, - CSSEdgeStart, - CSSEdgeEnd, - CSSEdgeHorizontal, - CSSEdgeVertical, - CSSEdgeAll, - CSSEdgeCount, -} CSSEdge; - -typedef enum CSSPrintOptions { - CSSPrintOptionsLayout = 1, - CSSPrintOptionsStyle = 2, - CSSPrintOptionsChildren = 4, -} CSSPrintOptions; - typedef struct CSSSize { float width; float height; } CSSSize; -typedef enum CSSLogLevel { - CSSLogLevelError, - CSSLogLevelWarn, - CSSLogLevelInfo, - CSSLogLevelDebug, - CSSLogLevelVerbose, -} CSSLogLevel; - typedef struct CSSNode *CSSNodeRef; typedef CSSSize (*CSSMeasureFunc)(CSSNodeRef node, float width, @@ -138,9 +47,10 @@ typedef CSSSize (*CSSMeasureFunc)(CSSNodeRef node, typedef void (*CSSPrintFunc)(CSSNodeRef node); typedef int (*CSSLogger)(CSSLogLevel level, const char *format, va_list args); -#ifdef CSS_ASSERT_FAIL_ENABLED -typedef void (*CSSAssertFailFunc)(const char *message); -#endif +typedef void *(*CSSMalloc)(size_t size); +typedef void *(*CSSCalloc)(size_t count, size_t size); +typedef void *(*CSSRealloc)(void *ptr, size_t size); +typedef void (*CSSFree)(void *ptr); // CSSNode WIN_EXPORT CSSNodeRef CSSNodeNew(void); @@ -191,6 +101,8 @@ WIN_EXPORT bool CSSNodeCanUseCachedMeasurement(const CSSMeasureMode widthMode, const float marginRow, const float marginColumn); +WIN_EXPORT void CSSNodeCopyStyle(const CSSNodeRef dstNode, const CSSNodeRef srcNode); + #define CSS_NODE_PROPERTY(type, name, paramName) \ WIN_EXPORT void CSSNodeSet##name(const CSSNodeRef node, type paramName); \ WIN_EXPORT type CSSNodeGet##name(const CSSNodeRef node); @@ -220,10 +132,7 @@ CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignContent, alignContent); CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignItems, alignItems); CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignSelf, alignSelf); CSS_NODE_STYLE_PROPERTY(CSSPositionType, PositionType, positionType); -// BEGIN_UNITY @joce 11-01-2016 CompileForC# -//CSS_NODE_STYLE_PROPERTY(CSSWrapType, FlexWrap, flexWrap); CSS_NODE_STYLE_PROPERTY(CSSWrap, FlexWrap, flexWrap); -// END_UNITY CSS_NODE_STYLE_PROPERTY(CSSOverflow, Overflow, overflow); WIN_EXPORT void CSSNodeStyleSetFlex(const CSSNodeRef node, const float flex); @@ -254,10 +163,13 @@ CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction); WIN_EXPORT void CSSLayoutSetLogger(CSSLogger logger); WIN_EXPORT void CSSLog(CSSLogLevel level, const char *message, ...); -#ifdef CSS_ASSERT_FAIL_ENABLED -// Assert -WIN_EXPORT void CSSAssertSetFailFunc(CSSAssertFailFunc func); -WIN_EXPORT void CSSAssertFail(const char *message); -#endif +WIN_EXPORT void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, + bool enabled); +WIN_EXPORT bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature); + +WIN_EXPORT void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc, + CSSCalloc cssCalloc, + CSSRealloc cssRealloc, + CSSFree cssFree); CSS_EXTERN_C_END diff --git a/CSSLayout/CSSMacros.h b/CSSLayout/CSSMacros.h index 65e6896..8d2375e 100644 --- a/CSSLayout/CSSMacros.h +++ b/CSSLayout/CSSMacros.h @@ -33,16 +33,10 @@ #define CSS_ABORT() #endif -#if CSS_ASSERT_FAIL_ENABLED -#define CSS_ERROR_FUNC(message) CSSAssertFail(message) -#else -#define CSS_ERROR_FUNC(message) CSSLog(CSSLogLevelError, "%s", message) -#endif - #ifndef CSS_ASSERT -#define CSS_ASSERT(X, message) \ - if (!(X)) { \ - CSS_ERROR_FUNC(message); \ - CSS_ABORT(); \ +#define CSS_ASSERT(X, message) \ + if (!(X)) { \ + CSSLog(CSSLogLevelError, "%s", message); \ + CSS_ABORT(); \ } #endif diff --git a/CSSLayout/CSSNodeList.cpp b/CSSLayout/CSSNodeList.cpp index 864061e..633b7a0 100644 --- a/CSSLayout/CSSNodeList.cpp +++ b/CSSLayout/CSSNodeList.cpp @@ -9,6 +9,10 @@ #include "CSSNodeList.h" +extern CSSMalloc gCSSMalloc; +extern CSSRealloc gCSSRealloc; +extern CSSFree gCSSFree; + struct CSSNodeList { uint32_t capacity; uint32_t count; @@ -17,17 +21,16 @@ struct CSSNodeList { CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity) { // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 - //const CSSNodeListRef list = malloc(sizeof(struct CSSNodeList)); - const CSSNodeListRef list = (CSSNodeListRef)malloc(sizeof(struct CSSNodeList)); + //const CSSNodeListRef list = gCSSMalloc(sizeof(struct CSSNodeList)); + const CSSNodeListRef list = (CSSNodeListRef)gCSSMalloc(sizeof(struct CSSNodeList)); // END_UNITY - CSS_ASSERT(list != NULL, "Could not allocate memory for list"); list->capacity = initialCapacity; list->count = 0; // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 - //list->items = malloc(sizeof(CSSNodeRef) * list->capacity); - list->items = (CSSNodeRef*)malloc(sizeof(CSSNodeRef) * list->capacity); + //list->items = gCSSMalloc(sizeof(CSSNodeRef) * list->capacity); + list->items = (CSSNodeRef*)gCSSMalloc(sizeof(CSSNodeRef) * list->capacity); // END_UNITY CSS_ASSERT(list->items != NULL, "Could not allocate memory for items"); @@ -36,8 +39,8 @@ CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity) { void CSSNodeListFree(const CSSNodeListRef list) { if (list) { - free(list->items); - free(list); + gCSSFree(list->items); + gCSSFree(list); } } @@ -64,8 +67,8 @@ void CSSNodeListInsert(CSSNodeListRef *listp, const CSSNodeRef node, const uint3 if (list->count == list->capacity) { list->capacity *= 2; // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 - //list->items = realloc(list->items, sizeof(CSSNodeRef) * list->capacity); - list->items = (CSSNodeRef*)realloc(list->items, sizeof(void *) * list->capacity); + //list->items = gCSSRealloc(list->items, sizeof(CSSNodeRef) * list->capacity); + list->items = (CSSNodeRef*)gCSSRealloc(list->items, sizeof(void *) * list->capacity); // END_UNITY CSS_ASSERT(list->items != NULL, "Could not extend allocation for items"); } @@ -83,7 +86,6 @@ CSSNodeRef CSSNodeListRemove(const CSSNodeListRef list, const uint32_t index) { //const CSSNodeRef removed = list->items[index]; const CSSNodeRef removed = (CSSNodeRef)list->items[index]; // END_UNITY - list->items[index] = NULL; for (uint32_t i = index; i < list->count - 1; i++) { diff --git a/uikit/CSSLayout/BUCK b/CSSLayoutKit/BUCK similarity index 63% rename from uikit/CSSLayout/BUCK rename to CSSLayoutKit/BUCK index 2c9ec8f..2f9f570 100644 --- a/uikit/CSSLayout/BUCK +++ b/CSSLayoutKit/BUCK @@ -7,12 +7,30 @@ include_defs('//CSSLAYOUT_DEFS') -UIKIT_CSSLAYOUT_COMPILER_FLAGS = ['-fobjc-arc'] +UIKIT_CSSLAYOUT_COMPILER_FLAGS = [ + '-fobjc-arc', + '-Wconditional-uninitialized', + '-Wdangling-else', + '-Wdeprecated-declarations', + '-Wimplicit-retain-self', + '-Wincomplete-implementation', + '-Wobjc-method-access', + '-Wobjc-missing-super-calls', + '-Wmismatched-return-types', + '-Wreturn-type', + '-Wno-global-constructors', + '-Wno-shadow', + '-Wunused-const-variable', + '-Wunused-function', + '-Wunused-property-ivar', + '-Wunused-result', + '-Wunused-value', +] apple_library( - name = 'CSSLayout', + name = 'CSSLayoutKit', compiler_flags = UIKIT_CSSLAYOUT_COMPILER_FLAGS, - tests = [':CSSLayoutTests'], + tests = [':CSSLayoutKitTests'], srcs = glob(['*.m']), exported_headers = glob(['*.h']), frameworks = [ @@ -26,7 +44,7 @@ apple_library( ) apple_test( - name = 'CSSLayoutTests', + name = 'CSSLayoutKitTests', compiler_flags = UIKIT_CSSLAYOUT_COMPILER_FLAGS, info_plist = 'Tests/Info.plist', srcs = glob(['Tests/**/*.m']), @@ -35,7 +53,7 @@ apple_test( '$PLATFORM_DIR/Developer/Library/Frameworks/XCTest.framework', ], deps = [ - ':CSSLayout', + ':CSSLayoutKit', ], visibility = ['PUBLIC'], ) diff --git a/CSSLayoutKit/Tests/CSSLayoutKitTests.m b/CSSLayoutKit/Tests/CSSLayoutKitTests.m new file mode 100644 index 0000000..720e0cb --- /dev/null +++ b/CSSLayoutKit/Tests/CSSLayoutKitTests.m @@ -0,0 +1,202 @@ +/** + * 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. + */ + +#import + +#import "UIView+CSSLayout.h" + +@interface CSSLayoutKitTests : XCTestCase +@end + +@implementation CSSLayoutKitTests + +#ifndef TRAVIS_CI + +- (void)testNodesAreDeallocedWithSingleView +{ + XCTAssertEqual(0, CSSNodeGetInstanceCount()); + + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + [view css_setFlexBasis:1]; + XCTAssertEqual(1, CSSNodeGetInstanceCount()); + view = nil; + + XCTAssertEqual(0, CSSNodeGetInstanceCount()); +} + +- (void)testNodesAreDeallocedCascade +{ + XCTAssertEqual(0, CSSNodeGetInstanceCount()); + + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + [view css_setFlexBasis:1]; + + for (int i=0; i<10; i++) { + UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; + [subview css_setFlexBasis:1]; + [view addSubview:subview]; + } + XCTAssertEqual(11, CSSNodeGetInstanceCount()); + view = nil; + + XCTAssertEqual(0, CSSNodeGetInstanceCount()); +} + +#endif + +- (void)testUsesFlexbox +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + XCTAssertFalse([view css_usesFlexbox]); + + [view css_setUsesFlexbox:YES]; + XCTAssertTrue([view css_usesFlexbox]); + + [view css_setUsesFlexbox:NO]; + XCTAssertFalse([view css_usesFlexbox]); +} + +- (void)testSizeThatFitsAsserts +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + dispatch_sync(dispatch_queue_create("com.facebook.CSSLayout.testing", DISPATCH_QUEUE_SERIAL), ^(void){ + XCTAssertThrows([view css_intrinsicSize]); + }); +} + +- (void)testSizeThatFitsSmoke +{ + UIView *container = [[UIView alloc] initWithFrame:CGRectZero]; + [container css_setUsesFlexbox:YES]; + [container css_setFlexDirection:CSSFlexDirectionRow]; + [container css_setAlignItems:CSSAlignFlexStart]; + + UILabel *longTextLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + longTextLabel.text = @"This is a very very very very very very very very long piece of text."; + longTextLabel.lineBreakMode = NSLineBreakByTruncatingTail; + longTextLabel.numberOfLines = 1; + [longTextLabel css_setUsesFlexbox:YES]; + [longTextLabel css_setFlexShrink:1]; + [container addSubview:longTextLabel]; + + UIView *textBadgeView = [[UIView alloc] initWithFrame:CGRectZero]; + [textBadgeView css_setUsesFlexbox:YES]; + [textBadgeView css_setMargin:3.0 forEdge:CSSEdgeLeft]; + [textBadgeView css_setWidth:10]; + [textBadgeView css_setHeight:10]; + [container addSubview:textBadgeView]; + + const CGSize containerSize = [container css_intrinsicSize]; + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(514,21), containerSize), @"Size is actually %@", NSStringFromCGSize(containerSize)); +} + +- (void)testFrameAndOriginPlacement +{ + const CGSize containerSize = CGSizeMake(320, 50); + + UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; + [container css_setUsesFlexbox:YES]; + [container css_setFlexDirection:CSSFlexDirectionRow]; + + for (int i = 0; i < 3; i++) { + UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; + [subview css_setUsesFlexbox:YES]; + [subview css_setFlexGrow:1]; + + [container addSubview:subview]; + } + [container css_applyLayout]; + + XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:1].frame)); + XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:1].frame, [container.subviews objectAtIndex:2].frame)); + XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:2].frame)); + + CGFloat totalWidth = 0; + for (UIView *view in container.subviews) { + totalWidth += view.bounds.size.width; + } + + XCTAssertEqual(containerSize.width, totalWidth, @"The container's width is %.6f, the subviews take up %.6f", containerSize.width, totalWidth); +} + +- (void)testThatWeRespectIncludeInLayoutFlag +{ + const CGSize containerSize = CGSizeMake(300, 50); + + UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; + [container css_setUsesFlexbox:YES]; + [container css_setFlexDirection:CSSFlexDirectionRow]; + + UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview1 css_setUsesFlexbox:YES]; + [subview1 css_setFlexGrow:1]; + [container addSubview:subview1]; + + UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview2 css_setUsesFlexbox:YES]; + [subview2 css_setFlexGrow:1]; + [container addSubview:subview2]; + + UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview3 css_setUsesFlexbox:YES]; + [subview3 css_setFlexGrow:1]; + [container addSubview:subview3]; + + [container css_applyLayout]; + + for (UIView *view in container.subviews) { + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(view.bounds.size)); + } + + [subview3 css_setIncludeInLayout:NO]; + [container css_applyLayout]; + + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size)); + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size)); + + // We don't set the frame to zero, so, it should be set to what it was previously at. + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview3.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview3.bounds.size)); +} + +- (void)testThatViewNotIncludedInFirstLayoutPassAreIncludedInSecond +{ + UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)]; + [container css_setUsesFlexbox:YES]; + [container css_setFlexDirection:CSSFlexDirectionRow]; + + UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview1 css_setUsesFlexbox:YES]; + [subview1 css_setFlexGrow:1]; + [container addSubview:subview1]; + + UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview2 css_setUsesFlexbox:YES]; + [subview2 css_setFlexGrow:1]; + [container addSubview:subview2]; + + UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; + [subview3 css_setUsesFlexbox:YES]; + [subview3 css_setFlexGrow:1]; + [subview3 css_setIncludeInLayout:NO]; + [container addSubview:subview3]; + + [container css_applyLayout]; + + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size)); + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size)); + XCTAssertTrue(CGSizeEqualToSize(CGSizeZero, subview3.bounds.size), @"Actual size %@", NSStringFromCGSize(subview3.bounds.size)); + + [subview3 css_setIncludeInLayout:YES]; + [container css_applyLayout]; + for (UIView *view in container.subviews) { + XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(view.bounds.size)); + } +} + +@end diff --git a/uikit/CSSLayout/Tests/Info.plist b/CSSLayoutKit/Tests/Info.plist similarity index 100% rename from uikit/CSSLayout/Tests/Info.plist rename to CSSLayoutKit/Tests/Info.plist diff --git a/uikit/CSSLayout/UIView+CSSLayout.h b/CSSLayoutKit/UIView+CSSLayout.h similarity index 62% rename from uikit/CSSLayout/UIView+CSSLayout.h rename to CSSLayoutKit/UIView+CSSLayout.h index f08daa9..d7702d0 100644 --- a/uikit/CSSLayout/UIView+CSSLayout.h +++ b/CSSLayoutKit/UIView+CSSLayout.h @@ -12,8 +12,15 @@ @interface UIView (CSSLayout) -- (void)css_setUsesFlexbox:(BOOL)enabled; -- (BOOL)css_usesFlexbox; +/** + The property that decides if we should include this view when calculating layout. Defaults to YES. + */ +@property (nonatomic, readwrite, assign, setter=css_setIncludeInLayout:) BOOL css_includeInLayout; + +/** + The property that decides during layout/sizing whether or not css_* properties should be applied. Defaults to NO. + */ +@property (nonatomic, readwrite, assign, setter=css_setUsesFlexbox:) BOOL css_usesFlexbox; - (void)css_setDirection:(CSSDirection)direction; - (void)css_setFlexDirection:(CSSFlexDirection)flexDirection; @@ -22,7 +29,7 @@ - (void)css_setAlignItems:(CSSAlign)alignItems; - (void)css_setAlignSelf:(CSSAlign)alignSelf; - (void)css_setPositionType:(CSSPositionType)positionType; -- (void)css_setFlexWrap:(CSSWrapType)flexWrap; +- (void)css_setFlexWrap:(CSSWrap)flexWrap; - (void)css_setFlexGrow:(CGFloat)flexGrow; - (void)css_setFlexShrink:(CGFloat)flexShrink; @@ -39,13 +46,19 @@ - (void)css_setMaxWidth:(CGFloat)maxWidth; - (void)css_setMaxHeight:(CGFloat)maxHeight; -// Get the resolved direction of this node. This won't be CSSDirectionInherit +/** + Get the resolved direction of this node. This won't be CSSDirectionInherit + */ - (CSSDirection)css_resolvedDirection; -//! @abstract Perform a layout calculation and update the frames of the views in the hierarchy with th results +/** + Perform a layout calculation and update the frames of the views in the hierarchy with th results + */ - (void)css_applyLayout; -//! @abstract Compute the size of a layout with a constrained size. -- (CGSize)css_sizeThatFits:(CGSize)constrainedSize; +/** + Returns the size of the view if no constraints were given. This could equivalent to calling [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + */ +- (CGSize)css_intrinsicSize; @end diff --git a/uikit/CSSLayout/UIView+CSSLayout.m b/CSSLayoutKit/UIView+CSSLayout.m similarity index 76% rename from uikit/CSSLayout/UIView+CSSLayout.m rename to CSSLayoutKit/UIView+CSSLayout.m index 31cfbf1..f166b5f 100644 --- a/uikit/CSSLayout/UIView+CSSLayout.m +++ b/CSSLayoutKit/UIView+CSSLayout.m @@ -33,16 +33,27 @@ @implementation UIView (CSSLayout) -- (CSSNodeRef)cssNode +- (BOOL)css_usesFlexbox { - CSSNodeBridge *node = objc_getAssociatedObject(self, @selector(cssNode)); - if (!node) { - node = [CSSNodeBridge new]; - CSSNodeSetContext(node.cnode, (__bridge void *) self); - objc_setAssociatedObject(self, @selector(cssNode), node, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } + NSNumber *usesFlexbox = objc_getAssociatedObject(self, @selector(css_usesFlexbox)); + return [usesFlexbox boolValue]; +} - return node.cnode; +- (BOOL)css_includeInLayout +{ + NSNumber *includeInLayout = objc_getAssociatedObject(self, @selector(css_includeInLayout)); + return (includeInLayout != nil) ? [includeInLayout boolValue] : YES; +} + +#pragma mark - Setters + +- (void)css_setIncludeInLayout:(BOOL)includeInLayout +{ + objc_setAssociatedObject( + self, + @selector(css_includeInLayout), + @(includeInLayout), + OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (void)css_setUsesFlexbox:(BOOL)enabled @@ -54,12 +65,6 @@ OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (BOOL)css_usesFlexbox -{ - NSNumber *usesFlexbox = objc_getAssociatedObject(self, @selector(css_usesFlexbox)); - return [usesFlexbox boolValue]; -} - - (void)css_setDirection:(CSSDirection)direction { CSSNodeStyleSetDirection([self cssNode], direction); @@ -95,7 +100,7 @@ CSSNodeStyleSetPositionType([self cssNode], positionType); } -- (void)css_setFlexWrap:(CSSWrapType)flexWrap +- (void)css_setFlexWrap:(CSSWrap)flexWrap { CSSNodeStyleSetFlexWrap([self cssNode], flexWrap); } @@ -160,23 +165,54 @@ CSSNodeStyleSetMaxHeight([self cssNode], maxHeight); } +#pragma mark - Layout and Sizing + - (CSSDirection)css_resolvedDirection { return CSSNodeLayoutGetDirection([self cssNode]); } -- (CGSize)css_sizeThatFits:(CGSize)constrainedSize +- (void)css_applyLayout +{ + [self calculateLayoutWithSize:self.bounds.size]; + CSSApplyLayoutToViewHierarchy(self); +} + +- (CGSize)css_intrinsicSize +{ + const CGSize constrainedSize = { + .width = CSSUndefined, + .height = CSSUndefined, + }; + return [self calculateLayoutWithSize:constrainedSize]; +} + +#pragma mark - Private + +- (CSSNodeRef)cssNode +{ + CSSNodeBridge *node = objc_getAssociatedObject(self, @selector(cssNode)); + if (!node) { + node = [CSSNodeBridge new]; + CSSNodeSetContext(node.cnode, (__bridge void *) self); + objc_setAssociatedObject(self, @selector(cssNode), node, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + + return node.cnode; +} + +- (CGSize)calculateLayoutWithSize:(CGSize)size { NSAssert([NSThread isMainThread], @"CSS Layout calculation must be done on main."); NSAssert([self css_usesFlexbox], @"CSS Layout is not enabled for this view."); - _attachNodesRecursive(self); + CSSAttachNodesFromViewHierachy(self); const CSSNodeRef node = [self cssNode]; CSSNodeCalculateLayout( node, - constrainedSize.width, - constrainedSize.height, + size.width, + size.height, CSSNodeStyleGetDirection(node)); return (CGSize) { @@ -185,15 +221,7 @@ }; } -- (void)css_applyLayout -{ - [self css_sizeThatFits:self.bounds.size]; - _updateFrameRecursive(self); -} - -#pragma mark - Private - -static CSSSize _measure( +static CSSSize CSSMeasureView( CSSNodeRef node, float width, CSSMeasureMode widthMode, @@ -210,12 +238,12 @@ static CSSSize _measure( }]; return (CSSSize) { - .width = _sanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), - .height = _sanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), + .width = CSSSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), + .height = CSSSanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), }; } -static CGFloat _sanitizeMeasurement( +static CGFloat CSSSanitizeMeasurement( CGFloat constrainedSize, CGFloat measuredSize, CSSMeasureMode measureMode) @@ -232,14 +260,14 @@ static CGFloat _sanitizeMeasurement( return result; } -static void _attachNodesRecursive(UIView *view) { +static void CSSAttachNodesFromViewHierachy(UIView *view) { CSSNodeRef node = [view cssNode]; const BOOL usesFlexbox = [view css_usesFlexbox]; const BOOL isLeaf = !usesFlexbox || view.subviews.count == 0; // Only leaf nodes should have a measure function if (isLeaf) { - CSSNodeSetMeasureFunc(node, _measure); + CSSNodeSetMeasureFunc(node, CSSMeasureView); // Clear any children while (CSSNodeChildCount(node) > 0) { @@ -248,23 +276,30 @@ static void _attachNodesRecursive(UIView *view) { } else { CSSNodeSetMeasureFunc(node, NULL); + NSUInteger numSubviewsInLayout = 0; // Add any children which were added since the last call to css_applyLayout for (NSUInteger i = 0; i < view.subviews.count; i++) { - CSSNodeRef childNode = [view.subviews[i] cssNode]; + UIView *const subview = view.subviews[i]; + if (![subview css_includeInLayout]) { + continue; + } + numSubviewsInLayout++; + + CSSNodeRef childNode = [subview cssNode]; if (CSSNodeChildCount(node) < i + 1 || CSSNodeGetChild(node, i) != childNode) { CSSNodeInsertChild(node, childNode, i); } - _attachNodesRecursive(view.subviews[i]); + CSSAttachNodesFromViewHierachy(subview); } // Remove any children which were removed since the last call to css_applyLayout - while (view.subviews.count < CSSNodeChildCount(node)) { + while (numSubviewsInLayout < CSSNodeChildCount(node)) { CSSNodeRemoveChild(node, CSSNodeGetChild(node, CSSNodeChildCount(node) - 1)); } } } -static CGFloat _roundPixelValue(CGFloat value) +static CGFloat CSSRoundPixelValue(CGFloat value) { static CGFloat scale; static dispatch_once_t onceToken; @@ -275,10 +310,13 @@ static CGFloat _roundPixelValue(CGFloat value) return round(value * scale) / scale; } -static void _updateFrameRecursive(UIView *view) { +static void CSSApplyLayoutToViewHierarchy(UIView *view) { NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread."); - CSSNodeRef node = [view cssNode]; + if (![view css_includeInLayout]) { + return; + } + CSSNodeRef node = [view cssNode]; const CGPoint topLeft = { CSSNodeLayoutGetLeft(node), CSSNodeLayoutGetTop(node), @@ -291,19 +329,19 @@ static void _updateFrameRecursive(UIView *view) { view.frame = (CGRect) { .origin = { - .x = _roundPixelValue(topLeft.x), - .y = _roundPixelValue(topLeft.y), + .x = CSSRoundPixelValue(topLeft.x), + .y = CSSRoundPixelValue(topLeft.y), }, .size = { - .width = _roundPixelValue(bottomRight.x) - _roundPixelValue(topLeft.x), - .height = _roundPixelValue(bottomRight.y) - _roundPixelValue(topLeft.y), + .width = CSSRoundPixelValue(bottomRight.x) - CSSRoundPixelValue(topLeft.x), + .height = CSSRoundPixelValue(bottomRight.y) - CSSRoundPixelValue(topLeft.y), }, }; const BOOL isLeaf = ![view css_usesFlexbox] || view.subviews.count == 0; if (!isLeaf) { for (NSUInteger i = 0; i < view.subviews.count; i++) { - _updateFrameRecursive(view.subviews[i]); + CSSApplyLayoutToViewHierarchy(view.subviews[i]); } } } diff --git a/README.md b/README.md index fb1f8b4..2b9c9f5 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ root.getLayoutHeight(); ``` ### UIKit -The full API can be found in `uikit/CSSLayout/UIView+CSSLayout.h`. +The full API can be found in `CSSLayoutKit/UIView+CSSLayout.h`. ```objective-c UIView *root = [UIView new]; diff --git a/benchmark/CSSBenchmark.c b/benchmark/CSSBenchmark.c index e08a1df..0bab951 100644 --- a/benchmark/CSSBenchmark.c +++ b/benchmark/CSSBenchmark.c @@ -59,7 +59,6 @@ CSS_BENCHMARKS({ for (uint32_t i = 0; i < 10; i++) { const CSSNodeRef child = CSSNodeNew(); - CSSNodeSetMeasureFunc(child, _measure); CSSNodeStyleSetFlex(child, 1); CSSNodeInsertChild(root, child, 0); diff --git a/csharp/Facebook.CSSLayout/CSSAlign.cs b/csharp/Facebook.CSSLayout/CSSAlign.cs index 7b8351c..56f891a 100644 --- a/csharp/Facebook.CSSLayout/CSSAlign.cs +++ b/csharp/Facebook.CSSLayout/CSSAlign.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -18,6 +18,6 @@ namespace UnityEngine.CSSLayout FlexStart, Center, FlexEnd, - Stretch + Stretch, } } diff --git a/csharp/Facebook.CSSLayout/CSSAssert.cs b/csharp/Facebook.CSSLayout/CSSAssert.cs deleted file mode 100644 index 69d078a..0000000 --- a/csharp/Facebook.CSSLayout/CSSAssert.cs +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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. - */ - -using System; -using System.Runtime.InteropServices; - -// BEGIN_UNITY @joce 11-07-2016 CompileForC#Bindings -//namespace Facebook.CSSLayout -namespace UnityEngine.CSSLayout -// END_UNITY -{ - internal static class CSSAssert - { -// TODO we don't support the assertion feature yet - -// [UnmanagedFunctionPointer(CallingConvention.Cdecl)] -// internal delegate void FailFunc(string message); -// -// private static bool _assertInitialized; -// private static FailFunc _failFunc; - - public static void Initialize() - { -// if (!_assertInitialized) -// { -// _failFunc = (message) => { -// throw new InvalidOperationException(message); -// }; -// Native.CSSAssertSetFailFunc(_failFunc); -// _assertInitialized = true; -// } - } - } -} diff --git a/csharp/Facebook.CSSLayout/CSSDIrection.cs b/csharp/Facebook.CSSLayout/CSSDIrection.cs index 1c692eb..0684608 100644 --- a/csharp/Facebook.CSSLayout/CSSDIrection.cs +++ b/csharp/Facebook.CSSLayout/CSSDIrection.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -15,7 +15,11 @@ namespace UnityEngine.CSSLayout internal enum CSSDirection { Inherit, - LeftToRight, - RightToLeft + LTR, + RTL, + [System.Obsolete("Use LTR instead")] + LeftToRight = LTR, + [System.Obsolete("Use RTL instead")] + RightToLeft = RTL, } } diff --git a/csharp/Facebook.CSSLayout/CSSDimension.cs b/csharp/Facebook.CSSLayout/CSSDimension.cs index 84ee90e..6e6b9b2 100644 --- a/csharp/Facebook.CSSLayout/CSSDimension.cs +++ b/csharp/Facebook.CSSLayout/CSSDimension.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -15,6 +15,6 @@ namespace UnityEngine.CSSLayout internal enum CSSDimension { Width, - Height + Height, } } diff --git a/csharp/Facebook.CSSLayout/CSSEdge.cs b/csharp/Facebook.CSSLayout/CSSEdge.cs index 7bd460c..f7b6d32 100644 --- a/csharp/Facebook.CSSLayout/CSSEdge.cs +++ b/csharp/Facebook.CSSLayout/CSSEdge.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -23,6 +23,5 @@ namespace UnityEngine.CSSLayout Horizontal, Vertical, All, - Count, } } diff --git a/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs b/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs new file mode 100644 index 0000000..0beacd3 --- /dev/null +++ b/csharp/Facebook.CSSLayout/CSSExperimentalFeature.cs @@ -0,0 +1,18 @@ +/** + * 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. + */ + +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings +//namespace Facebook.CSSLayout +namespace UnityEngine.CSSLayout +// END_UNITY +{ + public enum CSSExperimentalFeature + { + } +} diff --git a/csharp/Facebook.CSSLayout/CSSFlexDirection.cs b/csharp/Facebook.CSSLayout/CSSFlexDirection.cs index c8c2761..b6fa145 100644 --- a/csharp/Facebook.CSSLayout/CSSFlexDirection.cs +++ b/csharp/Facebook.CSSLayout/CSSFlexDirection.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * diff --git a/csharp/Facebook.CSSLayout/CSSJustify.cs b/csharp/Facebook.CSSLayout/CSSJustify.cs index 185b9d5..c51c842 100644 --- a/csharp/Facebook.CSSLayout/CSSJustify.cs +++ b/csharp/Facebook.CSSLayout/CSSJustify.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * diff --git a/csharp/Facebook.CSSLayout/CSSLogLevel.cs b/csharp/Facebook.CSSLayout/CSSLogLevel.cs index a0316b8..71f8a78 100644 --- a/csharp/Facebook.CSSLayout/CSSLogLevel.cs +++ b/csharp/Facebook.CSSLayout/CSSLogLevel.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -7,7 +7,10 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -namespace Facebook.CSSLayout +// BEGIN_UNITY @joce 11-07-2016 CompileForC#Bindings +//namespace Facebook.CSSLayout +namespace UnityEngine.CSSLayout +// END_UNITY { public enum CSSLogLevel { diff --git a/csharp/Facebook.CSSLayout/CSSLogger.cs b/csharp/Facebook.CSSLayout/CSSLogger.cs index 7fa4826..6ebc0d9 100644 --- a/csharp/Facebook.CSSLayout/CSSLogger.cs +++ b/csharp/Facebook.CSSLayout/CSSLogger.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -19,27 +19,32 @@ namespace UnityEngine.CSSLayout { // TODO we don't support the logging feature yet - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void Func(string message); -// -// private static bool _initialized; -// private static Func _managedLogger = null; -// - public static Func Logger = null; + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void Func(CSSLogLevel level, string message); +// +// private static bool _initialized; +// private static Func _managedLogger = null; +// + public static Func Logger = null; public static void Initialize() { -// if (!_initialized) -// { -// _managedLogger = (message) => { -// if (Logger != null) -// { -// Logger(message); -// } -// }; -// Native.CSSInteropSetLogger(_managedLogger); -// _initialized = true; -// } +// if (!_initialized) +// { +// _managedLogger = (level, message) => { +// if (Logger != null) +// { +// Logger(level, message); +// } +// +// if (level == CSSLogLevel.Error) +// { +// throw new InvalidOperationException(message); +// } +// }; +// Native.CSSInteropSetLogger(_managedLogger); +// _initialized = true; +// } } } } diff --git a/csharp/Facebook.CSSLayout/CSSMeasureMode.cs b/csharp/Facebook.CSSLayout/CSSMeasureMode.cs index 24849fa..f8305ce 100644 --- a/csharp/Facebook.CSSLayout/CSSMeasureMode.cs +++ b/csharp/Facebook.CSSLayout/CSSMeasureMode.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -17,6 +17,5 @@ namespace UnityEngine.CSSLayout Undefined, Exactly, AtMost, - Count, } } diff --git a/csharp/Facebook.CSSLayout/CSSNode.Create.cs b/csharp/Facebook.CSSLayout/CSSNode.Create.cs new file mode 100644 index 0000000..f787d76 --- /dev/null +++ b/csharp/Facebook.CSSLayout/CSSNode.Create.cs @@ -0,0 +1,240 @@ +/** + * 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. + */ + +using System; + +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings +//namespace Facebook.CSSLayout +namespace UnityEngine.CSSLayout +// END_UNITY +{ +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings + //public partial class CSSNode + internal partial class CSSNode +// END_UNITY + { + public static CSSNode Create( + CSSDirection? styleDirection = null, + CSSFlexDirection? flexDirection = null, + CSSJustify? justifyContent = null, + CSSAlign? alignContent = null, + CSSAlign? alignItems = null, + CSSAlign? alignSelf = null, + CSSPositionType? positionType = null, + CSSWrap? wrap = null, + CSSOverflow? overflow = null, + float? flex = null, + float? flexGrow = null, + float? flexShrink = null, + float? flexBasis = null, + Spacing position = null, + Spacing margin = null, + Spacing padding = null, + Spacing border = null, + float? styleWidth = null, + float? styleHeight = null, + float? styleMaxWidth = null, + float? styleMaxHeight = null, + float? styleMinWidth = null, + float? styleMinHeight = null) + { + CSSNode node = new CSSNode(); + + if (styleDirection.HasValue) + { + node.StyleDirection = styleDirection.Value; + } + + if (flexDirection.HasValue) + { + node.FlexDirection = flexDirection.Value; + } + + if (justifyContent.HasValue) + { + node.JustifyContent = justifyContent.Value; + } + + if (alignContent.HasValue) + { + node.AlignContent = alignContent.Value; + } + + if (alignItems.HasValue) + { + node.AlignItems = alignItems.Value; + } + + if (alignSelf.HasValue) + { + node.AlignSelf = alignSelf.Value; + } + + if (positionType.HasValue) + { + node.PositionType = positionType.Value; + } + + if (wrap.HasValue) + { + node.Wrap = wrap.Value; + } + + if (overflow.HasValue) + { + node.Overflow = overflow.Value; + } + + if (flex.HasValue) + { + node.Flex = flex.Value; + } + + if (flexGrow.HasValue) + { + node.FlexGrow = flexGrow.Value; + } + + if (flexShrink.HasValue) + { + node.FlexShrink = flexShrink.Value; + } + + if (flexBasis.HasValue) + { + node.FlexBasis = flexBasis.Value; + } + + if (position != null) + { + if (position.Top.HasValue) + { + node.SetPosition(CSSEdge.Top, position.Top.Value); + } + + if (position.Bottom.HasValue) + { + node.SetPosition(CSSEdge.Bottom, position.Bottom.Value); + } + + if (position.Left.HasValue) + { + node.SetPosition(CSSEdge.Left, position.Left.Value); + } + + if (position.Right.HasValue) + { + node.SetPosition(CSSEdge.Right, position.Right.Value); + } + } + + if (margin != null) + { + if (margin.Top.HasValue) + { + node.SetMargin(CSSEdge.Top, margin.Top.Value); + } + + if (margin.Bottom.HasValue) + { + node.SetMargin(CSSEdge.Bottom, margin.Bottom.Value); + } + + if (margin.Left.HasValue) + { + node.SetMargin(CSSEdge.Left, margin.Left.Value); + } + + if (margin.Right.HasValue) + { + node.SetMargin(CSSEdge.Right, margin.Right.Value); + } + } + + if (padding != null) + { + if (padding.Top.HasValue) + { + node.SetPadding(CSSEdge.Top, padding.Top.Value); + } + + if (padding.Bottom.HasValue) + { + node.SetPadding(CSSEdge.Bottom, padding.Bottom.Value); + } + + if (padding.Left.HasValue) + { + node.SetPadding(CSSEdge.Left, padding.Left.Value); + } + + if (padding.Right.HasValue) + { + node.SetPadding(CSSEdge.Right, padding.Right.Value); + } + } + + if (border != null) + { + if (border.Top.HasValue) + { + node.SetBorder(CSSEdge.Top, border.Top.Value); + } + + if (border.Bottom.HasValue) + { + node.SetBorder(CSSEdge.Bottom, border.Bottom.Value); + } + + if (border.Left.HasValue) + { + node.SetBorder(CSSEdge.Left, border.Left.Value); + } + + if (border.Right.HasValue) + { + node.SetBorder(CSSEdge.Right, border.Right.Value); + } + } + + if (styleWidth.HasValue) + { + node.StyleWidth = styleWidth.Value; + } + + if (styleHeight.HasValue) + { + node.StyleHeight = styleHeight.Value; + } + + if (styleMinWidth.HasValue) + { + node.StyleMinWidth = styleMinWidth.Value; + } + + if (styleMinHeight.HasValue) + { + node.StyleMinHeight = styleMinHeight.Value; + } + + if (styleMaxWidth.HasValue) + { + node.StyleMaxWidth = styleMaxWidth.Value; + } + + if (styleMaxHeight.HasValue) + { + node.StyleMaxHeight = styleMaxHeight.Value; + } + + return node; + } + } +} + diff --git a/csharp/Facebook.CSSLayout/CSSNode.cs b/csharp/Facebook.CSSLayout/CSSNode.cs index 41fefed..cf0fa04 100644 --- a/csharp/Facebook.CSSLayout/CSSNode.cs +++ b/csharp/Facebook.CSSLayout/CSSNode.cs @@ -18,7 +18,10 @@ using System.Text; namespace UnityEngine.CSSLayout // END_UNITY { - internal class CSSNode : IEnumerable +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings + //public partial class CSSNode : IEnumerable + internal partial class CSSNode : IEnumerable +// END_UNITY { private IntPtr _cssNode; private WeakReference _parent; @@ -32,7 +35,6 @@ namespace UnityEngine.CSSLayout public CSSNode() { - CSSAssert.Initialize(); CSSLogger.Initialize(); _cssNode = Native.CSSNodeNew(); @@ -97,6 +99,11 @@ namespace UnityEngine.CSSLayout } } + public void CopyStyle(CSSNode srcNode) + { + Native.CSSNodeCopyStyle(_cssNode, srcNode._cssNode); + } + public CSSDirection StyleDirection { get @@ -501,7 +508,7 @@ namespace UnityEngine.CSSLayout public void SetMeasureFunction(MeasureFunction measureFunction) { _measureFunction = measureFunction; - // BEGIN_UNITY + // BEGIN_UNITY @joce CompileForC#Bindings // TODO we don't support the measurement feature yet //_cssMeasureFunc = measureFunction != null ? MeasureInternal : (CSSMeasureFunc)null; //Native.CSSNodeSetMeasureFunc(_cssNode, _cssMeasureFunc); @@ -533,8 +540,9 @@ namespace UnityEngine.CSSLayout return new CSSSize { width = MeasureOutput.GetWidth(output), height = MeasureOutput.GetHeight(output) }; } -// BEGIN-UNITY -// Default arguments are not supported on all Unity platforms +// BEGIN_UNITY @joce CompileForC#Bindings - Default arguments are not supported on all Unity platforms + //public string Print(CSSPrintOptions options = + // CSSPrintOptions.Layout|CSSPrintOptions.Style|CSSPrintOptions.Children) public string Print() { return Print(CSSPrintOptions.Layout|CSSPrintOptions.Style|CSSPrintOptions.Children); @@ -542,7 +550,7 @@ namespace UnityEngine.CSSLayout public string Print(CSSPrintOptions options) { -// END-UNITY +// END_UNITY StringBuilder sb = new StringBuilder(); CSSLogger.Func orig = CSSLogger.Logger; CSSLogger.Logger = (level, message) => {sb.Append(message);}; @@ -567,5 +575,17 @@ namespace UnityEngine.CSSLayout { return Native.CSSNodeGetInstanceCount(); } + + public static void setExperimentalFeatureEnabled( + CSSExperimentalFeature feature, + bool enabled) + { + Native.CSSLayoutSetExperimentalFeatureEnabled(feature, enabled); + } + + public static bool isExperimentalFeatureEnabled(CSSExperimentalFeature feature) + { + return Native.CSSLayoutIsExperimentalFeatureEnabled(feature); + } } } diff --git a/csharp/Facebook.CSSLayout/CSSOverflow.cs b/csharp/Facebook.CSSLayout/CSSOverflow.cs index e3973a8..81d75a5 100644 --- a/csharp/Facebook.CSSLayout/CSSOverflow.cs +++ b/csharp/Facebook.CSSLayout/CSSOverflow.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -16,5 +16,6 @@ namespace UnityEngine.CSSLayout { Visible, Hidden, + Scroll, } } diff --git a/csharp/Facebook.CSSLayout/CSSPositionType.cs b/csharp/Facebook.CSSLayout/CSSPositionType.cs index f01152d..469144e 100644 --- a/csharp/Facebook.CSSLayout/CSSPositionType.cs +++ b/csharp/Facebook.CSSLayout/CSSPositionType.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * @@ -15,6 +15,6 @@ namespace UnityEngine.CSSLayout internal enum CSSPositionType { Relative, - Absolute + Absolute, } } diff --git a/csharp/Facebook.CSSLayout/CSSPrintOptions.cs b/csharp/Facebook.CSSLayout/CSSPrintOptions.cs index 128a1fd..9d44f44 100644 --- a/csharp/Facebook.CSSLayout/CSSPrintOptions.cs +++ b/csharp/Facebook.CSSLayout/CSSPrintOptions.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * diff --git a/csharp/Facebook.CSSLayout/CSSWrap.cs b/csharp/Facebook.CSSLayout/CSSWrap.cs index 6984055..01dd52b 100644 --- a/csharp/Facebook.CSSLayout/CSSWrap.cs +++ b/csharp/Facebook.CSSLayout/CSSWrap.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * diff --git a/csharp/Facebook.CSSLayout/MeasureFunction.cs b/csharp/Facebook.CSSLayout/MeasureFunction.cs index 76a8ea9..c87b41e 100644 --- a/csharp/Facebook.CSSLayout/MeasureFunction.cs +++ b/csharp/Facebook.CSSLayout/MeasureFunction.cs @@ -12,10 +12,13 @@ namespace UnityEngine.CSSLayout // END_UNITY { +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings + //internal delegate long MeasureFunction( internal delegate long MeasureFunction( - CSSNode node, - float width, - CSSMeasureMode widthMode, - float height, - CSSMeasureMode heightMode); +// END_UNITY + CSSNode node, + float width, + CSSMeasureMode widthMode, + float height, + CSSMeasureMode heightMode); } diff --git a/csharp/Facebook.CSSLayout/MeasureOutput.cs b/csharp/Facebook.CSSLayout/MeasureOutput.cs index e42335a..ad45256 100644 --- a/csharp/Facebook.CSSLayout/MeasureOutput.cs +++ b/csharp/Facebook.CSSLayout/MeasureOutput.cs @@ -14,19 +14,24 @@ namespace UnityEngine.CSSLayout { internal class MeasureOutput { + public static long Make(double width, double height) + { + return Make((int) width, (int) height); + } + public static long Make(int width, int height) { - return (long)(((ulong) width) << 32 | ((ulong) height)); + return (long)(((ulong) width) << 32 | ((uint) height)); } public static int GetWidth(long measureOutput) { - return (int) (0xFFFFFFFF & (measureOutput >> 32)); + return (int) (0xFFFFFFFF & (measureOutput >> 32)); } public static int GetHeight(long measureOutput) { - return (int) (0xFFFFFFFF & measureOutput); + return (int) (0xFFFFFFFF & measureOutput); } } } diff --git a/csharp/Facebook.CSSLayout/Native.bindings.cs b/csharp/Facebook.CSSLayout/Native.bindings.cs index bfff138..33f60d8 100644 --- a/csharp/Facebook.CSSLayout/Native.bindings.cs +++ b/csharp/Facebook.CSSLayout/Native.bindings.cs @@ -13,7 +13,7 @@ using Unity.Bindings; namespace UnityEngine.CSSLayout { - [NativeType(Header = "External/CSSLayout/CSSLayout.h")] + [NativeType(Header = "External/CSSLayout/CSSLayout/CSSLayout.h")] internal static partial class Native { #if UNITY_IOS && !UNITY_EDITOR @@ -23,16 +23,11 @@ namespace UnityEngine.CSSLayout #endif // BEGIN_UNITY -// TODO we don't support the logging & assert feature yet +// TODO we don't support the logging feature yet // [DllImport(DllName)] // public static extern void CSSInteropSetLogger( // [MarshalAs(UnmanagedType.FunctionPtr)] CSSLogger.Func func); -// -// [DllImport(DllName)] -// public static extern void CSSAssertSetFailFunc( -// [MarshalAs(UnmanagedType.FunctionPtr)] CSSAssert.FailFunc func); // END_UNITY - [NativeMethod(IsFreeFunction = true)] public static extern IntPtr CSSNodeNew(); @@ -48,6 +43,15 @@ namespace UnityEngine.CSSLayout [NativeMethod(IsFreeFunction = true)] public static extern int CSSNodeGetInstanceCount(); + [NativeMethod(IsFreeFunction = true)] + public static extern void CSSLayoutSetExperimentalFeatureEnabled( + CSSExperimentalFeature feature, + bool enabled); + + [NativeMethod(IsFreeFunction = true)] + public static extern bool CSSLayoutIsExperimentalFeatureEnabled( + CSSExperimentalFeature feature); + [NativeMethod(IsFreeFunction = true)] public static extern void CSSNodeInsertChild(IntPtr node, IntPtr child, uint index); @@ -78,6 +82,9 @@ namespace UnityEngine.CSSLayout [NativeMethod(IsFreeFunction = true)] public static extern bool CSSValueIsUndefined(float value); + [NativeMethod(IsFreeFunction = true)] + public static extern void CSSNodeCopyStyle(IntPtr dstNode, IntPtr srcNode); + #region CSS_NODE_PROPERTY [NativeMethod(IsFreeFunction = true)] @@ -97,12 +104,6 @@ namespace UnityEngine.CSSLayout // public static extern CSSMeasureFunc CSSNodeGetMeasureFunc(IntPtr node); // END_UNITY - [NativeMethod(IsFreeFunction = true)] - public static extern void CSSNodeSetIsTextnode(IntPtr node, bool isTextNode); - - [NativeMethod(IsFreeFunction = true)] - public static extern bool CSSNodeGetIsTextnode(IntPtr node); - [NativeMethod(IsFreeFunction = true)] public static extern void CSSNodeSetHasNewLayout(IntPtr node, bool hasNewLayout); diff --git a/csharp/Facebook.CSSLayout/Spacing.cs b/csharp/Facebook.CSSLayout/Spacing.cs new file mode 100644 index 0000000..c8a74c7 --- /dev/null +++ b/csharp/Facebook.CSSLayout/Spacing.cs @@ -0,0 +1,34 @@ +/** + * 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. + */ + +// BEGIN_UNITY @joce 11-21-2016 CompileForC#Bindings +//namespace Facebook.CSSLayout +namespace UnityEngine.CSSLayout +// END_UNITY +{ + public class Spacing + { + public float? Top; + public float? Bottom; + public float? Left; + public float? Right; + + public Spacing( + float? top = null, + float? bottom = null, + float? left = null, + float? right = null) + { + Top = top; + Bottom = bottom; + Left = left; + Right = right; + } + } +} diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutAbsolutePositionTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutAbsolutePositionTest.cs index 0aa5687..c76e6b5 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutAbsolutePositionTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutAbsolutePositionTest.cs @@ -31,6 +31,11 @@
+ +
+
+
+
* */ @@ -60,7 +65,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -73,7 +78,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -101,7 +106,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -114,7 +119,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -142,7 +147,7 @@ namespace CSSLayoutTests root_child0.SetPosition(CSSEdge.End, 10); root_child0.SetPosition(CSSEdge.Bottom, 10); root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -155,7 +160,7 @@ namespace CSSLayoutTests Assert.AreEqual(80, root_child0.LayoutWidth); Assert.AreEqual(80, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -185,7 +190,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -198,7 +203,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -231,7 +236,7 @@ namespace CSSLayoutTests root_child0_child0.StyleWidth = 100; root_child0_child0.StyleHeight = 100; root_child0.Insert(0, root_child0_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -249,7 +254,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0_child0.LayoutWidth); Assert.AreEqual(100, root_child0_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -268,5 +273,76 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0_child0.LayoutHeight); } + [Test] + public void Test_absolute_layout_within_border() + { + CSSNode root = new CSSNode(); + root.SetMargin(CSSEdge.Left, 10); + root.SetMargin(CSSEdge.Top, 10); + root.SetMargin(CSSEdge.Right, 10); + root.SetMargin(CSSEdge.Bottom, 10); + root.SetPadding(CSSEdge.Left, 10); + root.SetPadding(CSSEdge.Top, 10); + root.SetPadding(CSSEdge.Right, 10); + root.SetPadding(CSSEdge.Bottom, 10); + root.SetBorder(CSSEdge.Left, 10); + root.SetBorder(CSSEdge.Top, 10); + root.SetBorder(CSSEdge.Right, 10); + root.SetBorder(CSSEdge.Bottom, 10); + root.StyleWidth = 100; + root.StyleHeight = 100; + + CSSNode root_child0 = new CSSNode(); + root_child0.PositionType = CSSPositionType.Absolute; + root_child0.SetPosition(CSSEdge.Left, 0); + root_child0.SetPosition(CSSEdge.Top, 0); + root_child0.StyleWidth = 50; + root_child0.StyleHeight = 50; + root.Insert(0, root_child0); + + CSSNode root_child1 = new CSSNode(); + root_child1.PositionType = CSSPositionType.Absolute; + root_child1.SetPosition(CSSEdge.Right, 0); + root_child1.SetPosition(CSSEdge.Bottom, 0); + root_child1.StyleWidth = 50; + root_child1.StyleHeight = 50; + root.Insert(1, root_child1); + root.StyleDirection = CSSDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(10, root.LayoutX); + Assert.AreEqual(10, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(10, root_child0.LayoutX); + Assert.AreEqual(10, root_child0.LayoutY); + Assert.AreEqual(50, root_child0.LayoutWidth); + Assert.AreEqual(50, root_child0.LayoutHeight); + + Assert.AreEqual(40, root_child1.LayoutX); + Assert.AreEqual(40, root_child1.LayoutY); + Assert.AreEqual(50, root_child1.LayoutWidth); + Assert.AreEqual(50, root_child1.LayoutHeight); + + root.StyleDirection = CSSDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(10, root.LayoutX); + Assert.AreEqual(10, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(10, root_child0.LayoutX); + Assert.AreEqual(10, root_child0.LayoutY); + Assert.AreEqual(50, root_child0.LayoutWidth); + Assert.AreEqual(50, root_child0.LayoutHeight); + + Assert.AreEqual(40, root_child1.LayoutX); + Assert.AreEqual(40, root_child1.LayoutY); + Assert.AreEqual(50, root_child1.LayoutWidth); + Assert.AreEqual(50, root_child1.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignContentTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignContentTest.cs index 09b8f21..633573f 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignContentTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignContentTest.cs @@ -88,7 +88,7 @@ namespace CSSLayoutTests root_child4.StyleWidth = 50; root_child4.StyleHeight = 10; root.Insert(4, root_child4); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -121,7 +121,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child4.LayoutWidth); Assert.AreEqual(10, root_child4.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -188,7 +188,7 @@ namespace CSSLayoutTests root_child4.StyleWidth = 50; root_child4.StyleHeight = 10; root.Insert(4, root_child4); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -221,7 +221,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child4.LayoutWidth); Assert.AreEqual(10, root_child4.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -288,7 +288,7 @@ namespace CSSLayoutTests root_child4.StyleWidth = 50; root_child4.StyleHeight = 10; root.Insert(4, root_child4); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -321,7 +321,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child4.LayoutWidth); Assert.AreEqual(10, root_child4.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -383,7 +383,7 @@ namespace CSSLayoutTests CSSNode root_child4 = new CSSNode(); root_child4.StyleWidth = 50; root.Insert(4, root_child4); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -416,7 +416,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child4.LayoutWidth); Assert.AreEqual(0, root_child4.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignItemsTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignItemsTest.cs index d0452af..4db2b13 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignItemsTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignItemsTest.cs @@ -50,7 +50,7 @@ namespace CSSLayoutTests CSSNode root_child0 = new CSSNode(); root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -63,7 +63,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -89,7 +89,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -102,7 +102,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -128,7 +128,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -141,7 +141,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -167,7 +167,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -180,7 +180,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignSelfTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignSelfTest.cs index bc22f18..273560a 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignSelfTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutAlignSelfTest.cs @@ -52,7 +52,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -65,7 +65,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -91,7 +91,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -104,7 +104,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -130,7 +130,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -143,7 +143,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -170,7 +170,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -183,7 +183,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutBorderTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutBorderTest.cs index af18da8..557de49 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutBorderTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutBorderTest.cs @@ -51,7 +51,7 @@ namespace CSSLayoutTests root.SetBorder(CSSEdge.Top, 10); root.SetBorder(CSSEdge.Right, 10); root.SetBorder(CSSEdge.Bottom, 10); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -59,7 +59,7 @@ namespace CSSLayoutTests Assert.AreEqual(20, root.LayoutWidth); Assert.AreEqual(20, root.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -81,7 +81,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -94,7 +94,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -123,7 +123,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.StyleWidth = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -136,7 +136,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(80, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -164,7 +164,7 @@ namespace CSSLayoutTests CSSNode root_child0 = new CSSNode(); root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -177,7 +177,7 @@ namespace CSSLayoutTests Assert.AreEqual(80, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -207,7 +207,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -220,7 +220,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexDirectionTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexDirectionTest.cs index b0bc537..f6fbce6 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexDirectionTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexDirectionTest.cs @@ -77,7 +77,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -100,7 +100,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -142,7 +142,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -165,7 +165,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(100, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -207,7 +207,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -230,7 +230,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -273,7 +273,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -296,7 +296,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(100, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -339,7 +339,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -362,7 +362,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -405,7 +405,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -428,7 +428,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(100, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexTest.cs index bc4abcf..05b4d48 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexTest.cs @@ -41,6 +41,12 @@
+ +
+
+
+
+
* */ @@ -71,7 +77,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -89,7 +95,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child1.LayoutWidth); Assert.AreEqual(25, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -124,7 +130,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -142,7 +148,7 @@ namespace CSSLayoutTests Assert.AreEqual(25, root_child1.LayoutWidth); Assert.AreEqual(100, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -176,7 +182,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexBasis = 50; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -194,7 +200,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child1.LayoutWidth); Assert.AreEqual(50, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -229,7 +235,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexBasis = 50; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -247,7 +253,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child1.LayoutWidth); Assert.AreEqual(100, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -287,7 +293,7 @@ namespace CSSLayoutTests root_child2.StyleWidth = 50; root_child2.StyleHeight = 50; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -310,7 +316,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child2.LayoutWidth); Assert.AreEqual(50, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -356,7 +362,7 @@ namespace CSSLayoutTests root_child2.FlexGrow = 1; root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -379,7 +385,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child2.LayoutWidth); Assert.AreEqual(20, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -403,5 +409,56 @@ namespace CSSLayoutTests Assert.AreEqual(20, root_child2.LayoutHeight); } + [Test] + public void Test_flex_grow_shrink_at_most() + { + CSSNode root = new CSSNode(); + root.StyleWidth = 100; + root.StyleHeight = 100; + + CSSNode root_child0 = new CSSNode(); + root.Insert(0, root_child0); + + CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.FlexGrow = 1; + root_child0_child0.FlexShrink = 1; + root_child0.Insert(0, root_child0_child0); + root.StyleDirection = CSSDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(0, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(100, root_child0_child0.LayoutWidth); + Assert.AreEqual(0, root_child0_child0.LayoutHeight); + + root.StyleDirection = CSSDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(0, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(100, root_child0_child0.LayoutWidth); + Assert.AreEqual(0, root_child0_child0.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexWrapTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexWrapTest.cs index 17ed81e..ee4fd02 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexWrapTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutFlexWrapTest.cs @@ -78,7 +78,7 @@ namespace CSSLayoutTests root_child3.StyleWidth = 30; root_child3.StyleHeight = 30; root.Insert(3, root_child3); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -106,7 +106,7 @@ namespace CSSLayoutTests Assert.AreEqual(30, root_child3.LayoutWidth); Assert.AreEqual(30, root_child3.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -162,7 +162,7 @@ namespace CSSLayoutTests root_child3.StyleWidth = 30; root_child3.StyleHeight = 30; root.Insert(3, root_child3); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -190,7 +190,7 @@ namespace CSSLayoutTests Assert.AreEqual(30, root_child3.LayoutWidth); Assert.AreEqual(30, root_child3.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -247,7 +247,7 @@ namespace CSSLayoutTests root_child3.StyleWidth = 30; root_child3.StyleHeight = 30; root.Insert(3, root_child3); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -275,7 +275,7 @@ namespace CSSLayoutTests Assert.AreEqual(30, root_child3.LayoutWidth); Assert.AreEqual(30, root_child3.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -332,7 +332,7 @@ namespace CSSLayoutTests root_child3.StyleWidth = 30; root_child3.StyleHeight = 30; root.Insert(3, root_child3); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -360,7 +360,7 @@ namespace CSSLayoutTests Assert.AreEqual(30, root_child3.LayoutWidth); Assert.AreEqual(30, root_child3.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutJustifyContentTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutJustifyContentTest.cs index 50fb527..9d5ce74 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutJustifyContentTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutJustifyContentTest.cs @@ -103,7 +103,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -126,7 +126,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(102, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -170,7 +170,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -193,7 +193,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(102, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -237,7 +237,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -260,7 +260,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(102, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -304,7 +304,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -327,7 +327,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(102, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -371,7 +371,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleWidth = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -394,7 +394,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child2.LayoutWidth); Assert.AreEqual(102, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -435,7 +435,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -458,7 +458,7 @@ namespace CSSLayoutTests Assert.AreEqual(102, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -501,7 +501,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -524,7 +524,7 @@ namespace CSSLayoutTests Assert.AreEqual(102, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -567,7 +567,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -590,7 +590,7 @@ namespace CSSLayoutTests Assert.AreEqual(102, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -633,7 +633,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -656,7 +656,7 @@ namespace CSSLayoutTests Assert.AreEqual(102, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -699,7 +699,7 @@ namespace CSSLayoutTests CSSNode root_child2 = new CSSNode(); root_child2.StyleHeight = 10; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -722,7 +722,7 @@ namespace CSSLayoutTests Assert.AreEqual(102, root_child2.LayoutWidth); Assert.AreEqual(10, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutMarginTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutMarginTest.cs index bc32314..2911a7f 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutMarginTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutMarginTest.cs @@ -78,7 +78,7 @@ namespace CSSLayoutTests root_child0.SetMargin(CSSEdge.Start, 10); root_child0.StyleWidth = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -91,7 +91,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(100, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -116,7 +116,7 @@ namespace CSSLayoutTests root_child0.SetMargin(CSSEdge.Top, 10); root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -129,7 +129,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -156,7 +156,7 @@ namespace CSSLayoutTests root_child0.SetMargin(CSSEdge.End, 10); root_child0.StyleWidth = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -169,7 +169,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(100, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -195,7 +195,7 @@ namespace CSSLayoutTests root_child0.SetMargin(CSSEdge.Bottom, 10); root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -208,7 +208,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -234,7 +234,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.SetMargin(CSSEdge.Start, 10); root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -247,7 +247,7 @@ namespace CSSLayoutTests Assert.AreEqual(90, root_child0.LayoutWidth); Assert.AreEqual(100, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -272,7 +272,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.SetMargin(CSSEdge.Top, 10); root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -285,7 +285,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0.LayoutWidth); Assert.AreEqual(90, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -311,7 +311,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.SetMargin(CSSEdge.Top, 10); root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -324,7 +324,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0.LayoutWidth); Assert.AreEqual(90, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -349,7 +349,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.SetMargin(CSSEdge.Start, 10); root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -362,7 +362,7 @@ namespace CSSLayoutTests Assert.AreEqual(90, root_child0.LayoutWidth); Assert.AreEqual(100, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -391,7 +391,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -409,7 +409,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child1.LayoutWidth); Assert.AreEqual(100, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -442,7 +442,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -460,7 +460,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child1.LayoutWidth); Assert.AreEqual(50, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs index 54b3bab..c01a30a 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs @@ -47,6 +47,12 @@
+ +
+
+
+
+
* */ @@ -73,7 +79,7 @@ namespace CSSLayoutTests root_child0.StyleMaxWidth = 50; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -86,7 +92,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -112,7 +118,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleMaxHeight = 50; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -125,7 +131,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(50, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -154,7 +160,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -172,7 +178,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child1.LayoutWidth); Assert.AreEqual(20, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -207,7 +213,7 @@ namespace CSSLayoutTests CSSNode root_child1 = new CSSNode(); root_child1.FlexGrow = 1; root.Insert(1, root_child1); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -225,7 +231,7 @@ namespace CSSLayoutTests Assert.AreEqual(20, root_child1.LayoutWidth); Assert.AreEqual(100, root_child1.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -257,7 +263,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 60; root_child0.StyleHeight = 60; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -270,7 +276,7 @@ namespace CSSLayoutTests Assert.AreEqual(60, root_child0.LayoutWidth); Assert.AreEqual(60, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -297,7 +303,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 60; root_child0.StyleHeight = 60; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -310,7 +316,7 @@ namespace CSSLayoutTests Assert.AreEqual(60, root_child0.LayoutWidth); Assert.AreEqual(60, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -346,7 +352,7 @@ namespace CSSLayoutTests root_child2.StyleWidth = 50; root_child2.StyleHeight = 50; root.Insert(2, root_child2); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -369,7 +375,7 @@ namespace CSSLayoutTests Assert.AreEqual(50, root_child2.LayoutWidth); Assert.AreEqual(50, root_child2.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -409,7 +415,7 @@ namespace CSSLayoutTests root_child0_child0.FlexGrow = 1; root_child0_child0.StyleHeight = 20; root_child0.Insert(0, root_child0_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -427,7 +433,7 @@ namespace CSSLayoutTests Assert.AreEqual(100, root_child0_child0.LayoutWidth); Assert.AreEqual(20, root_child0_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -446,5 +452,58 @@ namespace CSSLayoutTests Assert.AreEqual(20, root_child0_child0.LayoutHeight); } + [Test] + public void Test_flex_grow_within_constrained_max_width() + { + CSSNode root = new CSSNode(); + root.StyleWidth = 200; + root.StyleHeight = 100; + + CSSNode root_child0 = new CSSNode(); + root_child0.FlexDirection = CSSFlexDirection.Row; + root_child0.StyleMaxWidth = 300; + root.Insert(0, root_child0); + + CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.FlexGrow = 1; + root_child0_child0.StyleHeight = 20; + root_child0.Insert(0, root_child0_child0); + root.StyleDirection = CSSDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(200, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(200, root_child0.LayoutWidth); + Assert.AreEqual(20, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(20, root_child0_child0.LayoutHeight); + + root.StyleDirection = CSSDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(200, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(200, root_child0.LayoutWidth); + Assert.AreEqual(20, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(20, root_child0_child0.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutPaddingTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutPaddingTest.cs index 8271ea2..2a24678 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSLayoutPaddingTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutPaddingTest.cs @@ -51,7 +51,7 @@ namespace CSSLayoutTests root.SetPadding(CSSEdge.Top, 10); root.SetPadding(CSSEdge.Right, 10); root.SetPadding(CSSEdge.Bottom, 10); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -59,7 +59,7 @@ namespace CSSLayoutTests Assert.AreEqual(20, root.LayoutWidth); Assert.AreEqual(20, root.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -81,7 +81,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -94,7 +94,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -123,7 +123,7 @@ namespace CSSLayoutTests root_child0.FlexGrow = 1; root_child0.StyleWidth = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -136,7 +136,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(80, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -164,7 +164,7 @@ namespace CSSLayoutTests CSSNode root_child0 = new CSSNode(); root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -177,7 +177,7 @@ namespace CSSLayoutTests Assert.AreEqual(80, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -207,7 +207,7 @@ namespace CSSLayoutTests root_child0.StyleWidth = 10; root_child0.StyleHeight = 10; root.Insert(0, root_child0); - root.StyleDirection = CSSDirection.LeftToRight; + root.StyleDirection = CSSDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); @@ -220,7 +220,7 @@ namespace CSSLayoutTests Assert.AreEqual(10, root_child0.LayoutWidth); Assert.AreEqual(10, root_child0.LayoutHeight); - root.StyleDirection = CSSDirection.RightToLeft; + root.StyleDirection = CSSDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0, root.LayoutX); diff --git a/csharp/tests/Facebook.CSSLayout/CSSNodeCreateTest.cs b/csharp/tests/Facebook.CSSLayout/CSSNodeCreateTest.cs new file mode 100644 index 0000000..b543df8 --- /dev/null +++ b/csharp/tests/Facebook.CSSLayout/CSSNodeCreateTest.cs @@ -0,0 +1,148 @@ +/** + * 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. + */ + +using NUnit.Framework; +using System; + +/** + * Tests for {@link CSSNode}. + */ +// BEGIN-UNITY +using UnityEngine.CSSLayout; + +// namespace Facebook.CSSLayout +namespace CSSLayoutTests +// END-UNITY +{ + [TestFixture] + public class CSSNodeCreateTest + { + [Test] + public void TestSimple() + { + CSSNode nodeDefault = new CSSNode(); + CSSNode nodeCreated = CSSNode.Create(flexDirection: CSSFlexDirection.Row); + Assert.AreEqual(CSSFlexDirection.Row, nodeCreated.FlexDirection); + Assert.IsFalse(nodeDefault.IsDirty); + nodeDefault.CopyStyle(nodeCreated); + Assert.IsTrue(nodeDefault.IsDirty); + } + + [Test] + public void TestSame() + { + CSSNode nodeDefault = new CSSNode(); + CSSNode nodeCreated = CSSNode.Create(); + Assert.IsFalse(nodeDefault.IsDirty); + nodeDefault.CopyStyle(nodeCreated); + Assert.IsFalse(nodeDefault.IsDirty); + } + + [Test] + public void TestMultiple() + { + CSSNode node = CSSNode.Create( + positionType: CSSPositionType.Absolute, + wrap: CSSWrap.Wrap, + position: new Spacing(top:6, right:4), + margin: new Spacing(bottom:5, left:3)); + + Assert.AreEqual(CSSFlexDirection.Column, node.FlexDirection); + Assert.AreEqual(CSSPositionType.Absolute, node.PositionType); + Assert.AreEqual(CSSWrap.Wrap, node.Wrap); + Assert.AreEqual(6, node.GetPosition(CSSEdge.Top)); + Assert.IsTrue(CSSConstants.IsUndefined(node.GetPosition(CSSEdge.Bottom))); + Assert.AreEqual(4, node.GetPosition(CSSEdge.Right)); + Assert.IsTrue(CSSConstants.IsUndefined(node.GetPosition(CSSEdge.Left))); + Assert.AreEqual(0, node.GetMargin(CSSEdge.Top)); + Assert.AreEqual(5, node.GetMargin(CSSEdge.Bottom)); + Assert.AreEqual(3, node.GetMargin(CSSEdge.Left)); + Assert.AreEqual(0, node.GetMargin(CSSEdge.Right)); + } + + [Test] + public void TestFull() + { + CSSNode node = CSSNode.Create( + styleDirection: CSSDirection.RTL, + flexDirection: CSSFlexDirection.RowReverse, + + justifyContent: CSSJustify.SpaceAround, + alignContent: CSSAlign.Center, + alignItems: CSSAlign.FlexEnd, + alignSelf: CSSAlign.Stretch, + + positionType: CSSPositionType.Absolute, + wrap: CSSWrap.Wrap, + overflow: CSSOverflow.Scroll, + + flex: 1, + flexGrow: 2, + flexShrink: 3, + flexBasis: 4, + + position: new Spacing(top: 5, bottom: 6, left: 7, right: 8), + margin: new Spacing(top: 9, bottom: 10, left: 11, right: 12), + padding: new Spacing(top: 13, bottom: 14, left: 15, right: 16), + border: new Spacing(top: 17, bottom: 18, left: 19, right: 20), + + styleWidth: 21, + styleHeight: 22, + styleMinWidth: 23, + styleMinHeight: 24, + styleMaxWidth: 25, + styleMaxHeight: 26); + + Assert.AreEqual(CSSDirection.RTL, node.StyleDirection); + Assert.AreEqual(CSSFlexDirection.RowReverse, node.FlexDirection); + + Assert.AreEqual(CSSJustify.SpaceAround, node.JustifyContent); + Assert.AreEqual(CSSAlign.Center, node.AlignContent); + Assert.AreEqual(CSSAlign.FlexEnd, node.AlignItems); + Assert.AreEqual(CSSAlign.Stretch, node.AlignSelf); + + Assert.AreEqual(CSSPositionType.Absolute, node.PositionType); + Assert.AreEqual(CSSWrap.Wrap, node.Wrap); + Assert.AreEqual(CSSOverflow.Scroll, node.Overflow); + + Assert.AreEqual(2, node.FlexGrow); + Assert.AreEqual(3, node.FlexShrink); + Assert.AreEqual(4, node.FlexBasis); + node.FlexGrow = CSSConstants.Undefined; + Assert.AreEqual(1, node.FlexGrow); + + Assert.AreEqual(5, node.GetPosition(CSSEdge.Top)); + Assert.AreEqual(6, node.GetPosition(CSSEdge.Bottom)); + Assert.AreEqual(7, node.GetPosition(CSSEdge.Left)); + Assert.AreEqual(8, node.GetPosition(CSSEdge.Right)); + + Assert.AreEqual(9, node.GetMargin(CSSEdge.Top)); + Assert.AreEqual(10, node.GetMargin(CSSEdge.Bottom)); + Assert.AreEqual(11, node.GetMargin(CSSEdge.Left)); + Assert.AreEqual(12, node.GetMargin(CSSEdge.Right)); + + Assert.AreEqual(13, node.GetPadding(CSSEdge.Top)); + Assert.AreEqual(14, node.GetPadding(CSSEdge.Bottom)); + Assert.AreEqual(15, node.GetPadding(CSSEdge.Left)); + Assert.AreEqual(16, node.GetPadding(CSSEdge.Right)); + + Assert.AreEqual(17, node.GetBorder(CSSEdge.Top)); + Assert.AreEqual(18, node.GetBorder(CSSEdge.Bottom)); + Assert.AreEqual(19, node.GetBorder(CSSEdge.Left)); + Assert.AreEqual(20, node.GetBorder(CSSEdge.Right)); + + Assert.AreEqual(21, node.StyleWidth); + Assert.AreEqual(22, node.StyleHeight); + Assert.AreEqual(23, node.StyleMinWidth); + Assert.AreEqual(24, node.StyleMinHeight); + Assert.AreEqual(25, node.StyleMaxWidth); + Assert.AreEqual(26, node.StyleMaxHeight); + } + } +} diff --git a/csharp/tests/Facebook.CSSLayout/CSSNodeTest.cs b/csharp/tests/Facebook.CSSLayout/CSSNodeTest.cs index 3f2a631..e6719e9 100644 --- a/csharp/tests/Facebook.CSSLayout/CSSNodeTest.cs +++ b/csharp/tests/Facebook.CSSLayout/CSSNodeTest.cs @@ -9,6 +9,10 @@ using NUnit.Framework; using System; + +/** + * Tests for {@link CSSNode}. + */ // BEGIN-UNITY using UnityEngine.CSSLayout; @@ -73,7 +77,7 @@ namespace CSSLayoutTests Assert.AreEqual(0, parent.Count); } -// BEGIN_UNITY +// BEGIN_UNITY @joce 11-21-2016 TestsForC# #if !UNITY_EDITOR // we don't currently support this library's assert system // END_UNITY [Test] @@ -105,7 +109,7 @@ namespace CSSLayoutTests parent1.Insert(0, child); parent2.Insert(0, child); } -// BEGIN_UNITY +// BEGIN_UNITY @joce 11-21-2016 TestsForC# #endif // END_UNITY @@ -119,7 +123,7 @@ namespace CSSLayoutTests Assert.AreEqual(instanceCount + 1, CSSNode.GetInstanceCount()); } -// BEGIN_UNITY +// BEGIN_UNITY @joce 11-21-2016 TestsForC# #if !UNITY_EDITOR // we don't currently support this library's assert system // END_UNITY [Test] @@ -141,7 +145,7 @@ namespace CSSLayoutTests parent.Insert(0, child); child.Reset(); } -// BEGIN_UNITY +// BEGIN_UNITY @joce 11-21-2016 TestsForC# #endif // END_UNITY @@ -162,8 +166,8 @@ namespace CSSLayoutTests Assert.AreEqual(instanceCount + 2, CSSNode.GetInstanceCount()); } -// BEGIN_UNITY -#if !UNITY_EDITOR // we don't currently support custom measurement +// BEGIN_UNITY @joce 11-21-2016 TestsForC# +#if !UNITY_EDITOR // we don't currently support this library's assert system // END_UNITY [Test] @@ -174,8 +178,44 @@ namespace CSSLayoutTests return MeasureOutput.Make(100, 150); }); node.CalculateLayout(); - Assert.AreEqual(100, (int)node.LayoutWidth); - Assert.AreEqual(150, (int)node.LayoutHeight); + Assert.AreEqual(100, node.LayoutWidth); + Assert.AreEqual(150, node.LayoutHeight); + } + + [Test] + public void TestMeasureFuncWithFloat() + { + CSSNode node = new CSSNode(); + node.SetMeasureFunction((_, width, widthMode, height, heightMode) => { + return MeasureOutput.Make(123.4f, 81.7f); + }); + node.CalculateLayout(); + Assert.AreEqual(123, node.LayoutWidth); + Assert.AreEqual(81, node.LayoutHeight); + } + + [Test] + [ExpectedException("System.InvalidOperationException")] + public void TestChildWithMeasureFunc() + { + CSSNode node = new CSSNode(); + node.SetMeasureFunction((_, width, widthMode, height, heightMode) => { + return MeasureOutput.Make(100, 150); + }); + CSSNode child = new CSSNode(); + node.Insert(0, child); + } + + [Test] + [ExpectedException("System.InvalidOperationException")] + public void TestMeasureFuncWithChild() + { + CSSNode node = new CSSNode(); + CSSNode child = new CSSNode(); + node.Insert(0, child); + node.SetMeasureFunction((_, width, widthMode, height, heightMode) => { + return MeasureOutput.Make(100, 150); + }); } [Test] @@ -195,16 +235,31 @@ namespace CSSLayoutTests parent.CalculateLayout(); Assert.AreEqual(parent.Print(), "{layout: {width: 100, height: 120, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 100, height: 120, children: [\n {layout: {width: 35, height: 45, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 35, height: 45, },\n {layout: {width: 30, height: 40, top: 45, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 30, height: 40, },\n]},\n"); } -// BEGIN_UNITY + +// BEGIN_UNITY @joce 11-21-2016 TestsForC# #endif // END_UNITY + + [Test] + public void TestCopyStyle() + { + CSSNode node0 = new CSSNode(); + Assert.IsTrue(CSSConstants.IsUndefined(node0.StyleMaxHeight)); + + CSSNode node1 = new CSSNode(); + node1.StyleMaxHeight = 100; + + node0.CopyStyle(node1); + Assert.AreEqual(100, node0.StyleMaxHeight); + } + +#if !UNITY_EDITOR private void ForceGC() { GC.Collect(GC.MaxGeneration); GC.WaitForPendingFinalizers(); } -#if !UNITY_EDITOR // note this was already excluded in the initial implementation [Test] public void TestDestructor() { diff --git a/csharp/tests/Facebook.CSSLayout/test_macos.sh b/csharp/tests/Facebook.CSSLayout/test_macos.sh index 27e39f6..566170e 100755 --- a/csharp/tests/Facebook.CSSLayout/test_macos.sh +++ b/csharp/tests/Facebook.CSSLayout/test_macos.sh @@ -9,11 +9,13 @@ if mcs --version >/dev/null 2>&1; then true; else exit 1 fi -if mono64 --version >/dev/null 2>&1; then true; else +if mono --version >/dev/null 2>&1; then true; else echo "ERROR: Can't execute mono64. You need to install Mono from http://www.mono-project.com/download/ and re-login to apply PATH environment." exit 1 fi +cd "$( dirname "$0" )" + NUNIT=NUnit-2.6.4/bin if [ -d $NUNIT \ -a -f $NUNIT/nunit-console.exe \ @@ -22,11 +24,10 @@ if [ -d $NUNIT \ -a -f $NUNIT/lib/nunit.core.interfaces.dll \ -a -f $NUNIT/lib/nunit.util.dll ]; then true; else curl -L -O https://github.com/nunit/nunitv2/releases/download/2.6.4/NUnit-2.6.4.zip - unzip NUnit-2.6.4.zip + unzip -qq NUnit-2.6.4.zip rm NUnit-2.6.4.zip fi -cd "$( dirname "$0" )" -clang -g -DCSS_ASSERT_FAIL_ENABLED -Wall -Wextra -dynamiclib -o libCSSLayout.dylib -I../../.. ../../../CSSLayout/*.c ../../CSSLayout/CSSInterop.cpp +clang -g -Wall -Wextra -dynamiclib -o libCSSLayout.dylib -I../../.. ../../../CSSLayout/*.c ../../CSSLayout/CSSInterop.cpp mcs -debug -t:library -r:$NUNIT/nunit.framework.dll -out:CSSLayoutTest.dll *.cs ../../../csharp/Facebook.CSSLayout/*cs -MONO_PATH=$NUNIT mono64 --debug $NUNIT/nunit-console.exe CSSLayoutTest.dll +MONO_PATH=$NUNIT mono --arch=64 --debug $NUNIT/nunit-console.exe CSSLayoutTest.dll diff --git a/enums.py b/enums.py new file mode 100644 index 0000000..40f36d5 --- /dev/null +++ b/enums.py @@ -0,0 +1,182 @@ +# 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. + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals +import os + +ENUMS = { + 'CSSDirection': [ + 'Inherit', + 'LTR', + 'RTL', + ], + 'CSSFlexDirection': [ + 'Column', + 'ColumnReverse', + 'Row', + 'RowReverse', + ], + 'CSSJustify': [ + 'FlexStart', + 'Center', + 'FlexEnd', + 'SpaceBetween', + 'SpaceAround', + ], + 'CSSOverflow': [ + 'Visible', + 'Hidden', + 'Scroll', + ], + 'CSSAlign': [ + 'Auto', + 'FlexStart', + 'Center', + 'FlexEnd', + 'Stretch', + ], + 'CSSPositionType': [ + 'Relative', + 'Absolute', + ], + 'CSSWrap': [ + 'NoWrap', + 'Wrap', + ], + 'CSSMeasureMode': [ + 'Undefined', + 'Exactly', + 'AtMost', + ], + 'CSSDimension': [ + 'Width', + 'Height', + ], + 'CSSEdge': [ + 'Left', + 'Top', + 'Right', + 'Bottom', + 'Start', + 'End', + 'Horizontal', + 'Vertical', + 'All', + ], + 'CSSLogLevel': [ + 'Error', + 'Warn', + 'Info', + 'Debug', + 'Verbose', + ], + 'CSSExperimentalFeature': [], + 'CSSPrintOptions': [ + ('Layout', 1), + ('Style', 2), + ('Children', 4), + ], +} + +LICENSE = """/** + * 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. + */ + +""" + +def to_java_upper(symbol): + symbol = str(symbol) + out = '' + for i in range(0, len(symbol)): + c = symbol[i] + if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]): + out += '_' + out += c.upper() + return out + + +root = os.path.dirname(__file__) + +# write out C header +with open(root + '/CSSLayout/CSSEnums.h', 'w') as f: + f.write(LICENSE) + remaining = len(ENUMS) + for name, values in ENUMS.items(): + f.write('typedef enum %s {\n' % name) + for value in values: + if isinstance(value, tuple): + f.write(' %s%s = %d,\n' % (name, value[0], value[1])) + else: + f.write(' %s%s,\n' % (name, value)) + f.write(' %sCount,\n' % name) + f.write('} %s;\n' % name) + if remaining > 1: + f.write('\n') + remaining = remaining - 1 + +# write out java files +for name, values in ENUMS.items(): + with open(root + '/java/com/facebook/csslayout/%s.java' % name, 'w') as f: + f.write(LICENSE) + f.write('package com.facebook.csslayout;\n\n') + f.write('public enum %s {\n' % name) + if len(values) > 0: + for value in values: + if isinstance(value, tuple): + f.write(' %s(%d)' % (to_java_upper(value[0]), value[1])) + else: + f.write(' %s(%d)' % (to_java_upper(value), values.index(value))) + if values.index(value) is len(values) - 1: + f.write(';\n') + else: + f.write(',\n') + else: + f.write('__EMPTY(-1);') + f.write('\n') + f.write(' private int mIntValue;\n') + f.write('\n') + f.write(' %s(int intValue) {\n' % name) + f.write(' mIntValue = intValue;\n') + f.write(' }\n') + f.write('\n') + f.write(' public int intValue() {\n') + f.write(' return mIntValue;\n') + f.write(' }\n') + f.write('\n') + f.write(' public static %s fromInt(int value) {\n' % name) + f.write(' switch (value) {\n') + for value in values: + if isinstance(value, tuple): + f.write(' case %d: return %s;\n' % (value[1], to_java_upper(value[0]))) + else: + f.write(' case %d: return %s;\n' % (values.index(value), to_java_upper(value))) + f.write(' default: throw new IllegalArgumentException("Unkown enum value: " + value);\n') + f.write(' }\n') + f.write(' }\n') + f.write('}\n') + +# write out csharp files +for name, values in ENUMS.items(): + with open(root + '/csharp/Facebook.CSSLayout/%s.cs' % name, 'w') as f: + f.write(LICENSE) + f.write('namespace Facebook.CSSLayout\n{\n') + f.write(' public enum %s\n {\n' % name) + for value in values: + if isinstance(value, tuple): + f.write(' %s = %d,\n' % (value[0], value[1])) + else: + f.write(' %s,\n' % value) + f.write(' }\n') + f.write('}\n') diff --git a/gentest/fixtures/CSSLayoutAbsolutePositionTest.html b/gentest/fixtures/CSSLayoutAbsolutePositionTest.html index 37ebffe..8530e04 100644 --- a/gentest/fixtures/CSSLayoutAbsolutePositionTest.html +++ b/gentest/fixtures/CSSLayoutAbsolutePositionTest.html @@ -19,3 +19,8 @@
+ +
+
+
+
diff --git a/gentest/fixtures/CSSLayoutFlexTest.html b/gentest/fixtures/CSSLayoutFlexTest.html index 5689a6e..30da202 100644 --- a/gentest/fixtures/CSSLayoutFlexTest.html +++ b/gentest/fixtures/CSSLayoutFlexTest.html @@ -29,3 +29,9 @@
+ +
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html index 599f3fe..6e46970 100644 --- a/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html +++ b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html @@ -35,3 +35,9 @@
+ +
+
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js index dc0427b..9e37881 100644 --- a/gentest/gentest-cpp.js +++ b/gentest/gentest-cpp.js @@ -84,8 +84,8 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { CSSPositionTypeAbsolute:{value:'CSSPositionTypeAbsolute'}, CSSPositionTypeRelative:{value:'CSSPositionTypeRelative'}, - CSSWrapTypeNoWrap:{value:'CSSWrapTypeNoWrap'}, - CSSWrapTypeWrap:{value:'CSSWrapTypeWrap'}, + CSSWrapNoWrap:{value:'CSSWrapNoWrap'}, + CSSWrapWrap:{value:'CSSWrapWrap'}, CSSUndefined:{value:'CSSUndefined'}, diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js index c2046ef..f96d557 100644 --- a/gentest/gentest-cs.js +++ b/gentest/gentest-cs.js @@ -71,8 +71,8 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { CSSAlignStretch:{value:'CSSAlign.Stretch'}, CSSDirectionInherit:{value:'CSSDirection.Inherit'}, - CSSDirectionLTR:{value:'CSSDirection.LeftToRight'}, - CSSDirectionRTL:{value:'CSSDirection.RightToLeft'}, + CSSDirectionLTR:{value:'CSSDirection.LTR'}, + CSSDirectionRTL:{value:'CSSDirection.RTL'}, CSSEdgeBottom:{value:'CSSEdge.Bottom'}, CSSEdgeEnd:{value:'CSSEdge.End'}, @@ -100,8 +100,8 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { CSSUndefined:{value:'CSSConstants.Undefined'}, - CSSWrapTypeNoWrap:{value:'CSSWrap.NoWrap'}, - CSSWrapTypeWrap:{value:'CSSWrap.Wrap'}, + CSSWrapNoWrap:{value:'CSSWrap.NoWrap'}, + CSSWrapWrap:{value:'CSSWrap.Wrap'}, CSSNodeCalculateLayout:{value:function(node, dir) { this.push(node + '.StyleDirection = ' + dir + ';'); diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js index f1dbb06..853bf65 100644 --- a/gentest/gentest-java.js +++ b/gentest/gentest-java.js @@ -93,8 +93,8 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { CSSUndefined:{value:'CSSConstants.UNDEFINED'}, - CSSWrapTypeNoWrap:{value:'CSSWrap.NO_WRAP'}, - CSSWrapTypeWrap:{value:'CSSWrap.WRAP'}, + CSSWrapNoWrap:{value:'CSSWrap.NO_WRAP'}, + CSSWrapWrap:{value:'CSSWrap.WRAP'}, CSSNodeCalculateLayout:{value:function(node, dir) { this.push(node + '.setDirection(' + dir + ');'); diff --git a/gentest/gentest.js b/gentest/gentest.js index 07fef38..26204c3 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -354,8 +354,8 @@ function overflowValue(e, value) { function wrapValue(e, value) { switch (value) { - case 'wrap': return e.CSSWrapTypeWrap; - case 'nowrap': return e.CSSWrapTypeNoWrap; + case 'wrap': return e.CSSWrapWrap; + case 'nowrap': return e.CSSWrapNoWrap; } } diff --git a/java/BUCK b/java/BUCK index 67c1217..25f5585 100644 --- a/java/BUCK +++ b/java/BUCK @@ -20,7 +20,9 @@ cxx_library( '-O3', '-std=c++11', ], - deps = JNI_DEPS + [ + deps = [ + FBJNI_TARGET, + JNI_TARGET, csslayout_dep(':CSSLayout'), ], visibility = ['PUBLIC'], @@ -30,7 +32,7 @@ java_library( name = 'java', srcs = glob(['com/facebook/csslayout/*.java']), tests=[ - csslayout_dep('/java:tests'), + csslayout_dep('java:tests'), ], source = '1.7', target = '1.7', @@ -47,10 +49,11 @@ java_library( java_test( name = 'tests', srcs = glob(['tests/**/*.java']), + use_cxx_libraries = True, + cxx_library_whitelist = CXX_LIBRARY_WHITELIST, deps = [ ':java', JUNIT_TARGET, ], - use_cxx_libraries = True, - cxx_library_whitelist = CXX_LIBRARY_WHITELIST, + visibility = ['PUBLIC'], ) diff --git a/java/com/facebook/csslayout/CSSAlign.java b/java/com/facebook/csslayout/CSSAlign.java index 3e3cb0e..2dedee0 100644 --- a/java/com/facebook/csslayout/CSSAlign.java +++ b/java/com/facebook/csslayout/CSSAlign.java @@ -10,9 +10,30 @@ package com.facebook.csslayout; public enum CSSAlign { - AUTO, - FLEX_START, - CENTER, - FLEX_END, - STRETCH, + AUTO(0), + FLEX_START(1), + CENTER(2), + FLEX_END(3), + STRETCH(4); + + private int mIntValue; + + CSSAlign(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSAlign fromInt(int value) { + switch (value) { + case 0: return AUTO; + case 1: return FLEX_START; + case 2: return CENTER; + case 3: return FLEX_END; + case 4: return STRETCH; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSDimension.java b/java/com/facebook/csslayout/CSSDimension.java new file mode 100644 index 0000000..e3fde02 --- /dev/null +++ b/java/com/facebook/csslayout/CSSDimension.java @@ -0,0 +1,33 @@ +/** + * 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.csslayout; + +public enum CSSDimension { + WIDTH(0), + HEIGHT(1); + + private int mIntValue; + + CSSDimension(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSDimension fromInt(int value) { + switch (value) { + case 0: return WIDTH; + case 1: return HEIGHT; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } +} diff --git a/java/com/facebook/csslayout/CSSDirection.java b/java/com/facebook/csslayout/CSSDirection.java index 0c27a92..c0e84f1 100644 --- a/java/com/facebook/csslayout/CSSDirection.java +++ b/java/com/facebook/csslayout/CSSDirection.java @@ -10,7 +10,26 @@ package com.facebook.csslayout; public enum CSSDirection { - INHERIT, - LTR, - RTL, + INHERIT(0), + LTR(1), + RTL(2); + + private int mIntValue; + + CSSDirection(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSDirection fromInt(int value) { + switch (value) { + case 0: return INHERIT; + case 1: return LTR; + case 2: return RTL; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSEdge.java b/java/com/facebook/csslayout/CSSEdge.java new file mode 100644 index 0000000..50d184e --- /dev/null +++ b/java/com/facebook/csslayout/CSSEdge.java @@ -0,0 +1,47 @@ +/** + * 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.csslayout; + +public enum CSSEdge { + LEFT(0), + TOP(1), + RIGHT(2), + BOTTOM(3), + START(4), + END(5), + HORIZONTAL(6), + VERTICAL(7), + ALL(8); + + private int mIntValue; + + CSSEdge(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSEdge fromInt(int value) { + switch (value) { + case 0: return LEFT; + case 1: return TOP; + case 2: return RIGHT; + case 3: return BOTTOM; + case 4: return START; + case 5: return END; + case 6: return HORIZONTAL; + case 7: return VERTICAL; + case 8: return ALL; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } +} diff --git a/java/com/facebook/csslayout/CSSExperimentalFeature.java b/java/com/facebook/csslayout/CSSExperimentalFeature.java new file mode 100644 index 0000000..e0b269f --- /dev/null +++ b/java/com/facebook/csslayout/CSSExperimentalFeature.java @@ -0,0 +1,29 @@ +/** + * 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.csslayout; + +public enum CSSExperimentalFeature { +__EMPTY(-1); + private int mIntValue; + + CSSExperimentalFeature(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSExperimentalFeature fromInt(int value) { + switch (value) { + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } +} diff --git a/java/com/facebook/csslayout/CSSFlexDirection.java b/java/com/facebook/csslayout/CSSFlexDirection.java index 30f92bd..10e5cd6 100644 --- a/java/com/facebook/csslayout/CSSFlexDirection.java +++ b/java/com/facebook/csslayout/CSSFlexDirection.java @@ -10,8 +10,28 @@ package com.facebook.csslayout; public enum CSSFlexDirection { - COLUMN, - COLUMN_REVERSE, - ROW, - ROW_REVERSE + COLUMN(0), + COLUMN_REVERSE(1), + ROW(2), + ROW_REVERSE(3); + + private int mIntValue; + + CSSFlexDirection(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSFlexDirection fromInt(int value) { + switch (value) { + case 0: return COLUMN; + case 1: return COLUMN_REVERSE; + case 2: return ROW; + case 3: return ROW_REVERSE; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSJustify.java b/java/com/facebook/csslayout/CSSJustify.java index dfcc1cd..2d36a85 100644 --- a/java/com/facebook/csslayout/CSSJustify.java +++ b/java/com/facebook/csslayout/CSSJustify.java @@ -10,9 +10,30 @@ package com.facebook.csslayout; public enum CSSJustify { - FLEX_START, - CENTER, - FLEX_END, - SPACE_BETWEEN, - SPACE_AROUND, + FLEX_START(0), + CENTER(1), + FLEX_END(2), + SPACE_BETWEEN(3), + SPACE_AROUND(4); + + private int mIntValue; + + CSSJustify(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSJustify fromInt(int value) { + switch (value) { + case 0: return FLEX_START; + case 1: return CENTER; + case 2: return FLEX_END; + case 3: return SPACE_BETWEEN; + case 4: return SPACE_AROUND; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSLogLevel.java b/java/com/facebook/csslayout/CSSLogLevel.java new file mode 100644 index 0000000..94551bc --- /dev/null +++ b/java/com/facebook/csslayout/CSSLogLevel.java @@ -0,0 +1,39 @@ +/** + * 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.csslayout; + +public enum CSSLogLevel { + ERROR(0), + WARN(1), + INFO(2), + DEBUG(3), + VERBOSE(4); + + private int mIntValue; + + CSSLogLevel(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSLogLevel fromInt(int value) { + switch (value) { + case 0: return ERROR; + case 1: return WARN; + case 2: return INFO; + case 3: return DEBUG; + case 4: return VERBOSE; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } +} diff --git a/java/com/facebook/csslayout/CSSLogger.java b/java/com/facebook/csslayout/CSSLogger.java new file mode 100644 index 0000000..f1f28fe --- /dev/null +++ b/java/com/facebook/csslayout/CSSLogger.java @@ -0,0 +1,21 @@ +/** + * 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.csslayout; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * Inteface for recieving logs from native layer. Use by setting CSSNode.setLogger(myLogger); + * See CSSLogLevel for the different log levels. + */ +public interface CSSLogger { + @DoNotStrip + void log(CSSLogLevel level, String message); +} diff --git a/java/com/facebook/csslayout/CSSMeasureMode.java b/java/com/facebook/csslayout/CSSMeasureMode.java index e8ebb34..d2c69e6 100644 --- a/java/com/facebook/csslayout/CSSMeasureMode.java +++ b/java/com/facebook/csslayout/CSSMeasureMode.java @@ -10,7 +10,26 @@ package com.facebook.csslayout; public enum CSSMeasureMode { - UNDEFINED, - EXACTLY, - AT_MOST, + UNDEFINED(0), + EXACTLY(1), + AT_MOST(2); + + private int mIntValue; + + CSSMeasureMode(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSMeasureMode fromInt(int value) { + switch (value) { + case 0: return UNDEFINED; + case 1: return EXACTLY; + case 2: return AT_MOST; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSNode.java b/java/com/facebook/csslayout/CSSNode.java index 612be24..95a5319 100644 --- a/java/com/facebook/csslayout/CSSNode.java +++ b/java/com/facebook/csslayout/CSSNode.java @@ -33,6 +33,26 @@ public class CSSNode implements CSSNodeAPI { * Get native instance count. Useful for testing only. */ static native int jni_CSSNodeGetInstanceCount(); + static native void jni_CSSLog(int level, String message); + + private static native void jni_CSSLayoutSetLogger(Object logger); + public static void setLogger(CSSLogger logger) { + jni_CSSLayoutSetLogger(logger); + } + + private static native void jni_CSSLayoutSetExperimentalFeatureEnabled( + int feature, + boolean enabled); + public static void setExperimentalFeatureEnabled( + CSSExperimentalFeature feature, + boolean enabled) { + jni_CSSLayoutSetExperimentalFeatureEnabled(feature.intValue(), enabled); + } + + private static native boolean jni_CSSLayoutIsExperimentalFeatureEnabled(int feature); + public static boolean isExperimentalFeatureEnabled(CSSExperimentalFeature feature) { + return jni_CSSLayoutIsExperimentalFeatureEnabled(feature.intValue()); + } private CSSNode mParent; private List mChildren; @@ -170,6 +190,12 @@ public class CSSNode implements CSSNodeAPI { jni_CSSNodeMarkLayoutSeen(mNativePointer); } + private native void jni_CSSNodeCopyStyle(long dstNativePointer, long srcNativePointer); + @Override + public void copyStyle(CSSNode srcNode) { + jni_CSSNodeCopyStyle(mNativePointer, srcNode.mNativePointer); + } + private native int jni_CSSNodeStyleGetDirection(long nativePointer); @Override public CSSDirection getStyleDirection() { @@ -179,7 +205,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetDirection(long nativePointer, int direction); @Override public void setDirection(CSSDirection direction) { - jni_CSSNodeStyleSetDirection(mNativePointer, direction.ordinal()); + jni_CSSNodeStyleSetDirection(mNativePointer, direction.intValue()); } private native int jni_CSSNodeStyleGetFlexDirection(long nativePointer); @@ -191,7 +217,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetFlexDirection(long nativePointer, int flexDirection); @Override public void setFlexDirection(CSSFlexDirection flexDirection) { - jni_CSSNodeStyleSetFlexDirection(mNativePointer, flexDirection.ordinal()); + jni_CSSNodeStyleSetFlexDirection(mNativePointer, flexDirection.intValue()); } private native int jni_CSSNodeStyleGetJustifyContent(long nativePointer); @@ -203,7 +229,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetJustifyContent(long nativePointer, int justifyContent); @Override public void setJustifyContent(CSSJustify justifyContent) { - jni_CSSNodeStyleSetJustifyContent(mNativePointer, justifyContent.ordinal()); + jni_CSSNodeStyleSetJustifyContent(mNativePointer, justifyContent.intValue()); } private native int jni_CSSNodeStyleGetAlignItems(long nativePointer); @@ -215,7 +241,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetAlignItems(long nativePointer, int alignItems); @Override public void setAlignItems(CSSAlign alignItems) { - jni_CSSNodeStyleSetAlignItems(mNativePointer, alignItems.ordinal()); + jni_CSSNodeStyleSetAlignItems(mNativePointer, alignItems.intValue()); } private native int jni_CSSNodeStyleGetAlignSelf(long nativePointer); @@ -227,7 +253,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetAlignSelf(long nativePointer, int alignSelf); @Override public void setAlignSelf(CSSAlign alignSelf) { - jni_CSSNodeStyleSetAlignSelf(mNativePointer, alignSelf.ordinal()); + jni_CSSNodeStyleSetAlignSelf(mNativePointer, alignSelf.intValue()); } private native int jni_CSSNodeStyleGetAlignContent(long nativePointer); @@ -239,7 +265,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetAlignContent(long nativePointer, int alignContent); @Override public void setAlignContent(CSSAlign alignContent) { - jni_CSSNodeStyleSetAlignContent(mNativePointer, alignContent.ordinal()); + jni_CSSNodeStyleSetAlignContent(mNativePointer, alignContent.intValue()); } private native int jni_CSSNodeStyleGetPositionType(long nativePointer); @@ -251,13 +277,13 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetPositionType(long nativePointer, int positionType); @Override public void setPositionType(CSSPositionType positionType) { - jni_CSSNodeStyleSetPositionType(mNativePointer, positionType.ordinal()); + jni_CSSNodeStyleSetPositionType(mNativePointer, positionType.intValue()); } private native void jni_CSSNodeStyleSetFlexWrap(long nativePointer, int wrapType); @Override public void setWrap(CSSWrap flexWrap) { - jni_CSSNodeStyleSetFlexWrap(mNativePointer, flexWrap.ordinal()); + jni_CSSNodeStyleSetFlexWrap(mNativePointer, flexWrap.intValue()); } private native int jni_CSSNodeStyleGetOverflow(long nativePointer); @@ -269,7 +295,7 @@ public class CSSNode implements CSSNodeAPI { private native void jni_CSSNodeStyleSetOverflow(long nativePointer, int overflow); @Override public void setOverflow(CSSOverflow overflow) { - jni_CSSNodeStyleSetOverflow(mNativePointer, overflow.ordinal()); + jni_CSSNodeStyleSetOverflow(mNativePointer, overflow.intValue()); } private native void jni_CSSNodeStyleSetFlex(long nativePointer, float flex); diff --git a/java/com/facebook/csslayout/CSSNodeAPI.java b/java/com/facebook/csslayout/CSSNodeAPI.java index dd18a54..d35d8b4 100644 --- a/java/com/facebook/csslayout/CSSNodeAPI.java +++ b/java/com/facebook/csslayout/CSSNodeAPI.java @@ -37,6 +37,7 @@ public interface CSSNodeAPI { void dirty(); void markLayoutSeen(); boolean valuesEqual(float f1, float f2); + void copyStyle(CSSNodeType srcNode); CSSDirection getStyleDirection(); void setDirection(CSSDirection direction); CSSFlexDirection getFlexDirection(); diff --git a/java/com/facebook/csslayout/CSSNodeDEPRECATED.java b/java/com/facebook/csslayout/CSSNodeDEPRECATED.java index dc31cc0..0031ee6 100644 --- a/java/com/facebook/csslayout/CSSNodeDEPRECATED.java +++ b/java/com/facebook/csslayout/CSSNodeDEPRECATED.java @@ -222,6 +222,11 @@ public class CSSNodeDEPRECATED implements CSSNodeAPI { return FloatUtil.floatsEqual(f1, f2); } + @Override + public void copyStyle(CSSNodeDEPRECATED srcNode) { + throw new UnsupportedOperationException("copyStyle is not implemented"); + } + /** * Get this node's direction, as defined in the style. */ diff --git a/java/com/facebook/csslayout/CSSOverflow.java b/java/com/facebook/csslayout/CSSOverflow.java index 9aae822..8ba708a 100644 --- a/java/com/facebook/csslayout/CSSOverflow.java +++ b/java/com/facebook/csslayout/CSSOverflow.java @@ -10,7 +10,26 @@ package com.facebook.csslayout; public enum CSSOverflow { - VISIBLE, - HIDDEN, - SCROLL, + VISIBLE(0), + HIDDEN(1), + SCROLL(2); + + private int mIntValue; + + CSSOverflow(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSOverflow fromInt(int value) { + switch (value) { + case 0: return VISIBLE; + case 1: return HIDDEN; + case 2: return SCROLL; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSPositionType.java b/java/com/facebook/csslayout/CSSPositionType.java index 19e27dd..4dcaa0d 100644 --- a/java/com/facebook/csslayout/CSSPositionType.java +++ b/java/com/facebook/csslayout/CSSPositionType.java @@ -10,6 +10,24 @@ package com.facebook.csslayout; public enum CSSPositionType { - RELATIVE, - ABSOLUTE, + RELATIVE(0), + ABSOLUTE(1); + + private int mIntValue; + + CSSPositionType(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSPositionType fromInt(int value) { + switch (value) { + case 0: return RELATIVE; + case 1: return ABSOLUTE; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/com/facebook/csslayout/CSSPrintOptions.java b/java/com/facebook/csslayout/CSSPrintOptions.java new file mode 100644 index 0000000..ec83ab4 --- /dev/null +++ b/java/com/facebook/csslayout/CSSPrintOptions.java @@ -0,0 +1,35 @@ +/** + * 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.csslayout; + +public enum CSSPrintOptions { + LAYOUT(1), + STYLE(2), + CHILDREN(4); + + private int mIntValue; + + CSSPrintOptions(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSPrintOptions fromInt(int value) { + switch (value) { + case 1: return LAYOUT; + case 2: return STYLE; + case 4: return CHILDREN; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } +} diff --git a/java/com/facebook/csslayout/CSSStyle.java b/java/com/facebook/csslayout/CSSStyle.java index c17ce52..916e54e 100644 --- a/java/com/facebook/csslayout/CSSStyle.java +++ b/java/com/facebook/csslayout/CSSStyle.java @@ -54,7 +54,7 @@ public class CSSStyle { alignItems = CSSAlign.STRETCH; alignSelf = CSSAlign.AUTO; positionType = CSSPositionType.RELATIVE; - flexWrap = CSSWrap.NOWRAP; + flexWrap = CSSWrap.NO_WRAP; overflow = CSSOverflow.VISIBLE; flexGrow = 0; flexShrink = 0; diff --git a/java/com/facebook/csslayout/CSSWrap.java b/java/com/facebook/csslayout/CSSWrap.java index 895bb5d..69a5905 100644 --- a/java/com/facebook/csslayout/CSSWrap.java +++ b/java/com/facebook/csslayout/CSSWrap.java @@ -10,6 +10,24 @@ package com.facebook.csslayout; public enum CSSWrap { - NOWRAP, - WRAP, + NO_WRAP(0), + WRAP(1); + + private int mIntValue; + + CSSWrap(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static CSSWrap fromInt(int value) { + switch (value) { + case 0: return NO_WRAP; + case 1: return WRAP; + default: throw new IllegalArgumentException("Unkown enum value: " + value); + } + } } diff --git a/java/jni/CSSJNI.cpp b/java/jni/CSSJNI.cpp index e1c8623..2c6ef3a 100644 --- a/java/jni/CSSJNI.cpp +++ b/java/jni/CSSJNI.cpp @@ -40,7 +40,8 @@ static void _jniTransferLayoutOutputsRecursive(CSSNodeRef root) { } static void _jniPrint(CSSNodeRef node) { - auto obj = adopt_local(Environment::current()->NewLocalRef(reinterpret_cast(CSSNodeGetContext(node)))); + auto obj = adopt_local( + Environment::current()->NewLocalRef(reinterpret_cast(CSSNodeGetContext(node)))); cout << obj->toString() << endl; } @@ -49,10 +50,11 @@ static CSSSize _jniMeasureFunc(CSSNodeRef node, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) { - auto obj = adopt_local(Environment::current()->NewLocalRef(reinterpret_cast(CSSNodeGetContext(node)))); + auto obj = adopt_local( + Environment::current()->NewLocalRef(reinterpret_cast(CSSNodeGetContext(node)))); static auto measureFunc = findClassLocal("com/facebook/csslayout/CSSNode") - ->getMethod("measure"); + ->getMethod("measure"); _jniTransferLayoutDirection(node, obj); const auto measureResult = measureFunc(obj, width, widthMode, height, heightMode); @@ -66,10 +68,63 @@ static CSSSize _jniMeasureFunc(CSSNodeRef node, return CSSSize{measuredWidth, measuredHeight}; } +struct JCSSLogLevel : public JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/facebook/csslayout/CSSLogLevel;"; +}; + +static global_ref *jLogger; +static int _jniLog(CSSLogLevel level, const char *format, va_list args) { + char buffer[256]; + int result = vsnprintf(buffer, sizeof(buffer), format, args); + + static auto logFunc = findClassLocal("com/facebook/csslayout/CSSLogger") + ->getMethod, jstring)>("log"); + + static auto logLevelFromInt = + JCSSLogLevel::javaClassStatic()->getStaticMethod("fromInt"); + + logFunc(jLogger->get(), + logLevelFromInt(JCSSLogLevel::javaClassStatic(), static_cast(level)), + Environment::current()->NewStringUTF(buffer)); + + return result; +} + static inline CSSNodeRef _jlong2CSSNodeRef(jlong addr) { return reinterpret_cast(static_cast(addr)); } +void jni_CSSLayoutSetLogger(alias_ref clazz, alias_ref logger) { + if (jLogger) { + jLogger->releaseAlias(); + delete jLogger; + } + + if (logger) { + jLogger = new global_ref(make_global(logger)); + CSSLayoutSetLogger(_jniLog); + } else { + jLogger = NULL; + CSSLayoutSetLogger(NULL); + } +} + +void jni_CSSLog(alias_ref clazz, jint level, jstring message) { + const char *nMessage = Environment::current()->GetStringUTFChars(message, 0); + CSSLog(static_cast(level), "%s", nMessage); + Environment::current()->ReleaseStringUTFChars(message, nMessage); +} + +void jni_CSSLayoutSetExperimentalFeatureEnabled(alias_ref clazz, + jint feature, + jboolean enabled) { + CSSLayoutSetExperimentalFeatureEnabled(static_cast(feature), enabled); +} + +jboolean jni_CSSLayoutIsExperimentalFeatureEnabled(alias_ref clazz, jint feature) { + return CSSLayoutIsExperimentalFeatureEnabled(static_cast(feature)); +} + jint jni_CSSNodeGetInstanceCount(alias_ref clazz) { return CSSNodeGetInstanceCount(); } @@ -137,6 +192,10 @@ void jni_CSSNodeMarkLayoutSeen(alias_ref, jlong nativePointer) { CSSNodeSetHasNewLayout(_jlong2CSSNodeRef(nativePointer), false); } +void jni_CSSNodeCopyStyle(alias_ref, jlong dstNativePointer, jlong srcNativePointer) { + CSSNodeCopyStyle(_jlong2CSSNodeRef(dstNativePointer), _jlong2CSSNodeRef(srcNativePointer)); +} + #define CSS_NODE_JNI_STYLE_PROP(javatype, type, name) \ javatype jni_CSSNodeStyleGet##name(alias_ref, jlong nativePointer) { \ return (javatype) CSSNodeStyleGet##name(_jlong2CSSNodeRef(nativePointer)); \ @@ -168,7 +227,7 @@ CSS_NODE_JNI_STYLE_PROP(jint, CSSAlign, AlignItems); CSS_NODE_JNI_STYLE_PROP(jint, CSSAlign, AlignSelf); CSS_NODE_JNI_STYLE_PROP(jint, CSSAlign, AlignContent); CSS_NODE_JNI_STYLE_PROP(jint, CSSPositionType, PositionType); -CSS_NODE_JNI_STYLE_PROP(jint, CSSWrapType, FlexWrap); +CSS_NODE_JNI_STYLE_PROP(jint, CSSWrap, FlexWrap); CSS_NODE_JNI_STYLE_PROP(jint, CSSOverflow, Overflow); void jni_CSSNodeStyleSetFlex(alias_ref, jlong nativePointer, jfloat value) { @@ -207,6 +266,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) { CSSMakeNativeMethod(jni_CSSNodeIsDirty), CSSMakeNativeMethod(jni_CSSNodeMarkLayoutSeen), CSSMakeNativeMethod(jni_CSSNodeSetHasMeasureFunc), + CSSMakeNativeMethod(jni_CSSNodeCopyStyle), CSSMakeNativeMethod(jni_CSSNodeStyleGetDirection), CSSMakeNativeMethod(jni_CSSNodeStyleSetDirection), @@ -254,6 +314,10 @@ jint JNI_OnLoad(JavaVM *vm, void *) { CSSMakeNativeMethod(jni_CSSNodeStyleSetMaxHeight), CSSMakeNativeMethod(jni_CSSNodeGetInstanceCount), + CSSMakeNativeMethod(jni_CSSLayoutSetLogger), + CSSMakeNativeMethod(jni_CSSLog), + CSSMakeNativeMethod(jni_CSSLayoutSetExperimentalFeatureEnabled), + CSSMakeNativeMethod(jni_CSSLayoutIsExperimentalFeatureEnabled), }); }); } diff --git a/java/tests/com/facebook/csslayout/CSSLayoutAbsolutePositionTest.java b/java/tests/com/facebook/csslayout/CSSLayoutAbsolutePositionTest.java index f3703e7..e4ced9f 100644 --- a/java/tests/com/facebook/csslayout/CSSLayoutAbsolutePositionTest.java +++ b/java/tests/com/facebook/csslayout/CSSLayoutAbsolutePositionTest.java @@ -31,6 +31,11 @@
+ +
+
+
+
* */ @@ -258,4 +263,74 @@ public class CSSLayoutAbsolutePositionTest { assertEquals(100, root_child0_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_absolute_layout_within_border() { + final CSSNode root = new CSSNode(); + root.setMargin(Spacing.LEFT, 10); + root.setMargin(Spacing.TOP, 10); + root.setMargin(Spacing.RIGHT, 10); + root.setMargin(Spacing.BOTTOM, 10); + root.setPadding(Spacing.LEFT, 10); + root.setPadding(Spacing.TOP, 10); + root.setPadding(Spacing.RIGHT, 10); + root.setPadding(Spacing.BOTTOM, 10); + root.setBorder(Spacing.LEFT, 10); + root.setBorder(Spacing.TOP, 10); + root.setBorder(Spacing.RIGHT, 10); + root.setBorder(Spacing.BOTTOM, 10); + root.setStyleWidth(100); + root.setStyleHeight(100); + + final CSSNode root_child0 = new CSSNode(); + root_child0.setPositionType(CSSPositionType.ABSOLUTE); + root_child0.setPosition(Spacing.LEFT, 0); + root_child0.setPosition(Spacing.TOP, 0); + root_child0.setStyleWidth(50); + root_child0.setStyleHeight(50); + root.addChildAt(root_child0, 0); + + final CSSNode root_child1 = new CSSNode(); + root_child1.setPositionType(CSSPositionType.ABSOLUTE); + root_child1.setPosition(Spacing.RIGHT, 0); + root_child1.setPosition(Spacing.BOTTOM, 0); + root_child1.setStyleWidth(50); + root_child1.setStyleHeight(50); + root.addChildAt(root_child1, 1); + root.setDirection(CSSDirection.LTR); + root.calculateLayout(null); + + assertEquals(10, root.getLayoutX(), 0.0f); + assertEquals(10, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(10, root_child0.getLayoutX(), 0.0f); + assertEquals(10, root_child0.getLayoutY(), 0.0f); + assertEquals(50, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40, root_child1.getLayoutX(), 0.0f); + assertEquals(40, root_child1.getLayoutY(), 0.0f); + assertEquals(50, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(CSSDirection.RTL); + root.calculateLayout(null); + + assertEquals(10, root.getLayoutX(), 0.0f); + assertEquals(10, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(10, root_child0.getLayoutX(), 0.0f); + assertEquals(10, root_child0.getLayoutY(), 0.0f); + assertEquals(50, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40, root_child1.getLayoutX(), 0.0f); + assertEquals(40, root_child1.getLayoutY(), 0.0f); + assertEquals(50, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50, root_child1.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/csslayout/CSSLayoutFlexTest.java b/java/tests/com/facebook/csslayout/CSSLayoutFlexTest.java index 5056e30..ccc641c 100644 --- a/java/tests/com/facebook/csslayout/CSSLayoutFlexTest.java +++ b/java/tests/com/facebook/csslayout/CSSLayoutFlexTest.java @@ -41,6 +41,12 @@
+ +
+
+
+
+
* */ @@ -392,4 +398,54 @@ public class CSSLayoutFlexTest { assertEquals(20, root_child2.getLayoutHeight(), 0.0f); } + @Test + public void test_flex_grow_shrink_at_most() { + final CSSNode root = new CSSNode(); + root.setStyleWidth(100); + root.setStyleHeight(100); + + final CSSNode root_child0 = new CSSNode(); + root.addChildAt(root_child0, 0); + + final CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.setFlexGrow(1); + root_child0_child0.setFlexShrink(1); + root_child0.addChildAt(root_child0_child0, 0); + root.setDirection(CSSDirection.LTR); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(0, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutHeight(), 0.0f); + + root.setDirection(CSSDirection.RTL); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(0, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java b/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java index 271f3a9..d513f5e 100644 --- a/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java +++ b/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java @@ -47,6 +47,12 @@
+ +
+
+
+
+
* */ @@ -433,4 +439,56 @@ public class CSSLayoutMinMaxDimensionTest { assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_flex_grow_within_constrained_max_width() { + final CSSNode root = new CSSNode(); + root.setStyleWidth(200); + root.setStyleHeight(100); + + final CSSNode root_child0 = new CSSNode(); + root_child0.setFlexDirection(CSSFlexDirection.ROW); + root_child0.setStyleMaxWidth(300); + root.addChildAt(root_child0, 0); + + final CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.setFlexGrow(1); + root_child0_child0.setStyleHeight(20); + root_child0.addChildAt(root_child0_child0, 0); + root.setDirection(CSSDirection.LTR); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(200, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0.getLayoutWidth(), 0.0f); + assertEquals(20, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f); + + root.setDirection(CSSDirection.RTL); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(200, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0.getLayoutWidth(), 0.0f); + assertEquals(20, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/csslayout/CSSNodeTest.java b/java/tests/com/facebook/csslayout/CSSNodeTest.java index c61b898..f269a91 100644 --- a/java/tests/com/facebook/csslayout/CSSNodeTest.java +++ b/java/tests/com/facebook/csslayout/CSSNodeTest.java @@ -12,6 +12,7 @@ package com.facebook.csslayout; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class CSSNodeTest { @@ -39,4 +40,48 @@ public class CSSNodeTest { assertEquals(100, (int) node.getLayoutWidth()); assertEquals(100, (int) node.getLayoutHeight()); } + + private CSSLogLevel mLogLevel; + private String mLogMessage; + + @Test + public void testLogger() { + CSSNode.setLogger(new CSSLogger() { + public void log(CSSLogLevel level, String message) { + mLogLevel = level; + mLogMessage = message; + } + }); + CSSNode.jni_CSSLog(CSSLogLevel.DEBUG.intValue(), "Hello"); + assertEquals(CSSLogLevel.DEBUG, mLogLevel); + assertEquals("Hello", mLogMessage); + } + + @Test + public void testUpdateLogger() { + CSSNode.setLogger(new CSSLogger() { + public void log(CSSLogLevel level, String message) {} + }); + CSSNode.setLogger(new CSSLogger() { + public void log(CSSLogLevel level, String message) { + mLogLevel = level; + mLogMessage = message; + } + }); + CSSNode.jni_CSSLog(CSSLogLevel.VERBOSE.intValue(), "Flexbox"); + assertEquals(CSSLogLevel.VERBOSE, mLogLevel); + assertEquals("Flexbox", mLogMessage); + } + + @Test + public void testCopyStyle() { + final CSSNode node0 = new CSSNode(); + assertTrue(CSSConstants.isUndefined(node0.getStyleMaxHeight())); + + final CSSNode node1 = new CSSNode(); + node1.setStyleMaxHeight(100); + + node0.copyStyle(node1); + assertEquals(100, (int) node0.getStyleMaxHeight()); + } } diff --git a/lib/fb/BUCK b/lib/fb/BUCK index 1177906..ea3fa8c 100644 --- a/lib/fb/BUCK +++ b/lib/fb/BUCK @@ -34,8 +34,9 @@ cxx_library( '-Wno-unused-parameter', '-std=c++11', ], - deps = JNI_DEPS + [ + deps = [ ':ndklog', + JNI_TARGET, ], visibility = ['PUBLIC'], ) diff --git a/lib/gtest/BUCK b/lib/gtest/BUCK index d1a01d5..d2e136b 100644 --- a/lib/gtest/BUCK +++ b/lib/gtest/BUCK @@ -7,22 +7,6 @@ include_defs('//CSSLAYOUT_DEFS') -with allow_unsafe_import(): - import os - import urllib2 - import zipfile - -# Download gtest dep if it does not exists in path -current_dir = os.path.dirname(os.path.realpath(__file__)) -gtest_folder = 'googletest-release-1.7.0' -if GTEST_DL_URL != None and not os.path.isdir(current_dir + gtest_folder): - gtest = urllib2.urlopen('https://github.com/google/googletest/archive/release-1.7.0.zip').read() - with open("gtest.zip", 'w') as f: - f.write(gtest) - with zipfile.ZipFile('gtest.zip',"r") as zip: - zip.extractall(os.path.dirname(os.path.realpath(__file__))) - os.remove('gtest.zip') - COMPILER_FLAGS = [ '-std=c++11', '-Wno-missing-prototypes', @@ -30,11 +14,11 @@ COMPILER_FLAGS = [ cxx_library( name = 'gtest', - srcs = glob([gtest_folder + '/src/*.cc']), + srcs = glob(['googletest/googletest/src/*.cc']), exported_headers = subdir_glob([ - (gtest_folder + '/include', '**/*.h'), - (gtest_folder, 'src/*.h'), - (gtest_folder, 'src/*.cc'), + ('googletest/googletest/include', '**/*.h'), + ('googletest/googletest', 'src/*.h'), + ('googletest/googletest', 'src/*.cc'), ]), header_namespace = '', compiler_flags = COMPILER_FLAGS, diff --git a/lib/gtest/googletest b/lib/gtest/googletest new file mode 160000 index 0000000..a2b8a8e --- /dev/null +++ b/lib/gtest/googletest @@ -0,0 +1 @@ +Subproject commit a2b8a8e07628e5fd60644b6dd99c1b5e7d7f1f47 diff --git a/lib/jni/BUCK b/lib/jni/BUCK new file mode 100644 index 0000000..5a8808f --- /dev/null +++ b/lib/jni/BUCK @@ -0,0 +1,17 @@ +# 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. + +cxx_library( + name = 'jni', + force_static = True, + header_namespace = '', + exported_headers = [ + 'jni.h', + 'real/jni.h', + ], + visibility = ['PUBLIC'], +) diff --git a/lib/jni/jni.h b/lib/jni/jni.h new file mode 100644 index 0000000..d768a11 --- /dev/null +++ b/lib/jni/jni.h @@ -0,0 +1,16 @@ +/** + * 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. + */ + +#pragma once + +#ifdef __ANDROID__ +#include_next +#else +#include "real/jni.h" +#endif diff --git a/lib/jni/real/jni.h b/lib/jni/real/jni.h new file mode 100644 index 0000000..1c2fb0c --- /dev/null +++ b/lib/jni/real/jni.h @@ -0,0 +1,1141 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * JNI specification, as defined by Sun: + * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html + * + * Everything here is expected to be VM-neutral. + */ + +#ifndef JNI_H_ +#define JNI_H_ + +#include +#include + +/* Primitive types that match up with Java equivalents. */ +typedef uint8_t jboolean; /* unsigned 8 bits */ +typedef int8_t jbyte; /* signed 8 bits */ +typedef uint16_t jchar; /* unsigned 16 bits */ +typedef int16_t jshort; /* signed 16 bits */ +typedef int32_t jint; /* signed 32 bits */ +typedef int64_t jlong; /* signed 64 bits */ +typedef float jfloat; /* 32-bit IEEE 754 */ +typedef double jdouble; /* 64-bit IEEE 754 */ + +/* "cardinal indices and sizes" */ +typedef jint jsize; + +#ifdef __cplusplus +/* + * Reference types, in C++ + */ +class _jobject {}; +class _jclass : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jobjectArray : public _jarray {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jthrowable : public _jobject {}; + +typedef _jobject* jobject; +typedef _jclass* jclass; +typedef _jstring* jstring; +typedef _jarray* jarray; +typedef _jobjectArray* jobjectArray; +typedef _jbooleanArray* jbooleanArray; +typedef _jbyteArray* jbyteArray; +typedef _jcharArray* jcharArray; +typedef _jshortArray* jshortArray; +typedef _jintArray* jintArray; +typedef _jlongArray* jlongArray; +typedef _jfloatArray* jfloatArray; +typedef _jdoubleArray* jdoubleArray; +typedef _jthrowable* jthrowable; +typedef _jobject* jweak; + + +#else /* not __cplusplus */ + +/* + * Reference types, in C. + */ +typedef void* jobject; +typedef jobject jclass; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jobjectArray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jobject jthrowable; +typedef jobject jweak; + +#endif /* not __cplusplus */ + +struct _jfieldID; /* opaque structure */ +typedef struct _jfieldID* jfieldID; /* field IDs */ + +struct _jmethodID; /* opaque structure */ +typedef struct _jmethodID* jmethodID; /* method IDs */ + +struct JNIInvokeInterface; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +typedef enum jobjectRefType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + +typedef struct { + const char* name; + const char* signature; + void* fnPtr; +} JNINativeMethod; + +struct _JNIEnv; +struct _JavaVM; +typedef const struct JNINativeInterface* C_JNIEnv; + +#if defined(__cplusplus) +typedef _JNIEnv JNIEnv; +typedef _JavaVM JavaVM; +#else +typedef const struct JNINativeInterface* JNIEnv; +typedef const struct JNIInvokeInterface* JavaVM; +#endif + +/* + * Table of interface function pointers. + */ +struct JNINativeInterface { + void* reserved0; + void* reserved1; + void* reserved2; + void* reserved3; + + jint (*GetVersion)(JNIEnv *); + + jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, + jsize); + jclass (*FindClass)(JNIEnv*, const char*); + + jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); + jfieldID (*FromReflectedField)(JNIEnv*, jobject); + /* spec doesn't show jboolean parameter */ + jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); + + jclass (*GetSuperclass)(JNIEnv*, jclass); + jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); + + /* spec doesn't show jboolean parameter */ + jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); + + jint (*Throw)(JNIEnv*, jthrowable); + jint (*ThrowNew)(JNIEnv *, jclass, const char *); + jthrowable (*ExceptionOccurred)(JNIEnv*); + void (*ExceptionDescribe)(JNIEnv*); + void (*ExceptionClear)(JNIEnv*); + void (*FatalError)(JNIEnv*, const char*); + + jint (*PushLocalFrame)(JNIEnv*, jint); + jobject (*PopLocalFrame)(JNIEnv*, jobject); + + jobject (*NewGlobalRef)(JNIEnv*, jobject); + void (*DeleteGlobalRef)(JNIEnv*, jobject); + void (*DeleteLocalRef)(JNIEnv*, jobject); + jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); + + jobject (*NewLocalRef)(JNIEnv*, jobject); + jint (*EnsureLocalCapacity)(JNIEnv*, jint); + + jobject (*AllocObject)(JNIEnv*, jclass); + jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); + jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); + jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); + + jclass (*GetObjectClass)(JNIEnv*, jobject); + jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); + jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); + jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); + jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); + jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); + jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); + jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); + jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); + jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); + jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); + jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); + void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); + void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + + jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + + jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); + jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); + jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); + jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); + jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); + jint (*GetIntField)(JNIEnv*, jobject, jfieldID); + jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); + jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID); + jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); + + void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); + void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); + void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); + void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); + void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); + void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); + void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); + void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat); + void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); + + jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); + jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); + jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, + va_list); + jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, + jvalue*); + jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); + jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); + jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); + jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); + jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); + jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); + jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); + jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); + void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); + void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + + jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, + const char*); + + jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); + jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); + jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); + jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); + jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); + jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); + jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); + jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID); + jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); + + void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); + void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); + void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); + void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); + void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); + void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); + void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); + void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat); + void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); + + jstring (*NewString)(JNIEnv*, const jchar*, jsize); + jsize (*GetStringLength)(JNIEnv*, jstring); + const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); + jstring (*NewStringUTF)(JNIEnv*, const char*); + jsize (*GetStringUTFLength)(JNIEnv*, jstring); + /* JNI spec says this returns const jbyte*, but that's inconsistent */ + const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); + jsize (*GetArrayLength)(JNIEnv*, jarray); + jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); + jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); + void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); + + jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); + jbyteArray (*NewByteArray)(JNIEnv*, jsize); + jcharArray (*NewCharArray)(JNIEnv*, jsize); + jshortArray (*NewShortArray)(JNIEnv*, jsize); + jintArray (*NewIntArray)(JNIEnv*, jsize); + jlongArray (*NewLongArray)(JNIEnv*, jsize); + jfloatArray (*NewFloatArray)(JNIEnv*, jsize); + jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); + + jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); + jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); + jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); + jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); + jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); + jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); + jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); + jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); + + void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, + jboolean*, jint); + void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, + jbyte*, jint); + void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, + jchar*, jint); + void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, + jshort*, jint); + void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, + jint*, jint); + void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, + jlong*, jint); + void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, + jfloat*, jint); + void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, + jdouble*, jint); + + void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, + jsize, jsize, jboolean*); + void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, + jsize, jsize, jbyte*); + void (*GetCharArrayRegion)(JNIEnv*, jcharArray, + jsize, jsize, jchar*); + void (*GetShortArrayRegion)(JNIEnv*, jshortArray, + jsize, jsize, jshort*); + void (*GetIntArrayRegion)(JNIEnv*, jintArray, + jsize, jsize, jint*); + void (*GetLongArrayRegion)(JNIEnv*, jlongArray, + jsize, jsize, jlong*); + void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, + jsize, jsize, jfloat*); + void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, + jsize, jsize, jdouble*); + + /* spec shows these without const; some jni.h do, some don't */ + void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, + jsize, jsize, const jboolean*); + void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, + jsize, jsize, const jbyte*); + void (*SetCharArrayRegion)(JNIEnv*, jcharArray, + jsize, jsize, const jchar*); + void (*SetShortArrayRegion)(JNIEnv*, jshortArray, + jsize, jsize, const jshort*); + void (*SetIntArrayRegion)(JNIEnv*, jintArray, + jsize, jsize, const jint*); + void (*SetLongArrayRegion)(JNIEnv*, jlongArray, + jsize, jsize, const jlong*); + void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, + jsize, jsize, const jfloat*); + void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, + jsize, jsize, const jdouble*); + + jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, + jint); + jint (*UnregisterNatives)(JNIEnv*, jclass); + jint (*MonitorEnter)(JNIEnv*, jobject); + jint (*MonitorExit)(JNIEnv*, jobject); + jint (*GetJavaVM)(JNIEnv*, JavaVM**); + + void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); + void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); + + void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); + void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); + + const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); + + jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); + void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); + + jboolean (*ExceptionCheck)(JNIEnv*); + + jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); + void* (*GetDirectBufferAddress)(JNIEnv*, jobject); + jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); + + /* added in JNI 1.6 */ + jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); +}; + +/* + * C++ object wrapper. + * + * This is usually overlaid on a C struct whose first element is a + * JNINativeInterface*. We rely somewhat on compiler behavior. + */ +struct _JNIEnv { + /* do not rename this; it does not seem to be entirely opaque */ + const struct JNINativeInterface* functions; + +#if defined(__cplusplus) + + jint GetVersion() + { return functions->GetVersion(this); } + + jclass DefineClass(const char *name, jobject loader, const jbyte* buf, + jsize bufLen) + { return functions->DefineClass(this, name, loader, buf, bufLen); } + + jclass FindClass(const char* name) + { return functions->FindClass(this, name); } + + jmethodID FromReflectedMethod(jobject method) + { return functions->FromReflectedMethod(this, method); } + + jfieldID FromReflectedField(jobject field) + { return functions->FromReflectedField(this, field); } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) + { return functions->ToReflectedMethod(this, cls, methodID, isStatic); } + + jclass GetSuperclass(jclass clazz) + { return functions->GetSuperclass(this, clazz); } + + jboolean IsAssignableFrom(jclass clazz1, jclass clazz2) + { return functions->IsAssignableFrom(this, clazz1, clazz2); } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) + { return functions->ToReflectedField(this, cls, fieldID, isStatic); } + + jint Throw(jthrowable obj) + { return functions->Throw(this, obj); } + + jint ThrowNew(jclass clazz, const char* message) + { return functions->ThrowNew(this, clazz, message); } + + jthrowable ExceptionOccurred() + { return functions->ExceptionOccurred(this); } + + void ExceptionDescribe() + { functions->ExceptionDescribe(this); } + + void ExceptionClear() + { functions->ExceptionClear(this); } + + void FatalError(const char* msg) + { functions->FatalError(this, msg); } + + jint PushLocalFrame(jint capacity) + { return functions->PushLocalFrame(this, capacity); } + + jobject PopLocalFrame(jobject result) + { return functions->PopLocalFrame(this, result); } + + jobject NewGlobalRef(jobject obj) + { return functions->NewGlobalRef(this, obj); } + + void DeleteGlobalRef(jobject globalRef) + { functions->DeleteGlobalRef(this, globalRef); } + + void DeleteLocalRef(jobject localRef) + { functions->DeleteLocalRef(this, localRef); } + + jboolean IsSameObject(jobject ref1, jobject ref2) + { return functions->IsSameObject(this, ref1, ref2); } + + jobject NewLocalRef(jobject ref) + { return functions->NewLocalRef(this, ref); } + + jint EnsureLocalCapacity(jint capacity) + { return functions->EnsureLocalCapacity(this, capacity); } + + jobject AllocObject(jclass clazz) + { return functions->AllocObject(this, clazz); } + + jobject NewObject(jclass clazz, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + jobject result = functions->NewObjectV(this, clazz, methodID, args); + va_end(args); + return result; + } + + jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) + { return functions->NewObjectV(this, clazz, methodID, args); } + + jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) + { return functions->NewObjectA(this, clazz, methodID, args); } + + jclass GetObjectClass(jobject obj) + { return functions->GetObjectClass(this, obj); } + + jboolean IsInstanceOf(jobject obj, jclass clazz) + { return functions->IsInstanceOf(this, obj, clazz); } + + jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) + { return functions->GetMethodID(this, clazz, name, sig); } + +#define CALL_TYPE_METHOD(_jtype, _jname) \ + _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->Call##_jname##MethodV(this, obj, methodID, \ + args); \ + va_end(args); \ + return result; \ + } +#define CALL_TYPE_METHODV(_jtype, _jname) \ + _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \ + va_list args) \ + { return functions->Call##_jname##MethodV(this, obj, methodID, args); } +#define CALL_TYPE_METHODA(_jtype, _jname) \ + _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \ + jvalue* args) \ + { return functions->Call##_jname##MethodA(this, obj, methodID, args); } + +#define CALL_TYPE(_jtype, _jname) \ + CALL_TYPE_METHOD(_jtype, _jname) \ + CALL_TYPE_METHODV(_jtype, _jname) \ + CALL_TYPE_METHODA(_jtype, _jname) + + CALL_TYPE(jobject, Object) + CALL_TYPE(jboolean, Boolean) + CALL_TYPE(jbyte, Byte) + CALL_TYPE(jchar, Char) + CALL_TYPE(jshort, Short) + CALL_TYPE(jint, Int) + CALL_TYPE(jlong, Long) + CALL_TYPE(jfloat, Float) + CALL_TYPE(jdouble, Double) + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallVoidMethodV(this, obj, methodID, args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args) + { functions->CallVoidMethodV(this, obj, methodID, args); } + void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) + { functions->CallVoidMethodA(this, obj, methodID, args); } + +#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \ + jmethodID methodID, ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->CallNonvirtual##_jname##MethodV(this, obj, \ + clazz, methodID, args); \ + va_end(args); \ + return result; \ + } +#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \ + jmethodID methodID, va_list args) \ + { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \ + methodID, args); } +#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \ + jmethodID methodID, jvalue* args) \ + { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \ + methodID, args); } + +#define CALL_NONVIRT_TYPE(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) + + CALL_NONVIRT_TYPE(jobject, Object) + CALL_NONVIRT_TYPE(jboolean, Boolean) + CALL_NONVIRT_TYPE(jbyte, Byte) + CALL_NONVIRT_TYPE(jchar, Char) + CALL_NONVIRT_TYPE(jshort, Short) + CALL_NONVIRT_TYPE(jint, Int) + CALL_NONVIRT_TYPE(jlong, Long) + CALL_NONVIRT_TYPE(jfloat, Float) + CALL_NONVIRT_TYPE(jdouble, Double) + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) + { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue* args) + { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } + + jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) + { return functions->GetFieldID(this, clazz, name, sig); } + + jobject GetObjectField(jobject obj, jfieldID fieldID) + { return functions->GetObjectField(this, obj, fieldID); } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) + { return functions->GetBooleanField(this, obj, fieldID); } + jbyte GetByteField(jobject obj, jfieldID fieldID) + { return functions->GetByteField(this, obj, fieldID); } + jchar GetCharField(jobject obj, jfieldID fieldID) + { return functions->GetCharField(this, obj, fieldID); } + jshort GetShortField(jobject obj, jfieldID fieldID) + { return functions->GetShortField(this, obj, fieldID); } + jint GetIntField(jobject obj, jfieldID fieldID) + { return functions->GetIntField(this, obj, fieldID); } + jlong GetLongField(jobject obj, jfieldID fieldID) + { return functions->GetLongField(this, obj, fieldID); } + jfloat GetFloatField(jobject obj, jfieldID fieldID) + { return functions->GetFloatField(this, obj, fieldID); } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) + { return functions->GetDoubleField(this, obj, fieldID); } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject value) + { functions->SetObjectField(this, obj, fieldID, value); } + void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) + { functions->SetBooleanField(this, obj, fieldID, value); } + void SetByteField(jobject obj, jfieldID fieldID, jbyte value) + { functions->SetByteField(this, obj, fieldID, value); } + void SetCharField(jobject obj, jfieldID fieldID, jchar value) + { functions->SetCharField(this, obj, fieldID, value); } + void SetShortField(jobject obj, jfieldID fieldID, jshort value) + { functions->SetShortField(this, obj, fieldID, value); } + void SetIntField(jobject obj, jfieldID fieldID, jint value) + { functions->SetIntField(this, obj, fieldID, value); } + void SetLongField(jobject obj, jfieldID fieldID, jlong value) + { functions->SetLongField(this, obj, fieldID, value); } + void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) + { functions->SetFloatField(this, obj, fieldID, value); } + void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) + { functions->SetDoubleField(this, obj, fieldID, value); } + + jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) + { return functions->GetStaticMethodID(this, clazz, name, sig); } + +#define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ + _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \ + ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->CallStatic##_jname##MethodV(this, clazz, \ + methodID, args); \ + va_end(args); \ + return result; \ + } +#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ + _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \ + va_list args) \ + { return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \ + args); } +#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \ + _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \ + jvalue* args) \ + { return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \ + args); } + +#define CALL_STATIC_TYPE(_jtype, _jname) \ + CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ + CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ + CALL_STATIC_TYPE_METHODA(_jtype, _jname) + + CALL_STATIC_TYPE(jobject, Object) + CALL_STATIC_TYPE(jboolean, Boolean) + CALL_STATIC_TYPE(jbyte, Byte) + CALL_STATIC_TYPE(jchar, Char) + CALL_STATIC_TYPE(jshort, Short) + CALL_STATIC_TYPE(jint, Int) + CALL_STATIC_TYPE(jlong, Long) + CALL_STATIC_TYPE(jfloat, Float) + CALL_STATIC_TYPE(jdouble, Double) + + void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallStaticVoidMethodV(this, clazz, methodID, args); + va_end(args); + } + void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args) + { functions->CallStaticVoidMethodV(this, clazz, methodID, args); } + void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) + { functions->CallStaticVoidMethodA(this, clazz, methodID, args); } + + jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig) + { return functions->GetStaticFieldID(this, clazz, name, sig); } + + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticObjectField(this, clazz, fieldID); } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticBooleanField(this, clazz, fieldID); } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticByteField(this, clazz, fieldID); } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticCharField(this, clazz, fieldID); } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticShortField(this, clazz, fieldID); } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticIntField(this, clazz, fieldID); } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticLongField(this, clazz, fieldID); } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticFloatField(this, clazz, fieldID); } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticDoubleField(this, clazz, fieldID); } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) + { functions->SetStaticObjectField(this, clazz, fieldID, value); } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) + { functions->SetStaticBooleanField(this, clazz, fieldID, value); } + void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) + { functions->SetStaticByteField(this, clazz, fieldID, value); } + void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) + { functions->SetStaticCharField(this, clazz, fieldID, value); } + void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) + { functions->SetStaticShortField(this, clazz, fieldID, value); } + void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) + { functions->SetStaticIntField(this, clazz, fieldID, value); } + void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) + { functions->SetStaticLongField(this, clazz, fieldID, value); } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) + { functions->SetStaticFloatField(this, clazz, fieldID, value); } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) + { functions->SetStaticDoubleField(this, clazz, fieldID, value); } + + jstring NewString(const jchar* unicodeChars, jsize len) + { return functions->NewString(this, unicodeChars, len); } + + jsize GetStringLength(jstring string) + { return functions->GetStringLength(this, string); } + + const jchar* GetStringChars(jstring string, jboolean* isCopy) + { return functions->GetStringChars(this, string, isCopy); } + + void ReleaseStringChars(jstring string, const jchar* chars) + { functions->ReleaseStringChars(this, string, chars); } + + jstring NewStringUTF(const char* bytes) + { return functions->NewStringUTF(this, bytes); } + + jsize GetStringUTFLength(jstring string) + { return functions->GetStringUTFLength(this, string); } + + const char* GetStringUTFChars(jstring string, jboolean* isCopy) + { return functions->GetStringUTFChars(this, string, isCopy); } + + void ReleaseStringUTFChars(jstring string, const char* utf) + { functions->ReleaseStringUTFChars(this, string, utf); } + + jsize GetArrayLength(jarray array) + { return functions->GetArrayLength(this, array); } + + jobjectArray NewObjectArray(jsize length, jclass elementClass, + jobject initialElement) + { return functions->NewObjectArray(this, length, elementClass, + initialElement); } + + jobject GetObjectArrayElement(jobjectArray array, jsize index) + { return functions->GetObjectArrayElement(this, array, index); } + + void SetObjectArrayElement(jobjectArray array, jsize index, jobject value) + { functions->SetObjectArrayElement(this, array, index, value); } + + jbooleanArray NewBooleanArray(jsize length) + { return functions->NewBooleanArray(this, length); } + jbyteArray NewByteArray(jsize length) + { return functions->NewByteArray(this, length); } + jcharArray NewCharArray(jsize length) + { return functions->NewCharArray(this, length); } + jshortArray NewShortArray(jsize length) + { return functions->NewShortArray(this, length); } + jintArray NewIntArray(jsize length) + { return functions->NewIntArray(this, length); } + jlongArray NewLongArray(jsize length) + { return functions->NewLongArray(this, length); } + jfloatArray NewFloatArray(jsize length) + { return functions->NewFloatArray(this, length); } + jdoubleArray NewDoubleArray(jsize length) + { return functions->NewDoubleArray(this, length); } + + jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy) + { return functions->GetBooleanArrayElements(this, array, isCopy); } + jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy) + { return functions->GetByteArrayElements(this, array, isCopy); } + jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy) + { return functions->GetCharArrayElements(this, array, isCopy); } + jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy) + { return functions->GetShortArrayElements(this, array, isCopy); } + jint* GetIntArrayElements(jintArray array, jboolean* isCopy) + { return functions->GetIntArrayElements(this, array, isCopy); } + jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy) + { return functions->GetLongArrayElements(this, array, isCopy); } + jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy) + { return functions->GetFloatArrayElements(this, array, isCopy); } + jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy) + { return functions->GetDoubleArrayElements(this, array, isCopy); } + + void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems, + jint mode) + { functions->ReleaseBooleanArrayElements(this, array, elems, mode); } + void ReleaseByteArrayElements(jbyteArray array, jbyte* elems, + jint mode) + { functions->ReleaseByteArrayElements(this, array, elems, mode); } + void ReleaseCharArrayElements(jcharArray array, jchar* elems, + jint mode) + { functions->ReleaseCharArrayElements(this, array, elems, mode); } + void ReleaseShortArrayElements(jshortArray array, jshort* elems, + jint mode) + { functions->ReleaseShortArrayElements(this, array, elems, mode); } + void ReleaseIntArrayElements(jintArray array, jint* elems, + jint mode) + { functions->ReleaseIntArrayElements(this, array, elems, mode); } + void ReleaseLongArrayElements(jlongArray array, jlong* elems, + jint mode) + { functions->ReleaseLongArrayElements(this, array, elems, mode); } + void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems, + jint mode) + { functions->ReleaseFloatArrayElements(this, array, elems, mode); } + void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems, + jint mode) + { functions->ReleaseDoubleArrayElements(this, array, elems, mode); } + + void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + jboolean* buf) + { functions->GetBooleanArrayRegion(this, array, start, len, buf); } + void GetByteArrayRegion(jbyteArray array, jsize start, jsize len, + jbyte* buf) + { functions->GetByteArrayRegion(this, array, start, len, buf); } + void GetCharArrayRegion(jcharArray array, jsize start, jsize len, + jchar* buf) + { functions->GetCharArrayRegion(this, array, start, len, buf); } + void GetShortArrayRegion(jshortArray array, jsize start, jsize len, + jshort* buf) + { functions->GetShortArrayRegion(this, array, start, len, buf); } + void GetIntArrayRegion(jintArray array, jsize start, jsize len, + jint* buf) + { functions->GetIntArrayRegion(this, array, start, len, buf); } + void GetLongArrayRegion(jlongArray array, jsize start, jsize len, + jlong* buf) + { functions->GetLongArrayRegion(this, array, start, len, buf); } + void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + jfloat* buf) + { functions->GetFloatArrayRegion(this, array, start, len, buf); } + void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + jdouble* buf) + { functions->GetDoubleArrayRegion(this, array, start, len, buf); } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean* buf) + { functions->SetBooleanArrayRegion(this, array, start, len, buf); } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte* buf) + { functions->SetByteArrayRegion(this, array, start, len, buf); } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar* buf) + { functions->SetCharArrayRegion(this, array, start, len, buf); } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort* buf) + { functions->SetShortArrayRegion(this, array, start, len, buf); } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint* buf) + { functions->SetIntArrayRegion(this, array, start, len, buf); } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong* buf) + { functions->SetLongArrayRegion(this, array, start, len, buf); } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat* buf) + { functions->SetFloatArrayRegion(this, array, start, len, buf); } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble* buf) + { functions->SetDoubleArrayRegion(this, array, start, len, buf); } + + jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, + jint nMethods) + { return functions->RegisterNatives(this, clazz, methods, nMethods); } + + jint UnregisterNatives(jclass clazz) + { return functions->UnregisterNatives(this, clazz); } + + jint MonitorEnter(jobject obj) + { return functions->MonitorEnter(this, obj); } + + jint MonitorExit(jobject obj) + { return functions->MonitorExit(this, obj); } + + jint GetJavaVM(JavaVM** vm) + { return functions->GetJavaVM(this, vm); } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf) + { functions->GetStringRegion(this, str, start, len, buf); } + + void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) + { return functions->GetStringUTFRegion(this, str, start, len, buf); } + + void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) + { return functions->GetPrimitiveArrayCritical(this, array, isCopy); } + + void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) + { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } + + const jchar* GetStringCritical(jstring string, jboolean* isCopy) + { return functions->GetStringCritical(this, string, isCopy); } + + void ReleaseStringCritical(jstring string, const jchar* carray) + { functions->ReleaseStringCritical(this, string, carray); } + + jweak NewWeakGlobalRef(jobject obj) + { return functions->NewWeakGlobalRef(this, obj); } + + void DeleteWeakGlobalRef(jweak obj) + { functions->DeleteWeakGlobalRef(this, obj); } + + jboolean ExceptionCheck() + { return functions->ExceptionCheck(this); } + + jobject NewDirectByteBuffer(void* address, jlong capacity) + { return functions->NewDirectByteBuffer(this, address, capacity); } + + void* GetDirectBufferAddress(jobject buf) + { return functions->GetDirectBufferAddress(this, buf); } + + jlong GetDirectBufferCapacity(jobject buf) + { return functions->GetDirectBufferCapacity(this, buf); } + + /* added in JNI 1.6 */ + jobjectRefType GetObjectRefType(jobject obj) + { return functions->GetObjectRefType(this, obj); } +#endif /*__cplusplus*/ +}; + + +/* + * JNI invocation interface. + */ +struct JNIInvokeInterface { + void* reserved0; + void* reserved1; + void* reserved2; + + jint (*DestroyJavaVM)(JavaVM*); + jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); + jint (*DetachCurrentThread)(JavaVM*); + jint (*GetEnv)(JavaVM*, void**, jint); + jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); +}; + +/* + * C++ version. + */ +struct _JavaVM { + const struct JNIInvokeInterface* functions; + +#if defined(__cplusplus) + jint DestroyJavaVM() + { return functions->DestroyJavaVM(this); } + jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) + { return functions->AttachCurrentThread(this, p_env, thr_args); } + jint DetachCurrentThread() + { return functions->DetachCurrentThread(this); } + jint GetEnv(void** env, jint version) + { return functions->GetEnv(this, env, version); } + jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) + { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); } +#endif /*__cplusplus*/ +}; + +struct JavaVMAttachArgs { + jint version; /* must be >= JNI_VERSION_1_2 */ + const char* name; /* NULL or name of thread as modified UTF-8 str */ + jobject group; /* global ref of a ThreadGroup object, or NULL */ +}; +typedef struct JavaVMAttachArgs JavaVMAttachArgs; + +/* + * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no + * longer supported.) + */ +typedef struct JavaVMOption { + const char* optionString; + void* extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; /* use JNI_VERSION_1_2 or later */ + + jint nOptions; + JavaVMOption* options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +#ifdef __cplusplus +extern "C" { +#endif +/* + * VM initialization functions. + * + * Note these are the only symbols exported for JNI by the VM. + */ +jint JNI_GetDefaultJavaVMInitArgs(void*); +jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*); +jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); + +#define JNIIMPORT +#define JNIEXPORT __attribute__ ((visibility ("default"))) +#define JNICALL + +/* + * Prototypes for functions exported by loadable shared libs. These are + * called by JNI, not provided by JNI. + */ +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved); +JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved); + +#ifdef __cplusplus +} +#endif + + +/* + * Manifest constants. + */ +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#define JNI_OK (0) /* no error */ +#define JNI_ERR (-1) /* generic error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ + +#define JNI_COMMIT 1 /* copy content, do not free buffer */ +#define JNI_ABORT 2 /* free buffer w/o copying back */ + +#endif /* JNI_H_ */ diff --git a/tests/CSSLayoutAbsolutePositionTest.cpp b/tests/CSSLayoutAbsolutePositionTest.cpp index 92fd8f0..905cd73 100644 --- a/tests/CSSLayoutAbsolutePositionTest.cpp +++ b/tests/CSSLayoutAbsolutePositionTest.cpp @@ -31,6 +31,11 @@
+ +
+
+
+
* */ @@ -248,3 +253,72 @@ TEST(CSSLayoutTest, do_not_clamp_height_of_absolute_node_to_height_of_its_overfl CSSNodeFreeRecursive(root); } + +TEST(CSSLayoutTest, absolute_layout_within_border) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetMargin(root, CSSEdgeLeft, 10); + CSSNodeStyleSetMargin(root, CSSEdgeTop, 10); + CSSNodeStyleSetMargin(root, CSSEdgeRight, 10); + CSSNodeStyleSetMargin(root, CSSEdgeBottom, 10); + CSSNodeStyleSetPadding(root, CSSEdgeLeft, 10); + CSSNodeStyleSetPadding(root, CSSEdgeTop, 10); + CSSNodeStyleSetPadding(root, CSSEdgeRight, 10); + CSSNodeStyleSetPadding(root, CSSEdgeBottom, 10); + CSSNodeStyleSetBorder(root, CSSEdgeLeft, 10); + CSSNodeStyleSetBorder(root, CSSEdgeTop, 10); + CSSNodeStyleSetBorder(root, CSSEdgeRight, 10); + CSSNodeStyleSetBorder(root, CSSEdgeBottom, 10); + CSSNodeStyleSetWidth(root, 100); + CSSNodeStyleSetHeight(root, 100); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeStyleSetPositionType(root_child0, CSSPositionTypeAbsolute); + CSSNodeStyleSetPosition(root_child0, CSSEdgeLeft, 0); + CSSNodeStyleSetPosition(root_child0, CSSEdgeTop, 0); + CSSNodeStyleSetWidth(root_child0, 50); + CSSNodeStyleSetHeight(root_child0, 50); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child1 = CSSNodeNew(); + CSSNodeStyleSetPositionType(root_child1, CSSPositionTypeAbsolute); + CSSNodeStyleSetPosition(root_child1, CSSEdgeRight, 0); + CSSNodeStyleSetPosition(root_child1, CSSEdgeBottom, 0); + CSSNodeStyleSetWidth(root_child1, 50); + CSSNodeStyleSetHeight(root_child1, 50); + CSSNodeInsertChild(root, root_child1, 1); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(10, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(10, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(10, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(10, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(40, CSSNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(40, CSSNodeLayoutGetTop(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child1)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(10, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(10, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(10, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(10, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(40, CSSNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(40, CSSNodeLayoutGetTop(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child1)); + + CSSNodeFreeRecursive(root); +} diff --git a/tests/CSSLayoutAlignContentTest.cpp b/tests/CSSLayoutAlignContentTest.cpp index 8d46e69..9fe462a 100644 --- a/tests/CSSLayoutAlignContentTest.cpp +++ b/tests/CSSLayoutAlignContentTest.cpp @@ -49,10 +49,7 @@ TEST(CSSLayoutTest, align_content_flex_start) { const CSSNodeRef root = CSSNodeNew(); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); CSSNodeStyleSetHeight(root, 100); @@ -150,10 +147,7 @@ TEST(CSSLayoutTest, align_content_flex_start) { TEST(CSSLayoutTest, align_content_flex_end) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetAlignContent(root, CSSAlignFlexEnd); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); CSSNodeStyleSetHeight(root, 100); @@ -251,10 +245,7 @@ TEST(CSSLayoutTest, align_content_flex_end) { TEST(CSSLayoutTest, align_content_center) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetAlignContent(root, CSSAlignCenter); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); CSSNodeStyleSetHeight(root, 100); @@ -352,10 +343,7 @@ TEST(CSSLayoutTest, align_content_center) { TEST(CSSLayoutTest, align_content_stretch) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetAlignContent(root, CSSAlignStretch); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); CSSNodeStyleSetHeight(root, 100); diff --git a/tests/CSSLayoutDefaultValuesTest.cpp b/tests/CSSLayoutDefaultValuesTest.cpp index 286a604..f9e1766 100644 --- a/tests/CSSLayoutDefaultValuesTest.cpp +++ b/tests/CSSLayoutDefaultValuesTest.cpp @@ -23,10 +23,7 @@ TEST(CSSLayoutTest, assert_default_values) { ASSERT_EQ(CSSAlignStretch, CSSNodeStyleGetAlignItems(root)); ASSERT_EQ(CSSAlignAuto, CSSNodeStyleGetAlignSelf(root)); ASSERT_EQ(CSSPositionTypeRelative, CSSNodeStyleGetPositionType(root)); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// ASSERT_EQ(CSSWrapTypeNoWrap, CSSNodeStyleGetFlexWrap(root)); ASSERT_EQ(CSSWrapNoWrap, CSSNodeStyleGetFlexWrap(root)); - // END_UNITY ASSERT_EQ(CSSOverflowVisible, CSSNodeStyleGetOverflow(root)); ASSERT_EQ(0, CSSNodeStyleGetFlexGrow(root)); ASSERT_EQ(0, CSSNodeStyleGetFlexShrink(root)); diff --git a/tests/CSSLayoutDirtyMarkingTest.cpp b/tests/CSSLayoutDirtyMarkingTest.cpp index 7bafe35..fed544f 100644 --- a/tests/CSSLayoutDirtyMarkingTest.cpp +++ b/tests/CSSLayoutDirtyMarkingTest.cpp @@ -83,11 +83,14 @@ TEST(CSSLayoutTest, dirty_node_only_if_children_are_actually_removed) { CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); - CSSNodeRemoveChild(root, CSSNodeNew()); + const CSSNodeRef child1 = CSSNodeNew(); + CSSNodeRemoveChild(root, child1); EXPECT_FALSE(CSSNodeIsDirty(root)); + CSSNodeFree(child1); CSSNodeRemoveChild(root, child0); EXPECT_TRUE(CSSNodeIsDirty(root)); + CSSNodeFree(child0); CSSNodeFreeRecursive(root); } diff --git a/tests/CSSLayoutFlexTest.cpp b/tests/CSSLayoutFlexTest.cpp index 7a5c76e..65991c0 100644 --- a/tests/CSSLayoutFlexTest.cpp +++ b/tests/CSSLayoutFlexTest.cpp @@ -41,6 +41,12 @@
+ +
+
+
+
+
* */ @@ -381,3 +387,52 @@ TEST(CSSLayoutTest, flex_basis_overrides_main_size) { CSSNodeFreeRecursive(root); } + +TEST(CSSLayoutTest, flex_grow_shrink_at_most) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetWidth(root, 100); + CSSNodeStyleSetHeight(root, 100); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child0_child0 = CSSNodeNew(); + CSSNodeStyleSetFlexGrow(root_child0_child0, 1); + CSSNodeStyleSetFlexShrink(root_child0_child0, 1); + CSSNodeInsertChild(root_child0, root_child0_child0, 0); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeFreeRecursive(root); +} diff --git a/tests/CSSLayoutFlexWrapTest.cpp b/tests/CSSLayoutFlexWrapTest.cpp index cf3cc65..74b2365 100644 --- a/tests/CSSLayoutFlexWrapTest.cpp +++ b/tests/CSSLayoutFlexWrapTest.cpp @@ -45,10 +45,7 @@ TEST(CSSLayoutTest, wrap_column) { const CSSNodeRef root = CSSNodeNew(); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetHeight(root, 100); const CSSNodeRef root_child0 = CSSNodeNew(); @@ -130,10 +127,7 @@ TEST(CSSLayoutTest, wrap_column) { TEST(CSSLayoutTest, wrap_row) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); const CSSNodeRef root_child0 = CSSNodeNew(); @@ -216,10 +210,7 @@ TEST(CSSLayoutTest, wrap_row_align_items_flex_end) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow); CSSNodeStyleSetAlignItems(root, CSSAlignFlexEnd); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); const CSSNodeRef root_child0 = CSSNodeNew(); @@ -302,10 +293,7 @@ TEST(CSSLayoutTest, wrap_row_align_items_center) { const CSSNodeRef root = CSSNodeNew(); CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow); CSSNodeStyleSetAlignItems(root, CSSAlignCenter); - // BEGIN_UNITY @joce 11-01-2016 CompileForC# -// CSSNodeStyleSetFlexWrap(root, CSSWrapTypeWrap); CSSNodeStyleSetFlexWrap(root, CSSWrapWrap); - // END_UNITY CSSNodeStyleSetWidth(root, 100); const CSSNodeRef root_child0 = CSSNodeNew(); diff --git a/tests/CSSLayoutMeasureCacheTest.cpp b/tests/CSSLayoutMeasureCacheTest.cpp index 00aab59..7a715e9 100644 --- a/tests/CSSLayoutMeasureCacheTest.cpp +++ b/tests/CSSLayoutMeasureCacheTest.cpp @@ -17,7 +17,7 @@ static CSSSize _measureMax(CSSNodeRef node, CSSMeasureMode heightMode) { int *measureCount = (int *)CSSNodeGetContext(node); - *measureCount = *measureCount + 1; + (*measureCount)++; // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 // return CSSSize { // .width = widthMode == CSSMeasureModeUndefined ? 10 : width, diff --git a/tests/CSSLayoutMeasureTest.cpp b/tests/CSSLayoutMeasureTest.cpp index a9d114d..790cdc7 100644 --- a/tests/CSSLayoutMeasureTest.cpp +++ b/tests/CSSLayoutMeasureTest.cpp @@ -10,27 +10,56 @@ #include #include -#if GTEST_HAS_DEATH_TEST static CSSSize _measure(CSSNodeRef node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) { - + int *measureCount = (int*) CSSNodeGetContext(node); + if (measureCount) { + (*measureCount)++; + } // BEGIN_UNITY @joce 10-26-2016 CompileForVS2010 +// return CSSSize { +// .width = 10, +// .height = 10, +// }; CSSSize size; - size.width = 0; - size.height = 0; + size.width = 10; + size.height = 10; return size; // END_UNITY } +TEST(CSSLayoutTest, dont_measure_single_grow_shrink_child) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetWidth(root, 100); + CSSNodeStyleSetHeight(root, 100); + + int measureCount = 0; + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeSetContext(root_child0, &measureCount); + CSSNodeSetMeasureFunc(root_child0, _measure); + CSSNodeStyleSetFlexGrow(root_child0, 1); + CSSNodeStyleSetFlexShrink(root_child0, 1); + CSSNodeInsertChild(root, root_child0, 0); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, measureCount); + + CSSNodeFreeRecursive(root); +} + +#if GTEST_HAS_DEATH_TEST TEST(CSSLayoutTest, cannot_add_child_to_node_with_measure_func) { const CSSNodeRef root = CSSNodeNew(); CSSNodeSetMeasureFunc(root, _measure); const CSSNodeRef root_child0 = CSSNodeNew(); ASSERT_DEATH(CSSNodeInsertChild(root, root_child0, 0), "Cannot add child.*"); + CSSNodeFree(root_child0); CSSNodeFreeRecursive(root); } diff --git a/tests/CSSLayoutMemoryFuncTest.cpp b/tests/CSSLayoutMemoryFuncTest.cpp new file mode 100644 index 0000000..fa1e390 --- /dev/null +++ b/tests/CSSLayoutMemoryFuncTest.cpp @@ -0,0 +1,77 @@ +/** + * 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. + */ + +#include +#include + +extern int32_t gNodeInstanceCount; + +static int testMallocCount; +static int testCallocCount; +static int testReallocCount; +static int testFreeCount; + +static void *testMalloc(size_t size) { + testMallocCount++; + return malloc(size); +} + +static void *testCalloc(size_t count, size_t size) { + testCallocCount++; + return calloc(count, size); +} + +static void *testRealloc(void *ptr, size_t size) { + testReallocCount++; + return realloc(ptr, size); +} + +static void testFree(void *ptr) { + testFreeCount++; + free(ptr); +} + +TEST(CSSLayoutTest, memory_func_default) { + gNodeInstanceCount = 0; // Reset CSSNode instance count for memory func test + CSSLayoutSetMemoryFuncs(NULL, NULL, NULL, NULL); + const CSSNodeRef root = CSSNodeNew(); + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeInsertChild(root, root_child0, 0); + CSSNodeFreeRecursive(root); +} + +TEST(CSSLayoutTest, memory_func_test_funcs) { + gNodeInstanceCount = 0; // Reset CSSNode instance count for memory func test + CSSLayoutSetMemoryFuncs(&testMalloc, &testCalloc, &testRealloc, &testFree); + const CSSNodeRef root = CSSNodeNew(); + for (int i = 0; i < 10; i++) { + const CSSNodeRef child = CSSNodeNew(); + CSSNodeInsertChild(root, child, 0); + } + CSSNodeFreeRecursive(root); + ASSERT_NE(testMallocCount, 0); + ASSERT_NE(testCallocCount, 0); + ASSERT_NE(testReallocCount, 0); + ASSERT_NE(testFreeCount, 0); + CSSLayoutSetMemoryFuncs(NULL, NULL, NULL, NULL); +} + +#if GTEST_HAS_DEATH_TEST +TEST(CSSLayoutTest, memory_func_assert_zero_nodes) { + gNodeInstanceCount = 0; // Reset CSSNode instance count for memory func test + const CSSNodeRef root = CSSNodeNew(); + ASSERT_DEATH(CSSLayoutSetMemoryFuncs(&testMalloc, &testCalloc, &testRealloc, &testFree), "Cannot set memory functions: all node must be freed first"); + CSSNodeFreeRecursive(root); +} + +TEST(CSSLayoutTest, memory_func_assert_all_non_null) { + gNodeInstanceCount = 0; // Reset CSSNode instance count for memory func test + ASSERT_DEATH(CSSLayoutSetMemoryFuncs(NULL, &testCalloc, &testRealloc, &testFree), "Cannot set memory functions: functions must be all NULL or Non-NULL"); +} +#endif diff --git a/tests/CSSLayoutMinMaxDimensionTest.cpp b/tests/CSSLayoutMinMaxDimensionTest.cpp index 38358a3..b9bec88 100644 --- a/tests/CSSLayoutMinMaxDimensionTest.cpp +++ b/tests/CSSLayoutMinMaxDimensionTest.cpp @@ -47,6 +47,12 @@
+ +
+
+
+
+
* */ @@ -420,3 +426,54 @@ TEST(CSSLayoutTest, flex_grow_within_max_width) { CSSNodeFreeRecursive(root); } + +TEST(CSSLayoutTest, flex_grow_within_constrained_max_width) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetWidth(root, 200); + CSSNodeStyleSetHeight(root, 100); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(root_child0, CSSFlexDirectionRow); + CSSNodeStyleSetMaxWidth(root_child0, 300); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child0_child0 = CSSNodeNew(); + CSSNodeStyleSetFlexGrow(root_child0_child0, 1); + CSSNodeStyleSetHeight(root_child0_child0, 20); + CSSNodeInsertChild(root_child0, root_child0_child0, 0); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeFreeRecursive(root); +} diff --git a/tests/CSSLayoutRelayoutTest.cpp b/tests/CSSLayoutRelayoutTest.cpp new file mode 100644 index 0000000..e30965d --- /dev/null +++ b/tests/CSSLayoutRelayoutTest.cpp @@ -0,0 +1,27 @@ +/** + * 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. + */ + +#include +#include + +TEST(CSSLayoutTest, dont_cache_computed_flex_basis_between_layouts) { + const CSSNodeRef root = CSSNodeNew(); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeStyleSetHeight(root_child0, 10); + CSSNodeStyleSetFlexBasis(root_child0, 20); + CSSNodeInsertChild(root, root_child0, 0); + + CSSNodeCalculateLayout(root, 100, CSSUndefined, CSSDirectionLTR); + CSSNodeCalculateLayout(root, 100, 100, CSSDirectionLTR); + + ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0)); + + CSSNodeFreeRecursive(root); +} diff --git a/tests/CSSLayoutStyleTest.cpp b/tests/CSSLayoutStyleTest.cpp new file mode 100644 index 0000000..6b7579a --- /dev/null +++ b/tests/CSSLayoutStyleTest.cpp @@ -0,0 +1,60 @@ +/** + * 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. + */ + +#include +#include + +TEST(CSSLayoutTest, copy_style_same) { + const CSSNodeRef node0 = CSSNodeNew(); + const CSSNodeRef node1 = CSSNodeNew(); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeCopyStyle(node0, node1); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +} + +TEST(CSSLayoutTest, copy_style_modified) { + const CSSNodeRef node0 = CSSNodeNew(); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + ASSERT_EQ(CSSFlexDirectionColumn, CSSNodeStyleGetFlexDirection(node0)); + ASSERT_TRUE(CSSValueIsUndefined(CSSNodeStyleGetMaxHeight(node0))); + + const CSSNodeRef node1 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node1, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node1, 10); + + CSSNodeCopyStyle(node0, node1); + ASSERT_TRUE(CSSNodeIsDirty(node0)); + ASSERT_EQ(CSSFlexDirectionRow, CSSNodeStyleGetFlexDirection(node0)); + ASSERT_EQ(10, CSSNodeStyleGetMaxHeight(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +} + +TEST(CSSLayoutTest, copy_style_modified_same) { + const CSSNodeRef node0 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node0, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node0, 10); + CSSNodeCalculateLayout(node0, CSSUndefined, CSSUndefined, CSSDirectionLTR); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + const CSSNodeRef node1 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node1, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node1, 10); + + CSSNodeCopyStyle(node0, node1); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +} diff --git a/uikit/CSSLayout/Tests/CSSLayoutTests.m b/uikit/CSSLayout/Tests/CSSLayoutTests.m deleted file mode 100644 index 4eb54b1..0000000 --- a/uikit/CSSLayout/Tests/CSSLayoutTests.m +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 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. - */ - -#import - -#import "UIView+CSSLayout.h" - -@interface CSSLayoutTests : XCTestCase -@end - -@implementation CSSLayoutTests - -- (void)testNodesAreDeallocedWithSingleView -{ - XCTAssertEqual(0, CSSNodeGetInstanceCount()); - - UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; - [view css_setFlexBasis:1]; - XCTAssertEqual(1, CSSNodeGetInstanceCount()); - view = nil; - - XCTAssertEqual(0, CSSNodeGetInstanceCount()); -} - -- (void)testNodesAreDeallocedCascade -{ - XCTAssertEqual(0, CSSNodeGetInstanceCount()); - - UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; - [view css_setFlexBasis:1]; - - for (int i=0; i<10; i++) { - UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; - [subview css_setFlexBasis:1]; - [view addSubview:subview]; - } - XCTAssertEqual(11, CSSNodeGetInstanceCount()); - view = nil; - - XCTAssertEqual(0, CSSNodeGetInstanceCount()); -} - -- (void)testUsesFlexbox -{ - UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; - XCTAssertFalse([view css_usesFlexbox]); - - [view css_setUsesFlexbox:YES]; - XCTAssertTrue([view css_usesFlexbox]); - - [view css_setUsesFlexbox:NO]; - XCTAssertFalse([view css_usesFlexbox]); -} - -- (void)testSizeThatFitsAsserts -{ - UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; - XCTAssertThrows([view css_sizeThatFits:CGSizeZero]); - - dispatch_sync(dispatch_queue_create("com.facebook.CSSLayout.testing", DISPATCH_QUEUE_SERIAL), ^(void){ - XCTAssertThrows([view css_sizeThatFits:CGSizeZero]); - }); -} - -- (void)testSizeThatFitsSmoke -{ - UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; - [view css_setUsesFlexbox:YES]; - - const CGSize constrainedSize = CGSizeMake(50, 50); - const CGSize actualSize = [view css_sizeThatFits:constrainedSize]; - XCTAssertTrue(CGSizeEqualToSize(constrainedSize, actualSize), @"Actual Size: %@", NSStringFromCGSize(actualSize)); -} - -- (void)testFrameAndOriginPlacement -{ - const CGSize containerSize = CGSizeMake(320, 50); - - UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; - [container css_setUsesFlexbox:YES]; - [container css_setFlexDirection:CSSFlexDirectionRow]; - - for (int i = 0; i < 3; i++) { - UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; - [subview css_setUsesFlexbox:YES]; - [subview css_setFlexGrow:1]; - - [container addSubview:subview]; - } - [container css_applyLayout]; - - XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:1].frame)); - XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:1].frame, [container.subviews objectAtIndex:2].frame)); - XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:2].frame)); - - CGFloat totalWidth = 0; - for (UIView *view in container.subviews) { - totalWidth += view.bounds.size.width; - } - - XCTAssertEqual(containerSize.width, totalWidth, @"The container's width is %.6f, the subviews take up %.6f", containerSize.width, totalWidth); -} - -@end