Improve font size rationalization (thanks to llasram). The new algorithm should be more consistent. However, the change means that some of you existing base font size settings may no longer be appropriate. So please check.

This commit is contained in:
Kovid Goyal 2008-06-14 08:22:49 -07:00
commit 8ead30992e

View File

@ -553,54 +553,40 @@ class Book(Delegator):
if isinstance(obj, Main): if isinstance(obj, Main):
main = obj main = obj
break 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)
elif isinstance(obj, Canvas):
for o in obj.contents:
if isinstance(o.content, TextBlock):
text_blocks.append(o.content)
text_styles = set([t.textStyle for t in text_blocks])
important_text_styles = []
for ts in text_styles:
temp = [len(tb.contents) for tb in text_blocks if tb.textStyle == ts]
avg_content_length = 0
if len(temp) > 0:
avg_content_length = sum(temp)/len(temp)
if avg_content_length > 4:
important_text_styles.append(ts)
fonts = {} fonts = {}
if not important_text_styles: for text in main.get_all(lambda x: isinstance(x, Text)):
important_text_styles = text_styles fs = base_font_size
ancestor = text.parent
for ts in important_text_styles: while ancestor:
fs = int(ts.attrs['fontsize']) try:
if fonts.has_key(fs): fs = int(ancestor.attrs['fontsize'])
fonts[fs] += 1 break
else: except (AttributeError, KeyError):
fonts[fs] = 1 pass
try:
fs = int(ancestor.textSettings['fontsize'])
break
except (AttributeError, KeyError):
pass
try:
fs = int(ancestor.textStyle.attrs['fontsize'])
break
except (AttributeError, KeyError):
pass
ancestor = ancestor.parent
length = len(text.text)
fonts[fs] = fonts.get(fs, 0) + length
if not fonts: if not fonts:
print 'WARNING: LRF seems to have no textual content. Cannot rationalize font sizes.' print 'WARNING: LRF seems to have no textual content. Cannot rationalize font sizes.'
return return
old_base_font_size = float(max(zip(fonts.keys(), fonts.values()), key=operator.itemgetter(1))[0]) old_base_font_size = float(max(fonts.items(), key=operator.itemgetter(1))[0])
factor = base_font_size / old_base_font_size
factor = base_font_size/old_base_font_size
def rescale(old): def rescale(old):
return str(int(int(old) * factor)) return str(int(int(old) * factor))
for ts in text_styles: text_blocks = list(main.get_all(lambda x: isinstance(x, TextBlock)))
ts.attrs['fontsize'] = rescale(ts.attrs['fontsize'])
ts.attrs['baselineskip'] = rescale(ts.attrs['baselineskip'])
for tb in text_blocks: for tb in text_blocks:
if tb.textSettings.has_key('fontsize'): if tb.textSettings.has_key('fontsize'):
tb.textSettings['fontsize'] = rescale(tb.textSettings['fontsize']) tb.textSettings['fontsize'] = rescale(tb.textSettings['fontsize'])
@ -609,7 +595,12 @@ class Book(Delegator):
span.attrs['fontsize'] = rescale(span.attrs['fontsize']) span.attrs['fontsize'] = rescale(span.attrs['fontsize'])
if span.attrs.has_key('baselineskip'): if span.attrs.has_key('baselineskip'):
span.attrs['baselineskip'] = rescale(span.attrs['baselineskip']) span.attrs['baselineskip'] = rescale(span.attrs['baselineskip'])
text_styles = set(tb.textStyle for tb in text_blocks)
for ts in text_styles:
ts.attrs['fontsize'] = rescale(ts.attrs['fontsize'])
ts.attrs['baselineskip'] = rescale(ts.attrs['baselineskip'])
def renderLrs(self, lrsFile, encoding="UTF-8"): def renderLrs(self, lrsFile, encoding="UTF-8"):
if isinstance(lrsFile, basestring): if isinstance(lrsFile, basestring):
@ -1603,6 +1594,8 @@ class Paragraph(LrsContainer):
LrsContainer.__init__(self, [Text, CR, DropCaps, CharButton, LrsContainer.__init__(self, [Text, CR, DropCaps, CharButton,
LrsSimpleChar1, basestring]) LrsSimpleChar1, basestring])
if text is not None: if text is not None:
if isinstance(text, basestring):
text = Text(text)
self.append(text) self.append(text)
def CR(self): def CR(self):
@ -1923,6 +1916,8 @@ class Span(LrsSimpleChar1, LrsContainer):
def __init__(self, text=None, **attrs): def __init__(self, text=None, **attrs):
LrsContainer.__init__(self, [LrsSimpleChar1, Text, basestring]) LrsContainer.__init__(self, [LrsSimpleChar1, Text, basestring])
if text is not None: if text is not None:
if isinstance(text, basestring):
text = Text(text)
self.append(text) self.append(text)
for attrname in attrs.keys(): for attrname in attrs.keys():