Esempio n. 1
0
    def drawTextItem(self, point, text_item):
        # return super(PdfEngine, self).drawTextItem(point, text_item)
        self.apply_graphics_state()
        gi = GlyphInfo(*self.qt_hack.get_glyphs(point, text_item))
        if not gi.indices:
            return
        metrics = self.fonts.get(gi.name)
        if metrics is None:
            from calibre.utils.fonts.utils import get_all_font_names
            try:
                names = get_all_font_names(gi.name, True)
                names = ' '.join('%s=%s'%(k, names[k]) for k in sorted(names))
            except Exception:
                names = 'Unknown'
            self.debug('Loading font: %s' % names)
            try:
                self.fonts[gi.name] = metrics = self.create_sfnt(text_item)
            except UnsupportedFont:
                return super(PdfEngine, self).drawTextItem(point, text_item)
        for glyph_id in gi.indices:
            try:
                metrics.glyph_map[glyph_id] = metrics.full_glyph_map[glyph_id]
            except (KeyError, ValueError):
                pass
        glyphs = []
        last_x = last_y = 0
        for glyph_index, (x, y) in zip(gi.indices, gi.positions):
            glyphs.append((x-last_x, last_y - y, glyph_index))
            last_x, last_y = x, y

        self.pdf.draw_glyph_run([gi.stretch, 0, 0, -1, 0, 0], gi.size, metrics,
                                glyphs)
Esempio n. 2
0
    def drawTextItem(self, point, text_item):
        self.content_written_to_current_page = 'drawTextItem'
        # return super(PdfEngine, self).drawTextItem(point, text_item)
        self.apply_graphics_state()
        gi = GlyphInfo(*self.qt_hack.get_glyphs(point, text_item))
        if not gi.indices:
            return
        metrics = self.fonts.get(gi.name)
        if metrics is None:
            from calibre.utils.fonts.utils import get_all_font_names
            try:
                names = get_all_font_names(gi.name, True)
                names = ' '.join('%s=%s'%(k, names[k]) for k in sorted(names))
            except Exception:
                names = 'Unknown'
            self.debug('Loading font: %s' % names)
            try:
                self.fonts[gi.name] = metrics = self.create_sfnt(text_item)
            except UnsupportedFont:
                return super(PdfEngine, self).drawTextItem(point, text_item)
        for glyph_id in gi.indices:
            try:
                metrics.glyph_map[glyph_id] = metrics.full_glyph_map[glyph_id]
            except (KeyError, ValueError):
                pass
        glyphs = []
        last_x = last_y = 0
        for glyph_index, (x, y) in zip(gi.indices, gi.positions):
            glyphs.append((x-last_x, last_y - y, glyph_index))
            last_x, last_y = x, y

        self.pdf.draw_glyph_run([gi.stretch, 0, 0, -1, 0, 0], gi.size, metrics,
                                glyphs)
Esempio n. 3
0
    def __init__(self, sfnt):
        for table in (b'head', b'hhea', b'hmtx', b'cmap', b'OS/2', b'post',
                      b'name'):
            if table not in sfnt:
                raise UnsupportedFont('This font has no %s table'%table)
        self.sfnt = sfnt

        self.head = self.sfnt[b'head']
        hhea = self.sfnt[b'hhea']
        hhea.read_data(self.sfnt[b'hmtx'])
        self.ascent = hhea.ascender
        self.descent = hhea.descender
        self.bbox = (self.head.x_min, self.head.y_min, self.head.x_max,
                     self.head.y_max)
        self._advance_widths = hhea.advance_widths
        self.cmap = self.sfnt[b'cmap']
        self.units_per_em = self.head.units_per_em
        self.os2 = self.sfnt[b'OS/2']
        self.os2.read_data()
        self.post = self.sfnt[b'post']
        self.post.read_data()
        self.names = get_all_font_names(self.sfnt[b'name'].raw, raw_is_table=True)
        self.is_otf = 'CFF ' in self.sfnt.tables
        self._sig = hash(self.sfnt[b'name'].raw)

        # Metrics for embedding in PDF
        pdf_scale = self.pdf_scale = lambda x:int(round(x*1000./self.units_per_em))
        self.pdf_ascent, self.pdf_descent = map(pdf_scale,
                        (self.os2.typo_ascender, self.os2.typo_descender))
        self.pdf_bbox = tuple(map(pdf_scale, self.bbox))
        self.pdf_capheight = pdf_scale(getattr(self.os2, 'cap_height',
                                               self.os2.typo_ascender))
        self.pdf_avg_width = pdf_scale(self.os2.average_char_width)
        self.pdf_stemv = 50 + int((self.os2.weight_class / 65.0) ** 2)
