mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-04 02:09:35 +02:00
RTF support
This commit is contained in:
parent
5f6eb8a469
commit
5f6223353d
17 changed files with 1562 additions and 4 deletions
|
@ -31,7 +31,7 @@ include $(CLEAR_VARS)
|
||||||
|
|
||||||
SHAREDIR_MACRO := share
|
SHAREDIR_MACRO := share
|
||||||
|
|
||||||
LOCAL_MODULE := NativeFormats-v1
|
LOCAL_MODULE := NativeFormats-v2
|
||||||
LOCAL_CFLAGS := -Wall -DBASEDIR=\"$(SHAREDIR_MACRO)\"
|
LOCAL_CFLAGS := -Wall -DBASEDIR=\"$(SHAREDIR_MACRO)\"
|
||||||
LOCAL_LDLIBS := -lz -llog
|
LOCAL_LDLIBS := -lz -llog
|
||||||
LOCAL_STATIC_LIBRARIES := expat
|
LOCAL_STATIC_LIBRARIES := expat
|
||||||
|
@ -92,6 +92,12 @@ LOCAL_SRC_FILES := \
|
||||||
NativeFormats/fbreader/src/formats/EncodedTextReader.cpp \
|
NativeFormats/fbreader/src/formats/EncodedTextReader.cpp \
|
||||||
NativeFormats/fbreader/src/formats/FormatPlugin.cpp \
|
NativeFormats/fbreader/src/formats/FormatPlugin.cpp \
|
||||||
NativeFormats/fbreader/src/formats/PluginCollection.cpp \
|
NativeFormats/fbreader/src/formats/PluginCollection.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfBookReader.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfDescriptionReader.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfImage.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfPlugin.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfReader.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/rtf/RtfReaderStream.cpp \
|
||||||
NativeFormats/fbreader/src/formats/txt/PlainTextFormat.cpp \
|
NativeFormats/fbreader/src/formats/txt/PlainTextFormat.cpp \
|
||||||
NativeFormats/fbreader/src/formats/txt/TxtBookReader.cpp \
|
NativeFormats/fbreader/src/formats/txt/TxtBookReader.cpp \
|
||||||
NativeFormats/fbreader/src/formats/txt/TxtPlugin.cpp \
|
NativeFormats/fbreader/src/formats/txt/TxtPlugin.cpp \
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
//#include "tcr/TcrPlugin.h"
|
//#include "tcr/TcrPlugin.h"
|
||||||
//#include "oeb/OEBPlugin.h"
|
//#include "oeb/OEBPlugin.h"
|
||||||
//#include "chm/CHMPlugin.h"
|
//#include "chm/CHMPlugin.h"
|
||||||
//#include "rtf/RtfPlugin.h"
|
#include "rtf/RtfPlugin.h"
|
||||||
//#include "openreader/OpenReaderPlugin.h"
|
//#include "openreader/OpenReaderPlugin.h"
|
||||||
////#include "pdf/PdfPlugin.h"
|
////#include "pdf/PdfPlugin.h"
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ PluginCollection &PluginCollection::Instance() {
|
||||||
// ourInstance->myPlugins.push_back(new TcrPlugin());
|
// ourInstance->myPlugins.push_back(new TcrPlugin());
|
||||||
// ourInstance->myPlugins.push_back(new CHMPlugin());
|
// ourInstance->myPlugins.push_back(new CHMPlugin());
|
||||||
//ourInstance->myPlugins.push_back(new OEBPlugin());
|
//ourInstance->myPlugins.push_back(new OEBPlugin());
|
||||||
//ourInstance->myPlugins.push_back(new RtfPlugin());
|
ourInstance->myPlugins.push_back(new RtfPlugin());
|
||||||
// ourInstance->myPlugins.push_back(new OpenReaderPlugin());
|
// ourInstance->myPlugins.push_back(new OpenReaderPlugin());
|
||||||
// //ourInstance->myPlugins.push_back(new PdfPlugin());
|
// //ourInstance->myPlugins.push_back(new PdfPlugin());
|
||||||
}
|
}
|
||||||
|
|
228
jni/NativeFormats/fbreader/src/formats/rtf/RtfBookReader.cpp
Normal file
228
jni/NativeFormats/fbreader/src/formats/rtf/RtfBookReader.cpp
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
|
||||||
|
#include "RtfBookReader.h"
|
||||||
|
#include "../../bookmodel/BookModel.h"
|
||||||
|
#include "RtfImage.h"
|
||||||
|
|
||||||
|
RtfBookReader::RtfBookReader(BookModel &model, const std::string &encoding) : RtfReader(encoding), myBookReader(model) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t maxBufferSize = 1024;
|
||||||
|
|
||||||
|
void RtfBookReader::addCharData(const char *data, size_t len, bool convert) {
|
||||||
|
if (myCurrentState.ReadText) {
|
||||||
|
if (convert || myConverter.isNull()) {
|
||||||
|
myOutputBuffer.append(data, len);
|
||||||
|
if (myOutputBuffer.size() >= maxBufferSize) {
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
flushBuffer();
|
||||||
|
std::string newString(data, len);
|
||||||
|
characterDataHandler(newString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::flushBuffer() {
|
||||||
|
if (!myOutputBuffer.empty()) {
|
||||||
|
if (myCurrentState.ReadText) {
|
||||||
|
if (!myConverter.isNull()) {
|
||||||
|
static std::string newString;
|
||||||
|
myConverter->convert(newString, myOutputBuffer.data(), myOutputBuffer.data() + myOutputBuffer.length());
|
||||||
|
characterDataHandler(newString);
|
||||||
|
newString.erase();
|
||||||
|
} else {
|
||||||
|
characterDataHandler(myOutputBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myOutputBuffer.erase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::switchDestination(DestinationType destination, bool on) {
|
||||||
|
switch (destination) {
|
||||||
|
case DESTINATION_NONE:
|
||||||
|
break;
|
||||||
|
case DESTINATION_SKIP:
|
||||||
|
case DESTINATION_INFO:
|
||||||
|
case DESTINATION_TITLE:
|
||||||
|
case DESTINATION_AUTHOR:
|
||||||
|
case DESTINATION_STYLESHEET:
|
||||||
|
myCurrentState.ReadText = !on;
|
||||||
|
break;
|
||||||
|
case DESTINATION_PICTURE:
|
||||||
|
if (on) {
|
||||||
|
flushBuffer();
|
||||||
|
if (myBookReader.paragraphIsOpen()) {
|
||||||
|
myBookReader.endParagraph();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myCurrentState.ReadText = !on;
|
||||||
|
break;
|
||||||
|
case DESTINATION_FOOTNOTE:
|
||||||
|
flushBuffer();
|
||||||
|
if (on) {
|
||||||
|
std::string id;
|
||||||
|
ZLStringUtil::appendNumber(id, myFootnoteIndex++);
|
||||||
|
|
||||||
|
myStateStack.push(myCurrentState);
|
||||||
|
myCurrentState.Id = id;
|
||||||
|
myCurrentState.ReadText = true;
|
||||||
|
|
||||||
|
myBookReader.addHyperlinkControl(FOOTNOTE, id);
|
||||||
|
myBookReader.addData(id);
|
||||||
|
myBookReader.addControl(FOOTNOTE, false);
|
||||||
|
|
||||||
|
myBookReader.setFootnoteTextModel(id);
|
||||||
|
myBookReader.pushKind(REGULAR);
|
||||||
|
myBookReader.beginParagraph();
|
||||||
|
} else {
|
||||||
|
myBookReader.endParagraph();
|
||||||
|
myBookReader.popKind();
|
||||||
|
|
||||||
|
if (!myStateStack.empty()) {
|
||||||
|
myCurrentState = myStateStack.top();
|
||||||
|
myStateStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myStateStack.empty()) {
|
||||||
|
myBookReader.setMainTextModel();
|
||||||
|
} else {
|
||||||
|
myBookReader.setFootnoteTextModel(myCurrentState.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::insertImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t size) {
|
||||||
|
std::string id;
|
||||||
|
ZLStringUtil::appendNumber(id, myImageIndex++);
|
||||||
|
myBookReader.addImageReference(id);
|
||||||
|
myBookReader.addImage(id, new RtfImage(mimeType, fileName, startOffset, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfBookReader::characterDataHandler(std::string &str) {
|
||||||
|
if (myCurrentState.ReadText) {
|
||||||
|
if (!myBookReader.paragraphIsOpen()) {
|
||||||
|
myBookReader.beginParagraph();
|
||||||
|
}
|
||||||
|
myBookReader.addData(str);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfBookReader::readDocument(const ZLFile &file) {
|
||||||
|
myImageIndex = 0;
|
||||||
|
myFootnoteIndex = 1;
|
||||||
|
|
||||||
|
myCurrentState.ReadText = true;
|
||||||
|
|
||||||
|
myBookReader.setMainTextModel();
|
||||||
|
myBookReader.pushKind(REGULAR);
|
||||||
|
myBookReader.beginParagraph();
|
||||||
|
|
||||||
|
bool code = RtfReader::readDocument(file);
|
||||||
|
|
||||||
|
flushBuffer();
|
||||||
|
myBookReader.endParagraph();
|
||||||
|
while (!myStateStack.empty()) {
|
||||||
|
myStateStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::setFontProperty(FontProperty property) {
|
||||||
|
if (!myCurrentState.ReadText) {
|
||||||
|
//DPRINT("change style not in text.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flushBuffer();
|
||||||
|
|
||||||
|
switch (property) {
|
||||||
|
case FONT_BOLD:
|
||||||
|
if (myState.Bold) {
|
||||||
|
myBookReader.pushKind(STRONG);
|
||||||
|
} else {
|
||||||
|
myBookReader.popKind();
|
||||||
|
}
|
||||||
|
myBookReader.addControl(STRONG, myState.Bold);
|
||||||
|
break;
|
||||||
|
case FONT_ITALIC:
|
||||||
|
if (myState.Italic) {
|
||||||
|
if (!myState.Bold) {
|
||||||
|
//DPRINT("add style emphasis.\n");
|
||||||
|
myBookReader.pushKind(EMPHASIS);
|
||||||
|
myBookReader.addControl(EMPHASIS, true);
|
||||||
|
} else {
|
||||||
|
//DPRINT("add style emphasis and strong.\n");
|
||||||
|
myBookReader.popKind();
|
||||||
|
myBookReader.addControl(STRONG, false);
|
||||||
|
|
||||||
|
myBookReader.pushKind(EMPHASIS);
|
||||||
|
myBookReader.addControl(EMPHASIS, true);
|
||||||
|
myBookReader.pushKind(STRONG);
|
||||||
|
myBookReader.addControl(STRONG, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!myState.Bold) {
|
||||||
|
//DPRINT("remove style emphasis.\n");
|
||||||
|
myBookReader.addControl(EMPHASIS, false);
|
||||||
|
myBookReader.popKind();
|
||||||
|
} else {
|
||||||
|
//DPRINT("remove style strong n emphasis, add strong.\n");
|
||||||
|
myBookReader.addControl(STRONG, false);
|
||||||
|
myBookReader.popKind();
|
||||||
|
myBookReader.addControl(EMPHASIS, false);
|
||||||
|
myBookReader.popKind();
|
||||||
|
|
||||||
|
myBookReader.pushKind(STRONG);
|
||||||
|
myBookReader.addControl(STRONG, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FONT_UNDERLINED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::newParagraph() {
|
||||||
|
flushBuffer();
|
||||||
|
myBookReader.endParagraph();
|
||||||
|
myBookReader.beginParagraph();
|
||||||
|
if (myState.Alignment != ALIGN_UNDEFINED) {
|
||||||
|
setAlignment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::setEncoding(int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfBookReader::setAlignment() {
|
||||||
|
ZLTextStyleEntry entry;
|
||||||
|
entry.setAlignmentType(myState.Alignment);
|
||||||
|
myBookReader.addControl(entry);
|
||||||
|
}
|
72
jni/NativeFormats/fbreader/src/formats/rtf/RtfBookReader.h
Normal file
72
jni/NativeFormats/fbreader/src/formats/rtf/RtfBookReader.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFBOOKREADER_H__
|
||||||
|
#define __RTFBOOKREADER_H__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "RtfReader.h"
|
||||||
|
#include "../../bookmodel/BookReader.h"
|
||||||
|
|
||||||
|
class ZLFile;
|
||||||
|
|
||||||
|
class BookModel;
|
||||||
|
class RtfImage;
|
||||||
|
|
||||||
|
class RtfBookReader : public RtfReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfBookReader(BookModel &model, const std::string &encoding);
|
||||||
|
~RtfBookReader();
|
||||||
|
|
||||||
|
bool readDocument(const ZLFile &file);
|
||||||
|
|
||||||
|
bool characterDataHandler(std::string &str);
|
||||||
|
void flushBuffer();
|
||||||
|
|
||||||
|
void setEncoding(int code);
|
||||||
|
void setAlignment();
|
||||||
|
void switchDestination(DestinationType destination, bool on);
|
||||||
|
void addCharData(const char *data, size_t len, bool convert);
|
||||||
|
void insertImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t size);
|
||||||
|
|
||||||
|
void setFontProperty(FontProperty property);
|
||||||
|
void newParagraph();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BookReader myBookReader;
|
||||||
|
|
||||||
|
std::string myOutputBuffer;
|
||||||
|
|
||||||
|
int myImageIndex;
|
||||||
|
int myFootnoteIndex;
|
||||||
|
|
||||||
|
struct RtfBookReaderState {
|
||||||
|
std::string Id;
|
||||||
|
bool ReadText;
|
||||||
|
};
|
||||||
|
|
||||||
|
RtfBookReaderState myCurrentState;
|
||||||
|
std::stack<RtfBookReaderState> myStateStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline RtfBookReader::~RtfBookReader() {}
|
||||||
|
|
||||||
|
#endif /* __RTFBOOKREADER_H__ */
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
|
||||||
|
#include "RtfDescriptionReader.h"
|
||||||
|
|
||||||
|
#include "../FormatPlugin.h"
|
||||||
|
#include "../../library/Book.h"
|
||||||
|
#include "../../library/Author.h"
|
||||||
|
|
||||||
|
RtfDescriptionReader::RtfDescriptionReader(Book &book) : RtfReader(book.encoding()), myBook(book) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::setEncoding(int code) {
|
||||||
|
ZLEncodingCollection &collection = ZLEncodingCollection::Instance();
|
||||||
|
myConverter = collection.converter(code);
|
||||||
|
if (!myConverter.isNull()) {
|
||||||
|
myBook.setEncoding(myConverter->name());
|
||||||
|
} else {
|
||||||
|
myConverter = collection.defaultConverter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfDescriptionReader::readDocument(const ZLFile &file) {
|
||||||
|
myDoRead = false;
|
||||||
|
bool code = RtfReader::readDocument(file);
|
||||||
|
if (myBook.encoding().empty()) {
|
||||||
|
myBook.setEncoding("utf-8");
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::addCharData(const char *data, size_t len, bool convert) {
|
||||||
|
if (myDoRead) {
|
||||||
|
if (convert) {
|
||||||
|
myConverter->convert(myBuffer, data, data + len);
|
||||||
|
} else {
|
||||||
|
myBuffer.append(data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::switchDestination(DestinationType destination, bool on) {
|
||||||
|
switch (destination) {
|
||||||
|
case DESTINATION_INFO:
|
||||||
|
if (!on) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DESTINATION_TITLE:
|
||||||
|
myDoRead = on;
|
||||||
|
if (!on) {
|
||||||
|
myBook.setTitle(myBuffer);
|
||||||
|
myBuffer.erase();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DESTINATION_AUTHOR:
|
||||||
|
myDoRead = on;
|
||||||
|
if (!on) {
|
||||||
|
myBook.addAuthor(myBuffer);
|
||||||
|
myBuffer.erase();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!myBook.title().empty() && !myBook.authors().empty() && !myBook.encoding().empty()) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::insertImage(const std::string&, const std::string&, size_t, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::setFontProperty(FontProperty) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::newParagraph() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDescriptionReader::setAlignment() {
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFDESCRIPTIONREADER_H__
|
||||||
|
#define __RTFDESCRIPTIONREADER_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "RtfReader.h"
|
||||||
|
|
||||||
|
class Book;
|
||||||
|
|
||||||
|
class RtfDescriptionReader : public RtfReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfDescriptionReader(Book &book);
|
||||||
|
~RtfDescriptionReader();
|
||||||
|
|
||||||
|
bool readDocument(const ZLFile &file);
|
||||||
|
|
||||||
|
void setEncoding(int code);
|
||||||
|
void setAlignment();
|
||||||
|
void switchDestination(DestinationType destination, bool on);
|
||||||
|
void addCharData(const char *data, size_t len, bool convert);
|
||||||
|
void insertImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t size);
|
||||||
|
|
||||||
|
void setFontProperty(FontProperty property);
|
||||||
|
void newParagraph();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Book &myBook;
|
||||||
|
|
||||||
|
bool myDoRead;
|
||||||
|
std::string myBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline RtfDescriptionReader::~RtfDescriptionReader() {}
|
||||||
|
|
||||||
|
#endif /* __RTFDESCRIPTIONREADER_H__ */
|
65
jni/NativeFormats/fbreader/src/formats/rtf/RtfImage.cpp
Normal file
65
jni/NativeFormats/fbreader/src/formats/rtf/RtfImage.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
#include <ZLFile.h>
|
||||||
|
|
||||||
|
#include "RtfImage.h"
|
||||||
|
|
||||||
|
inline static char convertXDigit(char d) {
|
||||||
|
if (isdigit(d)) {
|
||||||
|
return d - '0';
|
||||||
|
} else if (islower(d)) {
|
||||||
|
return d - 'a' + 10;
|
||||||
|
} else {
|
||||||
|
return d - 'A' + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfImage::read() const {
|
||||||
|
shared_ptr<ZLInputStream> stream = ZLFile(myFileName).inputStream();
|
||||||
|
if (!stream.isNull() && stream->open()) {
|
||||||
|
myData = new std::string();
|
||||||
|
myData->reserve(myLength / 2);
|
||||||
|
stream->seek(myStartOffset, false);
|
||||||
|
const size_t bufferSize = 1024;
|
||||||
|
char *buffer = new char[bufferSize];
|
||||||
|
for (unsigned int i = 0; i < myLength; i += bufferSize) {
|
||||||
|
size_t toRead = std::min(bufferSize, myLength - i);
|
||||||
|
if (stream->read(buffer, toRead) != toRead) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (size_t j = 0; j < toRead; j += 2) {
|
||||||
|
*myData += (convertXDigit(buffer[j]) << 4) + convertXDigit(buffer[j + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
stream->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shared_ptr<std::string> RtfImage::stringData() const {
|
||||||
|
if (myData.isNull()) {
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
return myData;
|
||||||
|
}
|
47
jni/NativeFormats/fbreader/src/formats/rtf/RtfImage.h
Normal file
47
jni/NativeFormats/fbreader/src/formats/rtf/RtfImage.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFIMAGE_H__
|
||||||
|
#define __RTFIMAGE_H__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <ZLImage.h>
|
||||||
|
|
||||||
|
class RtfImage : public ZLSingleImage {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t length);
|
||||||
|
~RtfImage();
|
||||||
|
const shared_ptr<std::string> stringData() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void read() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string myFileName;
|
||||||
|
size_t myStartOffset;
|
||||||
|
size_t myLength;
|
||||||
|
mutable shared_ptr<std::string> myData;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline RtfImage::RtfImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t length) : ZLSingleImage(mimeType), myFileName(fileName), myStartOffset(startOffset), myLength(length) {}
|
||||||
|
inline RtfImage::~RtfImage() {}
|
||||||
|
|
||||||
|
#endif /* __RTFIMAGE_H__ */
|
63
jni/NativeFormats/fbreader/src/formats/rtf/RtfPlugin.cpp
Normal file
63
jni/NativeFormats/fbreader/src/formats/rtf/RtfPlugin.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
|
||||||
|
#include "RtfPlugin.h"
|
||||||
|
#include "RtfDescriptionReader.h"
|
||||||
|
#include "RtfBookReader.h"
|
||||||
|
#include "RtfReaderStream.h"
|
||||||
|
|
||||||
|
#include "../../bookmodel/BookModel.h"
|
||||||
|
#include "../../library/Book.h"
|
||||||
|
|
||||||
|
bool RtfPlugin::providesMetaInfo() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string RtfPlugin::supportedFileType() const {
|
||||||
|
return "rtf";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfPlugin::readMetaInfo(Book &book) const {
|
||||||
|
shared_ptr<ZLInputStream> stream = new RtfReaderStream(book.file(), 50000);
|
||||||
|
|
||||||
|
if (stream.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
detectEncodingAndLanguage(book, *stream);
|
||||||
|
|
||||||
|
if (!RtfDescriptionReader(book).readDocument(book.file())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfPlugin::readModel(BookModel &model) const {
|
||||||
|
const Book &book = *model.book();
|
||||||
|
return RtfBookReader(model, book.encoding()).readDocument(book.file());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfPlugin::readLanguageAndEncoding(Book &book) const {
|
||||||
|
return true;
|
||||||
|
}
|
35
jni/NativeFormats/fbreader/src/formats/rtf/RtfPlugin.h
Normal file
35
jni/NativeFormats/fbreader/src/formats/rtf/RtfPlugin.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFPLUGIN_H__
|
||||||
|
#define __RTFPLUGIN_H__
|
||||||
|
|
||||||
|
#include "../FormatPlugin.h"
|
||||||
|
|
||||||
|
class RtfPlugin : public FormatPlugin {
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool providesMetaInfo() const;
|
||||||
|
const std::string supportedFileType() const;
|
||||||
|
bool readMetaInfo(Book &book) const;
|
||||||
|
bool readLanguageAndEncoding(Book &book) const;
|
||||||
|
bool readModel(BookModel &model) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __RTFPLUGIN_H__ */
|
455
jni/NativeFormats/fbreader/src/formats/rtf/RtfReader.cpp
Normal file
455
jni/NativeFormats/fbreader/src/formats/rtf/RtfReader.cpp
Normal file
|
@ -0,0 +1,455 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
|
||||||
|
#include "RtfReader.h"
|
||||||
|
|
||||||
|
std::map<std::string, RtfCommand*> RtfReader::ourKeywordMap;
|
||||||
|
|
||||||
|
static const int rtfStreamBufferSize = 4096;
|
||||||
|
|
||||||
|
RtfReader::RtfReader(const std::string &encoding) : EncodedTextReader(encoding) {
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfReader::~RtfReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfCommand::~RtfCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfNewParagraphCommand::run(RtfReader &reader, int*) const {
|
||||||
|
reader.newParagraph();
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfFontPropertyCommand::RtfFontPropertyCommand(RtfReader::FontProperty property) : myProperty(property) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfFontPropertyCommand::run(RtfReader &reader, int *parameter) const {
|
||||||
|
bool start = (parameter == 0) || (*parameter != 0);
|
||||||
|
switch (myProperty) {
|
||||||
|
case RtfReader::FONT_BOLD:
|
||||||
|
if (reader.myState.Bold != start) {
|
||||||
|
reader.myState.Bold = start;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_BOLD);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RtfReader::FONT_ITALIC:
|
||||||
|
if (reader.myState.Italic != start) {
|
||||||
|
reader.myState.Italic = start;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_ITALIC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RtfReader::FONT_UNDERLINED:
|
||||||
|
if (reader.myState.Underlined != start) {
|
||||||
|
reader.myState.Underlined = start;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_UNDERLINED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfAlignmentCommand::RtfAlignmentCommand(ZLTextAlignmentType alignment) : myAlignment(alignment) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfAlignmentCommand::run(RtfReader &reader, int*) const {
|
||||||
|
if (reader.myState.Alignment != myAlignment) {
|
||||||
|
reader.myState.Alignment = myAlignment;
|
||||||
|
reader.setAlignment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfCharCommand::RtfCharCommand(const std::string &chr) : myChar(chr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfCharCommand::run(RtfReader &reader, int*) const {
|
||||||
|
reader.processCharData(myChar.data(), myChar.length(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfDestinationCommand::RtfDestinationCommand(RtfReader::DestinationType destination) : myDestination(destination) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfDestinationCommand::run(RtfReader &reader, int*) const {
|
||||||
|
if (reader.myState.Destination == myDestination) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reader.myState.Destination = myDestination;
|
||||||
|
if (myDestination == RtfReader::DESTINATION_PICTURE) {
|
||||||
|
reader.myState.ReadDataAsHex = true;
|
||||||
|
}
|
||||||
|
reader.switchDestination(myDestination, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfStyleCommand::run(RtfReader &reader, int*) const {
|
||||||
|
if (reader.myState.Destination == RtfReader::DESTINATION_STYLESHEET) {
|
||||||
|
//std::cerr << "Add style index: " << val << "\n";
|
||||||
|
|
||||||
|
//sprintf(style_attributes[0], "%i", val);
|
||||||
|
} else /*if (myState.Destination == rdsContent)*/ {
|
||||||
|
//std::cerr << "Set style index: " << val << "\n";
|
||||||
|
|
||||||
|
//sprintf(style_attributes[0], "%i", val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfCodepageCommand::run(RtfReader &reader, int *parameter) const {
|
||||||
|
if (parameter != 0) {
|
||||||
|
reader.setEncoding(*parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfSpecialCommand::run(RtfReader &reader, int*) const {
|
||||||
|
reader.mySpecialMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfPictureCommand::RtfPictureCommand(const std::string &mimeType) : myMimeType(mimeType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfPictureCommand::run(RtfReader &reader, int*) const {
|
||||||
|
reader.myNextImageMimeType = myMimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfFontResetCommand::run(RtfReader &reader, int*) const {
|
||||||
|
if (reader.myState.Bold) {
|
||||||
|
reader.myState.Bold = false;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_BOLD);
|
||||||
|
}
|
||||||
|
if (reader.myState.Italic) {
|
||||||
|
reader.myState.Italic = false;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_ITALIC);
|
||||||
|
}
|
||||||
|
if (reader.myState.Underlined) {
|
||||||
|
reader.myState.Underlined = false;
|
||||||
|
reader.setFontProperty(RtfReader::FONT_UNDERLINED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReader::addAction(const std::string &tag, RtfCommand *command) {
|
||||||
|
ourKeywordMap.insert(std::make_pair(tag, command));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReader::fillKeywordMap() {
|
||||||
|
if (ourKeywordMap.empty()) {
|
||||||
|
addAction("*", new RtfSpecialCommand());
|
||||||
|
addAction("ansicpg", new RtfCodepageCommand());
|
||||||
|
|
||||||
|
static const char *keywordsToSkip[] = {"buptim", "colortbl", "comment", "creatim", "doccomm", "fonttbl", "footer", "footerf", "footerl", "footerr", "ftncn", "ftnsep", "ftnsepc", "header", "headerf", "headerl", "headerr", "keywords", "operator", "printim", "private1", "revtim", "rxe", "subject", "tc", "txe", "xe", 0};
|
||||||
|
RtfCommand *skipCommand = new RtfDestinationCommand(RtfReader::DESTINATION_SKIP);
|
||||||
|
for (const char **i = keywordsToSkip; *i != 0; ++i) {
|
||||||
|
addAction(*i, skipCommand);
|
||||||
|
}
|
||||||
|
addAction("info", new RtfDestinationCommand(RtfReader::DESTINATION_INFO));
|
||||||
|
addAction("title", new RtfDestinationCommand(RtfReader::DESTINATION_TITLE));
|
||||||
|
addAction("author", new RtfDestinationCommand(RtfReader::DESTINATION_AUTHOR));
|
||||||
|
addAction("pict", new RtfDestinationCommand(RtfReader::DESTINATION_PICTURE));
|
||||||
|
addAction("stylesheet", new RtfDestinationCommand(RtfReader::DESTINATION_STYLESHEET));
|
||||||
|
addAction("footnote", new RtfDestinationCommand(RtfReader::DESTINATION_FOOTNOTE));
|
||||||
|
|
||||||
|
RtfCommand *newParagraphCommand = new RtfNewParagraphCommand();
|
||||||
|
addAction("\n", newParagraphCommand);
|
||||||
|
addAction("\r", newParagraphCommand);
|
||||||
|
addAction("par", newParagraphCommand);
|
||||||
|
|
||||||
|
addAction("\x09", new RtfCharCommand("\x09"));
|
||||||
|
addAction("_", new RtfCharCommand("-"));
|
||||||
|
addAction("\\", new RtfCharCommand("\\"));
|
||||||
|
addAction("{", new RtfCharCommand("{"));
|
||||||
|
addAction("}", new RtfCharCommand("}"));
|
||||||
|
addAction("bullet", new RtfCharCommand("\xE2\x80\xA2")); // •
|
||||||
|
addAction("endash", new RtfCharCommand("\xE2\x80\x93")); // –
|
||||||
|
addAction("emdash", new RtfCharCommand("\xE2\x80\x94")); // —
|
||||||
|
addAction("~", new RtfCharCommand("\xC0\xA0")); //
|
||||||
|
addAction("enspace", new RtfCharCommand("\xE2\x80\x82")); //  
|
||||||
|
addAction("emspace", new RtfCharCommand("\xE2\x80\x83")); //  
|
||||||
|
addAction("lquote", new RtfCharCommand("\xE2\x80\x98")); // ‘
|
||||||
|
addAction("rquote", new RtfCharCommand("\xE2\x80\x99")); // ’
|
||||||
|
addAction("ldblquote", new RtfCharCommand("\xE2\x80\x9C")); // “
|
||||||
|
addAction("rdblquote", new RtfCharCommand("\xE2\x80\x9D")); // ”
|
||||||
|
|
||||||
|
addAction("jpegblip", new RtfPictureCommand("image/jpeg"));
|
||||||
|
addAction("pngblip", new RtfPictureCommand("image/png"));
|
||||||
|
|
||||||
|
addAction("s", new RtfStyleCommand());
|
||||||
|
|
||||||
|
addAction("qc", new RtfAlignmentCommand(ALIGN_CENTER));
|
||||||
|
addAction("ql", new RtfAlignmentCommand(ALIGN_LEFT));
|
||||||
|
addAction("qr", new RtfAlignmentCommand(ALIGN_RIGHT));
|
||||||
|
addAction("qj", new RtfAlignmentCommand(ALIGN_JUSTIFY));
|
||||||
|
addAction("pard", new RtfAlignmentCommand(ALIGN_UNDEFINED));
|
||||||
|
|
||||||
|
addAction("b", new RtfFontPropertyCommand(RtfReader::FONT_BOLD));
|
||||||
|
addAction("i", new RtfFontPropertyCommand(RtfReader::FONT_ITALIC));
|
||||||
|
addAction("u", new RtfFontPropertyCommand(RtfReader::FONT_UNDERLINED));
|
||||||
|
addAction("plain", new RtfFontResetCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfReader::parseDocument() {
|
||||||
|
enum {
|
||||||
|
READ_NORMAL_DATA,
|
||||||
|
READ_BINARY_DATA,
|
||||||
|
READ_HEX_SYMBOL,
|
||||||
|
READ_KEYWORD,
|
||||||
|
READ_KEYWORD_PARAMETER
|
||||||
|
} parserState = READ_NORMAL_DATA;
|
||||||
|
|
||||||
|
std::string keyword;
|
||||||
|
std::string parameterString;
|
||||||
|
std::string hexString;
|
||||||
|
int imageStartOffset = -1;
|
||||||
|
|
||||||
|
while (!myIsInterrupted) {
|
||||||
|
const char *ptr = myStreamBuffer;
|
||||||
|
const char *end = myStreamBuffer + myStream->read(myStreamBuffer, rtfStreamBufferSize);
|
||||||
|
if (ptr == end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const char *dataStart = ptr;
|
||||||
|
bool readNextChar = true;
|
||||||
|
while (ptr != end) {
|
||||||
|
switch (parserState) {
|
||||||
|
case READ_BINARY_DATA:
|
||||||
|
// TODO: optimize
|
||||||
|
processCharData(ptr, 1);
|
||||||
|
--myBinaryDataSize;
|
||||||
|
if (myBinaryDataSize == 0) {
|
||||||
|
parserState = READ_NORMAL_DATA;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_NORMAL_DATA:
|
||||||
|
switch (*ptr) {
|
||||||
|
case '{':
|
||||||
|
if (ptr > dataStart) {
|
||||||
|
processCharData(dataStart, ptr - dataStart);
|
||||||
|
}
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
myStateStack.push(myState);
|
||||||
|
myState.ReadDataAsHex = false;
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
{
|
||||||
|
if (ptr > dataStart) {
|
||||||
|
processCharData(dataStart, ptr - dataStart);
|
||||||
|
}
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
|
||||||
|
if (imageStartOffset >= 0) {
|
||||||
|
int imageSize = myStream->offset() + (ptr - end) - imageStartOffset;
|
||||||
|
insertImage(myNextImageMimeType, myFileName, imageStartOffset, imageSize);
|
||||||
|
imageStartOffset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myStateStack.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myState.Destination != myStateStack.top().Destination) {
|
||||||
|
switchDestination(myState.Destination, false);
|
||||||
|
switchDestination(myStateStack.top().Destination, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool oldItalic = myState.Italic;
|
||||||
|
bool oldBold = myState.Bold;
|
||||||
|
bool oldUnderlined = myState.Underlined;
|
||||||
|
ZLTextAlignmentType oldAlignment = myState.Alignment;
|
||||||
|
myState = myStateStack.top();
|
||||||
|
myStateStack.pop();
|
||||||
|
|
||||||
|
if (myState.Italic != oldItalic) {
|
||||||
|
setFontProperty(RtfReader::FONT_ITALIC);
|
||||||
|
}
|
||||||
|
if (myState.Bold != oldBold) {
|
||||||
|
setFontProperty(RtfReader::FONT_BOLD);
|
||||||
|
}
|
||||||
|
if (myState.Underlined != oldUnderlined) {
|
||||||
|
setFontProperty(RtfReader::FONT_UNDERLINED);
|
||||||
|
}
|
||||||
|
if (myState.Alignment != oldAlignment) {
|
||||||
|
setAlignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\\':
|
||||||
|
if (ptr > dataStart) {
|
||||||
|
processCharData(dataStart, ptr - dataStart);
|
||||||
|
}
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
keyword.erase();
|
||||||
|
parserState = READ_KEYWORD;
|
||||||
|
break;
|
||||||
|
case 0x0d:
|
||||||
|
case 0x0a: // cr and lf are noise characters...
|
||||||
|
if (ptr > dataStart) {
|
||||||
|
processCharData(dataStart, ptr - dataStart);
|
||||||
|
}
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (myState.ReadDataAsHex) {
|
||||||
|
if (imageStartOffset == -1) {
|
||||||
|
imageStartOffset = myStream->offset() + (ptr - end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_HEX_SYMBOL:
|
||||||
|
hexString += *ptr;
|
||||||
|
if (hexString.size() == 2) {
|
||||||
|
char ch = strtol(hexString.c_str(), 0, 16);
|
||||||
|
hexString.erase();
|
||||||
|
processCharData(&ch, 1);
|
||||||
|
parserState = READ_NORMAL_DATA;
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_KEYWORD:
|
||||||
|
if (!isalpha(*ptr)) {
|
||||||
|
if ((ptr == dataStart) && (keyword.empty())) {
|
||||||
|
if (*ptr == '\'') {
|
||||||
|
parserState = READ_HEX_SYMBOL;
|
||||||
|
} else {
|
||||||
|
keyword = *ptr;
|
||||||
|
processKeyword(keyword);
|
||||||
|
parserState = READ_NORMAL_DATA;
|
||||||
|
}
|
||||||
|
dataStart = ptr + 1;
|
||||||
|
} else {
|
||||||
|
keyword.append(dataStart, ptr - dataStart);
|
||||||
|
if ((*ptr == '-') || isdigit(*ptr)) {
|
||||||
|
dataStart = ptr;
|
||||||
|
parserState = READ_KEYWORD_PARAMETER;
|
||||||
|
} else {
|
||||||
|
readNextChar = *ptr == ' ';
|
||||||
|
processKeyword(keyword);
|
||||||
|
parserState = READ_NORMAL_DATA;
|
||||||
|
dataStart = readNextChar ? ptr + 1 : ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_KEYWORD_PARAMETER:
|
||||||
|
if (!isdigit(*ptr)) {
|
||||||
|
parameterString.append(dataStart, ptr - dataStart);
|
||||||
|
int parameter = atoi(parameterString.c_str());
|
||||||
|
parameterString.erase();
|
||||||
|
readNextChar = *ptr == ' ';
|
||||||
|
if ((keyword == "bin") && (parameter > 0)) {
|
||||||
|
myBinaryDataSize = parameter;
|
||||||
|
parserState = READ_BINARY_DATA;
|
||||||
|
} else {
|
||||||
|
processKeyword(keyword, ¶meter);
|
||||||
|
parserState = READ_NORMAL_DATA;
|
||||||
|
}
|
||||||
|
dataStart = readNextChar ? ptr + 1 : ptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (readNextChar) {
|
||||||
|
++ptr;
|
||||||
|
} else {
|
||||||
|
readNextChar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataStart < end) {
|
||||||
|
switch (parserState) {
|
||||||
|
case READ_NORMAL_DATA:
|
||||||
|
processCharData(dataStart, end - dataStart);
|
||||||
|
case READ_KEYWORD:
|
||||||
|
keyword.append(dataStart, end - dataStart);
|
||||||
|
break;
|
||||||
|
case READ_KEYWORD_PARAMETER:
|
||||||
|
parameterString.append(dataStart, end - dataStart);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return myIsInterrupted || myStateStack.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReader::processKeyword(const std::string &keyword, int *parameter) {
|
||||||
|
bool wasSpecialMode = mySpecialMode;
|
||||||
|
mySpecialMode = false;
|
||||||
|
if (myState.Destination == RtfReader::DESTINATION_SKIP) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, RtfCommand*>::const_iterator it = ourKeywordMap.find(keyword);
|
||||||
|
|
||||||
|
if (it == ourKeywordMap.end()) {
|
||||||
|
if (wasSpecialMode)
|
||||||
|
myState.Destination = RtfReader::DESTINATION_SKIP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->second->run(*this, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RtfReader::processCharData(const char *data, size_t len, bool convert) {
|
||||||
|
if (myState.Destination != RtfReader::DESTINATION_SKIP) {
|
||||||
|
addCharData(data, len, convert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReader::interrupt() {
|
||||||
|
myIsInterrupted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfReader::readDocument(const ZLFile &file) {
|
||||||
|
myFileName = file.path();
|
||||||
|
myStream = file.inputStream();
|
||||||
|
if (myStream.isNull() || !myStream->open()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillKeywordMap();
|
||||||
|
|
||||||
|
myStreamBuffer = new char[rtfStreamBufferSize];
|
||||||
|
|
||||||
|
myIsInterrupted = false;
|
||||||
|
|
||||||
|
mySpecialMode = false;
|
||||||
|
|
||||||
|
myState.Alignment = ALIGN_UNDEFINED;
|
||||||
|
myState.Italic = false;
|
||||||
|
myState.Bold = false;
|
||||||
|
myState.Underlined = false;
|
||||||
|
myState.Destination = RtfReader::DESTINATION_NONE;
|
||||||
|
myState.ReadDataAsHex = false;
|
||||||
|
|
||||||
|
bool code = parseDocument();
|
||||||
|
|
||||||
|
while (!myStateStack.empty()) {
|
||||||
|
myStateStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] myStreamBuffer;
|
||||||
|
myStream->close();
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
203
jni/NativeFormats/fbreader/src/formats/rtf/RtfReader.h
Normal file
203
jni/NativeFormats/fbreader/src/formats/rtf/RtfReader.h
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFREADER_H__
|
||||||
|
#define __RTFREADER_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include <ZLEncodingConverter.h>
|
||||||
|
|
||||||
|
#include <ZLTextAlignmentType.h>
|
||||||
|
|
||||||
|
#include "../EncodedTextReader.h"
|
||||||
|
|
||||||
|
class ZLFile;
|
||||||
|
class ZLInputStream;
|
||||||
|
class RtfCommand;
|
||||||
|
|
||||||
|
class RtfReader : public EncodedTextReader {
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void fillKeywordMap();
|
||||||
|
static void addAction(const std::string &tag, RtfCommand *command);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::map<std::string, RtfCommand*> ourKeywordMap;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RtfReader(const std::string &encoding);
|
||||||
|
virtual ~RtfReader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool readDocument(const ZLFile &file);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum DestinationType {
|
||||||
|
DESTINATION_NONE,
|
||||||
|
DESTINATION_SKIP,
|
||||||
|
DESTINATION_INFO,
|
||||||
|
DESTINATION_TITLE,
|
||||||
|
DESTINATION_AUTHOR,
|
||||||
|
DESTINATION_PICTURE,
|
||||||
|
DESTINATION_STYLESHEET,
|
||||||
|
DESTINATION_FOOTNOTE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FontProperty {
|
||||||
|
FONT_BOLD,
|
||||||
|
FONT_ITALIC,
|
||||||
|
FONT_UNDERLINED
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void addCharData(const char *data, size_t len, bool convert) = 0;
|
||||||
|
virtual void insertImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t size) = 0;
|
||||||
|
virtual void setEncoding(int code) = 0;
|
||||||
|
virtual void switchDestination(DestinationType destination, bool on) = 0;
|
||||||
|
virtual void setAlignment() = 0;
|
||||||
|
virtual void setFontProperty(FontProperty property) = 0;
|
||||||
|
virtual void newParagraph() = 0;
|
||||||
|
|
||||||
|
void interrupt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool parseDocument();
|
||||||
|
void processKeyword(const std::string &keyword, int *parameter = 0);
|
||||||
|
void processCharData(const char *data, size_t len, bool convert = true);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct RtfReaderState {
|
||||||
|
bool Bold;
|
||||||
|
bool Italic;
|
||||||
|
bool Underlined;
|
||||||
|
ZLTextAlignmentType Alignment;
|
||||||
|
DestinationType Destination;
|
||||||
|
|
||||||
|
bool ReadDataAsHex;
|
||||||
|
};
|
||||||
|
|
||||||
|
RtfReaderState myState;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mySpecialMode;
|
||||||
|
|
||||||
|
std::string myFileName;
|
||||||
|
shared_ptr<ZLInputStream> myStream;
|
||||||
|
char *myStreamBuffer;
|
||||||
|
|
||||||
|
std::stack<RtfReaderState> myStateStack;
|
||||||
|
|
||||||
|
int myBinaryDataSize;
|
||||||
|
std::string myNextImageMimeType;
|
||||||
|
|
||||||
|
int myIsInterrupted;
|
||||||
|
|
||||||
|
friend class RtfNewParagraphCommand;
|
||||||
|
friend class RtfFontPropertyCommand;
|
||||||
|
friend class RtfAlignmentCommand;
|
||||||
|
friend class RtfCharCommand;
|
||||||
|
friend class RtfDestinationCommand;
|
||||||
|
friend class RtfStyleCommand;
|
||||||
|
friend class RtfSpecialCommand;
|
||||||
|
friend class RtfPictureCommand;
|
||||||
|
friend class RtfFontResetCommand;
|
||||||
|
friend class RtfCodepageCommand;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfCommand {
|
||||||
|
protected:
|
||||||
|
virtual ~RtfCommand();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void run(RtfReader &reader, int *parameter) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfNewParagraphCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfFontPropertyCommand : public RtfCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfFontPropertyCommand(RtfReader::FontProperty property);
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RtfReader::FontProperty myProperty;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfAlignmentCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
RtfAlignmentCommand(ZLTextAlignmentType alignment);
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZLTextAlignmentType myAlignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfCharCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
RtfCharCommand(const std::string &chr);
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string myChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfDestinationCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
RtfDestinationCommand(RtfReader::DestinationType dest);
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RtfReader::DestinationType myDestination;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfStyleCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfSpecialCommand : public RtfCommand {
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfPictureCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
RtfPictureCommand(const std::string &mimeType);
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string myMimeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfFontResetCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RtfCodepageCommand : public RtfCommand {
|
||||||
|
public:
|
||||||
|
void run(RtfReader &reader, int *parameter) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __RTFREADER_H__ */
|
175
jni/NativeFormats/fbreader/src/formats/rtf/RtfReaderStream.cpp
Normal file
175
jni/NativeFormats/fbreader/src/formats/rtf/RtfReaderStream.cpp
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "RtfReader.h"
|
||||||
|
#include "RtfReaderStream.h"
|
||||||
|
|
||||||
|
class RtfTextOnlyReader : public RtfReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfTextOnlyReader(char *buffer, size_t maxSize);
|
||||||
|
~RtfTextOnlyReader();
|
||||||
|
size_t readSize() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void addCharData(const char *data, size_t len, bool convert);
|
||||||
|
void insertImage(const std::string &mimeType, const std::string &fileName, size_t startOffset, size_t size);
|
||||||
|
void setEncoding(int code);
|
||||||
|
void switchDestination(DestinationType destination, bool on);
|
||||||
|
void setAlignment();
|
||||||
|
void setFontProperty(FontProperty property);
|
||||||
|
void newParagraph();
|
||||||
|
|
||||||
|
void interrupt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct RtfTextOnlyReaderState {
|
||||||
|
bool ReadText;
|
||||||
|
};
|
||||||
|
|
||||||
|
RtfTextOnlyReaderState myCurrentState;
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* myBuffer;
|
||||||
|
const size_t myMaxSize;
|
||||||
|
size_t myFilledSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
RtfTextOnlyReader::RtfTextOnlyReader(char *buffer, size_t maxSize) : RtfReader(std::string()), myBuffer(buffer), myMaxSize(maxSize), myFilledSize(0) {
|
||||||
|
myCurrentState.ReadText = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfTextOnlyReader::~RtfTextOnlyReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::addCharData(const char *data, size_t len, bool) {
|
||||||
|
if (myBuffer == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myCurrentState.ReadText) {
|
||||||
|
if (myFilledSize < myMaxSize) {
|
||||||
|
len = std::min((size_t)len, myMaxSize - myFilledSize);
|
||||||
|
memcpy(myBuffer + myFilledSize, data, len);
|
||||||
|
myFilledSize += len;
|
||||||
|
}
|
||||||
|
if (myFilledSize < myMaxSize) {
|
||||||
|
myBuffer[myFilledSize++]=' ';
|
||||||
|
} else {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RtfTextOnlyReader::readSize() const {
|
||||||
|
return myFilledSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::insertImage(const std::string&, const std::string&, size_t, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::setEncoding(int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::switchDestination(DestinationType destination, bool on) {
|
||||||
|
switch (destination) {
|
||||||
|
case DESTINATION_NONE:
|
||||||
|
break;
|
||||||
|
case DESTINATION_SKIP:
|
||||||
|
case DESTINATION_INFO:
|
||||||
|
case DESTINATION_TITLE:
|
||||||
|
case DESTINATION_AUTHOR:
|
||||||
|
case DESTINATION_STYLESHEET:
|
||||||
|
myCurrentState.ReadText = !on;
|
||||||
|
break;
|
||||||
|
case DESTINATION_PICTURE:
|
||||||
|
myCurrentState.ReadText = !on;
|
||||||
|
break;
|
||||||
|
case DESTINATION_FOOTNOTE:
|
||||||
|
if (on) {
|
||||||
|
myCurrentState.ReadText = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::setAlignment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::setFontProperty(FontProperty) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::newParagraph() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfTextOnlyReader::interrupt() {
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfReaderStream::RtfReaderStream(const ZLFile& file, size_t maxSize) : myFile(file), myBuffer(0), mySize(maxSize) {
|
||||||
|
}
|
||||||
|
|
||||||
|
RtfReaderStream::~RtfReaderStream() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtfReaderStream::open() {
|
||||||
|
if (mySize != 0) {
|
||||||
|
myBuffer = new char[mySize];
|
||||||
|
}
|
||||||
|
RtfTextOnlyReader reader(myBuffer, mySize);
|
||||||
|
reader.readDocument(myFile);
|
||||||
|
mySize = reader.readSize();
|
||||||
|
myOffset = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RtfReaderStream::read(char *buffer, size_t maxSize) {
|
||||||
|
maxSize = std::min(maxSize, mySize - myOffset);
|
||||||
|
if ((buffer != 0) && (myBuffer !=0)) {
|
||||||
|
memcpy(buffer, myBuffer + myOffset, maxSize);
|
||||||
|
}
|
||||||
|
myOffset += maxSize;
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReaderStream::close() {
|
||||||
|
if (myBuffer != 0) {
|
||||||
|
delete[] myBuffer;
|
||||||
|
myBuffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtfReaderStream::seek(int offset, bool absoluteOffset) {
|
||||||
|
if (!absoluteOffset) {
|
||||||
|
offset += myOffset;
|
||||||
|
}
|
||||||
|
myOffset = std::min(mySize, (size_t)std::max(0, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RtfReaderStream::offset() const {
|
||||||
|
return myOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RtfReaderStream::sizeOfOpened() {
|
||||||
|
return mySize;
|
||||||
|
}
|
||||||
|
|
50
jni/NativeFormats/fbreader/src/formats/rtf/RtfReaderStream.h
Normal file
50
jni/NativeFormats/fbreader/src/formats/rtf/RtfReaderStream.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RTFREADERSTREAM_H__
|
||||||
|
#define __RTFREADERSTREAM_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
|
||||||
|
class RtfReaderStream : public ZLInputStream {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtfReaderStream(const ZLFile& file, size_t maxSize);
|
||||||
|
~RtfReaderStream();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool open();
|
||||||
|
size_t read(char *buffer, size_t maxSize);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
void seek(int offset, bool absoluteOffset);
|
||||||
|
size_t offset() const;
|
||||||
|
size_t sizeOfOpened();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ZLFile myFile;
|
||||||
|
char *myBuffer;
|
||||||
|
size_t mySize;
|
||||||
|
size_t myOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __RTFREADERSTREAM_H__ */
|
|
@ -298,3 +298,7 @@ void AndroidUtil::throwRuntimeException(JNIEnv *env, const std::string &message)
|
||||||
jclass cls = env->FindClass("java/lang/RuntimeException");
|
jclass cls = env->FindClass("java/lang/RuntimeException");
|
||||||
env->ThrowNew(cls, message.c_str());
|
env->ThrowNew(cls, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidUtil::throwBookReadingException(JNIEnv *env, const std::string &resourceId, const std::string &filePath) {
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ public:
|
||||||
static jobjectArray createStringArray(JNIEnv *env, const std::vector<std::string> &data);
|
static jobjectArray createStringArray(JNIEnv *env, const std::vector<std::string> &data);
|
||||||
|
|
||||||
static void throwRuntimeException(JNIEnv *env, const std::string &message);
|
static void throwRuntimeException(JNIEnv *env, const std::string &message);
|
||||||
|
static void throwBookReadingException(JNIEnv *env, const std::string &resourceId, const std::string &filePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ANDROIDUTIL_H__ */
|
#endif /* __ANDROIDUTIL_H__ */
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.geometerplus.fbreader.filetype.*;
|
||||||
|
|
||||||
public class PluginCollection {
|
public class PluginCollection {
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("NativeFormats-v1");
|
System.loadLibrary("NativeFormats-v2");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PluginCollection ourInstance;
|
private static PluginCollection ourInstance;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue