mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-06 03:50:19 +02:00
embedded fonts processing (in progress)
This commit is contained in:
parent
06e46d4c33
commit
59639078ea
12 changed files with 209 additions and 84 deletions
|
@ -105,6 +105,7 @@ LOCAL_SRC_FILES := \
|
||||||
NativeFormats/fbreader/src/formats/css/StringInputStream.cpp \
|
NativeFormats/fbreader/src/formats/css/StringInputStream.cpp \
|
||||||
NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp \
|
NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp \
|
||||||
NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp \
|
NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp \
|
||||||
|
NativeFormats/fbreader/src/formats/css/StyleSheetUtil.cpp \
|
||||||
NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp \
|
NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp \
|
||||||
NativeFormats/fbreader/src/formats/html/HtmlDescriptionReader.cpp \
|
NativeFormats/fbreader/src/formats/html/HtmlDescriptionReader.cpp \
|
||||||
NativeFormats/fbreader/src/formats/html/HtmlEntityCollection.cpp \
|
NativeFormats/fbreader/src/formats/html/HtmlEntityCollection.cpp \
|
||||||
|
|
|
@ -39,6 +39,21 @@ void FontEntry::addFile(const std::string &weight, const std::string &style, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FontEntry::merge(const FontEntry &fontEntry) {
|
||||||
|
if (!fontEntry.Normal.isNull()) {
|
||||||
|
Normal = fontEntry.Normal;
|
||||||
|
}
|
||||||
|
if (!fontEntry.Bold.isNull()) {
|
||||||
|
Bold = fontEntry.Bold;
|
||||||
|
}
|
||||||
|
if (!fontEntry.Italic.isNull()) {
|
||||||
|
Italic = fontEntry.Italic;
|
||||||
|
}
|
||||||
|
if (!fontEntry.BoldItalic.isNull()) {
|
||||||
|
BoldItalic = fontEntry.BoldItalic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool compareStringPtrs(shared_ptr<std::string> str0, shared_ptr<std::string> str1) {
|
static bool compareStringPtrs(shared_ptr<std::string> str0, shared_ptr<std::string> str1) {
|
||||||
return str0.isNull() ? str1.isNull() : (!str1.isNull() && *str0 == *str1);
|
return str0.isNull() ? str1.isNull() : (!str1.isNull() && *str0 == *str1);
|
||||||
}
|
}
|
||||||
|
@ -55,16 +70,55 @@ bool FontEntry::operator != (const FontEntry &other) const {
|
||||||
return !operator ==(other);
|
return !operator ==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FontMap::operator == (const FontMap &other) const {
|
void FontMap::append(const std::string &family, const std::string &weight, const std::string &style, const std::string &path) {
|
||||||
return myMap == other.myMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FontMap::operator != (const FontMap &other) const {
|
|
||||||
return !operator ==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontMap::appendFontFace(const std::string &family, const std::string &weight, const std::string &style, const std::string &path) {
|
|
||||||
const ZLFile fontFile(path);
|
const ZLFile fontFile(path);
|
||||||
myMap[family].addFile(weight, style, fontFile.path());
|
shared_ptr<FontEntry> entry = myMap[family];
|
||||||
ZLLogger::Instance().println("FONT", family + " => " + fontFile.path());
|
if (entry.isNull()) {
|
||||||
|
entry = new FontEntry();
|
||||||
|
myMap[family] = entry;
|
||||||
|
}
|
||||||
|
entry->addFile(weight, style, fontFile.path());
|
||||||
|
ZLLogger::Instance().println("FONT", family + "," + weight + "," + style + " => " + fontFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontMap::merge(const FontMap &fontMap) {
|
||||||
|
for (std::map<std::string,shared_ptr<FontEntry> >::const_iterator it = fontMap.myMap.begin(); it != fontMap.myMap.end(); ++it) {
|
||||||
|
if (!it->second.isNull()) {
|
||||||
|
shared_ptr<FontEntry> entry = myMap[it->first];
|
||||||
|
if (entry.isNull()) {
|
||||||
|
entry = new FontEntry();
|
||||||
|
myMap[it->first] = entry;
|
||||||
|
}
|
||||||
|
entry->merge(*it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<FontEntry> FontMap::get(const std::string &family) {
|
||||||
|
return myMap[family];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FontMap::put(const std::string &family, shared_ptr<FontEntry> entry) {
|
||||||
|
shared_ptr<FontEntry> existing = myMap[family];
|
||||||
|
if (existing.isNull() || *existing == *entry) {
|
||||||
|
myMap[family] = entry;
|
||||||
|
return family;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string,shared_ptr<FontEntry> >::const_iterator it = myMap.begin(); it != myMap.end(); ++it) {
|
||||||
|
if (*it->second == *entry) {
|
||||||
|
return it->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < 1000; ++i) {
|
||||||
|
std::string indexed = family + "#";
|
||||||
|
ZLStringUtil::appendNumber(indexed, i);
|
||||||
|
if (myMap[indexed].isNull()) {
|
||||||
|
myMap[indexed] = entry;
|
||||||
|
return indexed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class FontEntry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void addFile(const std::string &weight, const std::string &style, const std::string &filePath);
|
void addFile(const std::string &weight, const std::string &style, const std::string &filePath);
|
||||||
|
void merge(const FontEntry &fontEntry);
|
||||||
|
|
||||||
bool operator == (const FontEntry &other) const;
|
bool operator == (const FontEntry &other) const;
|
||||||
bool operator != (const FontEntry &other) const;
|
bool operator != (const FontEntry &other) const;
|
||||||
|
@ -43,13 +44,13 @@ public:
|
||||||
class FontMap {
|
class FontMap {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator == (const FontMap &other) const;
|
void append(const std::string &family, const std::string &weight, const std::string &style, const std::string &path);
|
||||||
bool operator != (const FontMap &other) const;
|
void merge(const FontMap &fontMap);
|
||||||
|
std::string put(const std::string &family, shared_ptr<FontEntry> entry);
|
||||||
void appendFontFace(const std::string &family, const std::string &weight, const std::string &style, const std::string &path);
|
shared_ptr<FontEntry> get(const std::string &family);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string,FontEntry> myMap;
|
std::map<std::string,shared_ptr<FontEntry> > myMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __FONTMAP_H__ */
|
#endif /* __FONTMAP_H__ */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <ZLLogger.h>
|
#include <ZLLogger.h>
|
||||||
|
|
||||||
#include "StyleSheetParser.h"
|
#include "StyleSheetParser.h"
|
||||||
|
#include "StyleSheetUtil.h"
|
||||||
#include "StringInputStream.h"
|
#include "StringInputStream.h"
|
||||||
#include "CSSInputStream.h"
|
#include "CSSInputStream.h"
|
||||||
#include "../util/MiscUtil.h"
|
#include "../util/MiscUtil.h"
|
||||||
|
@ -125,10 +126,8 @@ std::string StyleSheetParser::url2FullPath(const std::string &url) const {
|
||||||
ZLStringUtil::stringEndsWith(path, ")")) {
|
ZLStringUtil::stringEndsWith(path, ")")) {
|
||||||
path = path.substr(4, path.size() - 5);
|
path = path.substr(4, path.size() - 5);
|
||||||
}
|
}
|
||||||
if (path.size() > 2 && path[0] == path[path.size() - 1]) {
|
if (path.size() > 1 && (path[0] == '"' || path[0] == '\'') && path[0] == path[path.size() - 1]) {
|
||||||
if (path[0] == '\'' || path[0] == '"') {
|
path = path.substr(1, path.size() - 2);
|
||||||
path = path.substr(1, path.size() - 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return myPathPrefix + MiscUtil::decodeHtmlURL(path);
|
return myPathPrefix + MiscUtil::decodeHtmlURL(path);
|
||||||
}
|
}
|
||||||
|
@ -221,8 +220,12 @@ void StyleSheetParser::processWord(const std::string &word) {
|
||||||
myMap[myAttributeName].clear();
|
myMap[myAttributeName].clear();
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_VALUE:
|
case ATTRIBUTE_VALUE:
|
||||||
myMap[myAttributeName] = word;
|
{
|
||||||
|
std::string stripped = word;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(stripped);
|
||||||
|
myMap[myAttributeName] = stripped;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +240,7 @@ shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseSingleEntry(const
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetMultiStyleParser::StyleSheetMultiStyleParser(const std::string &pathPrefix, FontMap &fontMap) : StyleSheetParser(pathPrefix), myFontMap(fontMap) {
|
StyleSheetMultiStyleParser::StyleSheetMultiStyleParser(const std::string &pathPrefix, shared_ptr<FontMap> fontMap) : StyleSheetParser(pathPrefix), myFontMap(fontMap.isNull() ? new FontMap() : fontMap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
|
||||||
|
@ -279,11 +282,13 @@ static std::string value(const StyleSheetTable::AttributeMap &map, const std::st
|
||||||
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
|
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
|
||||||
ZLLogger::Instance().registerClass("FONT");
|
ZLLogger::Instance().registerClass("FONT");
|
||||||
if (name == "@font-face") {
|
if (name == "@font-face") {
|
||||||
const std::string family = value(attributes, "font-family");
|
std::string family = value(attributes, "font-family");
|
||||||
if (family.empty()) {
|
if (family.empty()) {
|
||||||
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
|
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
family = StyleSheetUtil::strip(family);
|
||||||
|
|
||||||
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
||||||
std::string path;
|
std::string path;
|
||||||
if (it != attributes.end()) {
|
if (it != attributes.end()) {
|
||||||
|
@ -301,7 +306,8 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St
|
||||||
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
|
ZLLogger::Instance().println("FONT", "Source not specified for " + family);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
myFontMap.appendFontFace(
|
|
||||||
|
myFontMap->append(
|
||||||
family,
|
family,
|
||||||
value(attributes, "font-weight"),
|
value(attributes, "font-weight"),
|
||||||
value(attributes, "font-style"),
|
value(attributes, "font-style"),
|
||||||
|
@ -310,14 +316,14 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetTableParser::StyleSheetTableParser(const std::string &pathPrefix, StyleSheetTable &styleTable, FontMap &fontMap) : StyleSheetMultiStyleParser(pathPrefix, fontMap), myStyleTable(styleTable) {
|
StyleSheetTableParser::StyleSheetTableParser(const std::string &pathPrefix, StyleSheetTable &styleTable, shared_ptr<FontMap> fontMap) : StyleSheetMultiStyleParser(pathPrefix, fontMap), myStyleTable(styleTable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
myStyleTable.addMap(tag, aClass, map);
|
myStyleTable.addMap(tag, aClass, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetParserWithCache::StyleSheetParserWithCache(const ZLFile &file, const std::string &pathPrefix, FontMap &fontMap, shared_ptr<EncryptionMap> encryptionMap) : StyleSheetMultiStyleParser(pathPrefix, fontMap), myEncryptionMap(encryptionMap) {
|
StyleSheetParserWithCache::StyleSheetParserWithCache(const ZLFile &file, const std::string &pathPrefix, shared_ptr<FontMap> fontMap, shared_ptr<EncryptionMap> encryptionMap) : StyleSheetMultiStyleParser(pathPrefix, fontMap), myEncryptionMap(encryptionMap) {
|
||||||
myProcessedFiles.insert(file.path());
|
myProcessedFiles.insert(file.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,9 +350,10 @@ void StyleSheetParserWithCache::importCSS(const std::string &path) {
|
||||||
myProcessedFiles.insert(fileToImport.path());
|
myProcessedFiles.insert(fileToImport.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetParserWithCache::applyToTable(StyleSheetTable &table) const {
|
void StyleSheetParserWithCache::applyToTables(StyleSheetTable &table, FontMap &fontMap) const {
|
||||||
for (std::list<shared_ptr<Entry> >::const_iterator it = myEntries.begin(); it != myEntries.end(); ++it) {
|
for (std::list<shared_ptr<Entry> >::const_iterator it = myEntries.begin(); it != myEntries.end(); ++it) {
|
||||||
const Entry &entry = **it;
|
const Entry &entry = **it;
|
||||||
table.addMap(entry.Tag, entry.Class, entry.Map);
|
table.addMap(entry.Tag, entry.Class, entry.Map);
|
||||||
}
|
}
|
||||||
|
fontMap.merge(*myFontMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
class StyleSheetMultiStyleParser : public StyleSheetParser {
|
class StyleSheetMultiStyleParser : public StyleSheetParser {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StyleSheetMultiStyleParser(const std::string &pathPrefix, FontMap &map);
|
StyleSheetMultiStyleParser(const std::string &pathPrefix, shared_ptr<FontMap> myFontMap);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) = 0;
|
virtual void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) = 0;
|
||||||
|
@ -96,13 +96,13 @@ private:
|
||||||
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
|
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FontMap &myFontMap;
|
shared_ptr<FontMap> myFontMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
|
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StyleSheetTableParser(const std::string &pathPrexix, StyleSheetTable &styleTable, FontMap &fontMap);
|
StyleSheetTableParser(const std::string &pathPrexix, StyleSheetTable &styleTable, shared_ptr<FontMap> fontMap);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -123,8 +123,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StyleSheetParserWithCache(const ZLFile &file, const std::string &pathPrefix, FontMap &fontMap, shared_ptr<EncryptionMap> encryptionMap);
|
StyleSheetParserWithCache(const ZLFile &file, const std::string &pathPrefix, shared_ptr<FontMap> fontMap, shared_ptr<EncryptionMap> encryptionMap);
|
||||||
void applyToTable(StyleSheetTable &table) const;
|
void applyToTables(StyleSheetTable &table, FontMap &fontMap) const;
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <ZLStringUtil.h>
|
#include <ZLStringUtil.h>
|
||||||
|
|
||||||
#include "StyleSheetTable.h"
|
#include "StyleSheetTable.h"
|
||||||
|
#include "StyleSheetUtil.h"
|
||||||
|
|
||||||
bool StyleSheetTable::isEmpty() const {
|
bool StyleSheetTable::isEmpty() const {
|
||||||
return myControlMap.empty() && myPageBreakBeforeMap.empty() && myPageBreakAfterMap.empty();
|
return myControlMap.empty() && myPageBreakBeforeMap.empty() && myPageBreakAfterMap.empty();
|
||||||
|
@ -138,53 +139,6 @@ const std::string &StyleSheetTable::value(const AttributeMap &map, const std::st
|
||||||
return emptyString;
|
return emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string strip(const std::string &data) {
|
|
||||||
std::string res = data;
|
|
||||||
ZLStringUtil::stripWhiteSpaces(res);
|
|
||||||
if (res.size() > 1 && (res[0] == '"' || res[0] == '\'') && res[0] == res[res.size() - 1]) {
|
|
||||||
return res.substr(1, res.size() - 2);
|
|
||||||
} else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> splitCommaSeparatedList(const std::string &data) {
|
|
||||||
std::vector<std::string> split;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
S_QUOTED,
|
|
||||||
D_QUOTED,
|
|
||||||
NORMAL
|
|
||||||
} state = NORMAL;
|
|
||||||
|
|
||||||
std::size_t start = 0;
|
|
||||||
for (std::size_t i = 0; i < data.size(); ++i) {
|
|
||||||
const char ch = data[i];
|
|
||||||
switch (state) {
|
|
||||||
case NORMAL:
|
|
||||||
if (ch == ',') {
|
|
||||||
if (i > start) {
|
|
||||||
split.push_back(strip(data.substr(start, i - start)));
|
|
||||||
}
|
|
||||||
start = i + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case S_QUOTED:
|
|
||||||
if (ch == '\'') {
|
|
||||||
state = NORMAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case D_QUOTED:
|
|
||||||
if (ch == '"') {
|
|
||||||
state = NORMAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return split;
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &styles) {
|
shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &styles) {
|
||||||
shared_ptr<ZLTextStyleEntry> entry = new ZLTextStyleEntry(ZLTextStyleEntry::STYLE_CSS_ENTRY);
|
shared_ptr<ZLTextStyleEntry> entry = new ZLTextStyleEntry(ZLTextStyleEntry::STYLE_CSS_ENTRY);
|
||||||
|
|
||||||
|
@ -240,7 +194,7 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &
|
||||||
|
|
||||||
const std::string &fontFamily = value(styles, "font-family");
|
const std::string &fontFamily = value(styles, "font-family");
|
||||||
if (!fontFamily.empty()) {
|
if (!fontFamily.empty()) {
|
||||||
std::vector<std::string> families = splitCommaSeparatedList(fontFamily);
|
std::vector<std::string> families = StyleSheetUtil::splitCommaSeparatedList(fontFamily);
|
||||||
// TODO: use all families
|
// TODO: use all families
|
||||||
if (!families.empty()) {
|
if (!families.empty()) {
|
||||||
entry->setFontFamily(families[0]);
|
entry->setFontFamily(families[0]);
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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 <ZLStringUtil.h>
|
||||||
|
|
||||||
|
#include "StyleSheetUtil.h"
|
||||||
|
|
||||||
|
std::string StyleSheetUtil::strip(const std::string &data) {
|
||||||
|
std::string res = data;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(res);
|
||||||
|
if (res.size() > 1 && (res[0] == '"' || res[0] == '\'') && res[0] == res[res.size() - 1]) {
|
||||||
|
return res.substr(1, res.size() - 2);
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> StyleSheetUtil::splitCommaSeparatedList(const std::string &data) {
|
||||||
|
std::vector<std::string> split;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
S_QUOTED,
|
||||||
|
D_QUOTED,
|
||||||
|
NORMAL
|
||||||
|
} state = NORMAL;
|
||||||
|
|
||||||
|
std::size_t start = 0;
|
||||||
|
for (std::size_t i = 0; i < data.size(); ++i) {
|
||||||
|
const char ch = data[i];
|
||||||
|
switch (state) {
|
||||||
|
case NORMAL:
|
||||||
|
if (ch == ',') {
|
||||||
|
if (i > start) {
|
||||||
|
split.push_back(strip(data.substr(start, i - start)));
|
||||||
|
}
|
||||||
|
start = i + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_QUOTED:
|
||||||
|
if (ch == '\'') {
|
||||||
|
state = NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case D_QUOTED:
|
||||||
|
if (ch == '"') {
|
||||||
|
state = NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return split;
|
||||||
|
}
|
30
jni/NativeFormats/fbreader/src/formats/css/StyleSheetUtil.h
Normal file
30
jni/NativeFormats/fbreader/src/formats/css/StyleSheetUtil.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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 __STYLESHEETUTIL_H__
|
||||||
|
#define __STYLESHEETUTIL_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct StyleSheetUtil {
|
||||||
|
static std::string strip(const std::string &data);
|
||||||
|
static std::vector<std::string> splitCommaSeparatedList(const std::string &data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __STYLESHEETUTIL_H__ */
|
|
@ -396,6 +396,7 @@ void HtmlBookReader::setProcessPreTag(bool process) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlBookReader::HtmlBookReader(const std::string &baseDirectoryPath, BookModel &model, const PlainTextFormat &format, const std::string &encoding) : HtmlReader(encoding), myBookReader(model), myBaseDirPath(baseDirectoryPath), myFormat(format), myBuildTableOfContent(true), myProcessPreTag(true) {
|
HtmlBookReader::HtmlBookReader(const std::string &baseDirectoryPath, BookModel &model, const PlainTextFormat &format, const std::string &encoding) : HtmlReader(encoding), myBookReader(model), myBaseDirPath(baseDirectoryPath), myFormat(format), myBuildTableOfContent(true), myProcessPreTag(true) {
|
||||||
|
myFontMap = new FontMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlBookReader::~HtmlBookReader() {
|
HtmlBookReader::~HtmlBookReader() {
|
||||||
|
|
|
@ -75,7 +75,7 @@ private:
|
||||||
|
|
||||||
StyleSheetTable myStyleSheetTable;
|
StyleSheetTable myStyleSheetTable;
|
||||||
shared_ptr<StyleSheetParser> myStyleSheetParser;
|
shared_ptr<StyleSheetParser> myStyleSheetParser;
|
||||||
FontMap myFontMap;
|
shared_ptr<FontMap> myFontMap;
|
||||||
|
|
||||||
int mySpaceCounter;
|
int mySpaceCounter;
|
||||||
int myBreakCounter;
|
int myBreakCounter;
|
||||||
|
|
|
@ -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.myPathPrefix, reader.myStyleSheetTable, *reader.myFontMap);
|
reader.myTableParser = new StyleSheetTableParser(reader.myPathPrefix, reader.myStyleSheetTable, reader.myFontMap);
|
||||||
ZLLogger::Instance().println("CSS", "parsing style tag content");
|
ZLLogger::Instance().println("CSS", "parsing style tag content");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
||||||
parser = new StyleSheetParserWithCache(
|
parser = new StyleSheetParserWithCache(
|
||||||
cssFile,
|
cssFile,
|
||||||
MiscUtil::htmlDirectoryPrefix(cssFilePath),
|
MiscUtil::htmlDirectoryPrefix(cssFilePath),
|
||||||
*reader.myFontMap,
|
0,
|
||||||
reader.myEncryptionMap
|
reader.myEncryptionMap
|
||||||
);
|
);
|
||||||
reader.myFileParsers[cssFilePath] = parser;
|
reader.myFileParsers[cssFilePath] = parser;
|
||||||
|
@ -280,7 +280,7 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
||||||
parser->parseStream(cssStream);
|
parser->parseStream(cssStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parser->applyToTable(reader.myStyleSheetTable);
|
parser->applyToTables(reader.myStyleSheetTable, *reader.myFontMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
||||||
|
@ -673,6 +673,13 @@ bool XHTMLReader::addTextStyleEntry(const std::string tag, const std::string aCl
|
||||||
void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) {
|
void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) {
|
||||||
if (entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) {
|
if (entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) {
|
||||||
ZLLogger::Instance().println("FONT", "Requested font family: " + entry.fontFamily());
|
ZLLogger::Instance().println("FONT", "Requested font family: " + entry.fontFamily());
|
||||||
|
shared_ptr<FontEntry> fontEntry = myFontMap->get(entry.fontFamily());
|
||||||
|
if (fontEntry.isNull()) {
|
||||||
|
ZLLogger::Instance().println("FONT", "Font entry not found for " + entry.fontFamily());
|
||||||
|
} else {
|
||||||
|
const std::string realFamily = myFinalFontMap.put(entry.fontFamily(), fontEntry);
|
||||||
|
ZLLogger::Instance().println("FONT", "Entry for " + entry.fontFamily() + " stored as " + realFamily);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
myModelReader.addStyleEntry(entry);
|
myModelReader.addStyleEntry(entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ private:
|
||||||
bool myNewParagraphInProgress;
|
bool myNewParagraphInProgress;
|
||||||
StyleSheetTable myStyleSheetTable;
|
StyleSheetTable myStyleSheetTable;
|
||||||
shared_ptr<FontMap> myFontMap;
|
shared_ptr<FontMap> myFontMap;
|
||||||
|
FontMap myFinalFontMap;
|
||||||
std::vector<int> myCSSStack;
|
std::vector<int> myCSSStack;
|
||||||
std::vector<shared_ptr<ZLTextStyleEntry> > myStyleEntryStack;
|
std::vector<shared_ptr<ZLTextStyleEntry> > myStyleEntryStack;
|
||||||
int myStylesToRemove;
|
int myStylesToRemove;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue