You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
기존에는 각 renderer가 PageRenderTree를 직접 해석하는 흐름에 가까웠습니다. 이 시리즈에서는 renderer backend가 공통으로 replay할 수 있는 PageLayerTree를 중간 IR로 두고, SVG / Canvas2D / native Skia / CanvasKit / PDF export backend가 같은 layer contract를 기준으로 동작하게 합니다.
native Skia 안에서도 equation, raw SVG, form control, text, image effect처럼 실패 양상이 다른 leaf replay는 독립적으로 검토합니다.
foundation만 추가하고 consumer가 없는 phase는 가능하면 다음 consumer 작업과 합칩니다.
Text IR v2는 source table, placement/cluster metadata, special visual externalization을 각각 쪼개지 않고 TextRun compatibility contract 단위로 묶습니다.
GlyphRun/GlyphOutline은 당분간 canonical path가 아니라 optional text variant로만 둡니다. TextRun fallback이 항상 남아 있어야 합니다.
text variant adoption은 writer contract, diagnostics, backend selection gate를 먼저 만들고, 실제 backend replay는 별도 phase에서 엽니다.
CanvasKit은 Canvas2D-assisted preview가 아니라 native Skia로 이어지는 독립 replay backend로 키웁니다. canvaskitMode=default는 direct replay 우선이며 Canvas2D overlay로 조용히 숨기지 않습니다. canvaskitMode=compat도 overlay fallback이 아니라 더 보수적인 CanvasKit direct replay policy입니다.
CanvasKit overlay 제거는 mode/diagnostics foundation -> raster image direct replay -> equation/formObject -> TextRun effects -> GlyphRun/GlyphOutline gates 순서로 진행합니다. 지원하지 않는 기능은 Canvas2D paint로 덮지 않고 TextRun fallback, deterministic reject reason, backend diagnostics로 드러냅니다. raster output은 fuzzy 허용, semantic decision은 exact 기준으로 둡니다.
CanvasKit direct replay가 기존 Canvas2D와 의도적으로 달라지는 경우는 Skia strict replay improvement로 fixture/diagnostics에 명시하고, compatibility mismatch와 구분합니다.
PDF export는 PNG raster export와 다른 출력 계약으로 보고 별도 PR로 둡니다. 다만 SVG->PDF MVP와 direct/vector hardening은 같은 PDF backend contract 안에서 같이 봅니다.
native binding/Swift package는 별도 사용자 표면입니다. native render/export API가 추가될 때마다 Swift/XCFramework/FFI 문서 영향 여부를 같이 확인합니다.
후속 구현 검토 결과, P21에서 replay-plane/z-order, renderer baseline runner, 작은 representative manifest, CanvasKit surface axis, native/browser performance report를 report-first 형태로 닫았습니다. large corpus 확장은 후속으로 분리합니다. P23에서는 PDF artifact를 hard gate로 넣지 않고, export-pdf 결과와 browser Canvas 출력을 비교하는 report-only PDF visual diff를 추가했습니다.
P22는 WebCanvas layer adapter 축소와 layer option metadata closure로 완료되었습니다. public Canvas route를 다시 바꾸지 않고, 이미 layer 기반인 route의 내부 adapter risk를 줄이는 boundary cleanup으로 닫았습니다.
P23은 PDF export/native API packaging으로 진행 중입니다. PR #1359에서 SVG-derived PDF export를 DocumentCore native API와 CLI가 공유하는 표면으로 올리고, render-diff CI에 report-only PDF visual diff summary/artifacts를 추가합니다.
strict BitmapGlyph/SvgGlyph, variation/TTC, shapedModern/cross-scope/MixedPerGlyph는 writer-ready 선언이 아니라 producer-output corpus와 proof gate 중심으로 유지합니다.
계획 업데이트 (2026-06-10)
CanvasKit 방향은 overlay fallback을 줄이는 수준이 아니라, browser CanvasKit과 future native Skia가 같은 replay contract를 공유할 수 있도록 overlay-free direct replay를 기본 전제로 둡니다. P16-P21이 devel에 반영되었으므로 이후 계획은 “초기 renderer 도입”이 아니라 “direct replay coverage를 어떤 contract 단위로 넓히고 검증할지”가 기준입니다.
canvaskitMode=default: direct CanvasKit replay 우선.
canvaskitMode=compat: Canvas2D overlay fallback이 아니라 conservative CanvasKit direct replay policy.
unsupported case: Canvas2D paint로 숨기지 않고 TextRun fallback, deterministic reject reason, backend diagnostics 중 하나로 처리.
P20은 glyph payload resource corpus와 font construction proof로 완료했습니다. PR #1159에서 static vector glyph/resource payload fixture, payloadResourceKey, cache-key/resource identity, face index/variation/exact typeface construction failure diagnostics를 묶어서 GlyphRun/GlyphOutline replay eligibility 전제를 단단히 했습니다.
P21은 renderer sweep / replay-plane ordering / surface axis를 합친 baseline infrastructure phase로 완료했습니다. PR #1312에서 SVG, Canvas2D, CanvasKit, native Skia를 작은 representative manifest/report에서 비교하는 report-first 파이프라인, Full Renderer Sweep manual workflow, browser/native baseline report, surface axis diagnostics를 정리했습니다. Large corpus 확장과 PDF artifact 수집은 P21에 넣지 않았습니다.
P22는 WebCanvas direct PaintOp replay와 layer option metadata closure로 완료했습니다. Canvas public path를 다시 바꾸지 않고, WebCanvas layer replay가 leaf payload를 임시 legacy node로 되돌리는 부분을 줄였고 buildOptions/debugOptions/outputOptions contract를 명확히 했습니다.
P23은 PDF export와 native render/export API packaging입니다. PR #1359에서는 먼저 SVG-derived PDF export를 DocumentCore native API로 올리고 CLI export-pdf가 같은 API를 쓰도록 정리합니다. render-diff CI에는 report-only PDF visual diff를 추가해 export-pdf raster와 browser Canvas 출력의 차이를 summary/artifact로 남깁니다. Direct/vector PageLayerTree -> PDF, PDF visual diff hard gate, Swift/XCFramework/FFI packaging 변경은 후속으로 남깁니다.
P24는 strict BitmapGlyph/SvgGlyph producer-output corpus widening입니다. 기존 handcrafted payload fixture를 더 늘리는 게 아니라, 실제 lowering/resource path를 통과한 one-strike bitmap payload와 sanitized static vector payload를 corpus로 추가합니다.
P25는 exact font replay corpus widening입니다. native Skia variation/TTC proof는 real variable-font / real collection corpus와 digest-pinned positive/negative controls로 넓히고, CanvasKit variation/TTC는 exact construction proof가 생길 때까지 conservative fallback을 유지합니다.
P26은 authority-gated v2 follow-up입니다. 추가 COLRv1 blend/composite/clip primitive, shapedModern width input/line breaking, cross-scope variants, public MixedPerGlyph writer emission은 concrete document/use case와 fallback/reject policy가 준비될 때까지 보류합니다.
direct replay가 Canvas2D와 의도적으로 달라지는 경우는 Skia strict replay improvement로 fixture/diagnostics에 명시하고, compatibility mismatch와 구분합니다.
crossScopeVariants, MixedPerGlyph, shapedModern layout mutation은 schema vocabulary와 validator gate는 유지하되, 실제 writer emission은 use case / corpus / backend semantics가 준비될 때까지 보류합니다.
Text IR v2 설계 상태
Text IR v2는 기존 TextRun fallback을 유지한 채, backend가 더 엄격한 text variant를 선택할 수 있는 compatibility contract를 단계적으로 여는 작업입니다.
P11: source table, source span, placement/cluster metadata, special visual op externalization, feature negotiation metadata를 추가했습니다.
P25는 native variation/TTC real corpus와 CanvasKit exact construction proof gate를 다룹니다.
P26은 authority-gated follow-up입니다.
COLRv1 추가 primitive, shapedModern, cross-scope variants, public MixedPerGlyph는 concrete corpus/use case가 생길 때까지 writer emission을 열지 않습니다.
최신 devel에는 layout/render/security 수정이 계속 들어오고 있으므로, 후속 renderer PR은 항상 최신 devel 위에서 시작합니다. broad layout fix나 extension fetch security fix는 renderer backend PR에 섞지 않고 이미 devel에 들어간 correctness/security fix를 전제로 삼습니다.
현재 진행상황
P22까지 devel에 반영되었습니다. 현재 next action은 P23입니다. P23 PR #1359에서는 PDF export를 native DocumentCore API와 CLI가 공유하는 표면으로 올리고, report-only PDF visual diff를 render-diff CI에 추가합니다. Direct/vector PDF backend와 PDF visual diff hard gate는 후속으로 분리합니다.
P1: 렌더러 프론트엔드/백엔드 1차 분리
PageLayerTree, LayerNode, PaintOp, LayerBuilder 추가
PDF는 PNG raster export와 다른 출력 계약입니다. P21에서는 PDF artifact를 baseline report에 넣지 않았으므로, export API 안정화는 별도 phase로 봅니다.
이번 PR은 native-only SVG-derived PDF export MVP를 DocumentCore::render_page_pdf_native, render_pages_pdf_native, render_document_pdf_native API로 올리고, CLI export-pdf가 같은 API를 쓰게 합니다.
render-diff CI에는 report-only PDF visual diff를 추가합니다. export-pdf 결과를 pdftoppm으로 rasterize하고 browser Canvas 출력과 비교해 JSON/Markdown summary와 artifacts를 남깁니다.
이후 PageLayerTree에서 직접 PDF/vector recording으로 가는 경로를 검토합니다.
Swift/XCFramework/FFI packaging 변경과 PDF visual diff hard gate는 후속으로 둡니다.
unsupported object는 기존 fallback을 유지합니다.
P24: Strict BitmapGlyph/SvgGlyph producer-output corpus widening
handcrafted strict payload fixture를 더 늘리는 대신 실제 lowering/resource path를 통과한 producer-output fixture를 추가합니다.
BitmapGlyph는 one producer-selected strike, deterministic alpha/scaling/filtering, no strict backendDefault, resource bytes in cache key, colorSpaceDefaulted diagnostics를 유지합니다.
SvgGlyph는 VectorResourceId, required viewBox, securityMode=staticSanitized, script/animation/external/interactivity hard false, no raw SVG-in-font replay를 유지합니다.
strictVisual without valid payload는 hard reject하고 compatibility export는 TextRun/GlyphRun fallback을 유지합니다.
CanvasKit variation/TTC는 public API path가 exact variation tuple / exact collection face construction을 증명할 때까지 variationUnsupported / faceIndexUnsupported fallback을 유지합니다.
public u32 glyph id range guard는 backend enablement 뒤에도 유지합니다.
P26: Guarded v2 authority follow-ups
COLRv1 추가 blend/composite/clip primitive는 concrete document가 있고 glyph-payload-local semantics를 유지할 때만 엽니다.
cross-scope variants는 same-scope fallback이 부족한 concrete use case가 생길 때까지 vocabulary/diagnostics만 유지합니다.
public MixedPerGlyph writer emission은 cluster/grapheme orientation, GlyphTransformRun, transform replay, vertical fixtures, backend fallback/reject policy가 안정될 때까지 homogeneous run split을 기본으로 둡니다.
합친 phase
P10은 P9에 합쳤습니다. 순수 리팩터링이라 별도 리뷰 단위로 두면 같은 text replay 코드를 두 번 보게 됩니다.
기존 P11/P12/P13은 P11로 합쳤습니다. source table, placement/cluster metadata, special visuals externalization은 모두 TextRun v2 compatibility contract를 완성하는 한 묶음입니다.
기존 P14/P15/P16은 P12로 합쳤습니다. font resource table만 따로 넣으면 consumer가 없는 foundation PR이 되고, native Skia guard는 같은 GlyphRun variant contract입니다.
P13은 diagnostics/shape profile/schema closeout을 합쳐 devel에 반영했습니다. variantOps/schema v2 compatibility는 실제 writer 전환 없이 후속 text variant adoption에서 다룹니다.
실제 P14가 GlyphOutline/Text variant adoption으로 반영됐고 P15가 diagnostics-only policy로 반영됐으므로, browser CanvasKit 구현은 P16부터 overlay-free direct renderer로 시작합니다.
image geometry/cache-key direct replay는 P18에서 완료했고, effect/filter와 broader object replay는 후속 direct replay coverage로 남깁니다.
advanced glyph payload gate는 P19로 완료했습니다. PR #1117은 payload validator, branch parity test, deterministic reject reason을 먼저 닫고, COLRv1 solid/linear/radial/sweep CanvasKit subset만 같은 gate 아래에서 열었습니다.
COLRv1 solid/linear/radial/sweep color glyph replay subset은 P19에 합쳤습니다. gate vocabulary만 두면 phase가 너무 작아지고, CanvasKit direct replay consumer가 같은 PR에 있어야 validator의 의미가 분명하기 때문입니다.
glyph payload resource corpus와 font construction proof는 P20으로 완료했습니다. resource identity/cache key와 exact typeface construction failure는 실제 glyph replay eligibility의 전제라 sweep보다 먼저 검증했습니다.
replay-plane ordering, 작은 renderer baseline manifest, surface-axis diagnostics, performance report는 P21로 완료했습니다. Large corpus manifest expansion과 PDF artifact collection은 P21에서 분리했습니다.
WebCanvas direct PaintOp replay와 layer option metadata는 P22에 합쳤습니다. 둘 다 public path 전환이 아니라 layer boundary cleanup이고, 같은 JSON/JS/Studio type contract를 확인해야 했기 때문입니다.
PDF export backend와 native render/export API packaging은 P23으로 이동했습니다. P21에서 PDF artifact collection은 분리했고, P23 PR #1359는 SVG-derived PDF export API surface를 안정화하면서 report-only PDF visual diff artifacts를 render-diff CI에 추가합니다.
strict BitmapGlyph와 SvgGlyph producer-output corpus widening은 P24에 묶습니다. 둘 다 strict payload resource family hardening이고, shared resource/cache/validator contract를 함께 확인해야 합니다.
variation font와 TTC/OTC exact replay corpus widening은 P25에 묶습니다. 둘 다 exact font construction proof와 digest/face/axis negative controls가 핵심입니다.
shapedModern, cross-scope variants, public MixedPerGlyph, 추가 COLRv1 primitive는 P26 authority-gated follow-up으로 유지합니다. concrete corpus/use case 없이 별도 구현 phase로 열지 않습니다.
제안 내용
멀티 렌더러를 안정적으로 지원할 수 있도록 렌더링 구조를 단계적으로 분리합니다.
기존에는 각 renderer가
PageRenderTree를 직접 해석하는 흐름에 가까웠습니다. 이 시리즈에서는 renderer backend가 공통으로 replay할 수 있는PageLayerTree를 중간 IR로 두고, SVG / Canvas2D / native Skia / CanvasKit / PDF export backend가 같은 layer contract를 기준으로 동작하게 합니다.이 이슈는 멀티 렌더러 작업을 리뷰 가능한 PR 단위로 나누어 추적하기 위한 tracking issue입니다. 기준은 단순히 변경 파일 수를 줄이는 것이 아니라, 각 PR이 독립적으로 설명 가능한 contract를 갖도록 만드는 것입니다.
분할 기준
TextRuncompatibility contract 단위로 묶습니다.TextRunfallback이 항상 남아 있어야 합니다.canvaskitMode=default는 direct replay 우선이며 Canvas2D overlay로 조용히 숨기지 않습니다.canvaskitMode=compat도 overlay fallback이 아니라 더 보수적인 CanvasKit direct replay policy입니다.Skia strict replay improvement로 fixture/diagnostics에 명시하고, compatibility mismatch와 구분합니다.최신 확인 결과 (2026-06-10)
devel은4574299f기준입니다. P22는 PR #1346으로 devel에 반영되었고 merge commit은2bc411f4입니다. 이후 devel에는 fix(hwpx): 그림 effects/shadow roundtrip 보존 #1349, Task #1350 useFontSpace 직렬화 시 항상 false 고정 (IR 값 무시) #1351, #1354도 반영되어 있습니다.default/compat모두 hidden Canvas2D overlay 없는 direct replay contract.c54e80d0,3945a937,225e8229,4d1938e7,90f6fa84,606505bd입니다.export-pdf결과와 browser Canvas 출력을 비교하는 report-only PDF visual diff를 추가했습니다.DocumentCorenative API와 CLI가 공유하는 표면으로 올리고, render-diff CI에 report-only PDF visual diff summary/artifacts를 추가합니다.BitmapGlyph/SvgGlyph, variation/TTC, shapedModern/cross-scope/MixedPerGlyph는 writer-ready 선언이 아니라 producer-output corpus와 proof gate 중심으로 유지합니다.계획 업데이트 (2026-06-10)
CanvasKit 방향은 overlay fallback을 줄이는 수준이 아니라, browser CanvasKit과 future native Skia가 같은 replay contract를 공유할 수 있도록 overlay-free direct replay를 기본 전제로 둡니다. P16-P21이 devel에 반영되었으므로 이후 계획은 “초기 renderer 도입”이 아니라 “direct replay coverage를 어떤 contract 단위로 넓히고 검증할지”가 기준입니다.
canvaskitMode=default: direct CanvasKit replay 우선.canvaskitMode=compat: Canvas2D overlay fallback이 아니라 conservative CanvasKit direct replay policy.canvaskitSurface=auto|webgpu|webgl|software: render mode와 별도인 diagnostics axis. browser baseline, native-vs-CanvasKit parity report, aggregate Markdown report에 요청 surface와 fallback reason을 보존합니다.compatdirect replay reporting, bridge fallback safety, schema metadata sync, deterministic reject reason 기준을 먼저 닫았습니다.payloadResourceKey, cache-key/resource identity, face index/variation/exact typeface construction failure diagnostics를 묶어서 GlyphRun/GlyphOutline replay eligibility 전제를 단단히 했습니다.Full Renderer Sweepmanual workflow, browser/native baseline report, surface axis diagnostics를 정리했습니다. Large corpus 확장과 PDF artifact 수집은 P21에 넣지 않았습니다.buildOptions/debugOptions/outputOptionscontract를 명확히 했습니다.DocumentCorenative API로 올리고 CLIexport-pdf가 같은 API를 쓰도록 정리합니다. render-diff CI에는 report-only PDF visual diff를 추가해export-pdfraster와 browser Canvas 출력의 차이를 summary/artifact로 남깁니다. Direct/vectorPageLayerTree -> PDF, PDF visual diff hard gate, Swift/XCFramework/FFI packaging 변경은 후속으로 남깁니다.BitmapGlyph/SvgGlyphproducer-output corpus widening입니다. 기존 handcrafted payload fixture를 더 늘리는 게 아니라, 실제 lowering/resource path를 통과한 one-strike bitmap payload와 sanitized static vector payload를 corpus로 추가합니다.MixedPerGlyphwriter emission은 concrete document/use case와 fallback/reject policy가 준비될 때까지 보류합니다.Skia strict replay improvement로 fixture/diagnostics에 명시하고, compatibility mismatch와 구분합니다.crossScopeVariants,MixedPerGlyph,shapedModernlayout mutation은 schema vocabulary와 validator gate는 유지하되, 실제 writer emission은 use case / corpus / backend semantics가 준비될 때까지 보류합니다.Text IR v2 설계 상태
Text IR v2는 기존
TextRunfallback을 유지한 채, backend가 더 엄격한 text variant를 선택할 수 있는 compatibility contract를 단계적으로 여는 작업입니다.GlyphRunoptional sidecar와 font/blob/face identity contract를 추가했습니다. native Skia와 Canvas2D/layered SVG는 fallback을 유지합니다.textV2diagnostics, validation issue, line-break risk telemetry, fallback-free profile guard를 schema minor1.10으로 정리했습니다.GlyphOutlinestrict sidecar와 backend text variant selection diagnostics를 schema minor1.11로 추가했습니다. 기존 renderers는TextRunfallback을 유지했습니다.GlyphOutlinepayload vocabulary와 COLRv1 bounded graph contract를 schema minor1.14로 추가했습니다. CanvasKit은 solid/linear/radial/full-circle sweep gradient subset만 direct replay하고, 나머지는 deterministic reject와TextRunfallback을 유지합니다.payloadResourceKey, resource table minor1.4, native font-construction proof diagnostics를 추가했습니다. exact glyph-id replay는 proof가 있는 native cases로만 제한하고, CanvasKit variation/TTC는 conservative fallback을 유지합니다.비목표도 유지합니다.
GlyphRun/GlyphOutline을 canonical text path로 전환하지 않습니다.P16 이후 보존/이동한 수정 방향
P16이 devel에 반영되었으므로, 이후 phase는 CanvasKit direct replay renderer를 더 크게 만드는 방식이 아니라 contract 단위로 안정성을 넓히는 방식으로 갑니다.
defaultmode에서는 unsupported op를 Canvas2D overlay로 조용히 가리지 않습니다.compatmode도 Canvas2D overlay fallback이 아니라 conservative direct replay mode입니다.compatdirect replay reportingGlyphRun/GlyphOutline은 canonical path가 아니라 gated text variant입니다.GlyphOutline은 genericPath처럼 섞지 않고 text variant gate로만 다룹니다.GlyphOutlinereplay branch parity를payloadKind,colorFormat, COLRv1 graphnode.kind기준으로 검증했습니다.payloadResourceKey로 color/bitmap/SVG glyph sidecar resource/cache identity를 분리했습니다.buildOptions,debugOptions,outputOptions는 build-time metadata, debug display metadata, replay semantics를 구분해서 내보냅니다.DocumentCorenative API와 CLI가 공유하는 표면으로 올립니다.export-pdfraster와 browser Canvas 출력의 차이를 JSON/Markdown summary와 artifact로 남깁니다.BitmapGlyph/SvgGlyphproducer-output corpus를 추가합니다.MixedPerGlyph는 concrete corpus/use case가 생길 때까지 writer emission을 열지 않습니다.현재 진행상황
P22까지 devel에 반영되었습니다. 현재 next action은 P23입니다. P23 PR #1359에서는 PDF export를 native
DocumentCoreAPI와 CLI가 공유하는 표면으로 올리고, report-only PDF visual diff를 render-diff CI에 추가합니다. Direct/vector PDF backend와 PDF visual diff hard gate는 후속으로 분리합니다.P1: 렌더러 프론트엔드/백엔드 1차 분리
PageLayerTree,LayerNode,PaintOp,LayerBuilder추가P2: Canvas 렌더링을
PageLayerTree기반으로 전환renderPageToCanvas를 layer replay 경로로 전환P3: Canvas visual diff 테스트 추가
P4: native Skia PNG raster backend 추가
native-skiafeature 추가PageLayerTree기반 Skia replay 구현P5: native Skia equation replay 추가
EquationNode.layout_box기반 replayP6: native Skia raw SVG fragment replay
RawSvgNode.svgfragment를 안전한 wrapper SVG로 감싼 뒤resvg/tiny-skia로 rasterizeP7: native Skia form control static replay
P8: Layer IR schema/resource key hardening
paint/schema.rs추가P9: native Skia text replay parity + module split
TextRunNode의 char overlap, tab leader, control mark, decoration, vertical rotation 정보를 소비하도록 보강renderer/skia/text_replay.rs로 분리P10: P9에 fold
P11: Text IR v2 compatibility contract
docs/text-ir-v2.md에 migration contract 문서화P12: Guarded GlyphRun variant contract
TextRunfallback을 유지한 상태에서GlyphRunoptional sidecar variant 도입249e5653; squashed feature commit:08af19b6P13: Text IR v2 diagnostics/schema closure
TextV2Diagnostics, slot diagnostics, validation issue, line-break risk, compatibility profile 추가1.1047c3e756P14: GlyphOutline text variant adoption + backend selection diagnostics
PaintOp::GlyphOutlinestrict sidecar contract 추가1.11text.glyphOutline/text.glyphOutline.strictSidecarJSON feature metadata 추가analyze_text_variant_selectionbackend selection diagnostics API 추가GlyphOutline을 직접 그리지 않고TextRunfallback을 유지586d914aP15: CanvasKit replay policy diagnostics
getCanvasKitReplayPlan(page, mode)diagnostics-only API 추가default/compatmode contract와 hidden overlay inventory 추가default는 hidden Canvas2D overlay를 금지하고,compat는 transition overlay를 명시적으로 보고하는 P15 기준 policy plan입니다.compat도 Canvas2D overlay fallback이 아니라 conservative direct replay policy로 구현합니다.e94b1d01P16: Browser CanvasKit direct renderer and overlay-free mode split
PageLayerTree를 직접 replay하며 Canvas2D overlay pass를 backend contract로 들여오지 않습니다.render-backend.ts에서canvas2d/canvaskitbackend,renderer=skiaalias,canvaskitMode=default|compat,canvaskitSurface=auto|webgpu|webgl|software,renderProfileresolver를 정리했습니다.defaultmode는 native-preparation direct replay입니다.compatmode는 conservative direct replay입니다. clip padding, sampling, variant selection, cache policy는 보수적으로 고를 수 있지만 Canvas2D paint를 덮는 fallback pass는 쓰지 않습니다.getPageLayerTreeObject(page, profile)bridge는 JSON parse/shape validation을 수행하고, legacy empty layer shape는 안전한 emptyPageLayerTree로 낮춥니다.3d4a9c34; feature commit:933c056e; follow-up docs commit:20482412P17: CanvasKit direct replay contract hardening
compatmode가 Canvas2D overlay fallback이 아니라 direct replay contract로 보고되도록 native/WASM/Studio diagnostics를 정리했습니다.DIRECT_ONLY계약으로 모아 hidden overlay 허용 여부와 direct replay required 여부를 한 곳에서 설명합니다.hiddenCanvas2dOverlayAllowed=false,directReplayRequired=truecontract를 유지합니다.LAYER_TREE_SCHEMA동기화 테스트를 보강했습니다.dbfd7563,06047e53; review/report commit:2b1cdb40P18: CanvasKit image replay coverage expansion
crop,originalSize,fillMode,transformpayload를 소비하도록 확장합니다.imageRef의 다른 payload 충돌을 막습니다.getCanvasKitReplayPlan은 simple image를 direct로 보고, image effect / brightness / contrast는 아직 diagnostics/detail로 남깁니다.6cbd25ea; 처리 기록 commit:17f6ad84P19: Text/glyph advanced payload gates + COLRv1 supported replay subset
c54e80d0,3945a937,225e8229,4d1938e7,90f6fa84,606505bd1.14와text.glyphOutline.advancedPayloadsfeature metadata를 추가했습니다.P20: Glyph payload resource corpus and font construction proof
0f1c22ba1.15, resource table minor1.4payloadResourceKey로 color/bitmap/SVG glyph sidecar resource/cache identity를 분리했습니다.ResourceArenafont blob ref lookup과 native Skia glyph-run replay proof diagnostics를 추가했습니다.P21: Renderer sweep, replay-plane ordering, surface axis, and report artifacts
785f5ef7scripts/renderer_baseline.pyreport pipeline을 추가했습니다.Full Renderer Sweepmanual workflow를 추가했습니다.P22: WebCanvas direct PaintOp replay and layer option metadata closure
2bc411f4PaintOpleaf payload를 직접 소비하도록 legacy wrapper adapter를 줄였습니다.buildOptions,debugOptions,outputOptionsmetadata를 분리하고 legacyoutputOptionsmirror를 compatibility field로 유지했습니다.다음 분할 후보
P23: PDF export and native render/export API packaging
DocumentCore::render_page_pdf_native,render_pages_pdf_native,render_document_pdf_nativeAPI로 올리고, CLIexport-pdf가 같은 API를 쓰게 합니다.export-pdf결과를pdftoppm으로 rasterize하고 browser Canvas 출력과 비교해 JSON/Markdown summary와 artifacts를 남깁니다.PageLayerTree에서 직접 PDF/vector recording으로 가는 경로를 검토합니다.P24: Strict BitmapGlyph/SvgGlyph producer-output corpus widening
BitmapGlyph는 one producer-selected strike, deterministic alpha/scaling/filtering, no strictbackendDefault, resource bytes in cache key,colorSpaceDefaulteddiagnostics를 유지합니다.SvgGlyph는VectorResourceId, requiredviewBox,securityMode=staticSanitized, script/animation/external/interactivity hard false, no raw SVG-in-font replay를 유지합니다.TextRun/GlyphRunfallback을 유지합니다.P25: Exact font replay corpus widening
variationUnsupported/faceIndexUnsupportedfallback을 유지합니다.u32glyph id range guard는 backend enablement 뒤에도 유지합니다.P26: Guarded v2 authority follow-ups
MixedPerGlyphwriter emission은 cluster/grapheme orientation,GlyphTransformRun, transform replay, vertical fixtures, backend fallback/reject policy가 안정될 때까지 homogeneous run split을 기본으로 둡니다.합친 phase
variantOps/schema v2 compatibility는 실제 writer 전환 없이 후속 text variant adoption에서 다룹니다.BitmapGlyph와SvgGlyphproducer-output corpus widening은 P24에 묶습니다. 둘 다 strict payload resource family hardening이고, shared resource/cache/validator contract를 함께 확인해야 합니다.MixedPerGlyph, 추가 COLRv1 primitive는 P26 authority-gated follow-up으로 유지합니다. concrete corpus/use case 없이 별도 구현 phase로 열지 않습니다.별도 트래킹
export-pngVLM preset 확장완료 기준
PageLayerTree기반으로 안정적으로 동작함PageLayerTreeJSON / JS export가 backend replay에 필요한 주요 정보를 안정적으로 보존함TextRunfallback이 유지되고 native Skia는 exact blob-backed typeface replay 전까지 fallback을 유지함textV2diagnostics contract로 설명함TextRunfallback이 유지됨default/compat모두 hidden Canvas2D overlay 없이 direct replay backend로 동작함GlyphOutlinereplay branch parity가payloadKind,colorFormat, COLRv1 graph node 기준으로 검증됨buildOptions/debugOptions/outputOptionsmetadata가 JSON/JS/Studio 타입과 backend replay semantics에서 일관됨GlyphRungate와GlyphOutlinestrict sidecar가TextRunfallback, deterministic fallback reason, anchor/fallback/monochrome fill-only 조건을 공유하고 genericPath로 섞이지 않음BitmapGlyphproducer-output corpus가 one-strike resource, deterministic scaling/filtering, color-space default diagnostics, cache-key contract를 검증함SvgGlyphproducer-output corpus가 sanitized static vector resource, requiredviewBox, hard-false safety flags, no raw SVG replay contract를 검증함MixedPerGlyph, 추가 COLRv1 primitive가 concrete corpus/use case 없이 writer emission으로 열리지 않음참고