Nik*_*s R 12 python layout reflow
我正在尝试实现自己的基于流量的小布局引擎.它应该模仿HTML布局的行为,但只模仿渲染树,而不是DOM部分.渲染树中元素的基类是 Node类.它有:
ContainerNode实例或无,见后面)layout()尺寸之后计算compute_size()位置.虽然位置由layout()父方法定义,但尺寸由选项参考定义).它的方法是:
reflow()调用compute_size()和layout()compute_size() 用于计算节点的宽度和高度.layout()用于定位节点的子节点,而不是节点本身.paint() 哪个被库的用户覆盖.该ContainerNode班正在实施的子节点的处理.它提供了一个名为的新方法add_node(),它将传递的节点添加到容器子节点.该函数还接受一个默认为False 的参数force,因为除了force设置为True 之外,允许容器拒绝传递的节点.
这两个类没有实现任何布局算法.我的目标是为不同类型的布局创建不同的类(在CSS中,主要由display属性定义).昨晚我做了一些文本布局测试,你可以在pastebin.com找到我的代码(需要pygame).您可以将其保存到python脚本文件并像这样调用它:
python text_test block -c -f "Georgia" -s 15
Run Code Online (Sandbox Code Playgroud)
注意:代码非常糟糕.我很欣赏有关深层次误解的评论.
InlineNodeRow上面提到的代码中的类实际上代表了我如何实现类似于display:inline属性的节点(与之结合NodeBox)的想法.
回到我在库中的当前方法:来自文本的单个单词也将表示为单个节点(就像上面的代码中一样).但我注意到<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
Run Code Online (Sandbox Code Playgroud)
node.w将包括边距和填充.我看到的下一个问题是,我正确地布置文本节点,我想将它们分成单个TextNodes用于每个单词,但是边距和填充将应用于所有这些节点,而边缘和填充在HTML中<span>仅限于标签.
我认为我目前将每个单词放入单独节点的想法并不理想.如何构建浏览器的渲染树,或者你有更好的想法?
该InlineNodeBox班目前只组织一行.在上面的代码示例中,我在前者拒绝接受节点InlineNodeBox的NodeBox时候创建了一个新的(这意味着它不适合).我不能用我当前的方法,因为我不想再重建渲染树.当一个节点被接受一次但超过了InlineNodeBox下一次重排时,我该如何正确地设置将该单词放入下一行(假设我保持InlineNodeBox该类的想法只组织一行节点)?
我真的希望这一切都有道理.如果您不理解我的概念,请随时询问.我也对其他概念,资源链接,文档,出版物等方面的批评和想法持开放态度.
问题2:
您可以像 HTML 渲染器一样渲染多行(例如检查要添加的新单词是否超过宽度,如果超过则添加新行)。您可以在您的 中做到这一点InlineNodeRow,也可以通过处理高度并在单词超过最大宽度时换行。
问题1:
如果您确实解决了文本的问题 2,那么您可以仅在第一行添加偏移量(水平填充)。
尽管<span>没有height考虑,但它确实需要line-height,因此您的计算可能是默认高度是字体高度,除非您有line-height可用的选项。
请注意,如果您有两个或多个连续的InlineNodeRow表示跨度,则需要一些智能逻辑来使第二个跨度从第一个跨度结束的位置继续:)
作为旁注,根据我对 Qt富文本标签的记忆,具有相同渲染属性的每组单词都被视为一个节点,并且其渲染函数负责计算所有内容。您的方法更加精细,从我看来,它的唯一缺点是您无法拆分单词。
哈特哈,