2015-02-20 23:45:12 +00:00
|
|
|
/**
|
2016-06-15 16:44:30 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2015-02-20 23:45:12 +00:00
|
|
|
* All rights reserved.
|
2016-07-13 17:15:44 +00:00
|
|
|
*
|
2015-02-20 23:45:12 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2016-06-15 16:44:30 +00:00
|
|
|
#ifndef __LAYOUT_H
|
|
|
|
#define __LAYOUT_H
|
|
|
|
|
|
|
|
#include <math.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
|
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
#define CSSUndefined NAN
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-13 17:15:44 +00:00
|
|
|
#include "CSSMacros.h"
|
|
|
|
|
|
|
|
CSS_EXTERN_C_BEGIN
|
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
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,
|
|
|
|
} CSSOverflow;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Note: auto is only a valid value for alignSelf. It is NOT a valid value for
|
|
|
|
// alignItems.
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef enum CSSAlign {
|
|
|
|
CSSAlignAuto,
|
|
|
|
CSSAlignFlexStart,
|
|
|
|
CSSAlignCenter,
|
|
|
|
CSSAlignFlexEnd,
|
|
|
|
CSSAlignStretch,
|
|
|
|
} CSSAlign;
|
|
|
|
|
|
|
|
typedef enum CSSPositionType {
|
|
|
|
CSSPositionTypeRelative,
|
|
|
|
CSSPositionTypeAbsolute,
|
|
|
|
} CSSPositionType;
|
|
|
|
|
|
|
|
typedef enum CSSWrapType {
|
|
|
|
CSSWrapTypeNoWrap,
|
|
|
|
CSSWrapTypeWrap,
|
|
|
|
} CSSWrapType;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Note: left and top are shared between position[2] and position[4], so
|
|
|
|
// they have to be before right and bottom.
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef enum CSSPosition {
|
|
|
|
CSSPositionLeft,
|
|
|
|
CSSPositionTop,
|
|
|
|
CSSPositionRight,
|
|
|
|
CSSPositionBottom,
|
|
|
|
CSSPositionStart,
|
|
|
|
CSSPositionEnd,
|
|
|
|
CSSPositionCount,
|
|
|
|
} CSSPosition;
|
|
|
|
|
|
|
|
typedef enum CSSMeasureMode {
|
|
|
|
CSSMeasureModeUndefined,
|
|
|
|
CSSMeasureModeExactly,
|
|
|
|
CSSMeasureModeAtMost,
|
|
|
|
CSSMeasureModeCount,
|
|
|
|
} CSSMeasureMode;
|
|
|
|
|
|
|
|
typedef enum CSSDimension {
|
|
|
|
CSSDimensionWidth,
|
|
|
|
CSSDimensionHeight,
|
|
|
|
} CSSDimension;
|
|
|
|
|
|
|
|
typedef struct CSSCachedMeasurement {
|
|
|
|
float availableWidth;
|
|
|
|
float availableHeight;
|
|
|
|
CSSMeasureMode widthMeasureMode;
|
|
|
|
CSSMeasureMode heightMeasureMode;
|
|
|
|
|
|
|
|
float computedWidth;
|
|
|
|
float computedHeight;
|
|
|
|
} CSSCachedMeasurement;
|
|
|
|
|
|
|
|
// This value was chosen based on empiracle data. Even the most complicated
|
|
|
|
// layouts should not require more than 16 entries to fit within the cache.
|
2016-06-15 16:44:30 +00:00
|
|
|
enum {
|
|
|
|
CSS_MAX_CACHED_RESULT_COUNT = 16
|
|
|
|
};
|
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef struct CSSLayout {
|
2016-06-15 16:44:30 +00:00
|
|
|
float position[4];
|
|
|
|
float dimensions[2];
|
2016-07-20 13:40:26 +00:00
|
|
|
CSSDirection direction;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
float flexBasis;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Instead of recomputing the entire layout every single time, we
|
|
|
|
// cache some information to break early when nothing changed
|
2016-07-20 13:40:26 +00:00
|
|
|
bool shouldUpdate;
|
|
|
|
int generationCount;
|
|
|
|
CSSDirection lastParentDirection;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
int nextCachedMeasurementsIndex;
|
|
|
|
CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
|
|
|
|
float measuredDimensions[2];
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
CSSCachedMeasurement cached_layout;
|
|
|
|
} CSSLayout;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef struct CSSMeasureResult {
|
2016-06-15 16:44:30 +00:00
|
|
|
float dimensions[2];
|
2016-07-20 13:40:26 +00:00
|
|
|
} CSSMeasureResult;
|
|
|
|
|
|
|
|
typedef struct CSSStyle {
|
|
|
|
CSSDirection direction;
|
|
|
|
CSSFlexDirection flexDirection;
|
|
|
|
CSSJustify justifyContent;
|
|
|
|
CSSAlign alignContent;
|
|
|
|
CSSAlign alignItems;
|
|
|
|
CSSAlign alignSelf;
|
|
|
|
CSSPositionType positionType;
|
|
|
|
CSSWrapType flexWrap;
|
|
|
|
CSSOverflow overflow;
|
2016-06-15 16:44:30 +00:00
|
|
|
float flex;
|
|
|
|
float margin[6];
|
|
|
|
float position[4];
|
|
|
|
/**
|
|
|
|
* You should skip all the rules that contain negative values for the
|
|
|
|
* following attributes. For example:
|
|
|
|
* {padding: 10, paddingLeft: -5}
|
|
|
|
* should output:
|
|
|
|
* {left: 10 ...}
|
|
|
|
* the following two are incorrect:
|
|
|
|
* {left: -5 ...}
|
|
|
|
* {left: 0 ...}
|
|
|
|
*/
|
|
|
|
float padding[6];
|
|
|
|
float border[6];
|
|
|
|
float dimensions[2];
|
|
|
|
float minDimensions[2];
|
|
|
|
float maxDimensions[2];
|
2016-07-20 13:40:26 +00:00
|
|
|
} CSSStyle;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef struct CSSNode {
|
|
|
|
CSSStyle style;
|
|
|
|
CSSLayout layout;
|
|
|
|
int childCount;
|
|
|
|
int lineIndex;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
struct CSSNode* nextChild;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
2016-07-20 13:40:26 +00:00
|
|
|
CSSMeasureResult (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
|
2016-06-15 16:44:30 +00:00
|
|
|
void (*print)(void *context);
|
2016-07-20 13:40:26 +00:00
|
|
|
struct CSSNode* (*getChild)(void *context, int i);
|
|
|
|
bool (*isDirty)(void *context);
|
|
|
|
bool (*isTextNode)(void *context);
|
2016-06-15 16:44:30 +00:00
|
|
|
void *context;
|
2016-07-20 13:40:26 +00:00
|
|
|
} CSSNode;
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Lifecycle of nodes and children
|
2016-07-20 13:40:26 +00:00
|
|
|
CSSNode *CSSNodeNew();
|
|
|
|
void CSSNodeInit(CSSNode *node);
|
|
|
|
void CSSNodeFree(CSSNode *node);
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Print utilities
|
2016-07-20 13:40:26 +00:00
|
|
|
typedef enum CSSPrintOptions {
|
|
|
|
CSSPrintOptionsLayout = 1,
|
|
|
|
CSSPrintOptionsStyle = 2,
|
|
|
|
CSSPrintOptionsChildren = 4,
|
|
|
|
} CSSPrintOptions;
|
|
|
|
|
|
|
|
void CSSNodePrint(CSSNode *node, CSSPrintOptions options);
|
2016-06-15 16:44:30 +00:00
|
|
|
|
|
|
|
// Function that computes the layout!
|
2016-07-20 13:40:26 +00:00
|
|
|
void layoutNode(CSSNode *node, float availableWidth, float availableHeight, CSSDirection parentDirection);
|
2016-06-15 16:44:30 +00:00
|
|
|
bool isUndefined(float value);
|
|
|
|
|
2016-07-13 17:15:44 +00:00
|
|
|
CSS_EXTERN_C_END
|
|
|
|
|
2016-06-15 16:44:30 +00:00
|
|
|
#endif
|