FBReader移植日记 第一天
1.目标是创建两个工程,一个j2se的桌面软件,用于编辑和预览epub等格式的电子书,预览的窗口可以设置分辨率来模拟不同的设备,把编辑的结果实时的显示出来。另一个是Android的应用,用于阅读,管理书籍,主要功能还是阅读。目标是两个平台使用同一套解析与排版代码,争取达到在桌面预览的效果就是在设备看到的效果
2.第一步:由于手头的FBReaderJ 1.8.2 代码是Android版本的,考虑到移植的难易程度,决定先从Android平台开始移植,由于FBReaderJ的代码模块化程度很高,期望移植完FBReaderJ的一部分模块后,对桌面程序的移植能起一个指导作用.
首先决定从与界面关联度最少的模块部分开始:那就是数据模型部分,切入点是Book类,这是所有FBReaderJ支持的书籍类型的总抽象,期望抽取出Book相关的数据类型,那么可以顺理成章的使用它解析各种文件格式,并且可以容易的移植到PC平台。
2.1 .首先创建自己的工程NewReader,创建基础的包com.yueang.newreader,这个相当于FBReaderJ的org.geometerplus.fbreader。我决定移植过来的代码包结构也按照FBReaderJ的代码结构进行组织,这样最省事易懂。首先从Book类入手,新建com.yueang.newreader.book包,拷贝Book.java到包中,在Eclipse中借助代码的自动检查功能可以看到缺失了那些代码,红红的一片,场面非常状况,不要慌张!一步一步来
2.2. 我们依次导入了文件系统相关的ZLFile系列类,XML解析相关的ZLXMLParser系列类(这个类非常重要,因为它不仅用在资源的解析中,更在书籍解析中大显身手),书籍信息相关的Author等类,内部模型表示的ZLTextModel,ZLTextParagraph以及与排版相关的ZLTextElement系列类,在这个过程中也导入了一些关联度很小的支持类,大部分分布在core.util和core.options包下
目前的结果如下
├─com
│ └─yueang
│ ├─log
│ │ MyLog.java
│ │ MyUtils.java
│ │
│ ├─newreader
│ │ │ MainActivity.java
│ │ │ Paths.java
│ │ │
│ │ ├─book
│ │ │ Author.java
│ │ │ Book.java
│ │ │ BookDatabase.java
│ │ │ Bookmark.java
│ │ │ FileInfo.java
│ │ │ FileInfoSet.java
│ │ │ Series.java
│ │ │ SeriesInfo.java
│ │ │ Tag.java
│ │ │ UID.java
│ │ │
│ │ ├─bookmodel
│ │ │ BookReadingException.java
│ │ │
│ │ └─sort
│ │ TitledEntity.java
│ │
│ └─zlibrary
│ ├─core
│ │ ├─config
│ │ │ ZLConfig.java
│ │ │
│ │ ├─filesystem
│ │ │ │ ZLArchiveEntryFile.java
│ │ │ │ ZLFile.java
│ │ │ │ ZLPhysicalFile.java
│ │ │ │ ZLResourceFile.java
│ │ │ │ ZLZipEntryFile.java
│ │ │ │
│ │ │ └─tar
│ │ │ ZLTarEntryFile.java
│ │ │ ZLTarHeader.java
│ │ │ ZLTarInputStream.java
│ │ │
│ │ ├─image
│ │ │ ZLImage.java
│ │ │ ZLImageData.java
│ │ │ ZLImageManager.java
│ │ │ ZLLoadableImage.java
│ │ │ ZLSingleImage.java
│ │ │
│ │ ├─language
│ │ │ Language.java
│ │ │
│ │ ├─library
│ │ │ ZLibrary.java
│ │ │
│ │ ├─options
│ │ │ ZLOption.java
│ │ │ ZLStringOption.java
│ │ │
│ │ ├─resources
│ │ │ ZLMissingResource.java
│ │ │ ZLResource.java
│ │ │ ZLTreeResource.java
│ │ │
│ │ ├─tree
│ │ │ ZLTree.java
│ │ │
│ │ ├─util
│ │ │ MimeType.java
│ │ │ MiscUtil.java
│ │ │ ZLArrayUtils.java
│ │ │ ZLBoolean3.java
│ │ │ ZLColor.java
│ │ │
│ │ └─xml
│ │ ZLDTDParser.java
│ │ ZLMutableString.java
│ │ ZLStringMap.java
│ │ ZLXMLParser.java
│ │ ZLXMLProcessor.java
│ │ ZLXMLReader.java
│ │ ZLXMLReaderAdapter.java
│ │
│ └─text
│ ├─model
│ │ ZLImageEntry.java
│ │ ZLTextMark.java
│ │ ZLTextMetrics.java
│ │ ZLTextModel.java
│ │ ZLTextParagraph.java
│ │ ZLTextStyleEntry.java
│ │
│ └─view
│ ZLPaintContext.java
│ ZLTextControlElement.java
│ ZLTextElement.java
│ ZLTextFixedHSpaceElement.java
│ ZLTextFixedPosition.java
│ ZLTextHyperlink.java
│ ZLTextHyperlinkControlElement.java
│ ZLTextImageElement.java
│ ZLTextParagraphCursor.java
│ ZLTextParagraphCursorCache.java
│ ZLTextPosition.java
│ ZLTextStyleElement.java
│ ZLTextWord.java
│ ZLTextWordCursor.java
│
└─org
├─amse
│ └─ys
│ └─zip
│ Decompressor.java
│ DeflatingDecompressor.java
│ LocalFileHeader.java
│ MyBufferedInputStream.java
│ NoCompressionDecompressor.java
│ ZipException.java
│ ZipFile.java
│ ZipInputStream.java
│
└─vimgadgets
└─linebreak
LineBreaker.java
│ └─yueang
│ ├─log
│ │ MyLog.java
│ │ MyUtils.java
│ │
│ ├─newreader
│ │ │ MainActivity.java
│ │ │ Paths.java
│ │ │
│ │ ├─book
│ │ │ Author.java
│ │ │ Book.java
│ │ │ BookDatabase.java
│ │ │ Bookmark.java
│ │ │ FileInfo.java
│ │ │ FileInfoSet.java
│ │ │ Series.java
│ │ │ SeriesInfo.java
│ │ │ Tag.java
│ │ │ UID.java
│ │ │
│ │ ├─bookmodel
│ │ │ BookReadingException.java
│ │ │
│ │ └─sort
│ │ TitledEntity.java
│ │
│ └─zlibrary
│ ├─core
│ │ ├─config
│ │ │ ZLConfig.java
│ │ │
│ │ ├─filesystem
│ │ │ │ ZLArchiveEntryFile.java
│ │ │ │ ZLFile.java
│ │ │ │ ZLPhysicalFile.java
│ │ │ │ ZLResourceFile.java
│ │ │ │ ZLZipEntryFile.java
│ │ │ │
│ │ │ └─tar
│ │ │ ZLTarEntryFile.java
│ │ │ ZLTarHeader.java
│ │ │ ZLTarInputStream.java
│ │ │
│ │ ├─image
│ │ │ ZLImage.java
│ │ │ ZLImageData.java
│ │ │ ZLImageManager.java
│ │ │ ZLLoadableImage.java
│ │ │ ZLSingleImage.java
│ │ │
│ │ ├─language
│ │ │ Language.java
│ │ │
│ │ ├─library
│ │ │ ZLibrary.java
│ │ │
│ │ ├─options
│ │ │ ZLOption.java
│ │ │ ZLStringOption.java
│ │ │
│ │ ├─resources
│ │ │ ZLMissingResource.java
│ │ │ ZLResource.java
│ │ │ ZLTreeResource.java
│ │ │
│ │ ├─tree
│ │ │ ZLTree.java
│ │ │
│ │ ├─util
│ │ │ MimeType.java
│ │ │ MiscUtil.java
│ │ │ ZLArrayUtils.java
│ │ │ ZLBoolean3.java
│ │ │ ZLColor.java
│ │ │
│ │ └─xml
│ │ ZLDTDParser.java
│ │ ZLMutableString.java
│ │ ZLStringMap.java
│ │ ZLXMLParser.java
│ │ ZLXMLProcessor.java
│ │ ZLXMLReader.java
│ │ ZLXMLReaderAdapter.java
│ │
│ └─text
│ ├─model
│ │ ZLImageEntry.java
│ │ ZLTextMark.java
│ │ ZLTextMetrics.java
│ │ ZLTextModel.java
│ │ ZLTextParagraph.java
│ │ ZLTextStyleEntry.java
│ │
│ └─view
│ ZLPaintContext.java
│ ZLTextControlElement.java
│ ZLTextElement.java
│ ZLTextFixedHSpaceElement.java
│ ZLTextFixedPosition.java
│ ZLTextHyperlink.java
│ ZLTextHyperlinkControlElement.java
│ ZLTextImageElement.java
│ ZLTextParagraphCursor.java
│ ZLTextParagraphCursorCache.java
│ ZLTextPosition.java
│ ZLTextStyleElement.java
│ ZLTextWord.java
│ ZLTextWordCursor.java
│
└─org
├─amse
│ └─ys
│ └─zip
│ Decompressor.java
│ DeflatingDecompressor.java
│ LocalFileHeader.java
│ MyBufferedInputStream.java
│ NoCompressionDecompressor.java
│ ZipException.java
│ ZipFile.java
│ ZipInputStream.java
│
└─vimgadgets
└─linebreak
LineBreaker.java
这还只是半成品,我们留下了Plugin相关的类还没有导入,这个留在最后,目前在导入Bookmark.java的时候遇到了真正的挑战,那就是:
1 public void findEnd(ZLTextView view) { 2 if (myEnd != null) { 3 return; 4 } 5 ZLTextWordCursor cursor = view.getStartCursor(); 6 if (cursor.isNull()) { 7 cursor = view.getEndCursor(); 8 } 9 if (cursor.isNull()) { 10 return; 11 } 12 cursor = new ZLTextWordCursor(cursor); 13 cursor.moveTo(this); 14 15 ZLTextWord word = null; 16 mainLoop: 17 for (int count = myLength; count > 0; cursor.nextWord()) { 18 while (cursor.isEndOfParagraph()) { 19 if (!cursor.nextParagraph()) { 20 break mainLoop; 21 } 22 } 23 final ZLTextElement element = cursor.getElement(); 24 if (element instanceof ZLTextWord) { 25 if (word != null) { 26 --count; 27 } 28 word = (ZLTextWord)element; 29 System.err.println(new String(word.Data, word.Offset, word.Length)); 30 count -= word.Length; 31 } 32 } 33 if (word != null) { 34 myEnd = new ZLTextFixedPosition( 35 cursor.getParagraphIndex(), 36 cursor.getElementIndex(), 37 word.Length 38 ); 39 } 40 }
我们遇到了ZLTextView,从这个类开始我们的代码将要进入另外一个部分,那就是与排版相关的代码,那么如果我们打算隔离开这些代码暂时完成解析相关的代码,该如何做呢?我们下一篇再继续,敬请期待