我正在尝试实现自己的基于流量的小型布局引擎。它应该模仿HTML布局的行为,但只模仿渲染树,而不是DOM部分。渲染树中元素的基类是Node
类。它有:
ContainerNode
实例或无,请参阅后面的内容)layout()
中计算大小后,位置在compute_size()
中计算。而位置由layout()
方法定义父级,大小由选项引用定义,例如)。它的方法是:
reflow()
调用compute_size()
和layout()
compute_size()
用于计算节点的宽度和高度。layout()
用于定位节点的子节点,而不是节点本身。paint()
,这将被图书馆的用户覆盖。 ContainerNode
类正在实现子节点的处理。它提供了一个名为add_node()
的新方法,它将传递的节点添加到容器子节点。该函数还接受参数 force ,默认为False,因为允许容器拒绝传递的节点,但 force 设置为True。
这两个类没有实现任何布局算法。我的目标是为不同类型的布局创建不同的类(在CSS中,主要由display
属性定义)。昨晚我做了一些文本布局测试,你可以在pastebin.com找到我的代码(需要pygame)。您可以将其保存到python脚本文件并像这样调用它:
python text_test block -c -f "Georgia" -s 15
注意:代码非常糟糕。我很欣赏有关深层次误解的评论。
上面提到的代码中的类InlineNodeRow
实际上代表了我如何实现类似于display:inline
属性的节点(与NodeBox
结合使用)的想法。< / p>
回到我目前在库中的方法:来自文本的单个单词也将表示为单个节点(就像上面的代码一样)。但我注意到<span>
标签中有两个关于边距和填充的内容。
请参阅http://jsfiddle.net/CeRkT/1/。
我在这里看到问题:当我想计算InlineNodeBox
的大小时,我会询问文本节点的大小并将其添加到节点的大小。但是文本节点大小包括它的边距和填充,这是不包含在HTML渲染器的定位中。因此,以下代码不正确:
def compute_size(self):
# Propagates the computation to the child-nodes.
super(InlineNodeBox, self).compute_size()
self.w = 0
self.h = 0
for node in self.nodes:
self.w += node.w
if self.h < node.h:
self.h = node.h
node.w
将包含边距和填充。我看到的下一个问题是,我正确地布置文本节点,我想将它们分成单个TextNode
s用于每个单词,但是边距和填充将应用于所有这些节点,而HTML中的边距和填充仅限于<span>
标记。
我认为我目前将每个单词放入单独节点的想法并不理想。如何构建浏览器的渲染树,或者你有更好的想法?
InlineNodeBox
课目前只会组织一行。在上面的代码示例中,当前者拒绝接受节点(这意味着它不适合)时,我在InlineNodeBox
内创建了一个新的NodeBox
。我不能用我当前的方法,因为我不想再重建渲染树。当一个节点被接受一次但超过下一次重排时的InlineNodeBox
时,如何正确设置将该单词放入下一行(假设我保持InlineNodeBox
类的想法仅组织一个单行节点)?
我真的希望这一切都有道理。如果您不理解我的概念,请随时询问。我也对其他概念,资源链接,文档,出版物等方面的批评和想法持开放态度。
答案 0 :(得分:1)
问题2 :
您可以像HTML渲染器那样执行此操作并渲染多行(例如,检查要添加的新单词是否超出宽度,如果有,则添加新行)。您可以在InlineNodeRow
中执行此操作,也可以通过处理高度并在超过最大宽度时包装单词。
问题1 :
如果你确实找出问题2的文字,那么你可以只为第一行输入偏移量(水平填充)。
虽然<span>
未考虑height
,但它确实需要line-height
,因此您的计算可能是默认高度是字体高度,除非您有{{1}可用选项。
请注意,如果你有两个或更多连续的line-height
代表跨度,你需要一些智能逻辑来使第二个继续从第一个结束的地方开始:)
作为旁注,根据我记得的Qt rich text label,每组具有相同渲染属性的单词被认为是一个节点,其渲染功能负责计算所有的东西。你的方法更精细,我所看到的唯一的缺点是你不能分割单词。
HTH,
答案 1 :(得分:1)
可能已找到box model documentation中问题1 的解决方案(您可能需要查看documentation about clearance和the one for overflow以及问题2 强>)。
"margins of absolutely positioned boxes do not collapse."
您可以查看this jsfiddle作为示例。