热门标签 | 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.


推荐阅读
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 在使用Eclipse进行调试时,如果遇到未解析的断点(unresolved breakpoint)并显示“未加载符号表,请使用‘file’命令加载目标文件以进行调试”的错误提示,这通常是因为调试器未能正确加载符号表。解决此问题的方法是通过GDB的`file`命令手动加载目标文件,以便调试器能够识别和解析断点。具体操作为在GDB命令行中输入 `(gdb) file `。这一步骤确保了调试环境能够正确访问和解析程序中的符号信息,从而实现有效的调试。 ... [详细]
  • 本指南详细介绍了如何利用华为云对象存储服务构建视频点播(VoD)平台。通过结合开源技术如Ceph、WordPress、PHP和Nginx,用户可以高效地实现数据存储、内容管理和网站搭建。主要内容涵盖华为云对象存储系统的配置步骤、性能优化及安全设置,为开发者提供全面的技术支持。 ... [详细]
  • VS2019 在创建 Windows 恢复点时出现卡顿问题及解决方法
    在使用 Visual Studio 2019 时,有时会在创建 Windows 恢复点时遇到卡顿问题。这可能是由于频繁的自动更新导致的,每次更新文件大小可能达到 1-2GB。尽管现代网络速度较快,但这些更新仍可能对系统性能产生影响。本文将探讨该问题的原因,并提供有效的解决方法,帮助用户提升开发效率。 ... [详细]
  • feat: Enhances Jest Testing Capabilities with Snapshot Support ... [详细]
  • 在分析和解决 Keepalived VIP 漂移故障的过程中,我们发现主备节点配置如下:主节点 IP 为 172.16.30.31,备份节点 IP 为 172.16.30.32,虚拟 IP 为 172.16.30.10。故障表现为监控系统显示 Keepalived 主节点状态异常,导致 VIP 漂移到备份节点。通过详细检查配置文件和日志,我们发现主节点上的 Keepalived 进程未能正常运行,最终通过优化配置和重启服务解决了该问题。此外,我们还增加了健康检查机制,以提高系统的稳定性和可靠性。 ... [详细]
  • 在最近的项目中,我们广泛使用了Qt框架的网络库,过程中遇到了一些挑战和问题。本文旨在记录这些经验和解决方案,以便日后参考。鉴于我们的客户端GUI完全基于Qt开发,我们期望利用其强大的网络功能进行Fiddler网络数据包的捕获与分析,以提升开发效率和应用性能。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 深入解析Android GPS机制:第五部分 ... [详细]
  • 为了提升单位内部沟通效率,我们开发了一套飞秋软件与OA系统的消息接口服务系统。该系统能够将OA系统中的审批、通知等信息自动同步至飞秋平台,确保员工在使用飞秋进行日常沟通的同时,也能及时获取OA系统的各类重要信息,从而实现无缝对接,提高工作效率。 ... [详细]
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社区 版权所有