# tinyflow **Repository Path**: oddity/tinyflow ## Basic Information - **Project Name**: tinyflow - **Description**: 一个从零设计的 2D 布局引擎。纯几何计算,不做渲染。没有 Web CSS 的历史包袱。 - **Primary Language**: C - **License**: BSD-2-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-03 - **Last Updated**: 2026-10-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # tinyflow A from-scratch 2D layout engine. Pure geometry, no rendering. No Web CSS legacy baggage. - **Pure C ABI** header + C++ implementation, compiles to static library - **Opaque handles** — zero internal leakage in public header - **User allocator** — all memory through your callbacks - **Two orthogonal systems** — Flow layout (Flow/Flex/Grid/Constraint, elements push each other) + Attach anchor layer (elements float above) - **Dirty incremental** — only recompute what changed; DIRTY_FLOW for self changes, DIRTY_DESCENDANT (v1.23.0) skips self size recompute and only relayouts dirty children, DIRTY_ATTACH propagates via reverse dependencies - **Four flow modes** — Flow (minimal stack with direction/lastChildFill, Flex subset), Flex (1D with wrap/grow/shrink), Grid (2D with areas/masonry/dense), Constraint (pin/bias positioning) - **Attach anchor layer** — cross-node anchoring, viewport alignment, sticky positioning, fallback chains, z-layer ordering - **StyleSheet** — named style classes for reuse - **Object pool** — recycled node memory, runtime configurable max size - **Flow node z-index** — explicit draw order and hit-test priority for flow nodes - **DPI aware** — dp unit with scale factor, auto-recompute on scale change - **Subtree compute** — layout only a specific subtree without affecting siblings (enables virtual scrolling) - **Virtual scrolling** — layout_enabled runtime state: disabled nodes keep previous result, skip subtree layout, re-enable auto-marks dirty - **Helper queries** — globalRect, isDirty, getDepth for upper-layer integration - **Stress tested** — 1000+ flow children, 500+ flex children, 200+ grid children, 500+ levels deep nesting, 4000+ test cases ## Quick Start ```cmake file(GLOB TINYFLOW_SOURCES src/*.cc) add_library(tinyflow STATIC ${TINYFLOW_SOURCES}) target_compile_definitions(tinyflow PUBLIC TINYFLOW_STATIC=1) target_include_directories(tinyflow PUBLIC include/) ``` ```c #include "tinyflow.h" tinyflow_allocator_callbacks alloc = { malloc, free }; tinyflow_set_allocator(&alloc); tinyflow_node* root = tinyflow_node_create(); // ... set styles, add children ... tinyflow_compute(root, &constraint, &ctx); tinyflow_compute_attaches(root, &ctx); ``` **C++ wrapper (header-only):** ```cpp #include "tinyflow.hpp" tinyflow::Engine engine; // sets allocator tinyflow::Node root; root.setFlexRow().addChild(child1).addChild(child2); root.compute(800, 600); auto r = root.result(); // r.local.x, r.local.y, r.local.w, r.local.h ``` ## Build ### xmake (recommended) ```bash # Build library only xmake # Build with tests xmake f --tests=y xmake # Run tests xmake run test_basic xmake run test_hpp xmake run benchmark ``` ### CMake ```bash # Configure cmake -S . -B build-cmake -G "Visual Studio 17 2022" -A x64 # Build cmake --build build-cmake --config Release # Run tests build-cmake/Release/tinyflow_test.exe build-cmake/Release/tinyflow_hpp_test.exe build-cmake/Release/tinyflow_benchmark.exe ``` ## Documentation Full documentation (design philosophy, core model, usage guide, API reference, integration guide, performance tuning, FAQ): **[docs/DOCUMENTATION.md](docs/DOCUMENTATION.md)** Version history and changelog: **[docs/CHANGELOG.md](docs/CHANGELOG.md)** ## Project Structure ``` tinyflow/ ├── xmake.lua # xmake build config (root) ├── CMakeLists.txt # CMake build config ├── README.md # This file ├── LICENSE # MIT ├── docs/ │ └── DOCUMENTATION.md # Full documentation (10+ chapters) ├── include/ │ ├── tinyflow.h # Pure C ABI public header │ └── tinyflow.hpp # C++ header-only RAII wrapper ├── src/ │ ├── tinyflow_internal.h # Internal header (structs, globals, decls) │ ├── tinyflow_core.cc # Global state, allocator, node lifecycle, object pool │ ├── tinyflow_tree.cc # Tree queries, children management, clone │ ├── tinyflow_style.cc # Style get/set, name, measure, scroll │ ├── tinyflow_stylesheet.cc # StyleSheet (named class styles) │ ├── tinyflow_result.cc # Layout result query, helper APIs (globalRect/isDirty/getDepth) │ ├── tinyflow_layout.cc # Layout entry, measurement, Flow layout │ ├── tinyflow_layout_flex.cc # Flex layout (wrap, grow/shrink, align-content, align-self) │ ├── tinyflow_layout_grid.cc # Grid layout (tracks, areas, masonry, dense auto-placement) │ ├── tinyflow_layout_constraint.cc # Constraint layout (pin edges, bias positioning) │ ├── tinyflow_attach.cc # Attach anchor layer (viewport/node anchor, sticky, fallback) │ └── tinyflow_public.cc # Public compute entry, subtree compute, dump, draw order, hit test └── tests/ ├── basic/ # C API test suite (16 test files, 2800+ assertions) │ ├── test_common.h │ ├── main.cc │ ├── test_lifecycle.cc │ ├── test_flow.cc │ ├── test_flex.cc │ ├── test_grid.cc │ ├── test_constraint.cc │ ├── test_attach.cc │ ├── test_tree.cc │ ├── test_style.cc │ ├── test_stylesheet.cc │ ├── test_fuzz.cc │ ├── test_zindex.cc │ ├── test_dpi.cc │ ├── test_subtree.cc │ ├── test_helpers.cc │ └── test_edge_cases.cc ├── hpp/ # C++ wrapper test suite (independent executable) │ ├── test_hpp.h │ ├── main.cc │ └── test_hpp.cc └── benchmark/ # Performance benchmark (independent executable) ├── bench_common.h ├── main.cc ├── bench_create.cc ├── bench_flow.cc ├── bench_flex.cc ├── bench_grid.cc ├── bench_nested.cc ├── bench_dirty.cc └── bench_attach.cc ``` ## Design Principles 1. **One model, not a stack of models** — Flow + Attach, two orthogonal systems. No inline/block/float/position legacy. 2. **Explicit over implicit** — no BFC, no containing block inference, no hidden formatting contexts. Every behavior is directly determined by the properties you set. 3. **Safe defaults** — flexShrink defaults to 0 (no surprise compression), no margin collapse, percentages reference corresponding axis (width for horizontal, height for vertical), box-sizing defaults to border-box. 4. **Pure geometry** — layout engine only computes positions and sizes. Clipping, scrolling, z-order rendering are handled by the rendering layer; layout only provides necessary info (contentRect, overflow flags, contentSize). 5. **Embeddable, non-intrusive** — pure C ABI, opaque handles, user allocator. Can be embedded in any UI library, any rendering backend. 6. **PC app focused** — Flow is vertical-only (use Flex row for horizontal), no inline concept, no responsive design. Controls are rectangles with explicit min/max sizes. ## What We Abandoned (Web CSS Legacy) - **inline / block / float** — only vertical Flow + Flex + Grid + Constraint - **margin collapse** — margins always add up, never collapse - **position: absolute/relative/fixed** — replaced by Attach anchor layer with explicit targets - **flexShrink default 1** — defaults to 0, no surprise compression - **percentage height referencing width** — percentages reference the corresponding axis - **BFC / containing block inference** — no implicit behavior, everything is explicit - **multi-column text layout** — removed in v1.16.0 (web document排版 legacy, no PC app use case) ## Version 1.38.0 — Performance optimization + virtual scroll APIs + error code coverage. Flow layout 8-9x faster by merging three redundant traversals (mainAlign/fillChild/overflow) into the main pass. Object pool default reduced from 1024 to 128 (benchmark-verified sufficient). Adds 3 virtual scroll convenience APIs: `tinyflow_flow_calc_visible_range()`, `tinyflow_flow_set_visible_range()`, `tinyflow_flow_estimate_content_height()` with C++ wrappers. Completes error code coverage across 19 getter/query APIs (NULL_ARG/INVALID_INDEX/NOT_FOUND/OK). 4322 C API tests all pass. See [docs/DOCUMENTATION.md](docs/DOCUMENTATION.md) and [docs/CHANGELOG.md](docs/CHANGELOG.md) for details. ### Recent Versions - **v1.38.0** — Performance optimization (Flow 8-9x faster, object pool 1024->128) + virtual scroll APIs + error code coverage (19 APIs, 4322 tests) - **v1.37.0** — Flow/Flex layout enhancement (flowDirection, fillChild, crossAlign, mainAlign, equalFill, reverse) + Flex main-axis justify - **v1.36.0** — Flex basis cache optimization (incremental measurement, massive perf gain for large Flex containers) - **v1.35.0** — API review and hardening (7 new APIs, nullptr safety, version check, error codes) - **v1.34.0** — More edge case tests (122 functions, ~850 assertions, Chinese test docs, fixed set_children double-free bug) - **v1.33.0** — Memory optimization (SmallVector for 4 fields, dedicated tests) - **v1.32.0** — Incremental layout edge case tests + computeNodeSize bug fix - **v1.31.0** — Comprehensive optimization + Constraint benchmark (15.9x faster) - **v1.30.0** — Constraint incremental layout (all four modes now support dirty incremental) - **v1.29.0** — Grid incremental layout (1.71x faster) - **v1.28.0** — Flex incremental layout (1.25x faster, larger gains with complex subtrees) - **v1.27.0** — Large-scale benchmarks + Flow performance optimization (1.29x faster) - **v1.26.0** — Flow middle-child optimization (layoutFlowFromIndex, 10.6x faster) - **v1.25.0** — Deep nesting optimization (dirtyChildren list, 1.4-1.75x faster) - **v1.24.0** — Performance benchmark comparison (DIRTY_DESCENDANT optimization quantified) - **v1.23.0** — Dirty flag refinement (DIRTY_DESCENDANT, smart escalation, incremental perf) - **v1.22.0** — Virtual scrolling support (layout_enabled runtime state) - **v1.21.0** — Helper query APIs (globalRect/isDirty/getDepth) + edge case tests - **v1.20.0** — Subtree compute API (layout only a specific subtree, enables virtual scrolling) - **v1.19.0** — DPI awareness hardening (fixed contentArea/attachMargin scale bugs, auto-recompute on scale change) - **v1.18.0** — Flow node z-index (explicit draw order and hit-test priority) - **v1.17.0** — Performance benchmark + object pool runtime configuration - **v1.16.0** — Removed Text multi-column layout mode (web legacy) - **v1.15.0** — Attach layer hardening (child layout, viewport anchor semantics, sticky fix) - **v1.14.0** — Stability audit (coordinate system fix, flex/grid measure callback, 25 bugs fixed)