1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 18:29:23 +02:00

<video> ePub3 support (in progress)

This commit is contained in:
Nikolay Pultsin 2014-03-08 17:50:20 +00:00
parent cf2683079d
commit e14011b7bb
18 changed files with 363 additions and 33 deletions

View file

@ -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 \

View file

@ -25,6 +25,7 @@
#include <ZLLogger.h>
#include <ZLCachedMemoryAllocator.h>
#include <ZLTextStyleEntry.h>
#include <ZLVideoEntry.h>
#include "BookReader.h"
#include "BookModel.h"
@ -230,6 +231,16 @@ void BookReader::addImage(const std::string &id, shared_ptr<const ZLImage> 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();

View file

@ -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<const ZLImage> image);
void addVideoEntry(const ZLVideoEntry &entry);
void beginContentsParagraph(int referenceNumber = -1);
void endContentsParagraph();
bool contentsParagraphIsOpen() const;

View file

@ -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<ZLXMLReader::NamePredicate> 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<FBTextKind> 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<ZLXMLReader::NamePredicate> 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();

View file

@ -25,6 +25,7 @@
#include <vector>
#include <ZLXMLReader.h>
#include <ZLVideoEntry.h>
#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<StyleSheetSingleStyleParser> myStyleParser;
shared_ptr<StyleSheetTableParser> myTableParser;
enum {
READ_NOTHING,
READ_STYLE,
READ_BODY
} myReadState;
XHTMLReadingState myReadState;
int myBodyCounter;
bool myMarkNextImageAsCover;
shared_ptr<ZLVideoEntry> 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__ */

View file

@ -26,11 +26,12 @@
//#include <ZLLanguageUtil.h>
#include <ZLUnicodeUtil.h>
//#include <ZLStringUtil.h>
//#include <ZLLogger.h>
#include <ZLLogger.h>
#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<std::string,std::string> &sources = entry.sources();
std::size_t len = 4;
for (std::map<std::string,std::string>::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<std::string,std::string>::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();
}

View file

@ -33,6 +33,7 @@
#include <ZLCachedMemoryAllocator.h>
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();

View file

@ -46,6 +46,8 @@ public:
STYLE_CLOSE_ENTRY = 7,
FIXED_HSPACE_ENTRY = 8,
RESET_BIDI_ENTRY = 9,
AUDIO_ENTRY = 10,
VIDEO_ENTRY = 11,
};
protected:

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2004-2014 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 "ZLVideoEntry.h"
void ZLVideoEntry::addSource(const std::string &type, const std::string &path) {
mySources.insert(std::make_pair(type, path));
}
const std::map<std::string,std::string> &ZLVideoEntry::sources() const {
return mySources;
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2004-2014 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 __ZLVIDEOENTRY_H__
#define __ZLVIDEOENTRY_H__
#include <map>
#include <string>
#include <ZLTextParagraph.h>
class ZLVideoEntry : public ZLTextParagraphEntry {
public:
void addSource(const std::string &type, const std::string &path);
const std::map<std::string,std::string> &sources() const;
private:
std::map<std::string,std::string> mySources;
};
#endif /* __ZLVIDEOENTRY_H__ */

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2007-2014 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.
*/
package org.geometerplus.zlibrary.text.model;
import java.util.Map;
import java.util.HashMap;
public class ZLVideoEntry {
private final Map<String,String> mySources = new HashMap<String,String>();
public void addSource(String mime, String path) {
mySources.put(mime, path);
}
public Map<String,String> sources() {
return mySources;
}
}

View file

@ -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<String,String> 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()));

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2007-2014 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.
*/
package org.geometerplus.zlibrary.text.view;
import java.util.Map;
public final class ZLTextVideoElement extends ZLTextElement {
public final Map<String,String> Sources;
ZLTextVideoElement(Map<String,String> sources) {
Sources = sources;
}
}

View file

@ -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;

View file

@ -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;
}