热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AbiwordLayoutCode

LayoutCodeContainerclassesHereisthegeneraldescriptionofhowAbiWordsupportslayoutobjectsli

Layout
Code



 >Container classes

Here is the general description of how AbiWord supports layoutobjects like
tables, footnotes, text frames, positioned images and to allow text to flow
around images and other embedded objects. Note that this text originates from
around 2001 and almost certainly contains inaccuracies. These will be corrected
as they are found and as time allows.


Basic layout on pages

To start with I‘ll recap how text is layed out on fp_Page.





























































Fixed size header
-------Line 1------ ----------Line 1----------
-------Line 2------ ----------Line 2----------
-------Line 3------ ----------Line 3----------
-------Line 4------ ----------Line 4----------
-------Column 1------ ----------Column2----------
-------Line 5------ ----------Line 5----------
-------Line 6------ ----------Line 6----------
-------Line 7------ ----------Line 7----------
-------Line 8------ ----------Line 8----------
-------Line 1------ ----------Line 1----------
-------Line 2------ ----------Line 2----------
-------Line 3------ ----------Line 3----------
-------Line 4------ ----------Line 4----------
-------Column 3------ ----------Column4----------
-------Line 5------ ----------Line 5----------
-------Line 6------ ----------Line 6----------
-------Line 7------ ----------Line 7----------
-------Line 8------ ----------Line 8----------
Fixed size footer


Images are embedded in lines. If an image is large it expands the height
of a line.

The lines are contained as a vector in the class fp_Column which derives from
the base class fp_Container.

Here is what we like to layout on a page.

 

----------Line 5---------- -------Line 6------ ----------Line
6---------- -------Line 7------ ----------Line 7---------- -------Line
8------ ----------Line 8---------- Table -------Line 1------ ----------Line
1---------- -------Line 2------ ----------Line 2---------- -------Line
3------ ----------Line 3---------- -------Line 4------ ----------Line
4---------- -------Column 3------ ----------Column4---------- -------Line
5------ ----------Line 5---------- -------Line 6------ ----------Line
6---------- ----------Line 7---------- Footnote ----------Line 8----------
Fixed size footer











Fixed size header
-------Line 1------ ----------Line 1----------
-------Line 2------ ----------Line 2----------
-------Line 3------ ----------Line 3----------
----------Line 4---------- Embeded Container


OK so under the new scheme we continue to have a fp_Page class whose job
it is to layout out fp_Columns on a page and place headers/footers in the
margins.

Now however fp_Columns can contain containers other than fp_Lines. fp_Columns
can contain lines, other containers or footnote containers.

In order to be able to continue to use a vector of void * pointers as the
content of the column, this means that fp_line should become a subclass of a
general container class. If we have getType() method in this class we can
dynamically determine what sort of container is returned from a

fp_ContainerObject * pCO = (fp_ContainerObject *) m_pLines.getNthItem(i);

assignment.

At present we have the following fp_* class heiracy.

fp_Run --> lots of run subclasses. fp_Line --> no Line subclasses
fp_Container ---> -----> fp_Column

-----> fp_HdrFtrContainer
-----> fp_ShadowContainer
-----> fp_EndNoteContainer

For the next generation I propose this: fp_ContainerObject---- --> fp_Run
---> Lots of subclasses

--> fp_Container -->

--> fp_TableContainer --> fp_CellContainer

--> fp_VerticalContainer

--> fp_Column- ->fp_ShadowColumn ->fp_PositionedColumn
-->fp_HdrFtrContainer -->fp_EndNoteContainer -->fp_FootnoteContainer
--> fp_RowContainer--> -----> fp_Line

I‘ve thought through a number of suggestions to make fp_Line derive from
fp_RowContainer. They make sense if fp_Run also derives from fp_ContainerObject.
Since fp_Run has all the required methods defined this is no problem at all.

The big win from this is to be able to "pack" arbitary collections of
containers, left,right, center and full justfied by using a generalized
fb_LineBreaker class.

Given this I thought we should have a fp_verticalContainer that enables the
"breakSection" method in fl_DocSectionLayout to layout vertical containers.
fp_Column now dervices this too since columns are vertical collections of
containers.

In answer to Tomas I think we want fp_Column to derive from fp_Container so
we can cast a getContainer() to fp_Column. The getContainer method of fp_Column
should always return NULL though.

Further thought revealed that restricting the tableContainer to a vertical
collection of rows is much too restrictive.

So tables need to have their own layout algorithmn to size and position their
containers. Such algorithms already exist. We could easily just grab the methods
in GtkTable for a simple 4-pass algorithm.

Then in addition to these methods available to all fp_ContainerObjects.

