mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Rendering book: Convert font sizes expressed in absolute units to rem
Also convert page-break-* properties to their CSS 3 and webkit equivalents to avoid having to do that work on the client
This commit is contained in:
parent
c403d8aa88
commit
cfbec65804
@ -83,7 +83,15 @@ class StyleDeclaration(object):
|
|||||||
if props:
|
if props:
|
||||||
self.changed = True
|
self.changed = True
|
||||||
for prop in props:
|
for prop in props:
|
||||||
self.css_declaration.setProperty(Property(prop.name, prop.value, prop.literalpriority, self.css_declaration))
|
self.css_declaration.setProperty(Property(prop.name, prop.value, prop.literalpriority, parent=self.css_declaration))
|
||||||
|
|
||||||
|
def set_property(self, name, value, priority='', replace=True):
|
||||||
|
# Note that this does not handle shorthand properties, so you must
|
||||||
|
# call remove_property() yourself in that case
|
||||||
|
self.changed = True
|
||||||
|
if replace:
|
||||||
|
self.css_declaration.removeProperty(name)
|
||||||
|
self.css_declaration.setProperty(Property(name, value, priority, parent=self.css_declaration))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return force_unicode(self.css_declaration.cssText, 'utf-8')
|
return force_unicode(self.css_declaration.cssText, 'utf-8')
|
||||||
|
@ -14,12 +14,16 @@ from urlparse import urlparse
|
|||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
from cssutils import replaceUrls
|
from cssutils import replaceUrls
|
||||||
|
from cssutils.css import CSSRule
|
||||||
|
|
||||||
|
from calibre.ebooks import parse_css_length
|
||||||
from calibre.ebooks.oeb.base import (
|
from calibre.ebooks.oeb.base import (
|
||||||
OEB_DOCS, OEB_STYLES, rewrite_links, XPath, urlunquote, XLINK, XHTML_NS, OPF, XHTML, EPUB_NS)
|
OEB_DOCS, OEB_STYLES, rewrite_links, XPath, urlunquote, XLINK, XHTML_NS, OPF, XHTML, EPUB_NS)
|
||||||
from calibre.ebooks.oeb.iterator.book import extract_book
|
from calibre.ebooks.oeb.iterator.book import extract_book
|
||||||
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
||||||
from calibre.ebooks.oeb.polish.cover import set_epub_cover, find_cover_image
|
from calibre.ebooks.oeb.polish.cover import set_epub_cover, find_cover_image
|
||||||
|
from calibre.ebooks.oeb.polish.css import transform_css
|
||||||
|
from calibre.ebooks.css_transform_rules import StyleDeclaration
|
||||||
from calibre.ebooks.oeb.polish.toc import get_toc
|
from calibre.ebooks.oeb.polish.toc import get_toc
|
||||||
from calibre.ebooks.oeb.polish.utils import guess_type
|
from calibre.ebooks.oeb.polish.utils import guess_type
|
||||||
from calibre.utils.short_uuid import uuid4
|
from calibre.utils.short_uuid import uuid4
|
||||||
@ -45,6 +49,44 @@ def decode_url(x):
|
|||||||
parts = x.split('#', 1)
|
parts = x.split('#', 1)
|
||||||
return decode_component(parts[0]), (parts[1] if len(parts) > 1 else '')
|
return decode_component(parts[0]), (parts[1] if len(parts) > 1 else '')
|
||||||
|
|
||||||
|
absolute_units = frozenset('px mm cm pt in pc q'.split())
|
||||||
|
length_factors = {'mm':2.8346456693, 'cm':28.346456693, 'in': 72, 'pc': 12, 'q':0.708661417325}
|
||||||
|
|
||||||
|
def convert_fontsize(length, unit, base_font_size=16.0, dpi=96.0):
|
||||||
|
' Convert font size to rem so that font size scaling works. Assumes the document has the specified base font size in px '
|
||||||
|
if unit == 'px':
|
||||||
|
return length/base_font_size
|
||||||
|
pt_to_px = dpi / 72.0
|
||||||
|
pt_to_rem = pt_to_px / base_font_size
|
||||||
|
return length * length_factors.get(unit, 1) * pt_to_rem
|
||||||
|
|
||||||
|
def transform_declaration(decl):
|
||||||
|
decl = StyleDeclaration(decl)
|
||||||
|
changed = False
|
||||||
|
for prop, parent_prop in tuple(decl):
|
||||||
|
if prop.name in {'page-break-before', 'page-break-after', 'page-break-inside'}:
|
||||||
|
changed = True
|
||||||
|
name = prop.name.partition('-')[2]
|
||||||
|
for prefix in ('', '-webkit-column-'):
|
||||||
|
# Note that Firefox does not support break-after at all
|
||||||
|
# https://bugzil.la/549114
|
||||||
|
decl.set_property(prefix + name, prop.value, prop.priority)
|
||||||
|
decl.remove_property(prop, parent_prop)
|
||||||
|
elif prop.name == 'font-size':
|
||||||
|
l, unit = parse_css_length(prop.value)
|
||||||
|
if unit in absolute_units:
|
||||||
|
changed = True
|
||||||
|
l = convert_fontsize(l, unit)
|
||||||
|
decl.change_property(prop, parent_prop, str(l) + 'rem')
|
||||||
|
return changed
|
||||||
|
|
||||||
|
def transform_sheet(sheet):
|
||||||
|
changed = False
|
||||||
|
for rule in sheet.cssRules.rulesOfType(CSSRule.STYLE_RULE):
|
||||||
|
if transform_declaration(rule.style):
|
||||||
|
changed = True
|
||||||
|
return changed
|
||||||
|
|
||||||
class Container(ContainerBase):
|
class Container(ContainerBase):
|
||||||
|
|
||||||
tweak_mode = True
|
tweak_mode = True
|
||||||
@ -73,6 +115,7 @@ class Container(ContainerBase):
|
|||||||
# Mark the spine as dirty since we have to ensure it is normalized
|
# Mark the spine as dirty since we have to ensure it is normalized
|
||||||
for name in data['spine']:
|
for name in data['spine']:
|
||||||
self.parsed(name), self.dirty(name)
|
self.parsed(name), self.dirty(name)
|
||||||
|
self.transform_css()
|
||||||
self.virtualized_names = set()
|
self.virtualized_names = set()
|
||||||
self.virtualize_resources()
|
self.virtualize_resources()
|
||||||
def manifest_data(name):
|
def manifest_data(name):
|
||||||
@ -115,6 +158,9 @@ class Container(ContainerBase):
|
|||||||
self.dirty(self.opf_name)
|
self.dirty(self.opf_name)
|
||||||
return raster_cover_name, titlepage_name
|
return raster_cover_name, titlepage_name
|
||||||
|
|
||||||
|
def transform_css(self):
|
||||||
|
transform_css(self, transform_sheet=transform_sheet, transform_style=transform_declaration)
|
||||||
|
|
||||||
def virtualize_resources(self):
|
def virtualize_resources(self):
|
||||||
|
|
||||||
changed = set()
|
changed = set()
|
||||||
@ -314,4 +360,4 @@ def render(pathtoebook, output_dir, book_hash=None):
|
|||||||
Container(pathtoebook, output_dir, book_hash=book_hash)
|
Container(pathtoebook, output_dir, book_hash=book_hash)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
c = Container(sys.argv[-2], sys.argv[-1])
|
render(sys.argv[-2], sys.argv[-1])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user