mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-03 17:59:33 +02:00
ePub embedded fonts support (in progress)
This commit is contained in:
parent
2f5e28d325
commit
8e925ef8d7
6 changed files with 85 additions and 13 deletions
|
@ -20,13 +20,15 @@
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <ZLStringUtil.h>
|
#include <ZLFile.h>
|
||||||
#include <ZLInputStream.h>
|
#include <ZLInputStream.h>
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
#include <ZLLogger.h>
|
#include <ZLLogger.h>
|
||||||
|
|
||||||
#include "StyleSheetParser.h"
|
#include "StyleSheetParser.h"
|
||||||
|
#include "../util/MiscUtil.h"
|
||||||
|
|
||||||
StyleSheetParser::StyleSheetParser() {
|
StyleSheetParser::StyleSheetParser(const std::string &pathPrefix) : myPathPrefix(pathPrefix) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +181,9 @@ void StyleSheetParser::processWordWithoutComments(const std::string &word) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyleSheetSingleStyleParser::StyleSheetSingleStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
|
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
|
||||||
myReadState = WAITING_FOR_ATTRIBUTE;
|
myReadState = WAITING_FOR_ATTRIBUTE;
|
||||||
parse(text, std::strlen(text), true);
|
parse(text, std::strlen(text), true);
|
||||||
|
@ -187,6 +192,9 @@ shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyleSheetMultiStyleParser::StyleSheetMultiStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
|
||||||
|
}
|
||||||
|
|
||||||
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
||||||
std::string s = selector;
|
std::string s = selector;
|
||||||
ZLStringUtil::stripWhiteSpaces(s);
|
ZLStringUtil::stripWhiteSpaces(s);
|
||||||
|
@ -215,8 +223,46 @@ void StyleSheetMultiStyleParser::storeData(const std::string &selector, const St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap&) {
|
static std::string firstValue(const StyleSheetTable::AttributeMap &map, const std::string &key) {
|
||||||
|
const StyleSheetTable::AttributeMap::const_iterator it = map.find(key);
|
||||||
|
if (it == map.end() || it->second.empty()) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
return it->second[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
|
||||||
|
ZLLogger::Instance().registerClass("FONT");
|
||||||
if (name == "@font-face") {
|
if (name == "@font-face") {
|
||||||
|
const std::string family = firstValue(attributes, "font-family");
|
||||||
|
if (family.empty()) {
|
||||||
|
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
||||||
|
std::string url;
|
||||||
|
if (it != attributes.end()) {
|
||||||
|
for (std::vector<std::string>::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
|
||||||
|
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
|
||||||
|
ZLStringUtil::stringEndsWith(*jt, ")")) {
|
||||||
|
url = jt->substr(4, jt->size() - 5);
|
||||||
|
if (url.size() > 2 && url[0] == url[url.size() - 1]) {
|
||||||
|
if (url[0] == '\'' || url[0] == '"') {
|
||||||
|
url = url.substr(1, url.size() - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url.empty()) {
|
||||||
|
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ZLFile fontFile(myPathPrefix + MiscUtil::decodeHtmlURL(url));
|
||||||
|
const bool bold = firstValue(attributes, "font-weight") == "bold";
|
||||||
|
const bool italic = firstValue(attributes, "font-style") == "italic";
|
||||||
|
ZLLogger::Instance().println("FONT", family + " => " + fontFile.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,13 +281,16 @@ void StyleSheetMultiStyleParser::parseStream(ZLInputStream &stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
|
StyleSheetTableParser::StyleSheetTableParser(const std::string &pathPrefix, StyleSheetTable &table) : StyleSheetMultiStyleParser(pathPrefix), myTable(table) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
||||||
myTable.addMap(tag, aClass, map);
|
myTable.addMap(tag, aClass, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyleSheetParserWithCache::StyleSheetParserWithCache(const std::string &pathPrefix) : StyleSheetMultiStyleParser(pathPrefix) {
|
||||||
|
}
|
||||||
|
|
||||||
void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
|
||||||
myEntries.push_back(new Entry(tag, aClass, map));
|
myEntries.push_back(new Entry(tag, aClass, map));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class ZLInputStream;
|
||||||
class StyleSheetParser {
|
class StyleSheetParser {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StyleSheetParser();
|
StyleSheetParser(const std::string &pathPrefix);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~StyleSheetParser();
|
virtual ~StyleSheetParser();
|
||||||
|
@ -45,6 +45,9 @@ private:
|
||||||
void processWordWithoutComments(const std::string &word);
|
void processWordWithoutComments(const std::string &word);
|
||||||
void processControl(const char control);
|
void processControl(const char control);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const std::string myPathPrefix;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string myWord;
|
std::string myWord;
|
||||||
std::string myAttributeName;
|
std::string myAttributeName;
|
||||||
|
@ -65,11 +68,15 @@ friend class StyleSheetSingleStyleParser;
|
||||||
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
class StyleSheetSingleStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
StyleSheetSingleStyleParser(const std::string &pathPrefix);
|
||||||
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
|
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
|
||||||
};
|
};
|
||||||
|
|
||||||
class StyleSheetMultiStyleParser : public StyleSheetParser {
|
class StyleSheetMultiStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
StyleSheetMultiStyleParser(const std::string &pathPrefix);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void parseStream(ZLInputStream &stream);
|
void parseStream(ZLInputStream &stream);
|
||||||
|
|
||||||
|
@ -84,7 +91,7 @@ private:
|
||||||
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
|
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StyleSheetTableParser(StyleSheetTable &table);
|
StyleSheetTableParser(const std::string &pathPrexix, StyleSheetTable &table);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
|
||||||
|
@ -105,6 +112,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
StyleSheetParserWithCache(const std::string &pathPrefix);
|
||||||
void applyToTable(StyleSheetTable &table) const;
|
void applyToTable(StyleSheetTable &table) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -274,7 +274,7 @@ HtmlStyleTagAction::HtmlStyleTagAction(HtmlBookReader &reader) : HtmlTagAction(r
|
||||||
}
|
}
|
||||||
|
|
||||||
void HtmlStyleTagAction::run(const HtmlReader::HtmlTag &tag) {
|
void HtmlStyleTagAction::run(const HtmlReader::HtmlTag &tag) {
|
||||||
myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myStyleSheetTable) : 0;
|
myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myBaseDirPath, myReader.myStyleSheetTable) : 0;
|
||||||
/*
|
/*
|
||||||
if (!tag.Start) {
|
if (!tag.Start) {
|
||||||
myReader.myStyleSheetTable.dump();
|
myReader.myStyleSheetTable.dump();
|
||||||
|
|
|
@ -229,7 +229,7 @@ void XHTMLTagStyleAction::doAtStart(XHTMLReader &reader, const char **xmlattribu
|
||||||
|
|
||||||
if (reader.myReadState == XHTML_READ_NOTHING) {
|
if (reader.myReadState == XHTML_READ_NOTHING) {
|
||||||
reader.myReadState = XHTML_READ_STYLE;
|
reader.myReadState = XHTML_READ_STYLE;
|
||||||
reader.myTableParser = new StyleSheetTableParser(reader.myStyleSheetTable);
|
reader.myTableParser = new StyleSheetTableParser(reader.myPathPrefix, reader.myStyleSheetTable);
|
||||||
ZLLogger::Instance().println("CSS", "parsing style tag content");
|
ZLLogger::Instance().println("CSS", "parsing style tag content");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,14 +259,15 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
|
std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
|
||||||
//ZLLogger::Instance().registerClass("CSS");
|
//ZLLogger::Instance().registerClass("CSS");
|
||||||
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
|
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
|
||||||
const ZLFile cssFile(cssFilePath);
|
const ZLFile cssFile(cssFilePath);
|
||||||
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFile.path()];
|
cssFilePath = cssFile.path();
|
||||||
|
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFilePath];
|
||||||
if (parser.isNull()) {
|
if (parser.isNull()) {
|
||||||
parser = new StyleSheetParserWithCache();
|
parser = new StyleSheetParserWithCache(MiscUtil::htmlDirectoryPrefix(cssFilePath));
|
||||||
reader.myFileParsers[cssFile.path()] = parser;
|
reader.myFileParsers[cssFilePath] = parser;
|
||||||
ZLLogger::Instance().println("CSS", "creating stream");
|
ZLLogger::Instance().println("CSS", "creating stream");
|
||||||
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
|
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
|
||||||
if (!cssStream.isNull()) {
|
if (!cssStream.isNull()) {
|
||||||
|
@ -639,7 +640,7 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName)
|
||||||
myStylesToRemove = 0;
|
myStylesToRemove = 0;
|
||||||
|
|
||||||
myDoPageBreakAfterStack.clear();
|
myDoPageBreakAfterStack.clear();
|
||||||
myStyleParser = new StyleSheetSingleStyleParser();
|
myStyleParser = new StyleSheetSingleStyleParser(myPathPrefix);
|
||||||
myTableParser.reset();
|
myTableParser.reset();
|
||||||
|
|
||||||
return readDocument(file.inputStream(myEncryptionMap));
|
return readDocument(file.inputStream(myEncryptionMap));
|
||||||
|
|
|
@ -103,6 +103,19 @@ std::vector<std::string> ZLStringUtil::split(const std::string &str, const std::
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ZLStringUtil::join(const std::vector<std::string> &data, const std::string &delimiter) {
|
||||||
|
std::string joined;
|
||||||
|
bool addDelimiter = false;
|
||||||
|
for (std::vector<std::string>::const_iterator it = data.begin(); it != data.end(); ++it) {
|
||||||
|
if (addDelimiter) {
|
||||||
|
joined += delimiter;
|
||||||
|
}
|
||||||
|
joined += *it;
|
||||||
|
addDelimiter = true;
|
||||||
|
}
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ZLStringUtil::printf(const std::string &format, const std::string &arg0) {
|
std::string ZLStringUtil::printf(const std::string &format, const std::string &arg0) {
|
||||||
int index = format.find("%s");
|
int index = format.find("%s");
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
static void stripWhiteSpaces(std::string &str);
|
static void stripWhiteSpaces(std::string &str);
|
||||||
|
|
||||||
static std::vector<std::string> split(const std::string &str, const std::string &delimiter);
|
static std::vector<std::string> split(const std::string &str, const std::string &delimiter);
|
||||||
|
static std::string join(const std::vector<std::string> &data, const std::string &delimiter);
|
||||||
|
|
||||||
static std::string printf(const std::string &format, const std::string &arg0);
|
static std::string printf(const std::string &format, const std::string &arg0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue