2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <ZLStringUtil.h>
24 #include "RtfBookReader.h"
25 #include "../../bookmodel/BookModel.h"
28 RtfBookReader::RtfBookReader(BookModel
&model
, const std::string
&encoding
) : RtfReader(encoding
), myBookReader(model
) {
31 static const size_t maxBufferSize
= 1024;
33 void RtfBookReader::addCharData(const char *data
, size_t len
, bool convert
) {
34 if (myCurrentState
.ReadText
) {
35 if (convert
|| myConverter
.isNull()) {
36 myOutputBuffer
.append(data
, len
);
37 if (myOutputBuffer
.size() >= maxBufferSize
) {
42 std::string
newString(data
, len
);
43 characterDataHandler(newString
);
48 void RtfBookReader::flushBuffer() {
49 if (!myOutputBuffer
.empty()) {
50 if (myCurrentState
.ReadText
) {
51 if (!myConverter
.isNull()) {
52 static std::string newString
;
53 myConverter
->convert(newString
, myOutputBuffer
.data(), myOutputBuffer
.data() + myOutputBuffer
.length());
54 characterDataHandler(newString
);
57 characterDataHandler(myOutputBuffer
);
60 myOutputBuffer
.erase();
64 void RtfBookReader::switchDestination(DestinationType destination
, bool on
) {
65 switch (destination
) {
66 case DESTINATION_NONE
:
68 case DESTINATION_SKIP
:
69 case DESTINATION_INFO
:
70 case DESTINATION_TITLE
:
71 case DESTINATION_AUTHOR
:
72 case DESTINATION_STYLESHEET
:
73 myCurrentState
.ReadText
= !on
;
75 case DESTINATION_PICTURE
:
78 if (myBookReader
.paragraphIsOpen()) {
79 myBookReader
.endParagraph();
82 myCurrentState
.ReadText
= !on
;
84 case DESTINATION_FOOTNOTE
:
88 ZLStringUtil::appendNumber(id
, myFootnoteIndex
++);
90 myStateStack
.push(myCurrentState
);
91 myCurrentState
.Id
= id
;
92 myCurrentState
.ReadText
= true;
94 myBookReader
.addHyperlinkControl(FOOTNOTE
, id
);
95 myBookReader
.addData(id
);
96 myBookReader
.addControl(FOOTNOTE
, false);
98 myBookReader
.setFootnoteTextModel(id
);
99 myBookReader
.pushKind(REGULAR
);
100 myBookReader
.beginParagraph();
102 myBookReader
.endParagraph();
103 myBookReader
.popKind();
105 if (!myStateStack
.empty()) {
106 myCurrentState
= myStateStack
.top();
110 if (myStateStack
.empty()) {
111 myBookReader
.setMainTextModel();
113 myBookReader
.setFootnoteTextModel(myCurrentState
.Id
);
120 void RtfBookReader::insertImage(const std::string
&mimeType
, const std::string
&fileName
, size_t startOffset
, size_t size
) {
122 ZLStringUtil::appendNumber(id
, myImageIndex
++);
123 myBookReader
.addImageReference(id
);
124 myBookReader
.addImage(id
, new RtfImage(mimeType
, fileName
, startOffset
, size
));
127 bool RtfBookReader::characterDataHandler(std::string
&str
) {
128 if (myCurrentState
.ReadText
) {
129 if (!myBookReader
.paragraphIsOpen()) {
130 myBookReader
.beginParagraph();
132 myBookReader
.addData(str
);
137 bool RtfBookReader::readDocument(const std::string
&fileName
) {
141 myCurrentState
.ReadText
= true;
143 myBookReader
.setMainTextModel();
144 myBookReader
.pushKind(REGULAR
);
145 myBookReader
.beginParagraph();
147 bool code
= RtfReader::readDocument(fileName
);
150 myBookReader
.endParagraph();
151 while (!myStateStack
.empty()) {
158 void RtfBookReader::setFontProperty(FontProperty property
) {
159 if (!myCurrentState
.ReadText
) {
160 //DPRINT("change style not in text.\n");
168 myBookReader
.pushKind(STRONG
);
170 myBookReader
.popKind();
172 myBookReader
.addControl(STRONG
, myState
.Bold
);
175 if (myState
.Italic
) {
177 //DPRINT("add style emphasis.\n");
178 myBookReader
.pushKind(EMPHASIS
);
179 myBookReader
.addControl(EMPHASIS
, true);
181 //DPRINT("add style emphasis and strong.\n");
182 myBookReader
.popKind();
183 myBookReader
.addControl(STRONG
, false);
185 myBookReader
.pushKind(EMPHASIS
);
186 myBookReader
.addControl(EMPHASIS
, true);
187 myBookReader
.pushKind(STRONG
);
188 myBookReader
.addControl(STRONG
, true);
192 //DPRINT("remove style emphasis.\n");
193 myBookReader
.addControl(EMPHASIS
, false);
194 myBookReader
.popKind();
196 //DPRINT("remove style strong n emphasis, add strong.\n");
197 myBookReader
.addControl(STRONG
, false);
198 myBookReader
.popKind();
199 myBookReader
.addControl(EMPHASIS
, false);
200 myBookReader
.popKind();
202 myBookReader
.pushKind(STRONG
);
203 myBookReader
.addControl(STRONG
, true);
207 case FONT_UNDERLINED
:
212 void RtfBookReader::newParagraph() {
214 myBookReader
.endParagraph();
215 myBookReader
.beginParagraph();
216 if (myState
.Alignment
!= ALIGN_UNDEFINED
) {
221 void RtfBookReader::setEncoding(int) {
224 void RtfBookReader::setAlignment() {
225 ZLTextForcedControlEntry entry
;
226 entry
.setAlignmentType(myState
.Alignment
);
227 myBookReader
.addControl(entry
);