From ac07a539cc58f142e1b2c1732f00d9124f89f91d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 10:09:21 +0530 Subject: [PATCH 1/9] Fix #1097047 (Incorrect Hungarian translation in Edit metadata in bulk dialog) --- src/calibre/gui2/dialogs/metadata_bulk.ui | 44 +++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index 917dfbb159..24a84eb1b4 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -1109,8 +1109,8 @@ not multiple and the destination field is multiple 0 0 - 205 - 66 + 934 + 213 @@ -1269,8 +1269,8 @@ not multiple and the destination field is multiple accept() - 252 - 382 + 258 + 638 157 @@ -1285,8 +1285,8 @@ not multiple and the destination field is multiple reject() - 320 - 382 + 326 + 638 286 @@ -1294,5 +1294,37 @@ not multiple and the destination field is multiple + + remove_all_tags + toggled(bool) + remove_tags + setDisabled(bool) + + + 888 + 266 + + + 814 + 268 + + + + + clear_languages + toggled(bool) + languages + setDisabled(bool) + + + 874 + 418 + + + 817 + 420 + + + From 21462e5ac51a92fd85652c4446cd8891624033d3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 10:16:07 +0530 Subject: [PATCH 2/9] Libartes by DM. Fixes #1097019 (New recipe for magazine Libartes) --- recipes/icons/libartes.png | Bin 0 -> 282 bytes recipes/libartes.recipe | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 recipes/icons/libartes.png create mode 100644 recipes/libartes.recipe diff --git a/recipes/icons/libartes.png b/recipes/icons/libartes.png new file mode 100644 index 0000000000000000000000000000000000000000..0954c402736128704ad77d4e16423e7b3380d2f6 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X_ISEDhE&{2`t$$4J+o#*XQPY5yf)=n9^NxNvyB%db>ERV zcP?$mE;bd8l*LS90*S%LKKzq&(#aE_@^Mek!<&&obB-u_w8%H)G3;V_p~CUwV`Jhp z$xY3MCI{{^Gv2>%eB@mUM=Yn&qkC~mPM!f18-ph}TDLd`a6Xa`YML4>Am*j8eV_Xd zM#(+<`Gpv**j6}bvn*qj;6D(+&U8|*t-9KQXMy Date: Tue, 8 Jan 2013 10:22:19 +0530 Subject: [PATCH 3/9] Update Boerse Online --- recipes/borse_online.recipe | 49 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/recipes/borse_online.recipe b/recipes/borse_online.recipe index c192ce2b8d..ddd9ac456b 100644 --- a/recipes/borse_online.recipe +++ b/recipes/borse_online.recipe @@ -1,33 +1,36 @@ from calibre.web.feeds.recipes import BasicNewsRecipe class AdvancedUserRecipe1303841067(BasicNewsRecipe): - title = u'Börse-online' - __author__ = 'schuster' - oldest_article = 1 + title = u'Börse-online' + __author__ = 'schuster, Armin Geller' + oldest_article = 1 max_articles_per_feed = 100 - no_stylesheets = True - use_embedded_content = False - language = 'de' - remove_javascript = True - cover_url = 'http://www.dpv.de/images/1995/source.gif' - masthead_url = 'http://www.zeitschriften-cover.de/cover/boerse-online-cover-januar-2010-x1387.jpg' - extra_css = ''' - h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;} - h4{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;} - img {min-width:300px; max-width:600px; min-height:300px; max-height:800px} - p{font-family:Arial,Helvetica,sans-serif;font-size:small;} - body{font-family:Helvetica,Arial,sans-serif;font-size:small;} - ''' - remove_tags_bevor = [dict(name='h3')] - remove_tags_after = [dict(name='div', attrs={'class':'artikelfuss'})] - remove_tags = [dict(attrs={'class':['moduleTopNav', 'moduleHeaderNav', 'text', 'blau', 'poll1150']}), - dict(id=['newsletterlayer', 'newsletterlayerClose', 'newsletterlayer_body', 'newsletterarray_error', 'newsletterlayer_emailadress', 'newsletterlayer_submit', 'kommentar']), - dict(name=['h2', 'Gesamtranking', 'h3',''])] + no_stylesheets = True + use_embedded_content = False + language = 'de' + remove_javascript = True + encoding = 'iso-8859-1' + timefmt = ' [%a, %d %b %Y]' + + + cover_url = 'http://www.wirtschaftsmedien-shop.de/s/media/coverimages/7576_2013107.jpg' + masthead_url = 'http://upload.wikimedia.org/wikipedia/de/5/56/B%C3%B6rse_Online_Logo.svg' + remove_tags_after = [dict(name='div', attrs={'class':['artikelfuss', 'rahmen600']})] + + remove_tags = [ + dict(name='div', attrs={'id':['breadcrumb', 'rightCol', 'clearall']}), + dict(name='div', attrs={'class':['footer', 'artikelfuss']}), + ] + + keep_only_tags = [ + dict(name='div', attrs={'id':['contentWrapper']}) + ] + + feeds = [(u'Börsennachrichten', u'http://www.boerse-online.de/rss/')] + def print_version(self, url): return url.replace('.html#nv=rss', '.html?mode=print') - feeds = [(u'Börsennachrichten', u'http://www.boerse-online.de/rss/')] - From 6bce49960c75b6477701e996e4a7ed81f6467e30 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 11:51:02 +0530 Subject: [PATCH 4/9] PDF Output: Dont abort when non-sfnt fonts are used, instead draw the text as outlines --- src/calibre/ebooks/pdf/render/engine.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/pdf/render/engine.py b/src/calibre/ebooks/pdf/render/engine.py index 149d75d1f0..136e622500 100644 --- a/src/calibre/ebooks/pdf/render/engine.py +++ b/src/calibre/ebooks/pdf/render/engine.py @@ -240,14 +240,17 @@ class PdfEngine(QPaintEngine): @store_error def drawTextItem(self, point, text_item): # super(PdfEngine, self).drawTextItem(point, text_item) - self.apply_graphics_state() gi = self.qt_hack.get_glyphs(point, text_item) if not gi.indices: sip.delete(gi) return name = hash(bytes(gi.name)) if name not in self.fonts: - self.fonts[name] = self.create_sfnt(text_item) + try: + self.fonts[name] = self.create_sfnt(text_item) + except UnsupportedFont: + return super(PdfEngine, self).drawTextItem(point, text_item) + self.apply_graphics_state() metrics = self.fonts[name] for glyph_id in gi.indices: try: From 56c161ec63e694b719bed21dfc97f2834d8e779d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 12:47:58 +0530 Subject: [PATCH 5/9] PDF Output: Fix side margins of last page in a flow being incorrect when large side margins are used. Fixes #1096290 (Margins off page in new PDF output) --- src/calibre/ebooks/pdf/render/from_html.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index edf5db1882..ea68ca89b1 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -147,9 +147,10 @@ class PDFWriter(QObject): opts = self.opts page_size = get_page_size(self.opts) xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY() + # We cannot set the side margins in the webview as there is no right + # margin for the last page (the margins are implemented with + # -webkit-column-gap) ml, mr = opts.margin_left, opts.margin_right - margin_side = min(ml, mr) - ml, mr = ml - margin_side, mr - margin_side self.doc = PdfDevice(out_stream, page_size=page_size, left_margin=ml, top_margin=0, right_margin=mr, bottom_margin=0, xdpi=xdpi, ydpi=ydpi, errors=self.log.error, @@ -162,9 +163,7 @@ class PDFWriter(QObject): self.total_items = len(items) mt, mb = map(self.doc.to_px, (opts.margin_top, opts.margin_bottom)) - ms = self.doc.to_px(margin_side, vertical=False) - self.margin_top, self.margin_size, self.margin_bottom = map( - lambda x:int(floor(x)), (mt, ms, mb)) + self.margin_top, self.margin_bottom = map(lambda x:int(floor(x)), (mt, mb)) self.painter = QPainter(self.doc) self.doc.set_metadata(title=pdf_metadata.title, @@ -258,7 +257,7 @@ class PDFWriter(QObject): paged_display.layout(); paged_display.fit_images(); py_bridge.value = book_indexing.all_links_and_anchors(); - '''%(self.margin_top, self.margin_size, self.margin_bottom)) + '''%(self.margin_top, 0, self.margin_bottom)) amap = self.bridge_value if not isinstance(amap, dict): From d5e9c105ab1759380843bad4a6b16d40bd21cdce Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 13:46:42 +0530 Subject: [PATCH 6/9] Use the Liberation fonts as the default fonts for generic css font specs on linux as the other fonts may result in bitmapped fonts being used --- .../ebooks/conversion/plugins/pdf_output.py | 14 ++++--- src/calibre/gui2/__init__.py | 37 +++++++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index e4eb45fc6a..b9d016de2d 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -10,7 +10,7 @@ Convert OEB ebook format to PDF. import glob, os -from calibre.constants import iswindows +from calibre.constants import iswindows, islinux from calibre.customize.conversion import (OutputFormatPlugin, OptionRecommendation) from calibre.ptempfile import TemporaryDirectory @@ -73,13 +73,13 @@ class PDFOutput(OutputFormatPlugin): ' of stretching it to fill the full first page of the' ' generated pdf.')), OptionRecommendation(name='pdf_serif_family', - recommended_value='Times New Roman', help=_( + recommended_value='Liberation Serif' if islinux else 'Times New Roman', help=_( 'The font family used to render serif fonts')), OptionRecommendation(name='pdf_sans_family', - recommended_value='Helvetica', help=_( + recommended_value='Liberation Sans' if islinux else 'Helvetica', help=_( 'The font family used to render sans-serif fonts')), OptionRecommendation(name='pdf_mono_family', - recommended_value='Courier New', help=_( + recommended_value='Liberation Mono' if islinux else 'Courier New', help=_( 'The font family used to render monospaced fonts')), OptionRecommendation(name='pdf_standard_font', choices=['serif', 'sans', 'mono'], @@ -102,6 +102,10 @@ class PDFOutput(OutputFormatPlugin): ]) def convert(self, oeb_book, output_path, input_plugin, opts, log): + from calibre.gui2 import must_use_qt, load_builtin_fonts + must_use_qt() + load_builtin_fonts() + self.oeb = oeb_book self.input_plugin, self.opts, self.log = input_plugin, opts, log self.output_path = output_path @@ -135,7 +139,6 @@ class PDFOutput(OutputFormatPlugin): If you ever move to Qt WebKit 2.3+ then this will be unnecessary. ''' from calibre.ebooks.oeb.base import urlnormalize - from calibre.gui2 import must_use_qt from calibre.utils.fonts.utils import remove_embed_restriction from PyQt4.Qt import QFontDatabase, QByteArray, QRawFont, QFont @@ -165,7 +168,6 @@ class PDFOutput(OutputFormatPlugin): raw = remove_embed_restriction(raw) except: continue - must_use_qt() fid = QFontDatabase.addApplicationFontFromData(QByteArray(raw)) family_name = None if fid > -1: diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 9dbf769511..d7a2669b0b 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -766,6 +766,26 @@ class Translator(QTranslator): gui_thread = None qt_app = None + +def load_builtin_fonts(): + global _rating_font + # Load the builtin fonts and any fonts added to calibre by the user to + # Qt + for ff in glob.glob(P('fonts/liberation/*.?tf')) + \ + [P('fonts/calibreSymbols.otf')] + \ + glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')): + if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}: + with open(ff, 'rb') as s: + # Windows requires font files to be executable for them to be + # loaded successfully, so we use the in memory loader + fid = QFontDatabase.addApplicationFontFromData(s.read()) + if fid > -1: + fam = QFontDatabase.applicationFontFamilies(fid) + fam = set(map(unicode, fam)) + if u'calibre Symbols' in fam: + _rating_font = u'calibre Symbols' + + class Application(QApplication): def __init__(self, args, force_calibre_style=False, @@ -798,27 +818,12 @@ class Application(QApplication): return ret def load_builtin_fonts(self, scan_for_fonts=False): - global _rating_font if scan_for_fonts: from calibre.utils.fonts.scanner import font_scanner # Start scanning the users computer for fonts font_scanner - # Load the builtin fonts and any fonts added to calibre by the user to - # Qt - for ff in glob.glob(P('fonts/liberation/*.?tf')) + \ - [P('fonts/calibreSymbols.otf')] + \ - glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')): - if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}: - with open(ff, 'rb') as s: - # Windows requires font files to be executable for them to be - # loaded successfully, so we use the in memory loader - fid = QFontDatabase.addApplicationFontFromData(s.read()) - if fid > -1: - fam = QFontDatabase.applicationFontFamilies(fid) - fam = set(map(unicode, fam)) - if u'calibre Symbols' in fam: - _rating_font = u'calibre Symbols' + load_builtin_fonts() def load_calibre_style(self): # On OS X QtCurve resets the palette, so we preserve it explicitly From 6d1a9dcc296fcaf6a275e7dd32e87fa81ffd26e9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 14:15:06 +0530 Subject: [PATCH 7/9] Fix clipping, considering that the clip path depends on the current painter transform, therefore the order of updateState() operations matters. So only track if the clip has been updated and always re-apply if it has. --- src/calibre/ebooks/pdf/render/graphics.py | 25 +++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/calibre/ebooks/pdf/render/graphics.py b/src/calibre/ebooks/pdf/render/graphics.py index 71a8a22e85..7fb87662b4 100644 --- a/src/calibre/ebooks/pdf/render/graphics.py +++ b/src/calibre/ebooks/pdf/render/graphics.py @@ -11,7 +11,7 @@ from math import sqrt from collections import namedtuple from PyQt4.Qt import ( - QBrush, QPen, Qt, QPointF, QTransform, QPainterPath, QPaintEngine, QImage) + QBrush, QPen, Qt, QPointF, QTransform, QPaintEngine, QImage) from calibre.ebooks.pdf.render.common import ( Name, Array, fmtnum, Stream, Dictionary) @@ -248,7 +248,7 @@ class TexturePattern(TilingPattern): class GraphicsState(object): FIELDS = ('fill', 'stroke', 'opacity', 'transform', 'brush_origin', - 'clip', 'do_fill', 'do_stroke') + 'clip_updated', 'do_fill', 'do_stroke') def __init__(self): self.fill = QBrush() @@ -256,7 +256,7 @@ class GraphicsState(object): self.opacity = 1.0 self.transform = QTransform() self.brush_origin = QPointF() - self.clip = QPainterPath() + self.clip_updated = False self.do_fill = False self.do_stroke = True self.qt_pattern_cache = {} @@ -274,7 +274,7 @@ class GraphicsState(object): ans.opacity = self.opacity ans.transform = self.transform * QTransform() ans.brush_origin = QPointF(self.brush_origin) - ans.clip = self.clip + ans.clip_updated = self.clip_updated ans.do_fill, ans.do_stroke = self.do_fill, self.do_stroke return ans @@ -311,7 +311,7 @@ class Graphics(object): s.opacity = state.opacity() if flags & QPaintEngine.DirtyClipPath or flags & QPaintEngine.DirtyClipRegion: - s.clip = painter.clipPath() + s.clip_updated = True def reset(self): self.current_state = GraphicsState() @@ -326,7 +326,7 @@ class Graphics(object): ps = self.pending_state pdf = self.pdf - if (ps.transform != pdf_state.transform or ps.clip != pdf_state.clip): + if ps.transform != pdf_state.transform or ps.clip_updated: pdf.restore_stack() pdf.save_stack() pdf_state = self.base_state @@ -341,11 +341,14 @@ class Graphics(object): pdf_state.brush_origin != ps.brush_origin): self.apply_fill(ps, pdf_system, painter) - if (pdf_state.clip != ps.clip): - p = convert_path(ps.clip) - fill_rule = {Qt.OddEvenFill:'evenodd', - Qt.WindingFill:'winding'}[ps.clip.fillRule()] - pdf.add_clip(p, fill_rule=fill_rule) + if ps.clip_updated: + ps.clip_updated = False + path = painter.clipPath() + if not path.isEmpty(): + p = convert_path(path) + fill_rule = {Qt.OddEvenFill:'evenodd', + Qt.WindingFill:'winding'}[path.fillRule()] + pdf.add_clip(p, fill_rule=fill_rule) self.current_state = self.pending_state self.pending_state = None From 77da4821bd636bdfd13042fc0354e01d0c4d2cf7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 14:15:31 +0530 Subject: [PATCH 8/9] ... --- src/calibre/ebooks/pdf/render/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/pdf/render/engine.py b/src/calibre/ebooks/pdf/render/engine.py index 136e622500..a987b3a54d 100644 --- a/src/calibre/ebooks/pdf/render/engine.py +++ b/src/calibre/ebooks/pdf/render/engine.py @@ -239,7 +239,8 @@ class PdfEngine(QPaintEngine): @store_error def drawTextItem(self, point, text_item): - # super(PdfEngine, self).drawTextItem(point, text_item) + # return super(PdfEngine, self).drawTextItem(point, text_item) + self.apply_graphics_state() gi = self.qt_hack.get_glyphs(point, text_item) if not gi.indices: sip.delete(gi) @@ -250,7 +251,6 @@ class PdfEngine(QPaintEngine): self.fonts[name] = self.create_sfnt(text_item) except UnsupportedFont: return super(PdfEngine, self).drawTextItem(point, text_item) - self.apply_graphics_state() metrics = self.fonts[name] for glyph_id in gi.indices: try: From d4819097f42257141c8f23720174e9de159122f9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Jan 2013 14:19:12 +0530 Subject: [PATCH 9/9] Properly abort PDF conversion if an error occurs during rendering --- src/calibre/ebooks/pdf/render/from_html.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index ea68ca89b1..191da98893 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -184,7 +184,8 @@ class PDFWriter(QObject): self.painter.restore() QTimer.singleShot(0, self.render_book) - self.loop.exec_() + if self.loop.exec_() == 1: + raise Exception('PDF Output failed, see log for details') if self.toc is not None and len(self.toc) > 0: self.doc.add_outline(self.toc)