目录
Bootstrap(引导)
包含在Android上引导LibreOffice([ˈliːbreɪ])的所有工程的通用代码。此外,它是LibreOfficeKit(LOK)的JNI类的主目录。
Stuff in Source Directory(源目录中的内容)
LibreOffice安卓应用的代码基于Fennec(Firefox浏览器针对移动电话和非个人计算机设备推出的一个浏览器版本)。它使用OpenGL ES 2去渲染文档瓦片(这些瓦片使用LOK去聚集)。应用程序在一个共享库(liblo-native-code.so,它与应用程序捆绑在一起)中包含LibreOffice核心。
Architecture and Threading(体系结构与线程)
应用程序使用4个线程实现编辑支持:
- 安卓UI线程,我们不能在这里执行任何操作,因为这会需要相当长的时间。
- 一个OpenGL线程,它包含OpenGL上下文并且负责绘制所有图层(包含瓦片)到屏幕上。
- 一个执行LibreOfficeKit调用的线程(LOKitThread),它的完成可能需要花费更多时间。此外,当回调发出一个事件时,它也从soffice线程(见下文)接收事件。事件存在于一个阻塞队列中(线程按FCFS[First Come First Served]顺序处理事件,当没有更多事件时休眠,当队列中再次有事件时唤醒)。
- 一个本地线程(native thread)经由LibreOffice创建(我们称它为soffice线程),LibreOffice自身运行于这个线程。它接受来自LOKitThread的调用,并根据需要发出回调事件。
LOKitThread(LOK线程)
LOKitThread(org.libreoffice.LOKitThread)通过JNI与LO通信(这只能在单个线程里完成)并处理从UI触发的事件(定义于org.libreoffice.LOEvent)。
Application Overview(应用程序概述)
LibreOfficeMainActivity(org.libreoffice.LibreOfficeMainActivity)是应用程序的入口点,任何启动与结束都经由这里(onCreate、onResume、onPause、onStart、onStop、onDestroy)。
Document View(文档视图)
从这里开始,最有趣的部分之一是围绕文档视图(document view)的类,其中包括监听触摸事件、重新计算视口(viewport)、瓦片处理以及将图层(layers)渲染到文档。
ViewPort - 当前文档的可见部分。它由视图矩形和缩放来定义。
Layers - 文档View的渲染使用许多图层。这些图层是:文档背景,滚动条,文档瓦片。
Document View Classes(文档视图类)
- LayerView(org.mozilla.gecko.gfx.LayerView)是应用程序的文档视图。它使用SurfaceView(android.view.SurfaceView)去承载并使用OpenGL ES 2进行绘制。
- GLController(org.mozilla.gecko.gfx.GLController) - OpenGL上下文的持有者。
- RenderControllerThread(org.mozilla.gecko.gfx.RenderControllerThread)通过LayerRender执行渲染请求。
- LayerRenderer(org.mozilla.gecko.gfx.LayerRenderer)渲染所有图层。
- GeckoLayerClient(org.mozilla.gecko.gfx.GeckoLayerClient)是应用程序的中间人,它将所有部分连接在一起。它是文档视图图层的持有者,这样所有的管理(包含瓦片渲染)通常都要使用到此类。它监听来自PanZoomController的绘制请求和视口变化(详见“Touch events”)。
Touch Events,Scrolling and Zooming(触摸事件,滚动和缩放)
处理触摸事件,滚动和缩放的主要类是JavaPanZoomController(org.mozilla.gecko.gfx.JavaPanZoomController)(PanZoomController接口的实现者)。当用户进行一次触摸动作,文档视图需要作出变化,意味着视口变化。JavaPanZoomController用于变化视口并通过PanZoomTarget(org.mozilla.gecko.gfx.PanZoomTarget)发出变化信号。
Tiled Rendering(瓦片渲染)
瓦片渲染是一种将文档分隔成同样大小的位图(典型地256×256)的技术,按需获取。
在应用程序里面,ComposedTileLayer(org.mozilla.gecko.gfx.ComposedTileLayer)是负责跟踪和管理瓦片的图层。在这种情况下,瓦片也是在SubTile(org.mozilla.gecko.gfx.SubTile)中实现的层(子层?),在这里每一个负责一个瓦片位图(实际是上传的OpenGL纹理)。
当视口变化,重检测瓦片的请求发送到LOKitThread(见LOKitThread#tileReevaluationRequest),在这里如果必要瓦片会被重检测,增加和移除。
ComposedTileLayer实际上是一个抽象类,它有两个实现类。一个是DynamicTileLayer(org.mozilla.gecko.gfx.DynamicTileLayer),它被用作主要的瓦片视图;另一个是FixedZoomTileLayer(org.mozilla.gecko.gfx.FixedZoomTileLayer),它就是在一个固定缩放级别的渲染瓦片。它被用作低分辨率的背景图层。
Tile Invalidation(瓦片刷新)
当用户改变内容(增加,删除文本或改变属性)时瓦片能够在LibreOffice中发生变化。在这种情况下,一个刷新矩形的信号从LibreOffice发出,它包含一个需要被刷新的矩形。在这种情况下,LOKitThread通过回调获取请求,并重检测所有需要被刷新的瓦片。(更多细节见LOKitThread#tileInvalidation)。
Editing(编辑)
对于编辑,LibreOffice APP有两个粗糙的任务必须做:
- 发送输入事件到LibreOffice核心(键盘,触摸和鼠标)
- 监听来自LibreOffice核心的消息(由回调提供)并作出相应反应
在大多数情况下,当发生一个输入事件并发送到LO核心时,一个来自LO核心的消息也紧随其后。例如:当用户写入键盘时,键事件被发送,一个来自LO核心的刷新请求紧随其后。当用户触摸一张图片时,一个鼠标事件被发送,一个来自LO核心的“新图片选择”消息也紧随其后。
所有键盘和触摸事件以LOEvents发送到LOKitThread。在LOKitThread中他们被处理并发送到LibreOffice核心。触摸事件起源于JavaPanZoomController,键盘事件起源于LOKitInputConnectionHandler(org.libreoffice.LOKitInputConnectionHandler),然而根据需求也有其他的部分。
InvalidationHandler(org.libreoffice.InvalidationHandler)是负责处理来自LibreOffice核心的消息并跟踪状态的。
Overlay(覆盖层)
覆盖元素(如光标和选择)不是由LO核心绘制的,相反,核心只提供数据(光标位置、选择矩形),应用程序需要绘制它们。DocumentOverlay(org.libreoffice.overlay.DocumentOverlay)和DocumentOverlayView(org.libreoffice.overlay.DocumentOverlayView)是在文档上提供覆盖层的类,在这里,选择和光标被绘制。