diff --git a/jni/Android.mk b/jni/Android.mk index e02a759d3..6e0dc2a62 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -83,6 +83,7 @@ LOCAL_SRC_FILES := \ NativeFormats/zlibrary/text/src/model/ZLCachedMemoryAllocator.cpp \ NativeFormats/zlibrary/text/src/model/ZLTextModel.cpp \ NativeFormats/zlibrary/text/src/model/ZLTextParagraph.cpp \ + NativeFormats/zlibrary/text/src/model/ZLVideoEntry.cpp \ NativeFormats/zlibrary/ui/src/android/filesystem/JavaFSDir.cpp \ NativeFormats/zlibrary/ui/src/android/filesystem/JavaInputStream.cpp \ NativeFormats/zlibrary/ui/src/android/filesystem/ZLAndroidFSManager.cpp \ diff --git a/jni/NativeFormats/fbreader/src/bookmodel/BookReader.cpp b/jni/NativeFormats/fbreader/src/bookmodel/BookReader.cpp index 0c85b2383..34837c18f 100644 --- a/jni/NativeFormats/fbreader/src/bookmodel/BookReader.cpp +++ b/jni/NativeFormats/fbreader/src/bookmodel/BookReader.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "BookReader.h" #include "BookModel.h" @@ -230,6 +231,16 @@ void BookReader::addImage(const std::string &id, shared_ptr image env->DeleteLocalRef(javaImage); } +void BookReader::addVideoEntry(const ZLVideoEntry &entry) { + if (myCurrentTextModel != 0) { + mySectionContainsRegularContents = true; + endParagraph(); + beginParagraph(); + myCurrentTextModel->addVideoEntry(entry); + endParagraph(); + } +} + void BookReader::insertEndParagraph(ZLTextParagraph::Kind kind) { if (myCurrentTextModel != 0 && mySectionContainsRegularContents) { std::size_t size = myCurrentTextModel->paragraphsNumber(); diff --git a/jni/NativeFormats/fbreader/src/bookmodel/BookReader.h b/jni/NativeFormats/fbreader/src/bookmodel/BookReader.h index 67ffca8fa..ec3979fe2 100644 --- a/jni/NativeFormats/fbreader/src/bookmodel/BookReader.h +++ b/jni/NativeFormats/fbreader/src/bookmodel/BookReader.h @@ -36,6 +36,7 @@ class ZLTextModel; class ZLInputStream; class ZLCachedMemoryAllocator; class ZLTextStyleEntry; +class ZLVideoEntry; class BookReader { @@ -68,6 +69,8 @@ public: void addImageReference(const std::string &id, short vOffset, bool isCover); void addImage(const std::string &id, shared_ptr image); + void addVideoEntry(const ZLVideoEntry &entry); + void beginContentsParagraph(int referenceNumber = -1); void endContentsParagraph(); bool contentsParagraphIsOpen() const; diff --git a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp index 18f262e7e..99a13d677 100644 --- a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp +++ b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp @@ -60,42 +60,82 @@ void XHTMLTagAction::endParagraph(XHTMLReader &reader) { reader.endParagraph(); } -class XHTMLTagStyleAction : public XHTMLTagAction { +class XHTMLGlobalTagAction : public XHTMLTagAction { + +private: + bool isEnabled(XHTMLReadingState state); +}; + +class XHTMLTextModeTagAction : public XHTMLTagAction { + +private: + bool isEnabled(XHTMLReadingState state); +}; + +bool XHTMLGlobalTagAction::isEnabled(XHTMLReadingState state) { + return true; +} + +bool XHTMLTextModeTagAction::isEnabled(XHTMLReadingState state) { + return state == XHTML_READ_BODY; +} + +class XHTMLTagStyleAction : public XHTMLGlobalTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagLinkAction : public XHTMLTagAction { +class XHTMLTagLinkAction : public XHTMLGlobalTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagParagraphAction : public XHTMLTagAction { +class XHTMLTagParagraphAction : public XHTMLTextModeTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagBodyAction : public XHTMLTagAction { +class XHTMLTagBodyAction : public XHTMLGlobalTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagRestartParagraphAction : public XHTMLTagAction { +class XHTMLTagRestartParagraphAction : public XHTMLTextModeTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagImageAction : public XHTMLTagAction { +class XHTMLTagVideoAction : public XHTMLTagAction { + +private: + bool isEnabled(XHTMLReadingState state); + +public: + void doAtStart(XHTMLReader &reader, const char **xmlattributes); + void doAtEnd(XHTMLReader &reader); +}; + +class XHTMLTagSourceAction : public XHTMLTagAction { + +private: + bool isEnabled(XHTMLReadingState state); + +public: + void doAtStart(XHTMLReader &reader, const char **xmlattributes); + void doAtEnd(XHTMLReader &reader); +}; + +class XHTMLTagImageAction : public XHTMLTextModeTagAction { public: XHTMLTagImageAction(shared_ptr predicate); @@ -120,7 +160,7 @@ private: friend class XHTMLTagSvgAction; }; -class XHTMLTagSvgAction : public XHTMLTagAction { +class XHTMLTagSvgAction : public XHTMLTextModeTagAction { public: XHTMLTagSvgAction(XHTMLSvgImageNamePredicate &predicate); @@ -131,14 +171,14 @@ private: XHTMLSvgImageNamePredicate &myPredicate; }; -class XHTMLTagItemAction : public XHTMLTagAction { +class XHTMLTagItemAction : public XHTMLTextModeTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); void doAtEnd(XHTMLReader &reader); }; -class XHTMLTagHyperlinkAction : public XHTMLTagAction { +class XHTMLTagHyperlinkAction : public XHTMLTextModeTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); @@ -148,7 +188,7 @@ private: std::stack myHyperlinkStack; }; -class XHTMLTagControlAction : public XHTMLTagAction { +class XHTMLTagControlAction : public XHTMLTextModeTagAction { public: XHTMLTagControlAction(FBTextKind control); @@ -160,7 +200,7 @@ private: FBTextKind myControl; }; -class XHTMLTagParagraphWithControlAction : public XHTMLTagAction { +class XHTMLTagParagraphWithControlAction : public XHTMLTextModeTagAction { public: XHTMLTagParagraphWithControlAction(FBTextKind control); @@ -172,7 +212,7 @@ private: FBTextKind myControl; }; -class XHTMLTagPreAction : public XHTMLTagAction { +class XHTMLTagPreAction : public XHTMLTextModeTagAction { public: void doAtStart(XHTMLReader &reader, const char **xmlattributes); @@ -187,16 +227,16 @@ void XHTMLTagStyleAction::doAtStart(XHTMLReader &reader, const char **xmlattribu return; } - if (reader.myReadState == XHTMLReader::READ_NOTHING) { - reader.myReadState = XHTMLReader::READ_STYLE; + if (reader.myReadState == XHTML_READ_NOTHING) { + reader.myReadState = XHTML_READ_STYLE; reader.myTableParser = new StyleSheetTableParser(reader.myStyleSheetTable); ZLLogger::Instance().println("CSS", "parsing style tag content"); } } void XHTMLTagStyleAction::doAtEnd(XHTMLReader &reader) { - if (reader.myReadState == XHTMLReader::READ_STYLE) { - reader.myReadState = XHTMLReader::READ_NOTHING; + if (reader.myReadState == XHTML_READ_STYLE) { + reader.myReadState = XHTML_READ_NOTHING; reader.myTableParser.reset(); } } @@ -248,7 +288,7 @@ void XHTMLTagParagraphAction::doAtEnd(XHTMLReader &reader) { void XHTMLTagBodyAction::doAtStart(XHTMLReader &reader, const char**) { ++reader.myBodyCounter; if (reader.myBodyCounter > 0) { - reader.myReadState = XHTMLReader::READ_BODY; + reader.myReadState = XHTML_READ_BODY; } } @@ -256,7 +296,7 @@ void XHTMLTagBodyAction::doAtEnd(XHTMLReader &reader) { endParagraph(reader); --reader.myBodyCounter; if (reader.myBodyCounter <= 0) { - reader.myReadState = XHTMLReader::READ_NOTHING; + reader.myReadState = XHTML_READ_NOTHING; } } @@ -284,6 +324,43 @@ void XHTMLTagItemAction::doAtEnd(XHTMLReader &reader) { endParagraph(reader); } +bool XHTMLTagVideoAction::isEnabled(XHTMLReadingState state) { + return state == XHTML_READ_BODY || state == XHTML_READ_VIDEO; +} + +void XHTMLTagVideoAction::doAtStart(XHTMLReader &reader, const char**) { + if (reader.myReadState == XHTML_READ_BODY) { + reader.myReadState = XHTML_READ_VIDEO; + reader.myVideoEntry = new ZLVideoEntry(); + } +} + +void XHTMLTagVideoAction::doAtEnd(XHTMLReader &reader) { + if (reader.myReadState == XHTML_READ_VIDEO) { + bookReader(reader).addVideoEntry(*reader.myVideoEntry); + reader.myVideoEntry.reset(); + reader.myReadState = XHTML_READ_BODY; + } +} + +bool XHTMLTagSourceAction::isEnabled(XHTMLReadingState state) { + return state == XHTML_READ_VIDEO; +} + +void XHTMLTagSourceAction::doAtStart(XHTMLReader &reader, const char **xmlattributes) { + const char *mime = reader.attributeValue(xmlattributes, "type"); + const char *href = reader.attributeValue(xmlattributes, "src"); + if (mime != 0 && href != 0) { + reader.myVideoEntry->addSource( + mime, + ZLFile(pathPrefix(reader) + MiscUtil::decodeHtmlURL(href)).path() + ); + } +} + +void XHTMLTagSourceAction::doAtEnd(XHTMLReader &reader) { +} + XHTMLTagImageAction::XHTMLTagImageAction(shared_ptr predicate) { myPredicate = predicate; } @@ -520,6 +597,9 @@ void XHTMLReader::fillTagTable() { //addAction("tr", new XHTMLTagAction()); //addAction("caption", new XHTMLTagAction()); //addAction("span", new XHTMLTagAction()); + + addAction("video", new XHTMLTagVideoAction()); + addAction("source", new XHTMLTagSourceAction()); } } @@ -543,7 +623,7 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName) myPreformatted = false; myNewParagraphInProgress = false; - myReadState = READ_NOTHING; + myReadState = XHTML_READ_NOTHING; myBodyCounter = 0; myCurrentParagraphIsEmpty = true; @@ -587,7 +667,7 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes) myDoPageBreakAfterStack.push_back(myStyleSheetTable.doBreakAfter(sTag, sClass)); XHTMLTagAction *action = getAction(sTag); - if (action != 0) { + if (action != 0 && action->isEnabled(myReadState)) { action->doAtStart(*this, attributes); } @@ -613,7 +693,7 @@ void XHTMLReader::endElementHandler(const char *tag) { myCSSStack.pop_back(); XHTMLTagAction *action = getAction(tag); - if (action != 0) { + if (action != 0 && action->isEnabled(myReadState)) { action->doAtEnd(*this); myNewParagraphInProgress = false; } @@ -675,14 +755,15 @@ void XHTMLReader::endParagraph() { void XHTMLReader::characterDataHandler(const char *text, std::size_t len) { switch (myReadState) { - case READ_NOTHING: + case XHTML_READ_NOTHING: + case XHTML_READ_VIDEO: break; - case READ_STYLE: + case XHTML_READ_STYLE: if (!myTableParser.isNull()) { myTableParser->parse(text, len); } break; - case READ_BODY: + case XHTML_READ_BODY: if (myPreformatted) { if (*text == '\r' || *text == '\n') { endParagraph(); diff --git a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.h b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.h index 90042b8e8..b7aacd63f 100644 --- a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.h +++ b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.h @@ -25,6 +25,7 @@ #include #include +#include #include "../css/StyleSheetTable.h" #include "../css/StyleSheetParser.h" @@ -36,6 +37,13 @@ class XHTMLReader; class EncryptionMap; +enum XHTMLReadingState { + XHTML_READ_NOTHING, + XHTML_READ_STYLE, + XHTML_READ_BODY, + XHTML_READ_VIDEO +}; + class XHTMLTagAction { public: @@ -43,6 +51,7 @@ public: virtual void doAtStart(XHTMLReader &reader, const char **xmlattributes) = 0; virtual void doAtEnd(XHTMLReader &reader) = 0; + virtual bool isEnabled(XHTMLReadingState state) = 0; protected: static BookReader &bookReader(XHTMLReader &reader); @@ -103,13 +112,10 @@ private: bool myCurrentParagraphIsEmpty; shared_ptr myStyleParser; shared_ptr myTableParser; - enum { - READ_NOTHING, - READ_STYLE, - READ_BODY - } myReadState; + XHTMLReadingState myReadState; int myBodyCounter; bool myMarkNextImageAsCover; + shared_ptr myVideoEntry; friend class XHTMLTagAction; friend class XHTMLTagStyleAction; @@ -120,6 +126,8 @@ private: friend class XHTMLTagBodyAction; friend class XHTMLTagRestartParagraphAction; friend class XHTMLTagImageAction; + friend class XHTMLTagVideoAction; + friend class XHTMLTagSourceAction; }; #endif /* __XHTMLREADER_H__ */ diff --git a/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.cpp b/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.cpp index 727fec30d..097278ecd 100644 --- a/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.cpp +++ b/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.cpp @@ -26,11 +26,12 @@ //#include #include //#include -//#include +#include #include "ZLTextModel.h" #include "ZLTextParagraph.h" #include "ZLTextStyleEntry.h" +#include "ZLVideoEntry.h" ZLTextModel::ZLTextModel(const std::string &id, const std::string &language, const std::size_t rowSize, const std::string &directoryName, const std::string &fileExtension) : @@ -352,6 +353,31 @@ void ZLTextModel::addBidiReset() { ++myParagraphLengths.back(); } +void ZLTextModel::addVideoEntry(const ZLVideoEntry &entry) { + const std::map &sources = entry.sources(); + + std::size_t len = 4; + for (std::map::const_iterator it = sources.begin(); it != sources.end(); ++it) { + len += 2 * (ZLUnicodeUtil::utf8Length(it->first) + ZLUnicodeUtil::utf8Length(it->second)) + 4; + } + + myLastEntryStart = myAllocator->allocate(len); + *myLastEntryStart = ZLTextParagraphEntry::VIDEO_ENTRY; + *(myLastEntryStart + 1) = 0; + char *p = ZLCachedMemoryAllocator::writeUInt16(myLastEntryStart + 2, sources.size()); + for (std::map::const_iterator it = sources.begin(); it != sources.end(); ++it) { + ZLUnicodeUtil::Ucs2String first; + ZLUnicodeUtil::utf8ToUcs2(first, it->first); + p = ZLCachedMemoryAllocator::writeString(p, first); + ZLUnicodeUtil::Ucs2String second; + ZLUnicodeUtil::utf8ToUcs2(second, it->second); + p = ZLCachedMemoryAllocator::writeString(p, second); + } + + myParagraphs.back()->addEntry(myLastEntryStart); + ++myParagraphLengths.back(); +} + void ZLTextModel::flush() { myAllocator->flush(); } diff --git a/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.h b/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.h index bb517228b..fa828b976 100644 --- a/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.h +++ b/jni/NativeFormats/zlibrary/text/src/model/ZLTextModel.h @@ -33,6 +33,7 @@ #include class ZLTextStyleEntry; +class ZLVideoEntry; class ZLTextModel { @@ -73,6 +74,7 @@ public: void addImage(const std::string &id, short vOffset, bool isCover); void addFixedHSpace(unsigned char length); void addBidiReset(); + void addVideoEntry(const ZLVideoEntry &entry); void flush(); diff --git a/jni/NativeFormats/zlibrary/text/src/model/ZLTextParagraph.h b/jni/NativeFormats/zlibrary/text/src/model/ZLTextParagraph.h index 036d5dc15..8dd97bcba 100644 --- a/jni/NativeFormats/zlibrary/text/src/model/ZLTextParagraph.h +++ b/jni/NativeFormats/zlibrary/text/src/model/ZLTextParagraph.h @@ -46,6 +46,8 @@ public: STYLE_CLOSE_ENTRY = 7, FIXED_HSPACE_ENTRY = 8, RESET_BIDI_ENTRY = 9, + AUDIO_ENTRY = 10, + VIDEO_ENTRY = 11, }; protected: diff --git a/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.cpp b/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.cpp new file mode 100644 index 000000000..99e1075aa --- /dev/null +++ b/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2004-2014 Geometer Plus + * + * 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 "ZLVideoEntry.h" + +void ZLVideoEntry::addSource(const std::string &type, const std::string &path) { + mySources.insert(std::make_pair(type, path)); +} + +const std::map &ZLVideoEntry::sources() const { + return mySources; +} diff --git a/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.h b/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.h new file mode 100644 index 000000000..9b396d743 --- /dev/null +++ b/jni/NativeFormats/zlibrary/text/src/model/ZLVideoEntry.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2004-2014 Geometer Plus + * + * 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 __ZLVIDEOENTRY_H__ +#define __ZLVIDEOENTRY_H__ + +#include +#include + +#include + +class ZLVideoEntry : public ZLTextParagraphEntry { + +public: + void addSource(const std::string &type, const std::string &path); + const std::map &sources() const; + +private: + std::map mySources; +}; + +#endif /* __ZLVIDEOENTRY_H__ */ diff --git a/src/org/geometerplus/zlibrary/core/util/MimeType.java b/src/org/geometerplus/zlibrary/core/util/MimeType.java index 432d82de2..ae75d0766 100644 --- a/src/org/geometerplus/zlibrary/core/util/MimeType.java +++ b/src/org/geometerplus/zlibrary/core/util/MimeType.java @@ -134,6 +134,11 @@ public final class MimeType { // ??? public static final MimeType IMAGE_XDJVU = get("image/x-djvu"); + // video + public static final MimeType VIDEO_MP4 = get("video/mp4"); + public static final MimeType VIDEO_WEBM = get("video/webm"); + public static final MimeType VIDEO_OGG = get("video/ogg"); + public static final MimeType UNKNOWN = get("*/*"); public static final MimeType NULL = new MimeType(null, null); diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextParagraph.java b/src/org/geometerplus/zlibrary/text/model/ZLTextParagraph.java index a193f0f09..ba73ca9f6 100644 --- a/src/org/geometerplus/zlibrary/text/model/ZLTextParagraph.java +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextParagraph.java @@ -30,6 +30,8 @@ public interface ZLTextParagraph { byte STYLE_CLOSE = 7; byte FIXED_HSPACE = 8; byte RESET_BIDI = 9; + byte AUDIO = 10; + byte VIDEO = 11; } interface EntryIterator { @@ -46,6 +48,7 @@ public interface ZLTextParagraph { String getHyperlinkId(); ZLImageEntry getImageEntry(); + ZLVideoEntry getVideoEntry(); ZLTextStyleEntry getStyleEntry(); short getFixedHSpaceLength(); diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java b/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java index 0e754e719..2d1ea33b8 100644 --- a/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java @@ -64,6 +64,9 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature { // ImageEntry private ZLImageEntry myImageEntry; + // VideoEntry + private ZLVideoEntry myVideoEntry; + // StyleEntry private ZLTextStyleEntry myStyleEntry; @@ -114,6 +117,10 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature { return myImageEntry; } + public ZLVideoEntry getVideoEntry() { + return myVideoEntry; + } + public ZLTextStyleEntry getStyleEntry() { return myStyleEntry; } @@ -163,11 +170,11 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature { } case ZLTextParagraph.Entry.HYPERLINK_CONTROL: { - short kind = (short)data[dataOffset++]; + final short kind = (short)data[dataOffset++]; myControlKind = (byte)kind; myControlIsStart = true; myHyperlinkType = (byte)(kind >> 8); - short labelLength = (short)data[dataOffset++]; + final short labelLength = (short)data[dataOffset++]; myHyperlinkId = new String(data, dataOffset, labelLength); dataOffset += labelLength; break; @@ -223,6 +230,24 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature { case ZLTextParagraph.Entry.RESET_BIDI: // No data break; + case ZLTextParagraph.Entry.AUDIO: + // No data + break; + case ZLTextParagraph.Entry.VIDEO: + { + myVideoEntry = new ZLVideoEntry(); + final short mapSize = (short)data[dataOffset++]; + for (short i = 0; i < mapSize; ++i) { + short len = (short)data[dataOffset++]; + final String mime = new String(data, dataOffset, len); + dataOffset += len; + len = (short)data[dataOffset++]; + final String src = new String(data, dataOffset, len); + dataOffset += len; + myVideoEntry.addSource(mime, src); + } + break; + } } ++myCounter; myDataOffset = dataOffset; diff --git a/src/org/geometerplus/zlibrary/text/model/ZLVideoEntry.java b/src/org/geometerplus/zlibrary/text/model/ZLVideoEntry.java new file mode 100644 index 000000000..41024fc9a --- /dev/null +++ b/src/org/geometerplus/zlibrary/text/model/ZLVideoEntry.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007-2014 Geometer Plus + * + * 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. + */ + +package org.geometerplus.zlibrary.text.model; + +import java.util.Map; +import java.util.HashMap; + +public class ZLVideoEntry { + private final Map mySources = new HashMap(); + + public void addSource(String mime, String path) { + mySources.put(mime, path); + } + + public Map sources() { + return mySources; + } +} diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextParagraphCursor.java b/src/org/geometerplus/zlibrary/text/view/ZLTextParagraphCursor.java index 3e36f495b..aa1d88b42 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextParagraphCursor.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextParagraphCursor.java @@ -100,6 +100,16 @@ public final class ZLTextParagraphCursor { } } break; + case ZLTextParagraph.Entry.AUDIO: + break; + case ZLTextParagraph.Entry.VIDEO: + final ZLVideoEntry videoEntry = it.getVideoEntry(); + elements.add(new ZLTextVideoElement(videoEntry.sources())); + System.err.println("VIDEO === VIDEO"); + for (Map.Entry entry : videoEntry.sources().entrySet()) { + System.err.println(entry.getKey() + " ===> " + entry.getValue()); + } + break; case ZLTextParagraph.Entry.STYLE_CSS: case ZLTextParagraph.Entry.STYLE_OTHER: elements.add(new ZLTextStyleElement(it.getStyleEntry())); diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextVideoElement.java b/src/org/geometerplus/zlibrary/text/view/ZLTextVideoElement.java new file mode 100644 index 000000000..8037c113c --- /dev/null +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextVideoElement.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2007-2014 Geometer Plus + * + * 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. + */ + +package org.geometerplus.zlibrary.text.view; + +import java.util.Map; + +public final class ZLTextVideoElement extends ZLTextElement { + public final Map Sources; + + ZLTextVideoElement(Map sources) { + Sources = sources; + } +} diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java index 943e43651..a3fe75418 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java @@ -908,6 +908,21 @@ public abstract class ZLTextView extends ZLTextViewBase { getScalingType(imageElement), getAdjustingModeForImages() ); + } else if (element instanceof ZLTextVideoElement) { + // TODO: draw + context.setLineColor(getTextColor(ZLTextHyperlink.NO_LINK)); + context.drawLine(area.XStart, area.YStart, area.XStart, area.YEnd); + context.drawLine(area.XStart, area.YEnd, area.XEnd, area.YEnd); + context.drawLine(area.XEnd, area.YEnd, area.XEnd, area.YStart); + context.drawLine(area.XEnd, area.YStart, area.XStart, area.YStart); + final int l = area.XStart + (area.XEnd - area.XStart) * 7 / 16; + final int r = area.XStart + (area.XEnd - area.XStart) * 10 / 16; + final int t = area.YStart + (area.YEnd - area.YStart) * 2 / 6; + final int b = area.YStart + (area.YEnd - area.YStart) * 4 / 6; + final int c = area.YStart + (area.YEnd - area.YStart) / 2; + context.drawLine(l, t, l, b); + context.drawLine(l, t, r, c); + context.drawLine(l, b, r, c); } else if (element == ZLTextElement.HSpace) { final int cw = context.getSpaceWidth(); /* @@ -1075,6 +1090,9 @@ public abstract class ZLTextView extends ZLTextViewBase { } else if (element instanceof ZLTextImageElement) { wordOccurred = true; isVisible = true; + } else if (element instanceof ZLTextVideoElement) { + wordOccurred = true; + isVisible = true; } else if (isStyleChangeElement(element)) { applyStyleChangeElement(element); } @@ -1251,7 +1269,7 @@ public abstract class ZLTextView extends ZLTextViewBase { wordOccurred = false; --spaceCounter; } - } else if (element instanceof ZLTextWord || element instanceof ZLTextImageElement) { + } else if (element instanceof ZLTextWord || element instanceof ZLTextImageElement || element instanceof ZLTextVideoElement) { final int height = getElementHeight(element); final int descent = getElementDescent(element); final int length = element instanceof ZLTextWord ? ((ZLTextWord)element).Length : 0; diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java b/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java index 78ad22e32..cd136fad7 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java @@ -197,6 +197,8 @@ abstract class ZLTextViewBase extends ZLView { getScalingType(imageElement) ); return size != null ? size.Width : 0; + } else if (element instanceof ZLTextVideoElement) { + return 300; } else if (element == ZLTextElement.Indent) { return myTextStyle.getFirstLineIndentDelta(); } else if (element instanceof ZLTextFixedHSpaceElement) { @@ -217,6 +219,8 @@ abstract class ZLTextViewBase extends ZLView { ); return (size != null ? size.Height : 0) + Math.max(getContext().getStringHeight() * (myTextStyle.getLineSpacePercent() - 100) / 100, 3); + } else if (element instanceof ZLTextVideoElement) { + return 200; } return 0; }