Add PPTExporter with PPTX export support for PAGX documents#3361
Add PPTExporter with PPTX export support for PAGX documents#3361OnionsYu wants to merge 66 commits intoTencent:mainfrom
Conversation
…ile mode instead of stretch mode.
…ect ratio instead of tile mode.
…correct x-y order.
…tch when tileModeX or tileModeY is Repeat or Mirror.
…mage is smaller than the shape.
…mage pattern and shadow code.
1bc505f to
cdaf2a3
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3361 +/- ##
==========================================
+ Coverage 78.22% 80.18% +1.96%
==========================================
Files 529 541 +12
Lines 40527 45295 +4768
Branches 12234 12767 +533
==========================================
+ Hits 31701 36321 +4620
- Misses 6349 6400 +51
- Partials 2477 2574 +97 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…ents and shadows.
… methods and cache image type flags.
…and Keynote renderer compatibility.
# Conflicts: # src/pagx/PAGXExporter.cpp resolved by main version
… the removed size member.
56f6b20 to
664c2dd
Compare
… sites to descriptive method names.
…rt_ppt2 # Conflicts: # src/pagx/PAGXExporter.cpp resolved by origin/main(远端) version
…writeRawLine and writeComment methods.
…n and improve readability.
df0a742 to
4a3415f
Compare
…id test resource.
…sistent rendering across apps.
…ture constant, and extract tiled pattern render helper.
shlzxjp
left a comment
There was a problem hiding this comment.
Code Review 第二轮:之前的26条评论中绝大多数已确认修复(包括 const_cast、静态常量命名、Xform初始化、UTF-8字符数、lambda消除、幻灯片等比缩放、zipWrite返回值检查等),修复质量很好。本轮新发现 12 个问题(1 Critical、3 Major、8 Minor),详见行级评论。
shlzxjp
left a comment
There was a problem hiding this comment.
Code Review 第三轮:新发现 10 个问题(1 Critical、4 Major、5 Minor),详见行级评论。
| ok = ok && AddZipString(zf, "ppt/slides/slide1.xml", slide); | ||
| ok = ok && AddZipString(zf, "ppt/slides/_rels/slide1.xml.rels", GenerateSlideRels(context)); | ||
| ok = ok && AddZipString(zf, "ppt/slideMasters/slideMaster1.xml", GenerateSlideMaster()); | ||
| ok = ok && |
There was a problem hiding this comment.
[Critical] ToFile 中16个 AddZipString 调用和 AddZipEntry 循环的返回值全部被丢弃。任何一步写入失败后仍继续写入后续条目,最终只靠 zipClose 判断成败,但此时已产生部分写入的损坏文件。建议用 bool ok = true; ok = ok && AddZipString(...); 链式检查,首次失败即 zipClose 并返回 false。
| .closeElementSelfClosing(); | ||
| out.closeElement(); // a:path | ||
| out.closeElement(); // a:gradFill | ||
| break; |
There was a problem hiding this comment.
[Major] RadialGradient 导出硬编码 fillToRect l/t/r/b=50000,渐变中心始终在形状正中。但 RadialGradient 节点有 matrix、startPoint、endPoint 等属性控制渐变位置,全部被忽略。如果 PAGX 文档中径向渐变中心偏移,导出结果将不正确。
| } | ||
| if (hasItalic) { | ||
| out.addRequiredAttribute("i", "1"); | ||
| } |
There was a problem hiding this comment.
[Major] writeNativeText 只处理 SolidColor 填充,遇到 LinearGradient、RadialGradient 或 ImagePattern 时直接跳过,文本将以默认黑色显示且无任何警告。OOXML 的 a:rPr 支持 a:gradFill,建议至少对渐变填充做基本支持,或添加 fallback 提取渐变首色作为纯色近似。
| out.openElement("a:ln").closeElementStart(); | ||
| out.openElement("a:noFill").closeElementSelfClosing(); | ||
| out.closeElement(); | ||
| writeEffects(out, filters); |
There was a problem hiding this comment.
[Major] writeEffects 在 p:spPr 内调用,阴影效果应用于整个文本框形状而非文本本身。OOXML 中文本阴影应通过 a:rPr 内的效果属性应用,否则阴影会出现在文本框边界而非文字轮廓上,视觉效果不正确。
| void writePicture(XMLBuilder& out, const std::string& relId, int64_t offX, int64_t offY, | ||
| int64_t extCX, int64_t extCY); | ||
|
|
||
| // Write non-tiling ImagePattern fill as a separate p:pic element. |
There was a problem hiding this comment.
[Minor] DecomposeScale 实现了关键的矩阵分解逻辑(被 decomposeXform 和 writeTextAsPath 使用),但作为文件级 static 函数无法被单元测试覆盖。建议移入 ExporterUtils 使其可测试。
| float maxY = std::numeric_limits<float>::lowest(); | ||
| for (const auto& contour : allContours) { | ||
| ExpandBounds(minX, minY, maxX, maxY, contour.start); | ||
| for (const auto& seg : contour.segs) { |
There was a problem hiding this comment.
[Minor] writeTextAsPath 的 bounds 计算只遍历轮廓端点(start + seg endpoints),对于 cubic bezier 段,曲线实际范围可能超出端点围成的区域。字形路径段密度高,实际偏差很小,但在极端情况下可能导致裁剪。建议添加注释说明此为端点近似。
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
[Minor] 内层轮廓归属查找用 break 选择第一个(按数组顺序)包含它的 depth=0 轮廓。如果存在多个不相交的外层轮廓,且因端点近似误差导致 PointInsideContour 误判,可能将内层轮廓归错组。概率低但逻辑上存在,建议添加注释说明此限制。
新增 PPT 导出功能,支持将 PAGX 文档导出为 PPTX 格式。
主要变更: