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:
parent
100b27cc7a
commit
974eec8264
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue