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:
|
||||
self.changed = True
|
||||
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):
|
||||
return force_unicode(self.css_declaration.cssText, 'utf-8')
|
||||
|
@ -14,12 +14,16 @@ from urlparse import urlparse
|
||||
from urllib import quote
|
||||
|
||||
from cssutils import replaceUrls
|
||||
from cssutils.css import CSSRule
|
||||
|
||||
from calibre.ebooks import parse_css_length
|
||||
from calibre.ebooks.oeb.base import (
|
||||
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.polish.container import Container as ContainerBase
|
||||
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.utils import guess_type
|
||||
from calibre.utils.short_uuid import uuid4
|
||||
@ -45,6 +49,44 @@ def decode_url(x):
|
||||
parts = x.split('#', 1)
|
||||
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):
|
||||
|
||||
tweak_mode = True
|
||||
@ -73,6 +115,7 @@ class Container(ContainerBase):
|
||||
# Mark the spine as dirty since we have to ensure it is normalized
|
||||
for name in data['spine']:
|
||||
self.parsed(name), self.dirty(name)
|
||||
self.transform_css()
|
||||
self.virtualized_names = set()
|
||||
self.virtualize_resources()
|
||||
def manifest_data(name):
|
||||
@ -115,6 +158,9 @@ class Container(ContainerBase):
|
||||
self.dirty(self.opf_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):
|
||||
|
||||
changed = set()
|
||||
@ -314,4 +360,4 @@ def render(pathtoebook, output_dir, book_hash=None):
|
||||
Container(pathtoebook, output_dir, book_hash=book_hash)
|
||||
|
||||
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