推荐:比 yoga 更强大的布局引擎

Clay,开源地址:https://github.com/nicbarker/clayicon-default.png?t=O83Ahttps://github.com/nicbarker/clay

这是一个 C 语言开发的高性能 2D 开源布局引擎。

主要特点:

  • 微秒级布局性能。

  • Flex-box的布局模型,支持复杂、响应式布局,类似于react的嵌套声明性语法。

  • 支持容器内文本换行、scrolling容器,宽高等比例缩放等。

  • 单个clay.h头文件,零依赖(甚至不包括C标准库)。

  • Wasm支持:可编译成15kb未压缩的.wasm文件。

  • 基于静态内存池的方式使用内存,没有 malloc 和 free,总内存开销低(8192个布局元素约占3.5MB内存)。

  • 渲染引擎无关:输出一个排序后的渲染原语列表,这些渲染原语可以轻松地在任何渲染引擎中合成,甚至可以编译成HTML。

yoga没有scrolling容器,也不处理文本换行,也不会为开发者输出渲染原语列表。

如下是一段 CLay 的示例代码:


#include <iostream>
#define CLAY_IMPLEMENTATION
#include "clay.h"

Clay_LayoutConfig layoutElement = Clay_LayoutConfig { 
  .padding = {5} 
};

int main(void) {
    uint64_t totalMemorySize = Clay_MinMemorySize();
    Clay_Arena clayMemory = Clay_Arena { 
      .label = CLAY_STRING("Clay Memory Arena"), 
      .capacity = totalMemorySize, 
      .memory = (char *)malloc(totalMemorySize) 
    };
    Clay_Initialize(clayMemory, Clay_Dimensions {1024,768});
    Clay_BeginLayout();
    CLAY(
      CLAY_RECTANGLE({ .color = {255,255,255,0} }), 
      CLAY_LAYOUT(layoutElement)
      ) {}
    Clay_EndLayout();
    return 0;
}

更详细的使用方法请读者看项目ReadMe。

以下是我自己对这个开源库的一些观点:

容器内文本换行这个特性,是需要开发者把“文本测量”的方法指针交给CLay 的,如下代码所示:

Clay_SetMeasureTextFunction((*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config))

这个方法的参数就是文本测量的函数指针,该函数可用于测量字符串的宽度、高度。Clay 在布局期间使用此方法确定 CLAY_TEXT 元素的大小。Clay_TextElementConfig对象包含字体字号等信息。 

然而有些渲染引擎根本就不需要Clay多此一举,比如 Direct2D 和 DirectWrite 绘制大段文本,如下代码所示:


#include <d2d1.h>
#include <dwrite.h>
ComPtr<IDWriteTextLayout> pTextLayout;
m_pWriteFactory->CreateTextLayout(
  text.c_str(),               //文本内容
  (UINT32)text.length(),      //字符长度
  pTextFormat.Get(),          //文本格式
  rect.right - rect.left,     //最大宽度
  rect.bottom - rect.top,     //最大高度
  &pTextLayout
);
m_pRenderTarget->DrawTextLayout(
  D2D1_POINT_2F{ rect.left, rect.top },
  pTextLayout.Get(),
  m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black)),
  D2D1_DRAW_TEXT_OPTIONS_CLIP
);

如你所见,Direct2D 渲染引擎根本就不需要布局引擎做这个事,它自己就能做。

而且,很多渲染引擎的文本测量方法都是根据字体来的,如下代码所示(Skia渲染引擎):


std::wstring text{ L"你好,世界!" };
auto length = text.size() * sizeof(wchar_t);
SkRect measureRect;
font.measureText(text.c_str(), 
  length, 
  SkTextEncoding::kUTF16, 
  &measureRect);

当大段文本中包含不同字体,不同字号时,我不确定Clay是否能很好的计算文本的尺寸。

另外,Clay用一大堆宏来公开API,这看上去也非常之别扭。

其他方面,待我进一步研究之后,再给大家分享。


补充:

这两天 Clay 发布了新版本,用于包装文本和缓存文本度量的内部算法已经全部重写,从而使布局计算的性能提高了大约2-4倍。因此,相当复杂的布局工作也会在100微秒内完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值