Esempio n. 4
0
    def __init__(self, sfnt):
        self.sfnt = sfnt

        self.head = self.sfnt[b"head"]
        hhea = self.sfnt[b"hhea"]
        hhea.read_data(self.sfnt[b"hmtx"])
        self.ascent = hhea.ascender
        self.descent = hhea.descender
        self.bbox = (self.head.x_min, self.head.y_min, self.head.x_max, self.head.y_max)
        self._advance_widths = hhea.advance_widths
        self.cmap = self.sfnt[b"cmap"]
        self.units_per_em = self.head.units_per_em
        self.os2 = self.sfnt[b"OS/2"]
        self.os2.read_data()
        self.post = self.sfnt[b"post"]
        self.post.read_data()
        self.names = get_all_font_names(self.sfnt[b"name"].raw, raw_is_table=True)
        self.is_otf = "CFF " in self.sfnt.tables
        self._sig = hash(self.sfnt[b"name"].raw)

        # Metrics for embedding in PDF
        pdf_scale = self.pdf_scale = lambda x: int(round(x * 1000.0 / self.units_per_em))
        self.pdf_ascent, self.pdf_descent = map(pdf_scale, (self.os2.typo_ascender, self.os2.typo_descender))
        self.pdf_bbox = tuple(map(pdf_scale, self.bbox))
        self.pdf_capheight = pdf_scale(getattr(self.os2, "cap_height", self.os2.typo_ascender))
        self.pdf_avg_width = pdf_scale(self.os2.average_char_width)
        self.pdf_stemv = 50 + int((self.os2.weight_class / 65.0) ** 2)
Esempio n. 5
0
    def __init__(self, sfnt):
        for table in (b'head', b'hhea', b'hmtx', b'cmap', b'OS/2', b'post',
                      b'name'):
            if table not in sfnt:
                raise UnsupportedFont('This font has no %s table'%table)
        self.sfnt = sfnt

        self.head = self.sfnt[b'head']
        hhea = self.sfnt[b'hhea']
        hhea.read_data(self.sfnt[b'hmtx'])
        self.ascent = hhea.ascender
        self.descent = hhea.descender
        self.bbox = (self.head.x_min, self.head.y_min, self.head.x_max,
                     self.head.y_max)
        self._advance_widths = hhea.advance_widths
        self.cmap = self.sfnt[b'cmap']
        self.units_per_em = self.head.units_per_em
        self.os2 = self.sfnt[b'OS/2']
        self.os2.read_data()
        self.post = self.sfnt[b'post']
        self.post.read_data()
        self.names = get_all_font_names(self.sfnt[b'name'].raw, raw_is_table=True)
        self.is_otf = 'CFF ' in self.sfnt.tables
        self._sig = hash(self.sfnt[b'name'].raw)

        # Metrics for embedding in PDF
        pdf_scale = self.pdf_scale = lambda x:int(round(x*1000./self.units_per_em))
        self.pdf_ascent, self.pdf_descent = map(pdf_scale,
                        (self.os2.typo_ascender, self.os2.typo_descender))
        self.pdf_bbox = tuple(map(pdf_scale, self.bbox))
        self.pdf_capheight = pdf_scale(getattr(self.os2, 'cap_height',
                                               self.os2.typo_ascender))
        self.pdf_avg_width = pdf_scale(self.os2.average_char_width)
        self.pdf_stemv = 50 + int((self.os2.weight_class / 65.0) ** 2)