getContainerType(void) draw( drawArgs) clearScreen() getX(void) getY(void)
getWidth(void) getHeight(void) getXLayoutUnits(void) getYLayoutUnits(void)
getWidthLayoutUnits(void) getHeightUnits(void) getNext(void) getPrev(void)
getSectionLayout(void) setX(UT_sint32 ) setY(UT_sint32 ) setWidth(UT_uint32)
setHeight(UT_uint32 ) setXLayoutUnits(UT_uint32 ) setYLayoutUnits(UT_uint32 )
setWidthLayoutUnits(UT_uint32) setHeightUnits(UT_uint32)
setNext(fp_ContainerObject *) setPrev(fp_ContainerObject *) isVBreakable(void)
isHBreakable(void) wantVBreakAt(UT_sint32 ) wantHBreakAt(UT_sint32 )
fp_ContainerObject * VBreakAt(UT_sint32) fp_ContainerObject *
HBreakAt(UT_sint32)

The fp_Container class have:

getColumn(void); getContainer(void); UT_Vector * (fp_ContainerObject *)
getContainerChildren();

The getColumn would work by just recursively calling getColumn until a column
was obtained. The getContainer() would just return the holding container.

The getContainerChilder(0 method returns a pointer to vector of pointers to
the children of the container. This is a useful generic way of obtaining all the
children of a given container.

fp_Column classes have:

getPage() getColumnLeader() getFollower()


The advantage of this aproach is that it makes it possible to nest
containers inside each other while preserving the distinction of fp_Columns
which get layed out right on a page.

Ome further thought on this. Once we get allow positioned objects we have to
start worrying about itterative layout on pages in conjunction with the new
section breaker class. When we start to layout columns on the page we don‘t know
whether there will be a positioned object on the page or container. If a
positioned object is found, it should be placed on the current page and the
layed out around it. This means breaking the containers up into rectangular
objects that get positioned


Logical Layout Fl_* classes

To make the Tables/footnotes/positioned objects work we need additional
fl_Layout classes as well as the fp_Container classes. The idea of course is to
rewrite as little as possible of our current code.

The fl_Layout classes contain the logical assembly of text and images in the
document.

Currently our fl_Layout classes consist of:

fl_Layout - generic Base class. fl_DocLayout - overall class for the entire
document - contains all the sectionlayouts and pages. fl_SectionLayout - generic
SectionLayout for collecting groups of

fl_BlockLayouts.

fl_DocSectionLayout - Collection of fl_BlockLayout‘s within a given

section of the document. It positions lines in containers.

fl_HdrFtrSectionLayout - Collection of fl_BlockLayout‘s that make up an

invisible HdrFtr for a given DocSectionLayout

fl_ShadowLayout Collection of fl_BlockLayout‘s that are copies of

the master HdrFtr that are actually visible and
drawn to the screen.

fl_BlockLayout Container of text and image runs that make up the

document.

fl_DocListener Interface between the pieceTable and the Layout

classes

The primary job of the layout classes is to assemble smaller pieces into
larger collections. So fl_BlockLayout assembles runs into lines,
fl_DocSectionLayout assembles lines into columns, fl_HdrFtrSectionLayout
assembles lines into a header/footer etc.

The current class heiracy is:

fl_Layout |

|--> fl_DocLayout
|--> fl_BlockLayout
|--> fl_SectionLayout
|--> fl_DocSectionLayout
|--> fl_HdrFtrSectionLayout
|--> fl_EndNoteSectionLayout

Within fl_DocSectionLayout is a method called breakSection() and some
associated methods. I think these should be liberated and placed into seperate
classes called fb_BreakSection in analagy with fb_LineBreaker.

The linked list of classes was:

m_pFirstSection->DocSec<=>DocSec<=>DocSec<=>EndNoteSec<=>HdrFtrSec=>NULL

Within each section is a linked list of fl_BlockLayouts.

m_pFirstBlockLayout<=>Block<=>Block<=>Block<=>NULL.

Each block has is own linked list runs and lines.

So for the next generation code we add cells, tables, footnotes and endnotes.
These must be contained by fl_DocSectionLayout and they also contain
fl_BlockLayouts.

So we need new classes derived from fl_SectionLayout to contain the
fl_BlockLayouts for these new containers.

These are fl_TableSectionLayout, fl_CellSectionLayout,
fl_FootnoteSectionLayout. The class heiracy I propose is:

fl_Layout |

|--> fl_DocLayout
|--> fl_ContainerLayout
|--> fl_BlockLayout
|--> fl_SectionLayout
|--> fl_HdrFtrSectionLayout
|-->fl_BreakSectionLayout
|--> fl_DocSectionLayout
|--> fl_EndNoteSectionLayout
|--> fl_TableSectionLayout
|--> fl_PositionedSectionLayout
|--> fl_CellSectionLayout
|--> fl_FootnoteSectionLayout

The idea of putting fl_BlockLayout and fl_SectionLayout under a new base
class is that methods like the following can be applied to any
fl_ContainerLayout

purgeLayout(void); collapse(void); isCollapsed(void); setNeedsReformat(void);
needsReformat(void); setNeedsRedraw(void); markAllRunsDirty(void); format(void);
getLayoutType(void); clearScreen(void); getNext(void);
setNext(fl_ContainerLayout *); updateBackgroundColor(void);

Maybe others too.

This allows us to easily generalize the simple linked list of fl_BlockLayout
classes which used to be all a DocSection could hold to something like:

m_pFirstBlockLayout<=>fl_Block<=>fl_Table<=>fl_Block<=>fl_Position<=>
fl_Table<=>fl_Footnotefl_EndNote=>NULL

Then each Table holds the following linked list
m_pFirstCell<=>fl_Cell<=>fl_Cell<=>fl_Cell=>NULL

Each Cell holds:

m_pFirstBlock=>fl_Block<=>fl_Table<=>fl_Block=>NULL

each.

By placing all these classes under generic heiracy we can treat each layout
as a type of container and apply the same methods to each.

So a collapse method on a DocSectionLayout is translated down through all the
layout classes under it‘s linked list.

Now the other thing we do is to generalize fb_BreakSection to assemble not
just lines into columns but any container found in the DocSection into a column.
This code can also be made generic so that for example a cell can assemble text
into itself and we allow containers to be broken.

fl_TableSectionLayout of course needs a method to assemble cells into a
table.

What of fl_DocListener? Well we‘ll need new piecetable struxes to hold the
properties of the new containers Table,cell,footnote, positionedObject. If a
property of any of these containers change, the contents of the container are
cleared and then recalculate, the same way we do things for DocSectionLayouts
now.

OK folks, opinions on this? Once again I think it will not be too hard to
refactor the code to allow these generalizations.

 

PieceTable Changes

To build tables/footnotes/positioned objects etc we also need to make some
changes to the piecetable. My proposal is to add new frag_stux‘s

In particular:

PTX_SectionTable, PTX_SectionTableEnd,PTX_SectionCell,
PTX_SectionFootnote,PTX_SectionFootnoteEnd,PTX_SectionPositioned,
PTX_SectionPositionedEnd

These derive directly from the pf_Frag_Section class. The only difference is
the type.

We need to the PTX_SectionTableEnd, PTX_SectionFootnoteEnd and
PTX_SectionPositionedEnd

struxes to close off the table, footnote and positioned object
definitions.

The properties associated with the table,cell,footnote and positionedobject
struxes define the type of structure.

Editting operations. All normal editting operations will be passed throough
to the fl_BlockLayouts as before. I see no need to change this.

Operations on cell/table/footnote/positionedobject struxes will be
transmitted via fl_DocListener to the SectionLayout classes associated with
these piecetable items. The associated layouts will be collapsed and redrawn
with the new properties, the same way we do things for fl_DocSectionLayout
now.

The fb_SectionBreaker classes will take care of breaking these objects so
they fit into columns on a page.

Migration to the new Layout Engine

Ok the final email on these new classes is a strategy for migrating our code
base to use the new layout engine. Here is my proposal.

When we‘re happy that we‘ve reached consesus the way we want to go,

Hub creates new CVS modules which are initially just a copy of the current
modules.

We implement the fp_Container class heiracy and make the current code work
for the new heiracy with fp_Lines as fp_ContainerObjects etc. We generalize
fb_LineBreaker to break any fp_ContainerObjects into horizontally laid out
lines.

Once the new class heiracy works with existing documents we go to stage
3.

We implement the new Layout class heiracy with fl_BLockLayout and
fl_SectionLayout as subclasses of fl_ContainerLayout. The fl_ContainerLayout
abstract base class is fully defined. We create the new fb_SectionBreaker class
to layout any collection of objects vertically.

Once we‘ve made this new heiracy work with our existing code we go to stage
4.

Put the new struxes into the piecetable and investigate the properties we
need them to define. I suggest we use RTF as a model here. RTF version 1.6 is
basically a blueprint on how MS Word 2000 works.

Now the fun really starts. We implement the new fp_Container classes, then
the fl_Section classes and connect them to the piecetable via fl_Doclistener.
Once this is done we define the new tags needed for our AbiWord_2
importer/exporter. This is actually very easy. We just invent tag names for our
new struxes and include them in the "case" statements.

Once we can import/export tables/footnotes/endnotes to *.abw we begin work on
the Table/footnote/endnote/positioned object UI.

IMHO MS Word provides a base from which to work here. In my opinion this is
still rather cumbersome so I‘d love to get some help for how to do a better
Table UI.

We will definitely need to rework how to do selections and how to keep the
cursor inside a container. The latter can be done with a generalization of
getEdittableBounds().

In the case of the former may not want to draw a selection over
footnotes/endnotes and positioned object‘s.

For deletions that cross cell boundaries we will want to pop up a little
window to ask above deleting cells/rows/columns etc the way Gnumeric/excell/MS
Word does now. It should not be hard to trigger this. Just put a hook into in to
detect attempts to delete Table or cell struxes.

This strategy allows us several checkpoints to make sure we‘re on the right
track to a much more sophisticated layout engine.


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
author-avatar
hy11011_847
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有