def use_pango_font(font, start, count, will_call_prepost=False): import gi gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo #from gi.repository import Cairo as cairo import cairo fontDesc = Pango.FontDescription(font) a = array.array('b', itertools.repeat(0, 256 * 256)) surface = cairo.ImageSurface.create_for_data(a, cairo.FORMAT_A8, 256, 256) context = cairo.Context(surface) pango_context = PangoCairo.create_context(context) layout = PangoCairo.create_layout(context) fontmap = PangoCairo.font_map_get_default() font = fontmap.load_font(fontmap.create_context(), fontDesc) layout.set_font_description(fontDesc) metrics = font.get_metrics() descent = metrics.get_descent() d = descent / Pango.SCALE linespace = metrics.get_ascent() + metrics.get_descent() width = metrics.get_approximate_char_width() glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT) glPixelStorei(GL_UNPACK_SWAP_BYTES, 0) glPixelStorei(GL_UNPACK_LSB_FIRST, 1) glPixelStorei(GL_UNPACK_ROW_LENGTH, 256) glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 256) glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0) glPixelStorei(GL_UNPACK_SKIP_ROWS, 0) glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glPixelZoom(1, -1) base = glGenLists(count) for i in range(count): ch = chr(start + i) layout.set_text(ch, -1) w, h = layout.get_size() context.save() context.new_path() context.rectangle(0, 0, 256, 256) context.set_source_rgba(0., 0., 0., 0.) context.set_operator(cairo.OPERATOR_SOURCE) context.paint() context.restore() context.save() context.set_source_rgba(1., 1., 1., 1.) context.set_operator(cairo.OPERATOR_SOURCE) context.move_to(0, 0) PangoCairo.update_context(context, pango_context) PangoCairo.show_layout(context, layout) context.restore() w, h = int(w / Pango.SCALE), int(h / Pango.SCALE) glNewList(base + i, GL_COMPILE) glBitmap(0, 0, 0, 0, 0, h - d, ''.encode()) #glDrawPixels(0, 0, 0, 0, 0, h-d, ''); if not will_call_prepost: pango_font_pre() if w and h: try: pass glDrawPixels(w, h, GL_LUMINANCE, GL_UNSIGNED_BYTE, a.tostring()) except Exception as e: print("glnav Exception ", e) glBitmap(0, 0, 0, 0, w, -h + d, ''.encode()) if not will_call_prepost: pango_font_post() glEndList() glPopClientAttrib() return base, int(width / Pango.SCALE), int(linespace / Pango.SCALE)
def run(self): """Create the output file. The derived class overrides EXT and create_cairo_surface """ # get paper dimensions paper_width = self.paper.get_size().get_width() * DPI / 2.54 paper_height = self.paper.get_size().get_height() * DPI / 2.54 page_width = round(self.paper.get_usable_width() * DPI / 2.54) page_height = round(self.paper.get_usable_height() * DPI / 2.54) left_margin = self.paper.get_left_margin() * DPI / 2.54 top_margin = self.paper.get_top_margin() * DPI / 2.54 # create cairo context and pango layout filename = self._backend.filename # Cairo can't reliably handle unicode filenames on Linux or # Windows, so open the file for it. with open(filename, 'wb') as fd: try: surface = self.create_cairo_surface(fd, paper_width, paper_height) surface.set_fallback_resolution(300, 300) cr = cairo.Context(surface) fontmap = PangoCairo.font_map_new() fontmap.set_resolution(DPI) pango_context = fontmap.create_context() options = cairo.FontOptions() options.set_hint_metrics(cairo.HINT_METRICS_OFF) PangoCairo.context_set_font_options(pango_context, options) layout = Pango.Layout(pango_context) PangoCairo.update_context(cr, pango_context) # paginate the document self.paginate_document(layout, page_width, page_height, DPI, DPI) body_pages = self._pages # build the table of contents and alphabetical index toc_page = None index_page = None toc = [] index = {} for page_nr, page in enumerate(body_pages): if page.has_toc(): toc_page = page_nr if page.has_index(): index_page = page_nr for mark in page.get_marks(): if mark.type == INDEX_TYPE_ALP: if mark.key in index: if page_nr + 1 not in index[mark.key]: index[mark.key].append(page_nr + 1) else: index[mark.key] = [page_nr + 1] elif mark.type == INDEX_TYPE_TOC: toc.append([mark, page_nr + 1]) # paginate the table of contents rebuild_required = False if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) offset = len(toc_pages) - 1 if offset > 0: self.__increment_pages(toc, index, toc_page, offset) rebuild_required = True else: toc_pages = [] # paginate the index if index_page is not None: index_pages = self.__generate_index( layout, page_width, page_height, index) offset = len(index_pages) - 1 if offset > 0: self.__increment_pages(toc, index, index_page, offset) rebuild_required = True else: index_pages = [] # rebuild the table of contents and index if required if rebuild_required: if toc_page is not None: toc_pages = self.__generate_toc( layout, page_width, page_height, toc) if index_page is not None: index_pages = self.__generate_index( layout, page_width, page_height, index) # render the pages if toc_page is not None: body_pages = body_pages[:toc_page] + toc_pages + \ body_pages[toc_page+1:] if index_page is not None: body_pages = body_pages[:index_page] + index_pages + \ body_pages[index_page+1:] self._pages = body_pages for page_nr in range(len(self._pages)): cr.save() cr.translate(left_margin, top_margin) self.draw_page(page_nr, cr, layout, page_width, page_height, DPI, DPI) cr.show_page() cr.restore() # close the surface (file) surface.finish() except IOError as msg: errmsg = "%s\n%s" % (_("Could not create %s") % filename, msg) raise ReportError(errmsg) except Exception as err: errmsg = "%s\n%s" % (_("Could not create %s") % filename, err) raise ReportError(errmsg)
def run(self): """Create the output file. The derived class overrides EXT and create_cairo_surface """ # get paper dimensions paper_width = self.paper.get_size().get_width() * DPI / 2.54 paper_height = self.paper.get_size().get_height() * DPI / 2.54 page_width = round(self.paper.get_usable_width() * DPI / 2.54) page_height = round(self.paper.get_usable_height() * DPI / 2.54) left_margin = self.paper.get_left_margin() * DPI / 2.54 top_margin = self.paper.get_top_margin() * DPI / 2.54 # create cairo context and pango layout filename = self._backend.filename # Cairo can't reliably handle unicode filenames on Linux or # Windows, so open the file for it. with open(filename, 'wb') as fd: try: surface = self.create_cairo_surface(fd, paper_width, paper_height) surface.set_fallback_resolution(300, 300) cr = cairo.Context(surface) fontmap = PangoCairo.font_map_new() fontmap.set_resolution(DPI) pango_context = fontmap.create_context() options = cairo.FontOptions() options.set_hint_metrics(cairo.HINT_METRICS_OFF) PangoCairo.context_set_font_options(pango_context, options) layout = Pango.Layout(pango_context) PangoCairo.update_context(cr, pango_context) # paginate the document self.paginate_document(layout, page_width, page_height, DPI, DPI) body_pages = self._pages # build the table of contents and alphabetical index toc_page = None index_page = None toc = [] index = {} for page_nr, page in enumerate(body_pages): if page.has_toc(): toc_page = page_nr if page.has_index(): index_page = page_nr for mark in page.get_marks(): if mark.type == INDEX_TYPE_ALP: if mark.key in index: if page_nr + 1 not in index[mark.key]: index[mark.key].append(page_nr + 1) else: index[mark.key] = [page_nr + 1] elif mark.type == INDEX_TYPE_TOC: toc.append([mark, page_nr + 1]) # paginate the table of contents rebuild_required = False if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) offset = len(toc_pages) - 1 if offset > 0: self.__increment_pages(toc, index, toc_page, offset) rebuild_required = True else: toc_pages = [] # paginate the index if index_page is not None: index_pages = self.__generate_index(layout, page_width, page_height, index) offset = len(index_pages) - 1 if offset > 0: self.__increment_pages(toc, index, index_page, offset) rebuild_required = True else: index_pages = [] # rebuild the table of contents and index if required if rebuild_required: if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) if index_page is not None: index_pages = self.__generate_index(layout, page_width, page_height, index) # render the pages if toc_page is not None: body_pages = body_pages[:toc_page] + toc_pages + \ body_pages[toc_page+1:] if index_page is not None: body_pages = body_pages[:index_page] + index_pages + \ body_pages[index_page+1:] self._pages = body_pages for page_nr in range(len(self._pages)): cr.save() cr.translate(left_margin, top_margin) self.draw_page(page_nr, cr, layout, page_width, page_height, DPI, DPI) cr.show_page() cr.restore() # close the surface (file) surface.finish() except IOError as msg: errmsg = "%s\n%s" % (_("Could not create %s") % filename, msg) raise ReportError(errmsg) except Exception as err: errmsg = "%s\n%s" % (_("Could not create %s") % filename, err) raise ReportError(errmsg)