Esempio n. 6
0
    def drawTextItem(self, point, text_item):
        # return super(PdfEngine, self).drawTextItem(point, text_item)
        self.apply_graphics_state()
        gi = GlyphInfo(*self.qt_hack.get_glyphs(point, text_item))
        if not gi.indices:
            return
        metrics = self.fonts.get(gi.name)
        if metrics is None:
            from calibre.utils.fonts.utils import get_all_font_names
            try:
                names = get_all_font_names(gi.name, True)
                names = ' '.join('%s=%s' % (k, names[k])
                                 for k in sorted(names))
            except Exception:
                names = 'Unknown'
            self.debug('Loading font: %s' % names)
            try:
                self.fonts[gi.name] = metrics = self.create_sfnt(text_item)
            except UnsupportedFont:
                self.debug(
                    'Failed to load font: %s, drawing text as outlines...' %
                    names)
                return super(PdfEngine, self).drawTextItem(point, text_item)
        indices, positions = [], []
        ignore_glyphs = metrics.ignore_glyphs
        for glyph_id, gpos in zip(gi.indices, gi.positions):
            if glyph_id not in ignore_glyphs:
                indices.append(glyph_id), positions.append(gpos)
        for glyph_id in indices:
            try:
                metrics.glyph_map[glyph_id] = metrics.full_glyph_map[glyph_id]
            except (KeyError, ValueError):
                pass
        glyphs = []
        last_x = last_y = 0
        for glyph_index, (x, y) in zip(indices, positions):
            glyphs.append((x - last_x, last_y - y, glyph_index))
            last_x, last_y = x, y

        if not self.content_written_to_current_page:
            dy = self.graphics.current_state.transform.dy()
            ypositions = [y + dy for x, y in positions]
            miny = min(ypositions or (0, ))
            maxy = max(ypositions or (self.pixel_height, ))
            page_top = self.header_height if self.has_headers else 0
            page_bottom = self.pixel_height - (self.footer_height
                                               if self.has_footers else 0)
            if page_top <= miny <= page_bottom or page_top <= maxy <= page_bottom:
                self.content_written_to_current_page = 'drawTextItem'
            else:
                self.debug(
                    'Text in header/footer: miny=%s maxy=%s page_top=%s page_bottom=%s'
                    % (miny, maxy, page_top, page_bottom))
        self.pdf.draw_glyph_run([gi.stretch, 0, 0, -1, 0, 0], gi.size, metrics,
                                glyphs)
Esempio n. 7
0
def check_fonts(container):
    font_map = {}
    errors = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_FONTS:
            raw = container.raw_data(name)
            try:
                name_map = get_all_font_names(raw)
            except Exception as e:
                errors.append(InvalidFont(_('Not a valid font: %s') % e, name))
                continue
            font_map[name] = name_map.get('family_name', None) or name_map.get(
                'preferred_family_name', None) or name_map.get(
                    'wws_family_name', None)
            try:
                embeddable, fs_type = is_font_embeddable(raw)
            except UnsupportedFont:
                embeddable = True
            if not embeddable:
                errors.append(NotEmbeddable(name, fs_type))

    sheets = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_STYLES:
            try:
                sheets.append((name, container.parsed(name), None))
            except Exception:
                pass  # Could not parse, ignore
        elif mt in OEB_DOCS:
            for style in container.parsed(name).xpath(
                    '//*[local-name()="style"]'):
                if style.get('type', 'text/css') == 'text/css' and style.text:
                    sheets.append((name, container.parse_css(style.text),
                                   style.sourceline))

    for name, sheet, line_offset in sheets:
        for rule in sheet.cssRules.rulesOfType(CSSRule.FONT_FACE_RULE):
            src = rule.style.getPropertyCSSValue('src')
            if src is not None and src.length > 0:
                href = getattr(src.item(0), 'uri', None)
                if href is not None:
                    fname = container.href_to_name(href, name)
                    font_name = font_map.get(fname, None)
                    if font_name is None:
                        continue
                    families = parse_font_family(
                        rule.style.getPropertyValue('font-family'))
                    if families:
                        if families[0] != font_name:
                            errors.append(
                                FontAliasing(font_name, families[0], name,
                                             line_offset))

    return errors
Esempio n. 8
0
def check_fonts(container):
    font_map = {}
    errors = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_FONTS:
            raw = container.raw_data(name)
            if mt == guess_type('a.woff'):
                try:
                    raw = woff.from_woff(raw)
                except Exception as e:
                    errors.append(
                        InvalidFont(_('Not a valid WOFF font: %s') % e, name))
                    continue
            try:
                name_map = get_all_font_names(raw)
            except Exception as e:
                errors.append(InvalidFont(_('Not a valid font: %s') % e, name))
                continue
            font_map[name] = name_map.get('family_name', None) or name_map.get(
                'preferred_family_name', None) or name_map.get(
                    'wws_family_name', None)

    sheets = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_STYLES:
            sheets.append((name, container.parsed(name), None))
        elif mt in OEB_DOCS:
            for style in container.parsed(name).xpath(
                    '//*[local-name()="style"]'):
                if style.get('type', 'text/css') == 'text/css':
                    sheets.append((name, container.parse_css(style.text),
                                   style.sourceline))

    for name, sheet, line_offset in sheets:
        for rule in sheet.cssRules.rulesOfType(CSSRule.FONT_FACE_RULE):
            src = rule.style.getPropertyCSSValue('src')
            if src is not None and src.length > 0:
                href = getattr(src.item(0), 'uri', None)
                if href is not None:
                    fname = container.href_to_name(href, name)
                    font_name = font_map.get(fname, None)
                    if font_name is None:
                        continue
                    ff = rule.style.getPropertyCSSValue('font-family')
                    if ff is not None and ff.length > 0:
                        ff = getattr(ff.item(0), 'value', None)
                        if ff is not None and ff != font_name:
                            errors.append(
                                FontAliasing(font_name, ff, name, line_offset))

    return errors
Esempio n. 9
0
    def drawTextItem(self, point, text_item):
        # return super(PdfEngine, self).drawTextItem(point, text_item)
        self.apply_graphics_state()
        gi = GlyphInfo(*self.qt_hack.get_glyphs(point, text_item))
        if not gi.indices:
            return
        metrics = self.fonts.get(gi.name)
        if metrics is None:
            from calibre.utils.fonts.utils import get_all_font_names
            try:
                names = get_all_font_names(gi.name, True)
                names = ' '.join('%s=%s'%(k, names[k]) for k in sorted(names))
            except Exception:
                names = 'Unknown'
            self.debug('Loading font: %s' % names)
            try:
                self.fonts[gi.name] = metrics = self.create_sfnt(text_item)
            except UnsupportedFont:
                self.debug('Failed to load font: %s, drawing text as outlines...' % names)
                return super(PdfEngine, self).drawTextItem(point, text_item)
        indices, positions = [], []
        ignore_glyphs = metrics.ignore_glyphs
        for glyph_id, gpos in zip(gi.indices, gi.positions):
            if glyph_id not in ignore_glyphs:
                indices.append(glyph_id), positions.append(gpos)
        for glyph_id in indices:
            try:
                metrics.glyph_map[glyph_id] = metrics.full_glyph_map[glyph_id]
            except (KeyError, ValueError):
                pass
        glyphs = []
        last_x = last_y = 0
        for glyph_index, (x, y) in zip(indices, positions):
            glyphs.append((x-last_x, last_y - y, glyph_index))
            last_x, last_y = x, y

        if not self.content_written_to_current_page:
            dy = self.graphics.current_state.transform.dy()
            ypositions = [y + dy for x, y in positions]
            miny = min(ypositions or (0,))
            maxy = max(ypositions or (self.pixel_height,))
            page_top = self.header_height if self.has_headers else 0
            page_bottom = self.pixel_height - (self.footer_height if self.has_footers else 0)
            if page_top <= miny <= page_bottom or page_top <= maxy <= page_bottom:
                self.content_written_to_current_page = 'drawTextItem'
            else:
                self.debug('Text in header/footer: miny=%s maxy=%s page_top=%s page_bottom=%s'% (
                    miny, maxy, page_top, page_bottom))
        self.pdf.draw_glyph_run([gi.stretch, 0, 0, -1, 0, 0], gi.size, metrics,
                                glyphs)
