From 29ecca2c11915101b27b10675650e703d70fc878 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 15 Nov 2007 01:14:57 +0000 Subject: [PATCH] Fix #282. Implement the --base-font-size option --- src/libprs500/ebooks/lrf/__init__.py | 13 +++-- src/libprs500/ebooks/lrf/html/convert_from.py | 4 ++ src/libprs500/ebooks/lrf/pylrs/pylrs.py | 49 ++++++++++++++++++- src/libprs500/gui2/dialogs/lrf_single.ui | 13 +++-- src/libprs500/gui2/lrf_renderer/main.py | 4 +- src/libprs500/gui2/lrf_renderer/main.ui | 2 +- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/libprs500/ebooks/lrf/__init__.py b/src/libprs500/ebooks/lrf/__init__.py index 7823e2a1e7..64be956f9e 100644 --- a/src/libprs500/ebooks/lrf/__init__.py +++ b/src/libprs500/ebooks/lrf/__init__.py @@ -114,11 +114,8 @@ def option_parser(usage): parser.add_option('--ignore-tables', action='store_true', default=False, dest='ignore_tables', help=_('Render HTML tables as blocks of text instead of actual tables. This is neccessary if the HTML contains very large or complex tables.')) laf = parser.add_option_group('LOOK AND FEEL') - laf.add_option('--font-delta', action='store', type='float', default=0., \ - help=_("""Increase the font size by 2 * FONT_DELTA pts and """ - '''the line spacing by FONT_DELTA pts. FONT_DELTA can be a fraction.''' - """If FONT_DELTA is negative, the font size is decreased."""), - dest='font_delta') + laf.add_option('--base-font-size', action='store', type='float', default=10., + help=_('''Specify the base font size in pts. All fonts are rescaled accordingly. This option obsoletes the --font-delta option and takes precendence over it. To use --font-delta, set this to 0.''')) laf.add_option('--enable-autorotation', action='store_true', default=False, help=_('Enable autorotation of images that are wider than the screen width.'), dest='autorotation') @@ -134,6 +131,12 @@ def option_parser(usage): help=_('Override the CSS. Can be either a path to a CSS stylesheet or a string. If it is a string it is interpreted as CSS.')) laf.add_option('--use-spine', default=False, dest='use_spine', action='store_true', help=_('Use the element from the OPF file to determine the order in which the HTML files are appended to the LRF. The .opf file must be in the same directory as the base HTML file.')) + laf.add_option('--font-delta', action='store', type='float', default=0., \ + help=_("""Increase the font size by 2 * FONT_DELTA pts and """ + '''the line spacing by FONT_DELTA pts. FONT_DELTA can be a fraction.''' + """If FONT_DELTA is negative, the font size is decreased."""), + dest='font_delta') + page = parser.add_option_group('PAGE OPTIONS') profiles = profile_map.keys() diff --git a/src/libprs500/ebooks/lrf/html/convert_from.py b/src/libprs500/ebooks/lrf/html/convert_from.py index 5fcdbad15e..78f478b3d7 100644 --- a/src/libprs500/ebooks/lrf/html/convert_from.py +++ b/src/libprs500/ebooks/lrf/html/convert_from.py @@ -263,6 +263,10 @@ class HTMLConverter(object): for text, tb in self.extra_toc_entries: ascii_text = text.encode('ascii', 'ignore') self.book.addTocEntry(ascii_text, tb) + + if self.base_font_size > 0: + self.logger.info('\tRationalizing font sizes...') + self.book.rationalize_font_sizes(self.base_font_size) def is_baen(self, soup): return bool(soup.find('meta', attrs={'name':'Publisher', diff --git a/src/libprs500/ebooks/lrf/pylrs/pylrs.py b/src/libprs500/ebooks/lrf/pylrs/pylrs.py index ea8c358d33..fc975e1967 100644 --- a/src/libprs500/ebooks/lrf/pylrs/pylrs.py +++ b/src/libprs500/ebooks/lrf/pylrs/pylrs.py @@ -36,7 +36,7 @@ # Plot, Image (outside of ImageBlock), # EmpLine, EmpDots -import os, re, codecs +import os, re, codecs, operator from datetime import date try: from elementtree.ElementTree import (Element, SubElement) @@ -310,6 +310,14 @@ class LrsContainer(object): self.contents.append(content) return self + + def get_all(self, predicate=lambda x: x): + for child in self.contents: + if predicate(child): + yield child + if hasattr(child, 'get_all'): + for grandchild in child.get_all(predicate): + yield grandchild @@ -532,7 +540,44 @@ class Book(Delegator): method(content) - + + def rationalize_font_sizes(self, base_font_size=10): + base_font_size *= 10. + main = None + for obj in self.delegates: + if isinstance(obj, Main): + main = obj + break + pages = [obj for obj in main.contents if isinstance(obj, Page)] + text_blocks = [] + for p in pages: + for obj in p.contents: + if isinstance(obj, TextBlock): + text_blocks.append(obj) + + text_styles = set([t.textStyle for t in text_blocks]) + fonts = {} + for ts in text_styles: + fs = int(ts.attrs['fontsize']) + if fonts.has_key(fs): + fonts[fs] += 1 + else: + fonts[fs] = 1 + + old_base_font_size = float(max(zip(fonts.keys(), fonts.values()), key=operator.itemgetter(1))[0]) + + def rescale(old): + return str(int(int(old) * (base_font_size/old_base_font_size))) + + for ts in text_styles: + ts.attrs['fontsize'] = rescale(ts.attrs['fontsize']) + + for tb in text_blocks: + if tb.textSettings.has_key('fontsize'): + tb.textSettings['fontsize'] = rescale(tb.textSettings['fontsize']) + for span in tb.get_all(lambda x: isinstance(x, Span) and x.attrs.has_key('fontsize')): + span.attrs['fontsize'] = rescale(span.attrs['fontsize']) + def renderLrs(self, lrsFile): if isinstance(lrsFile, basestring): lrsFile = codecs.open(lrsFile, "wb", encoding="utf-16") diff --git a/src/libprs500/gui2/dialogs/lrf_single.ui b/src/libprs500/gui2/dialogs/lrf_single.ui index 4f6510d3de..fe2d8f127f 100644 --- a/src/libprs500/gui2/dialogs/lrf_single.ui +++ b/src/libprs500/gui2/dialogs/lrf_single.ui @@ -472,15 +472,15 @@ - &Font delta: + Base &font size: - gui_font_delta + gui_base_font_size - + QAbstractSpinBox::PlusMinus @@ -491,14 +491,17 @@ 1 - -5.000000000000000 + 2.000000000000000 - 5.000000000000000 + 20.000000000000000 0.100000000000000 + + 10.000000000000000 + diff --git a/src/libprs500/gui2/lrf_renderer/main.py b/src/libprs500/gui2/lrf_renderer/main.py index 6c8441d0ff..4f848e22ec 100644 --- a/src/libprs500/gui2/lrf_renderer/main.py +++ b/src/libprs500/gui2/lrf_renderer/main.py @@ -166,10 +166,10 @@ class Main(MainWindow, Ui_MainWindow): if not self.renderer.aborted and self.renderer.lrf is not None: width, height = self.renderer.lrf.device_info.width, \ self.renderer.lrf.device_info.height - self.graphics_view.resize_for(width, height) + self.graphics_view.resize_for(width+5, height+5) desktop = QCoreApplication.instance().desktop() screen_height = desktop.availableGeometry().height() - height = min(screen_height, height+50) + height = min(screen_height, height+55) self.resize(self.size().width(), height) self.setWindowTitle(self.renderer.lrf.metadata.title + ' - ' + __appname__) self.document_title = self.renderer.lrf.metadata.title diff --git a/src/libprs500/gui2/lrf_renderer/main.ui b/src/libprs500/gui2/lrf_renderer/main.ui index 3ffc9e0eb8..6cbaaf1f4b 100644 --- a/src/libprs500/gui2/lrf_renderer/main.ui +++ b/src/libprs500/gui2/lrf_renderer/main.ui @@ -5,7 +5,7 @@ 0 0 - 614 + 615 702