首页 > 解决方案 > 使用 Chromium 直接渲染到我自己的“画布”(例如 GDI+)

问题描述

首先,快速描述最终目标:

我正在构建一个跨平台、基于 .NET Core 的打印应用程序。此应用程序将能够使用自定义页面设置打印各种文件类型,例如页眉、页脚和页边距。一个关键特性是它支持多页向上(例如,一张横向纸与两个并排呈现的纵向页面......称为“2up”)。

示例 2up 页面

打印 HTML 很重要,不仅因为打印 HTML,而且我想将所有基于 HTML 的出色语法高亮用于源代码(例如 www.prismjs.com)。

该应用程序基本上完成了,但有一个主要问题:我无法让 HTML 渲染得足够好。到目前为止,我已经实现了源代码打印三种方式:

1) 使用我自己的行号和换行引擎作为纯文本。这对于我可以扔给它的所有东西都非常有效,但它不支持语法突出显示。2) 使用Html-Renderer( https://github.com/ArthurHub/HTML-Renderer/issues ) 一个基于 OSS .NET 的 Html 渲染器。这个实现是最弱的,因为 Html-Renderer 的 CSS 支持真的很弱。它几乎prismjs无法highlightjs' generate. 3) Using通过LiteHtmlSharp. 这是非常有前途的,我几乎可以让它与一些主要的黑客一起工作,但litehtml也不支持关键的、现代的、HTML/CSS 特性。

既不也不Html-Renderer支持litehtmlCSSpage-break-before功能,当与它结合使用时,media print我可以确保行不会在页面之间拆分。

我真正想要使用的是 Chromium 渲染引擎。litehtml为这类问题提供了一个很棒的 AP​​I:它在需要渲染时调用我,我使用 GDI+ 绘制(文本、表格边框、图像等)。我的梦想是在 Chromium(CEF、Puppeteer、???)中找到提供类似 API 的东西。

或者,另一种选择,一个 API 可以让我传入 GDI+ 图形(或 HDC),然后渲染器将渲染到该表面。

Html-Renderer我测量计算 # 个这样的页面。

SizeF size = HtmlRender.MeasureGdiPlus(g, html, containingSheet.GetPageWidth());
int numPages = (int)(size.Height / containingSheet.GetPageHeight());

我的页面渲染代码(例如OnPaint)如下所示:

SizeF size = new SizeF(containingSheet.GetPageWidth(), containingSheet.GetPageHeight());
HtmlRender.RenderGdiPlus(g, html, PointF(0, 0), size );

代码htmllite如下OnPaint所示:

// Set the clip such that any extraLines are clipped off bottom
            g.SetClip(new Rectangle(0, 0, (int)Math.Round(PageSize.Width), (int)Math.Round(PageSize.Height - remainingPartialLineHeight)));
            LiteHtmlSize size = new LiteHtmlSize(Math.Round(PageSize.Width), Math.Ceiling(PageSize.Height));
            litehtml.Document.Draw((int)-0, (int)-yPos, new position {
                x = 0,
                y = 0,
                width = (int)size.Width,
                height = (int)size.Height
            });

在这种情况下,调用会litehtml.Document.Draw导致我的应用程序中出现一堆回调,我使用与调用相同Graphics的方法来处理这些回调OnPaint

大多数关于 CEF 和 Chromium 的讨论都指向ScreenshotAsync等……因为我需要渲染到 PRINTERS HDC(或 GDI+)并且位图会降低质量,所以不会这样做。

我已经倾注了 Chromium 源代码,但我找不到对 CEF/Chromium 说“将第 1 页(定义为高度/宽度)渲染到此 GDI+ 图形对象”然后“渲染第 2 页......”等的明显方式...打印支持(以及如何集成 pdfium!)。

Chromium 问题311308表明我已经被水洗了,直到重新开始这项工作。

注意:我在我的应用程序中拥有完全访问权限nodejs。我已经构建了一个 dotnet/nodejs 桥,这就是我如何通过 prismjs 将源代码文件的原始文本文件转换为格式丰富、行编号、语法突出显示的 html。puppeteer这意味着如果我能找出正确的 API,我就可以轻松使用/Headless Chrome。

有没有人有可能有帮助的建议?如果不是大心脏手术,我愿意为 Chromium 做出贡献。

标签: puppeteerchromiumcefsharpchromium-embeddedpuppeteer-sharp

解决方案


推荐阅读