Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG export module, converting drawing commands to SVG text #367

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

YGaurora
Copy link
Collaborator

@YGaurora YGaurora commented Dec 6, 2024

SVG导出部分的实现,将canvas的绘制指令转成SVG文本

src/svg/Caster.cpp Outdated Show resolved Hide resolved
src/svg/Caster.h Outdated Show resolved Hide resolved
src/svg/SVGContext.h Outdated Show resolved Hide resolved
src/svg/SVGContext.h Outdated Show resolved Hide resolved
src/svg/SVGContext.cpp Outdated Show resolved Hide resolved
src/svg/SVGExporter.cpp Outdated Show resolved Hide resolved
include/tgfx/svg/SVGExporter.h Outdated Show resolved Hide resolved
src/core/utils/GlyphConverter.cpp Show resolved Hide resolved
src/core/vectors/freetype/FTTypeface.cpp Outdated Show resolved Hide resolved
* unicode. The array length is glyphsCount().
* The length of the array is not required, it will be resized within the method.
*/
virtual std::vector<Unichar> getGlyphToUnicodeMap() const = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的vector表示了两层含义,替代了map的作用,理解上不是太直观

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

它这里要兼顾性能,GlyphID是连续线性,直接构造vector的查性能最高,用map会很慢。Skia也是这么处理。


class ShaderCaster {
public:
static std::shared_ptr<const ColorShader> AsColorShader(const std::shared_ptr<Shader>& shader);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个方法有地方使用吗?没搜索到调用的地方,下面的几个方法都看看是在哪些地方使用的。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

都是在ElementWriter中使用
Clipboard_Screenshot_1734333874

Comment on lines +143 to +145
Rect srcRect = Rect::MakeWH(image->width(), image->height());
float scaleX = rect.width() / srcRect.width();
float scaleY = rect.height() / srcRect.height();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rect在exportGlyphsAsImage方法中,是通过image来构造的,这里rect.width() / srcRect.width()不是一直等于1吗?

Copy link
Collaborator Author

@YGaurora YGaurora Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实drawImageRect也是drawContext的虚函数,一些带矩阵渲染图片的接口,都会进入到这个函数实现
Clipboard_Screenshot_1734335852

src/svg/SVGUtils.cpp Show resolved Hide resolved
src/svg/SVGExportingContext.cpp Outdated Show resolved Hide resolved
src/svg/xml/XMLWriter.h Outdated Show resolved Hide resolved
src/svg/SVGTextBuilder.h Show resolved Hide resolved
src/svg/SVGUtils.cpp Outdated Show resolved Hide resolved
src/svg/SVGUtils.cpp Outdated Show resolved Hide resolved
src/svg/SVGUtils.cpp Outdated Show resolved Hide resolved
src/svg/SVGUtils.cpp Outdated Show resolved Hide resolved
src/svg/SVGUtils.cpp Outdated Show resolved Hide resolved
* SVG will be clipped.
* @param options Options for exporting SVG text.
*/
static std::shared_ptr<SVGExporter> Make(std::stringstream& svgStream, Context* context,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不能直接用std::stringsteam, 这个会一直在内存里,我们之所以要支持stream就是为了可以减少内存占用,背后可以包装一个FILE对象,直接写入磁盘。这里应该像Skia一样定义一个WStream基类,但是提供一些基本的实现,有FileWStream,也可以创建MemoryWStream,内部实现再包装std::stringstream

@@ -110,6 +110,7 @@ void Canvas::restore() {
*mcState = canvasState->mcState;
auto layer = std::move(canvasState->savedLayer);
stateStack.pop();
drawContext->onRestore();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上次讨论的方案是不在DrawContext上加这些通知方法吧?SVGExportingContext里写个applyClip之类的公共函数就行了,每个draw都调用这个方法,这个方法内部记录一下上层传入进来的 clip ,然后判断是否相等就好了。不等就创建新的,关闭上次的。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修改

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants