Add CSSLayout to ReactCommon

Summary: First step to sharing CSSLayout code between iOS and Android.

Reviewed By: emilsjolander

Differential Revision: D4160286

fbshipit-source-id: 976f5820b19a7011e0a14317c858465f932e1f59
This commit is contained in:
Andy Street 2016-11-11 10:50:09 -08:00 committed by Facebook Github Bot
parent 100b27cc7a
commit 974eec8264
6 changed files with 3222 additions and 0 deletions

View File

@ -0,0 +1,296 @@
/**
* 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 <CSSLayout/CSSLayout.h>
#include <fb/fbjni.h>
#include <iostream>
using namespace facebook::jni;
using namespace std;
static void _jniTransferLayoutDirection(CSSNodeRef node, alias_ref<jobject> javaNode) {
static auto layoutDirectionField = javaNode->getClass()->getField<jint>("mLayoutDirection");
javaNode->setFieldValue(layoutDirectionField, static_cast<jint>(CSSNodeLayoutGetDirection(node)));
}
static void _jniTransferLayoutOutputsRecursive(CSSNodeRef root) {
auto javaNode = adopt_local(
Environment::current()->NewLocalRef(reinterpret_cast<jweak>(CSSNodeGetContext(root))));
static auto widthField = javaNode->getClass()->getField<jfloat>("mWidth");
static auto heightField = javaNode->getClass()->getField<jfloat>("mHeight");
static auto leftField = javaNode->getClass()->getField<jfloat>("mLeft");
static auto topField = javaNode->getClass()->getField<jfloat>("mTop");
javaNode->setFieldValue(widthField, CSSNodeLayoutGetWidth(root));
javaNode->setFieldValue(heightField, CSSNodeLayoutGetHeight(root));
javaNode->setFieldValue(leftField, CSSNodeLayoutGetLeft(root));
javaNode->setFieldValue(topField, CSSNodeLayoutGetTop(root));
_jniTransferLayoutDirection(root, javaNode);
for (uint32_t i = 0; i < CSSNodeChildCount(root); i++) {
_jniTransferLayoutOutputsRecursive(CSSNodeGetChild(root, i));
}
}
static void _jniPrint(CSSNodeRef node) {
auto obj = adopt_local(
Environment::current()->NewLocalRef(reinterpret_cast<jweak>(CSSNodeGetContext(node))));
cout << obj->toString() << endl;
}
static CSSSize _jniMeasureFunc(CSSNodeRef node,
float width,
CSSMeasureMode widthMode,
float height,
CSSMeasureMode heightMode) {
auto obj = adopt_local(
Environment::current()->NewLocalRef(reinterpret_cast<jweak>(CSSNodeGetContext(node))));
static auto measureFunc = findClassLocal("com/facebook/csslayout/CSSNode")
->getMethod<jlong(jfloat, jint, jfloat, jint)>("measure");
_jniTransferLayoutDirection(node, obj);
const auto measureResult = measureFunc(obj, width, widthMode, height, heightMode);
static_assert(sizeof(measureResult) == 8,
"Expected measureResult to be 8 bytes, or two 32 bit ints");
const float measuredWidth = static_cast<float>(0xFFFFFFFF & (measureResult >> 32));
const float measuredHeight = static_cast<float>(0xFFFFFFFF & measureResult);
return CSSSize{measuredWidth, measuredHeight};
}
static global_ref<jobject> *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<void(jint, jstring)>("log");
logFunc(jLogger->get(), static_cast<jint>(level), Environment::current()->NewStringUTF(buffer));
return result;
}
static inline CSSNodeRef _jlong2CSSNodeRef(jlong addr) {
return reinterpret_cast<CSSNodeRef>(static_cast<intptr_t>(addr));
}
void jni_CSSLayoutSetLogger(alias_ref<jclass> clazz, alias_ref<jobject> logger) {
if (jLogger) {
jLogger->releaseAlias();
delete jLogger;
}
if (logger) {
jLogger = new global_ref<jobject>(make_global(logger));
CSSLayoutSetLogger(_jniLog);
} else {
jLogger = NULL;
CSSLayoutSetLogger(NULL);
}
}
void jni_CSSLog(alias_ref<jclass> clazz, jint level, jstring message) {
const char *nMessage = Environment::current()->GetStringUTFChars(message, 0);
CSSLog(static_cast<CSSLogLevel>(level), "%s", nMessage);
Environment::current()->ReleaseStringUTFChars(message, nMessage);
}
jint jni_CSSNodeGetInstanceCount(alias_ref<jclass> clazz) {
return CSSNodeGetInstanceCount();
}
jlong jni_CSSNodeNew(alias_ref<jobject> thiz) {
const CSSNodeRef node = CSSNodeNew();
CSSNodeSetContext(node, Environment::current()->NewWeakGlobalRef(thiz.get()));
CSSNodeSetPrintFunc(node, _jniPrint);
return reinterpret_cast<jlong>(node);
}
void jni_CSSNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
Environment::current()->DeleteWeakGlobalRef(
reinterpret_cast<jweak>(CSSNodeGetContext(_jlong2CSSNodeRef(nativePointer))));
CSSNodeFree(_jlong2CSSNodeRef(nativePointer));
}
void jni_CSSNodeReset(alias_ref<jobject> thiz, jlong nativePointer) {
const CSSNodeRef node = _jlong2CSSNodeRef(nativePointer);
void *context = CSSNodeGetContext(node);
CSSNodeReset(node);
CSSNodeSetContext(node, context);
CSSNodeSetPrintFunc(node, _jniPrint);
}
void jni_CSSNodeInsertChild(alias_ref<jobject>,
jlong nativePointer,
jlong childPointer,
jint index) {
CSSNodeInsertChild(_jlong2CSSNodeRef(nativePointer), _jlong2CSSNodeRef(childPointer), index);
}
void jni_CSSNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer) {
CSSNodeRemoveChild(_jlong2CSSNodeRef(nativePointer), _jlong2CSSNodeRef(childPointer));
}
void jni_CSSNodeCalculateLayout(alias_ref<jobject>, jlong nativePointer) {
const CSSNodeRef root = _jlong2CSSNodeRef(nativePointer);
CSSNodeCalculateLayout(root,
CSSUndefined,
CSSUndefined,
CSSNodeStyleGetDirection(_jlong2CSSNodeRef(nativePointer)));
_jniTransferLayoutOutputsRecursive(root);
}
void jni_CSSNodeMarkDirty(alias_ref<jobject>, jlong nativePointer) {
CSSNodeMarkDirty(_jlong2CSSNodeRef(nativePointer));
}
jboolean jni_CSSNodeIsDirty(alias_ref<jobject>, jlong nativePointer) {
return (jboolean) CSSNodeIsDirty(_jlong2CSSNodeRef(nativePointer));
}
void jni_CSSNodeSetHasMeasureFunc(alias_ref<jobject>,
jlong nativePointer,
jboolean hasMeasureFunc) {
CSSNodeSetMeasureFunc(_jlong2CSSNodeRef(nativePointer), hasMeasureFunc ? _jniMeasureFunc : NULL);
}
jboolean jni_CSSNodeHasNewLayout(alias_ref<jobject>, jlong nativePointer) {
return (jboolean) CSSNodeGetHasNewLayout(_jlong2CSSNodeRef(nativePointer));
}
void jni_CSSNodeMarkLayoutSeen(alias_ref<jobject>, jlong nativePointer) {
CSSNodeSetHasNewLayout(_jlong2CSSNodeRef(nativePointer), false);
}
#define CSS_NODE_JNI_STYLE_PROP(javatype, type, name) \
javatype jni_CSSNodeStyleGet##name(alias_ref<jobject>, jlong nativePointer) { \
return (javatype) CSSNodeStyleGet##name(_jlong2CSSNodeRef(nativePointer)); \
} \
\
void jni_CSSNodeStyleSet##name(alias_ref<jobject>, jlong nativePointer, javatype value) { \
CSSNodeStyleSet##name(_jlong2CSSNodeRef(nativePointer), static_cast<type>(value)); \
}
#define CSS_NODE_JNI_STYLE_EDGE_PROP(javatype, type, name) \
javatype jni_CSSNodeStyleGet##name(alias_ref<jobject>, jlong nativePointer, jint edge) { \
return (javatype) CSSNodeStyleGet##name(_jlong2CSSNodeRef(nativePointer), \
static_cast<CSSEdge>(edge)); \
} \
\
void jni_CSSNodeStyleSet##name(alias_ref<jobject>, \
jlong nativePointer, \
jint edge, \
javatype value) { \
CSSNodeStyleSet##name(_jlong2CSSNodeRef(nativePointer), \
static_cast<CSSEdge>(edge), \
static_cast<type>(value)); \
}
CSS_NODE_JNI_STYLE_PROP(jint, CSSDirection, Direction);
CSS_NODE_JNI_STYLE_PROP(jint, CSSFlexDirection, FlexDirection);
CSS_NODE_JNI_STYLE_PROP(jint, CSSJustify, JustifyContent);
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, CSSOverflow, Overflow);
void jni_CSSNodeStyleSetFlex(alias_ref<jobject>, jlong nativePointer, jfloat value) {
CSSNodeStyleSetFlex(_jlong2CSSNodeRef(nativePointer), static_cast<float>(value));
}
CSS_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, FlexBasis);
CSS_NODE_JNI_STYLE_EDGE_PROP(jfloat, float, Position);
CSS_NODE_JNI_STYLE_EDGE_PROP(jfloat, float, Margin);
CSS_NODE_JNI_STYLE_EDGE_PROP(jfloat, float, Padding);
CSS_NODE_JNI_STYLE_EDGE_PROP(jfloat, float, Border);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, Width);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MinWidth);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MaxWidth);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, Height);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MinHeight);
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MaxHeight);
#define CSSMakeNativeMethod(name) makeNativeMethod(#name, name)
jint JNI_OnLoad(JavaVM *vm, void *) {
return initialize(vm, [] {
registerNatives("com/facebook/csslayout/CSSNode",
{
CSSMakeNativeMethod(jni_CSSNodeNew),
CSSMakeNativeMethod(jni_CSSNodeFree),
CSSMakeNativeMethod(jni_CSSNodeReset),
CSSMakeNativeMethod(jni_CSSNodeInsertChild),
CSSMakeNativeMethod(jni_CSSNodeRemoveChild),
CSSMakeNativeMethod(jni_CSSNodeCalculateLayout),
CSSMakeNativeMethod(jni_CSSNodeHasNewLayout),
CSSMakeNativeMethod(jni_CSSNodeMarkDirty),
CSSMakeNativeMethod(jni_CSSNodeIsDirty),
CSSMakeNativeMethod(jni_CSSNodeMarkLayoutSeen),
CSSMakeNativeMethod(jni_CSSNodeSetHasMeasureFunc),
CSSMakeNativeMethod(jni_CSSNodeStyleGetDirection),
CSSMakeNativeMethod(jni_CSSNodeStyleSetDirection),
CSSMakeNativeMethod(jni_CSSNodeStyleGetFlexDirection),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlexDirection),
CSSMakeNativeMethod(jni_CSSNodeStyleGetJustifyContent),
CSSMakeNativeMethod(jni_CSSNodeStyleSetJustifyContent),
CSSMakeNativeMethod(jni_CSSNodeStyleGetAlignItems),
CSSMakeNativeMethod(jni_CSSNodeStyleSetAlignItems),
CSSMakeNativeMethod(jni_CSSNodeStyleGetAlignSelf),
CSSMakeNativeMethod(jni_CSSNodeStyleSetAlignSelf),
CSSMakeNativeMethod(jni_CSSNodeStyleGetAlignContent),
CSSMakeNativeMethod(jni_CSSNodeStyleSetAlignContent),
CSSMakeNativeMethod(jni_CSSNodeStyleGetPositionType),
CSSMakeNativeMethod(jni_CSSNodeStyleSetPositionType),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlexWrap),
CSSMakeNativeMethod(jni_CSSNodeStyleGetOverflow),
CSSMakeNativeMethod(jni_CSSNodeStyleSetOverflow),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlex),
CSSMakeNativeMethod(jni_CSSNodeStyleGetFlexGrow),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlexGrow),
CSSMakeNativeMethod(jni_CSSNodeStyleGetFlexShrink),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlexShrink),
CSSMakeNativeMethod(jni_CSSNodeStyleGetFlexBasis),
CSSMakeNativeMethod(jni_CSSNodeStyleSetFlexBasis),
CSSMakeNativeMethod(jni_CSSNodeStyleGetMargin),
CSSMakeNativeMethod(jni_CSSNodeStyleSetMargin),
CSSMakeNativeMethod(jni_CSSNodeStyleGetPadding),
CSSMakeNativeMethod(jni_CSSNodeStyleSetPadding),
CSSMakeNativeMethod(jni_CSSNodeStyleGetBorder),
CSSMakeNativeMethod(jni_CSSNodeStyleSetBorder),
CSSMakeNativeMethod(jni_CSSNodeStyleGetPosition),
CSSMakeNativeMethod(jni_CSSNodeStyleSetPosition),
CSSMakeNativeMethod(jni_CSSNodeStyleGetWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleSetWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleGetHeight),
CSSMakeNativeMethod(jni_CSSNodeStyleSetHeight),
CSSMakeNativeMethod(jni_CSSNodeStyleGetMinWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleSetMinWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleGetMinHeight),
CSSMakeNativeMethod(jni_CSSNodeStyleSetMinHeight),
CSSMakeNativeMethod(jni_CSSNodeStyleGetMaxWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleSetMaxWidth),
CSSMakeNativeMethod(jni_CSSNodeStyleGetMaxHeight),
CSSMakeNativeMethod(jni_CSSNodeStyleSetMaxHeight),
CSSMakeNativeMethod(jni_CSSNodeGetInstanceCount),
CSSMakeNativeMethod(jni_CSSLayoutSetLogger),
CSSMakeNativeMethod(jni_CSSLog),
});
});
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,241 @@
/**
* 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
#include <assert.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
// Not defined in MSVC++
#ifndef NAN
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
#define NAN (*(const float *) __nan)
#endif
#define CSSUndefined NAN
#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;
typedef enum CSSWrapType {
CSSWrapTypeNoWrap,
CSSWrapTypeWrap,
} CSSWrapType;
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,
CSSMeasureMode widthMode,
float height,
CSSMeasureMode heightMode);
typedef void (*CSSPrintFunc)(CSSNodeRef node);
typedef int (*CSSLogger)(CSSLogLevel level, const char *format, va_list args);
// CSSNode
WIN_EXPORT CSSNodeRef CSSNodeNew(void);
WIN_EXPORT void CSSNodeInit(const CSSNodeRef node);
WIN_EXPORT void CSSNodeFree(const CSSNodeRef node);
WIN_EXPORT void CSSNodeFreeRecursive(const CSSNodeRef node);
WIN_EXPORT void CSSNodeReset(const CSSNodeRef node);
WIN_EXPORT int32_t CSSNodeGetInstanceCount(void);
WIN_EXPORT void CSSNodeInsertChild(const CSSNodeRef node,
const CSSNodeRef child,
const uint32_t index);
WIN_EXPORT void CSSNodeRemoveChild(const CSSNodeRef node, const CSSNodeRef child);
WIN_EXPORT CSSNodeRef CSSNodeGetChild(const CSSNodeRef node, const uint32_t index);
WIN_EXPORT uint32_t CSSNodeChildCount(const CSSNodeRef node);
WIN_EXPORT void CSSNodeCalculateLayout(const CSSNodeRef node,
const float availableWidth,
const float availableHeight,
const CSSDirection parentDirection);
// Mark a node as dirty. Only valid for nodes with a custom measure function
// set.
// CSSLayout knows when to mark all other nodes as dirty but because nodes with
// measure functions
// depends on information not known to CSSLayout they must perform this dirty
// marking manually.
WIN_EXPORT void CSSNodeMarkDirty(const CSSNodeRef node);
WIN_EXPORT bool CSSNodeIsDirty(const CSSNodeRef node);
WIN_EXPORT void CSSNodePrint(const CSSNodeRef node, const CSSPrintOptions options);
WIN_EXPORT bool CSSValueIsUndefined(const float value);
WIN_EXPORT 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);
#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);
#define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \
WIN_EXPORT void CSSNodeStyleSet##name(const CSSNodeRef node, const type paramName); \
WIN_EXPORT type CSSNodeStyleGet##name(const CSSNodeRef node);
#define CSS_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \
WIN_EXPORT void CSSNodeStyleSet##name(const CSSNodeRef node, \
const CSSEdge edge, \
const type paramName); \
WIN_EXPORT type CSSNodeStyleGet##name(const CSSNodeRef node, const CSSEdge edge);
#define CSS_NODE_LAYOUT_PROPERTY(type, name) \
WIN_EXPORT type CSSNodeLayoutGet##name(const CSSNodeRef node);
CSS_NODE_PROPERTY(void *, Context, context);
CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc);
CSS_NODE_PROPERTY(CSSPrintFunc, PrintFunc, printFunc);
CSS_NODE_PROPERTY(bool, HasNewLayout, hasNewLayout);
CSS_NODE_STYLE_PROPERTY(CSSDirection, Direction, direction);
CSS_NODE_STYLE_PROPERTY(CSSFlexDirection, FlexDirection, flexDirection);
CSS_NODE_STYLE_PROPERTY(CSSJustify, JustifyContent, justifyContent);
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);
CSS_NODE_STYLE_PROPERTY(CSSWrapType, FlexWrap, flexWrap);
CSS_NODE_STYLE_PROPERTY(CSSOverflow, Overflow, overflow);
WIN_EXPORT void CSSNodeStyleSetFlex(const CSSNodeRef node, const float flex);
CSS_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow);
CSS_NODE_STYLE_PROPERTY(float, FlexShrink, flexShrink);
CSS_NODE_STYLE_PROPERTY(float, FlexBasis, flexBasis);
CSS_NODE_STYLE_EDGE_PROPERTY(float, Position, position);
CSS_NODE_STYLE_EDGE_PROPERTY(float, Margin, margin);
CSS_NODE_STYLE_EDGE_PROPERTY(float, Padding, padding);
CSS_NODE_STYLE_EDGE_PROPERTY(float, Border, border);
CSS_NODE_STYLE_PROPERTY(float, Width, width);
CSS_NODE_STYLE_PROPERTY(float, Height, height);
CSS_NODE_STYLE_PROPERTY(float, MinWidth, minWidth);
CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight);
CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth);
CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
CSS_NODE_LAYOUT_PROPERTY(float, Left);
CSS_NODE_LAYOUT_PROPERTY(float, Top);
CSS_NODE_LAYOUT_PROPERTY(float, Right);
CSS_NODE_LAYOUT_PROPERTY(float, Bottom);
CSS_NODE_LAYOUT_PROPERTY(float, Width);
CSS_NODE_LAYOUT_PROPERTY(float, Height);
CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction);
WIN_EXPORT void CSSLayoutSetLogger(CSSLogger logger);
WIN_EXPORT void CSSLog(CSSLogLevel level, const char *message, ...);
CSS_EXTERN_C_END

View File

@ -0,0 +1,42 @@
/**
* 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 __cplusplus
#define CSS_EXTERN_C_BEGIN extern "C" {
#define CSS_EXTERN_C_END }
#else
#define CSS_EXTERN_C_BEGIN
#define CSS_EXTERN_C_END
#endif
#ifdef _WINDLL
#define WIN_EXPORT __declspec(dllexport)
#else
#define WIN_EXPORT
#endif
#ifndef FB_ASSERTIONS_ENABLED
#define FB_ASSERTIONS_ENABLED 1
#endif
#if FB_ASSERTIONS_ENABLED
#define CSS_ABORT() abort()
#else
#define CSS_ABORT()
#endif
#ifndef CSS_ASSERT
#define CSS_ASSERT(X, message) \
if (!(X)) { \
CSSLog(CSSLogLevelError, "%s", message); \
CSS_ABORT(); \
}
#endif

View File

@ -0,0 +1,100 @@
/**
* 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 "CSSNodeList.h"
struct CSSNodeList {
uint32_t capacity;
uint32_t count;
CSSNodeRef *items;
};
CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity) {
const CSSNodeListRef list = malloc(sizeof(struct CSSNodeList));
CSS_ASSERT(list != NULL, "Could not allocate memory for list");
list->capacity = initialCapacity;
list->count = 0;
list->items = malloc(sizeof(CSSNodeRef) * list->capacity);
CSS_ASSERT(list->items != NULL, "Could not allocate memory for items");
return list;
}
void CSSNodeListFree(const CSSNodeListRef list) {
if (list) {
free(list->items);
free(list);
}
}
uint32_t CSSNodeListCount(const CSSNodeListRef list) {
if (list) {
return list->count;
}
return 0;
}
void CSSNodeListAdd(CSSNodeListRef *listp, const CSSNodeRef node) {
if (!*listp) {
*listp = CSSNodeListNew(4);
}
CSSNodeListInsert(listp, node, (*listp)->count);
}
void CSSNodeListInsert(CSSNodeListRef *listp, const CSSNodeRef node, const uint32_t index) {
if (!*listp) {
*listp = CSSNodeListNew(4);
}
CSSNodeListRef list = *listp;
if (list->count == list->capacity) {
list->capacity *= 2;
list->items = realloc(list->items, sizeof(CSSNodeRef) * list->capacity);
CSS_ASSERT(list->items != NULL, "Could not extend allocation for items");
}
for (uint32_t i = list->count; i > index; i--) {
list->items[i] = list->items[i - 1];
}
list->count++;
list->items[index] = node;
}
CSSNodeRef CSSNodeListRemove(const CSSNodeListRef list, const uint32_t index) {
const CSSNodeRef removed = list->items[index];
list->items[index] = NULL;
for (uint32_t i = index; i < list->count - 1; i++) {
list->items[i] = list->items[i + 1];
list->items[i + 1] = NULL;
}
list->count--;
return removed;
}
CSSNodeRef CSSNodeListDelete(const CSSNodeListRef list, const CSSNodeRef node) {
for (uint32_t i = 0; i < list->count; i++) {
if (list->items[i] == node) {
return CSSNodeListRemove(list, i);
}
}
return NULL;
}
CSSNodeRef CSSNodeListGet(const CSSNodeListRef list, const uint32_t index) {
if (CSSNodeListCount(list) > 0) {
return list->items[index];
}
return NULL;
}

View File

@ -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.
*/
#pragma once
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "CSSLayout.h"
#include "CSSMacros.h"
CSS_EXTERN_C_BEGIN
typedef struct CSSNodeList *CSSNodeListRef;
CSSNodeListRef CSSNodeListNew(const uint32_t initialCapacity);
void CSSNodeListFree(const CSSNodeListRef list);
uint32_t CSSNodeListCount(const CSSNodeListRef list);
void CSSNodeListAdd(CSSNodeListRef *listp, const CSSNodeRef node);
void CSSNodeListInsert(CSSNodeListRef *listp, const CSSNodeRef node, const uint32_t index);
CSSNodeRef CSSNodeListRemove(const CSSNodeListRef list, const uint32_t index);
CSSNodeRef CSSNodeListDelete(const CSSNodeListRef list, const CSSNodeRef node);
CSSNodeRef CSSNodeListGet(const CSSNodeListRef list, const uint32_t index);
CSS_EXTERN_C_END