Esempio n. 10
0
def check_fonts(container):
    font_map = {}
    errors = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_FONTS:
            raw = container.raw_data(name)
            if mt == guess_type('a.woff'):
                try:
                    raw = woff.from_woff(raw)
                except Exception as e:
                    errors.append(InvalidFont(_('Not a valid WOFF font: %s') % e, name))
                    continue
            try:
                name_map = get_all_font_names(raw)
            except Exception as e:
                errors.append(InvalidFont(_('Not a valid font: %s') % e, name))
                continue
            font_map[name] = name_map.get('family_name', None) or name_map.get('preferred_family_name', None) or name_map.get('wws_family_name', None)

    sheets = []
    for name, mt in container.mime_map.iteritems():
        if mt in OEB_STYLES:
            try:
                sheets.append((name, container.parsed(name), None))
            except Exception:
                pass  # Could not parse, ignore
        elif mt in OEB_DOCS:
            for style in container.parsed(name).xpath('//*[local-name()="style"]'):
                if style.get('type', 'text/css') == 'text/css' and style.text:
                    sheets.append((name, container.parse_css(style.text), style.sourceline))

    for name, sheet, line_offset in sheets:
        for rule in sheet.cssRules.rulesOfType(CSSRule.FONT_FACE_RULE):
            src = rule.style.getPropertyCSSValue('src')
            if src is not None and src.length > 0:
                href = getattr(src.item(0), 'uri', None)
                if href is not None:
                    fname = container.href_to_name(href, name)
                    font_name = font_map.get(fname, None)
                    if font_name is None:
                        continue
                    ff = rule.style.getPropertyCSSValue('font-family')
                    if ff is not None and ff.length > 0:
                        ff = getattr(ff.item(0), 'value', None)
                        if ff is not None and ff != font_name:
                            errors.append(FontAliasing(font_name, ff, name, line_offset))

    return errors
Esempio n. 11
0
def check_fonts(container):
    font_map = {}
    errors = []
    for name, mt in iteritems(container.mime_map):
        if mt in OEB_FONTS:
            raw = container.raw_data(name)
            try:
                name_map = get_all_font_names(raw)
            except Exception as e:
                errors.append(InvalidFont(_('Not a valid font: %s') % e, name))
                continue
            font_map[name] = name_map.get('family_name', None) or name_map.get('preferred_family_name', None) or name_map.get('wws_family_name', None)
            try:
                embeddable, fs_type = is_font_embeddable(raw)
            except UnsupportedFont:
                embeddable = True
            if not embeddable:
                errors.append(NotEmbeddable(name, fs_type))

    sheets = []
    for name, mt in iteritems(container.mime_map):
        if mt in OEB_STYLES:
            try:
                sheets.append((name, container.parsed(name), None))
            except Exception:
                pass  # Could not parse, ignore
        elif mt in OEB_DOCS:
            for style in container.parsed(name).xpath('//*[local-name()="style"]'):
                if style.get('type', 'text/css') == 'text/css' and style.text:
                    sheets.append((name, container.parse_css(style.text), style.sourceline))

    for name, sheet, line_offset in sheets:
        for rule in sheet.cssRules.rulesOfType(CSSRule.FONT_FACE_RULE):
            src = rule.style.getPropertyCSSValue('src')
            if src is not None and src.length > 0:
                href = getattr(src.item(0), 'uri', None)
                if href is not None:
                    fname = container.href_to_name(href, name)
                    font_name = font_map.get(fname, None)
                    if font_name is None:
                        continue
                    families = parse_font_family(rule.style.getPropertyValue('font-family'))
                    if families:
                        if families[0] != font_name:
                            errors.append(FontAliasing(font_name, families[0], name, line_offset))

    return errors