pagyra-js 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/.eslintrc.json +30 -0
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +275 -0
  4. package/UA_Styles_Chromium.md +93 -0
  5. package/_ext/woff2_conversion/brotli-decode.d.ts +139 -0
  6. package/_ext/woff2_conversion/brotli-encode.d.ts +129 -0
  7. package/_ext/woff2_conversion/brotli-port.d.ts +12 -0
  8. package/_ext/woff2_conversion/brotli-shared-dictionary.d.ts +25 -0
  9. package/_ext/woff2_conversion/brotli-types.d.ts +15 -0
  10. package/_ext/woff2_conversion/woff2-common.d.ts +37 -0
  11. package/_ext/woff2_conversion/woff2-decode.d.ts +32 -0
  12. package/_ext/woff2_conversion/woff2-encode.d.ts +31 -0
  13. package/_ext/woff2_conversion/woff2-output.d.ts +39 -0
  14. package/_ext/woff2_original_cpp/brotli/brotli.c +1559 -0
  15. package/_ext/woff2_original_cpp/brotli/brotli.md +116 -0
  16. package/_ext/woff2_original_cpp/brotli/decode.h +409 -0
  17. package/_ext/woff2_original_cpp/brotli/encode.h +505 -0
  18. package/_ext/woff2_original_cpp/brotli/port.h +302 -0
  19. package/_ext/woff2_original_cpp/brotli/shared_dictionary.h +100 -0
  20. package/_ext/woff2_original_cpp/brotli/types.h +83 -0
  21. package/_ext/woff2_original_cpp/cmake/FindBrotliDec.cmake +35 -0
  22. package/_ext/woff2_original_cpp/cmake/FindBrotliEnc.cmake +35 -0
  23. package/_ext/woff2_original_cpp/include/woff2/decode.h +36 -0
  24. package/_ext/woff2_original_cpp/include/woff2/encode.h +43 -0
  25. package/_ext/woff2_original_cpp/include/woff2/output.h +86 -0
  26. package/_ext/woff2_original_cpp/src/buffer.h +164 -0
  27. package/_ext/woff2_original_cpp/src/convert_woff2ttf_fuzzer.cc +13 -0
  28. package/_ext/woff2_original_cpp/src/convert_woff2ttf_fuzzer_new_entry.cc +12 -0
  29. package/_ext/woff2_original_cpp/src/file.h +30 -0
  30. package/_ext/woff2_original_cpp/src/font.cc +400 -0
  31. package/_ext/woff2_original_cpp/src/font.h +105 -0
  32. package/_ext/woff2_original_cpp/src/glyph.cc +383 -0
  33. package/_ext/woff2_original_cpp/src/glyph.h +71 -0
  34. package/_ext/woff2_original_cpp/src/normalize.cc +314 -0
  35. package/_ext/woff2_original_cpp/src/normalize.h +39 -0
  36. package/_ext/woff2_original_cpp/src/port.h +66 -0
  37. package/_ext/woff2_original_cpp/src/round.h +27 -0
  38. package/_ext/woff2_original_cpp/src/store_bytes.h +55 -0
  39. package/_ext/woff2_original_cpp/src/table_tags.cc +82 -0
  40. package/_ext/woff2_original_cpp/src/table_tags.h +30 -0
  41. package/_ext/woff2_original_cpp/src/transform.cc +430 -0
  42. package/_ext/woff2_original_cpp/src/transform.h +26 -0
  43. package/_ext/woff2_original_cpp/src/variable_length.cc +129 -0
  44. package/_ext/woff2_original_cpp/src/variable_length.h +30 -0
  45. package/_ext/woff2_original_cpp/src/woff2_common.cc +50 -0
  46. package/_ext/woff2_original_cpp/src/woff2_common.h +64 -0
  47. package/_ext/woff2_original_cpp/src/woff2_compress.cc +43 -0
  48. package/_ext/woff2_original_cpp/src/woff2_dec.cc +1398 -0
  49. package/_ext/woff2_original_cpp/src/woff2_decompress.cc +41 -0
  50. package/_ext/woff2_original_cpp/src/woff2_enc.cc +458 -0
  51. package/_ext/woff2_original_cpp/src/woff2_info.cc +142 -0
  52. package/_ext/woff2_original_cpp/src/woff2_out.cc +63 -0
  53. package/assets/fonts/ttf/arimo/Arimo-Bold.ttf +0 -0
  54. package/assets/fonts/ttf/arimo/Arimo-BoldItalic.ttf +0 -0
  55. package/assets/fonts/ttf/arimo/Arimo-Italic.ttf +0 -0
  56. package/assets/fonts/ttf/arimo/Arimo-Regular.ttf +0 -0
  57. package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Black.ttf +0 -0
  58. package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Bold.ttf +0 -0
  59. package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Regular.ttf +0 -0
  60. package/assets/fonts/ttf/dejavu/DejaVuSans.ttf +0 -0
  61. package/assets/fonts/ttf/firecode/FiraCode-Bold.ttf +0 -0
  62. package/assets/fonts/ttf/firecode/FiraCode-Light.ttf +0 -0
  63. package/assets/fonts/ttf/firecode/FiraCode-Medium.ttf +0 -0
  64. package/assets/fonts/ttf/firecode/FiraCode-Regular.ttf +0 -0
  65. package/assets/fonts/ttf/firecode/FiraCode-SemiBold.ttf +0 -0
  66. package/assets/fonts/ttf/notoemoji/NotoEmoji-Bold.ttf +0 -0
  67. package/assets/fonts/ttf/notoemoji/NotoEmoji-Light.ttf +0 -0
  68. package/assets/fonts/ttf/notoemoji/NotoEmoji-Medium.ttf +0 -0
  69. package/assets/fonts/ttf/notoemoji/NotoEmoji-Regular.ttf +0 -0
  70. package/assets/fonts/ttf/notoemoji/NotoEmoji-SemiBold.ttf +0 -0
  71. package/assets/fonts/ttf/notosans/NotoSans-Regular.ttf +0 -0
  72. package/assets/fonts/ttf/roboto/Roboto-Bold.ttf +0 -0
  73. package/assets/fonts/ttf/roboto/Roboto-BoldItalic.ttf +0 -0
  74. package/assets/fonts/ttf/roboto/Roboto-Italic.ttf +0 -0
  75. package/assets/fonts/ttf/roboto/Roboto-Regular.ttf +0 -0
  76. package/assets/fonts/ttf/stixtwomath/STIXTwoMath-Regular.ttf +0 -0
  77. package/assets/fonts/ttf/tinos/Tinos-Bold.ttf +0 -0
  78. package/assets/fonts/ttf/tinos/Tinos-BoldItalic.ttf +0 -0
  79. package/assets/fonts/ttf/tinos/Tinos-Italic.ttf +0 -0
  80. package/assets/fonts/ttf/tinos/Tinos-Regular.ttf +0 -0
  81. package/assets/fonts/woff/lato/lato-latin-400-italic.woff +0 -0
  82. package/assets/fonts/woff/lato/lato-latin-400-normal.woff +0 -0
  83. package/assets/fonts/woff/lato/lato-latin-700-italic.woff +0 -0
  84. package/assets/fonts/woff/lato/lato-latin-700-normal.woff +0 -0
  85. package/assets/fonts/woff2/caveat/Caveat-Bold.woff2 +0 -0
  86. package/assets/fonts/woff2/caveat/Caveat-Regular.woff2 +0 -0
  87. package/assets/fonts/woff2/lato/lato-latin-400-italic.woff2 +0 -0
  88. package/assets/fonts/woff2/lato/lato-latin-400-normal.woff2 +0 -0
  89. package/assets/fonts/woff2/lato/lato-latin-700-italic.woff2 +0 -0
  90. package/assets/fonts/woff2/lato/lato-latin-700-normal.woff2 +0 -0
  91. package/docs/AGENTS.md +288 -0
  92. package/docs/BACKGROUND-REPEAT-IMPLEMENTATION.md +127 -0
  93. package/docs/BACKGROUND-REPEAT-REFERENCE.md +127 -0
  94. package/docs/BACKGROUND-REPEAT-SPACE-ROUND.md +164 -0
  95. package/docs/css-properties-support.md +256 -0
  96. package/docs/src_modules_table.md +172 -0
  97. package/docs/text-overlap-fix.md +85 -0
  98. package/docs/text-overlap-investigation.md +27 -0
  99. package/eslint.config.js +36 -0
  100. package/glyph_measure.htm +1458 -0
  101. package/package.json +50 -0
  102. package/playground/browser-entry.ts +2 -0
  103. package/playground/exports/background-text-debug.pdf +0 -0
  104. package/playground/public/app.js +875 -0
  105. package/playground/public/assets/1.webp +0 -0
  106. package/playground/public/examples/accents-test.html +24 -0
  107. package/playground/public/examples/advanced-selectors-demo.html +118 -0
  108. package/playground/public/examples/background-advanced-showcase.html +82 -0
  109. package/playground/public/examples/background-clip-text.html +36 -0
  110. package/playground/public/examples/background-origin-showcase.html +137 -0
  111. package/playground/public/examples/background-position-showcase.html +83 -0
  112. package/playground/public/examples/background-repeat-showcase.html +83 -0
  113. package/playground/public/examples/background-repeat-space-round.html +348 -0
  114. package/playground/public/examples/background-size-showcase.html +82 -0
  115. package/playground/public/examples/background-text-debug.html +18 -0
  116. package/playground/public/examples/baseline-test.html +24 -0
  117. package/playground/public/examples/bold-showcase.html +150 -0
  118. package/playground/public/examples/bold-strike-example.html +12 -0
  119. package/playground/public/examples/border-collapse-test.html +23 -0
  120. package/playground/public/examples/centered-shadow-div.html +72 -0
  121. package/playground/public/examples/css-variables.html +50 -0
  122. package/playground/public/examples/debug-accents.html +11 -0
  123. package/playground/public/examples/debug-text-overlap.html +46 -0
  124. package/playground/public/examples/flex-gap-column.html +130 -0
  125. package/playground/public/examples/flex-gap-row.html +137 -0
  126. package/playground/public/examples/flex-padding-test.html +29 -0
  127. package/playground/public/examples/flexbox-text-test.html +193 -0
  128. package/playground/public/examples/fonts-demo.html +126 -0
  129. package/playground/public/examples/footer-example.html +4 -0
  130. package/playground/public/examples/gradient-text.html +54 -0
  131. package/playground/public/examples/grid-gap-demo.html +156 -0
  132. package/playground/public/examples/header-example.html +4 -0
  133. package/playground/public/examples/header-footer-example.html +27 -0
  134. package/playground/public/examples/image-showcase.html +33 -0
  135. package/playground/public/examples/justify-text.html +22 -0
  136. package/playground/public/examples/linear-gradient-example.html +38 -0
  137. package/playground/public/examples/lorem-span.html +14 -0
  138. package/playground/public/examples/margin-block-showcase.html +21 -0
  139. package/playground/public/examples/margin-inline-showcase.html +21 -0
  140. package/playground/public/examples/monthly-summary.html +95 -0
  141. package/playground/public/examples/multi-page-lorem.html +190 -0
  142. package/playground/public/examples/opacity-debug.html +39 -0
  143. package/playground/public/examples/opacity-example.html +70 -0
  144. package/playground/public/examples/png-image-example.html +13 -0
  145. package/playground/public/examples/red-rectangle.html +18 -0
  146. package/playground/public/examples/repro.html +24 -0
  147. package/playground/public/examples/rounded-borders-test.html +24 -0
  148. package/playground/public/examples/simple-list.html +89 -0
  149. package/playground/public/examples/simple-svg.html +37 -0
  150. package/playground/public/examples/simple-table.html +52 -0
  151. package/playground/public/examples/skew-div.html +138 -0
  152. package/playground/public/examples/skew-text.html +21 -0
  153. package/playground/public/examples/starter-report.css +51 -0
  154. package/playground/public/examples/starter-report.html +23 -0
  155. package/playground/public/examples/svg-aspect-ratio-showcase.html +116 -0
  156. package/playground/public/examples/svg-gradients-linear.html +28 -0
  157. package/playground/public/examples/svg-gradients-radial.html +29 -0
  158. package/playground/public/examples/svg-gradients-showcase.html +66 -0
  159. package/playground/public/examples/svg-image-path-test.html +43 -0
  160. package/playground/public/examples/svg-images-clipping.html +27 -0
  161. package/playground/public/examples/svg-path-gallery.html +118 -0
  162. package/playground/public/examples/svg-radial-transform-demo.html +78 -0
  163. package/playground/public/examples/svg-transform-stack.html +103 -0
  164. package/playground/public/examples/svg-transforms-demo.html +127 -0
  165. package/playground/public/examples/table-merge-test.html +34 -0
  166. package/playground/public/examples/text-decoration-showcase.html +138 -0
  167. package/playground/public/examples/text-indent-showcase.html +137 -0
  168. package/playground/public/examples/text-shadow-example.html +29 -0
  169. package/playground/public/examples/very-complex-css.html +293 -0
  170. package/playground/public/examples/webp-example.html +13 -0
  171. package/playground/public/examples/z-index-demo.html +93 -0
  172. package/playground/public/examples.json +240 -0
  173. package/playground/public/images/dice.png +0 -0
  174. package/playground/public/images/duck.jpg +0 -0
  175. package/playground/public/index.html +149 -0
  176. package/playground/public/mode.js +1 -0
  177. package/playground/public/styles.css +382 -0
  178. package/playground/public/tmp-h2-debug.html +33 -0
  179. package/playground/public/tmp-italic-debug.html +32 -0
  180. package/playground/public/vendor/codemirror/codemirror.min.css +1 -0
  181. package/playground/public/vendor/codemirror/codemirror.min.js +1 -0
  182. package/playground/public/vendor/codemirror/css.min.js +1 -0
  183. package/playground/public/vendor/codemirror/darcula.min.css +1 -0
  184. package/playground/public/vendor/codemirror/htmlmixed.min.js +1 -0
  185. package/playground/public/vendor/codemirror/javascript.min.js +1 -0
  186. package/playground/public/vendor/codemirror/xml.min.js +1 -0
  187. package/playground/public/vendor/pagyra-playground-browser.js +165966 -0
  188. package/playground/public/vendor/pagyra-playground-browser.js.map +7 -0
  189. package/playground/server.d.ts +1 -0
  190. package/playground/server.js +68 -0
  191. package/playground/server.ts +128 -0
  192. package/scripts/browser-build.ts +101 -0
  193. package/scripts/build-browser-bundle.ts +52 -0
  194. package/scripts/glyph-comparison/simulate.ts +744 -0
  195. package/scripts/playground-browser-server.ts +57 -0
  196. package/scripts/probe-roboto.ts +6 -0
  197. package/scripts/render-playground-example.ts +121 -0
  198. package/scripts/run-glyph-atlas-tuner-runner.mjs +113 -0
  199. package/scripts/run-glyph-atlas-tuner.ts +141 -0
  200. package/scripts/top-ts-files.ps1 +39 -0
  201. package/scripts/top-ts-files.sh +37 -0
  202. package/scripts/woff2_info.ps1 +132 -0
  203. package/src/browser-entry.ts +14 -0
  204. package/src/compression/adler32.ts +45 -0
  205. package/src/compression/brotli/brotli.ts +463 -0
  206. package/src/compression/brotli/index.ts +15 -0
  207. package/src/compression/brotli/transform.ts +184 -0
  208. package/src/compression/brotli/types.ts +58 -0
  209. package/src/compression/brotli/utils.ts +157 -0
  210. package/src/compression/brotli/vendor/bit_reader.js +124 -0
  211. package/src/compression/brotli/vendor/context.js +250 -0
  212. package/src/compression/brotli/vendor/decode.d.ts +2 -0
  213. package/src/compression/brotli/vendor/decode.js +938 -0
  214. package/src/compression/brotli/vendor/dictionary-data.js +9469 -0
  215. package/src/compression/brotli/vendor/dictionary.js +36 -0
  216. package/src/compression/brotli/vendor/huffman.js +123 -0
  217. package/src/compression/brotli/vendor/package.json +3 -0
  218. package/src/compression/brotli/vendor/prefix.js +60 -0
  219. package/src/compression/brotli/vendor/streams.js +31 -0
  220. package/src/compression/brotli/vendor/transform.js +247 -0
  221. package/src/compression/brotli/vendor-decode.d.ts +4 -0
  222. package/src/compression/brotli/woff2-glyf-transform.ts +623 -0
  223. package/src/compression/decompress.ts +16 -0
  224. package/src/compression/deflate.ts +295 -0
  225. package/src/compression/index.ts +4 -0
  226. package/src/compression/types.ts +26 -0
  227. package/src/compression/utils.ts +107 -0
  228. package/src/core.ts +18 -0
  229. package/src/css/apply-declarations.ts +86 -0
  230. package/src/css/background-types.ts +65 -0
  231. package/src/css/browser-defaults.ts +16 -0
  232. package/src/css/clip-path-types.ts +13 -0
  233. package/src/css/compute-style.ts +494 -0
  234. package/src/css/css-unit-resolver.ts +65 -0
  235. package/src/css/custom-properties.ts +215 -0
  236. package/src/css/enums.ts +127 -0
  237. package/src/css/font-face-parser.ts +233 -0
  238. package/src/css/font-weight.ts +65 -0
  239. package/src/css/inline-style-parser.ts +27 -0
  240. package/src/css/layout-property-resolver.ts +75 -0
  241. package/src/css/length.ts +141 -0
  242. package/src/css/line-height.ts +96 -0
  243. package/src/css/named-colors.ts +150 -0
  244. package/src/css/parsers/background-parser-extended.ts +111 -0
  245. package/src/css/parsers/background-parser.ts +456 -0
  246. package/src/css/parsers/border-block-parser.ts +26 -0
  247. package/src/css/parsers/border-inline-parser.ts +26 -0
  248. package/src/css/parsers/border-parser-extended.ts +256 -0
  249. package/src/css/parsers/border-parser.ts +175 -0
  250. package/src/css/parsers/box-shadow-parser.ts +106 -0
  251. package/src/css/parsers/clip-path-parser.ts +92 -0
  252. package/src/css/parsers/color-parser.ts +14 -0
  253. package/src/css/parsers/dimension-parser.ts +117 -0
  254. package/src/css/parsers/display-flex-parser.ts +59 -0
  255. package/src/css/parsers/flex-parser.ts +144 -0
  256. package/src/css/parsers/font-parser.ts +40 -0
  257. package/src/css/parsers/gradient-parser.ts +366 -0
  258. package/src/css/parsers/grid-parser-extended.ts +55 -0
  259. package/src/css/parsers/grid-parser.ts +218 -0
  260. package/src/css/parsers/length-parser.ts +95 -0
  261. package/src/css/parsers/list-style-parser.ts +39 -0
  262. package/src/css/parsers/margin-block-parser.ts +12 -0
  263. package/src/css/parsers/margin-inline-parser.ts +12 -0
  264. package/src/css/parsers/margin-parser.ts +30 -0
  265. package/src/css/parsers/opacity-parser.ts +32 -0
  266. package/src/css/parsers/overflow-wrap-parser.ts +38 -0
  267. package/src/css/parsers/padding-block-parser.ts +12 -0
  268. package/src/css/parsers/padding-inline-parser.ts +12 -0
  269. package/src/css/parsers/padding-parser.ts +30 -0
  270. package/src/css/parsers/position-parser.ts +75 -0
  271. package/src/css/parsers/register-parsers.ts +302 -0
  272. package/src/css/parsers/registry.ts +18 -0
  273. package/src/css/parsers/text-parser-extended.ts +144 -0
  274. package/src/css/parsers/text-parser.ts +25 -0
  275. package/src/css/parsers/text-shadow-parser.ts +94 -0
  276. package/src/css/properties/box-model.ts +82 -0
  277. package/src/css/properties/flexbox.ts +44 -0
  278. package/src/css/properties/gap.ts +14 -0
  279. package/src/css/properties/grid.ts +94 -0
  280. package/src/css/properties/layout.ts +59 -0
  281. package/src/css/properties/misc.ts +44 -0
  282. package/src/css/properties/typography.ts +71 -0
  283. package/src/css/properties/visual.ts +68 -0
  284. package/src/css/selectors/matcher.ts +219 -0
  285. package/src/css/selectors/parser.ts +163 -0
  286. package/src/css/selectors/simple-key.ts +31 -0
  287. package/src/css/selectors/specificity.ts +41 -0
  288. package/src/css/selectors/types.ts +31 -0
  289. package/src/css/shorthands/border-shorthand.ts +68 -0
  290. package/src/css/shorthands/box-shorthand.ts +33 -0
  291. package/src/css/style-inheritance.ts +50 -0
  292. package/src/css/style.ts +402 -0
  293. package/src/css/ua-defaults/base-defaults.ts +266 -0
  294. package/src/css/ua-defaults/browser-defaults.ts +134 -0
  295. package/src/css/ua-defaults/element-defaults.ts +374 -0
  296. package/src/css/ua-defaults/types.ts +43 -0
  297. package/src/css/unit-conversion.ts +24 -0
  298. package/src/css/utils.ts +108 -0
  299. package/src/css/viewport.ts +17 -0
  300. package/src/debug/audit.ts +20 -0
  301. package/src/debug/ids.ts +13 -0
  302. package/src/debug/log.js +28 -0
  303. package/src/debug/log.ts +52 -0
  304. package/src/debug/tree.ts +57 -0
  305. package/src/dom/node.ts +133 -0
  306. package/src/environment/browser-environment.ts +78 -0
  307. package/src/environment/environment.ts +35 -0
  308. package/src/environment/global.ts +13 -0
  309. package/src/environment/node-environment.browser.ts +28 -0
  310. package/src/environment/node-environment.ts +64 -0
  311. package/src/fonts/detector.ts +28 -0
  312. package/src/fonts/engines/ttf-engine.ts +28 -0
  313. package/src/fonts/engines/woff-engine.ts +38 -0
  314. package/src/fonts/engines/woff2-engine.ts +41 -0
  315. package/src/fonts/extractors/metrics-extractor.ts +362 -0
  316. package/src/fonts/font-registry-resolver.ts +132 -0
  317. package/src/fonts/index.ts +3 -0
  318. package/src/fonts/orchestrator.ts +92 -0
  319. package/src/fonts/parsers/base-parser.ts +23 -0
  320. package/src/fonts/types.ts +85 -0
  321. package/src/fonts/utils/ttf-reconstructor.ts +120 -0
  322. package/src/fonts/woff/decoder.ts +105 -0
  323. package/src/fonts/woff2/buffer.ts +106 -0
  324. package/src/fonts/woff2/decoder.ts +981 -0
  325. package/src/geometry/box.ts +48 -0
  326. package/src/geometry/matrix.ts +59 -0
  327. package/src/html/css/parse-css.ts +85 -0
  328. package/src/html/dom-converter.ts +433 -0
  329. package/src/html/image-converter.ts +200 -0
  330. package/src/html-to-pdf.ts +410 -0
  331. package/src/image/base-decoder.ts +149 -0
  332. package/src/image/image-service.ts +188 -0
  333. package/src/image/jpeg-decoder.ts +73 -0
  334. package/src/image/png-decoder.ts +550 -0
  335. package/src/image/types.ts +20 -0
  336. package/src/image/webp-decoder.ts +242 -0
  337. package/src/image/webp-huffman.ts +218 -0
  338. package/src/image/webp-riff-parser.ts +54 -0
  339. package/src/image/webp-vp8l-decoder.ts +199 -0
  340. package/src/index.ts +35 -0
  341. package/src/layout/context/float-context.ts +62 -0
  342. package/src/layout/context/layout-environment.ts +29 -0
  343. package/src/layout/debug.ts +18 -0
  344. package/src/layout/inline/bounding-box-calculator.ts +132 -0
  345. package/src/layout/inline/font-baseline-calculator.ts +76 -0
  346. package/src/layout/inline/inline-utils.ts +94 -0
  347. package/src/layout/inline/layout.ts +285 -0
  348. package/src/layout/inline/line_breaker.ts +109 -0
  349. package/src/layout/inline/measurement.ts +144 -0
  350. package/src/layout/inline/run-placer.ts +139 -0
  351. package/src/layout/inline/text-alignment.ts +70 -0
  352. package/src/layout/inline/tokenizer.ts +195 -0
  353. package/src/layout/inline/types.ts +76 -0
  354. package/src/layout/pipeline/context-factory.ts +16 -0
  355. package/src/layout/pipeline/default-engine.ts +24 -0
  356. package/src/layout/pipeline/engine.ts +59 -0
  357. package/src/layout/pipeline/layout-tree.ts +13 -0
  358. package/src/layout/pipeline/out-of-flow-manager.ts +73 -0
  359. package/src/layout/pipeline/strategy.ts +12 -0
  360. package/src/layout/pipeline/text-metrics-initializer.ts +13 -0
  361. package/src/layout/strategies/block.ts +236 -0
  362. package/src/layout/strategies/display-none.ts +14 -0
  363. package/src/layout/strategies/fallback.ts +15 -0
  364. package/src/layout/strategies/flex.ts +477 -0
  365. package/src/layout/strategies/fragmentation.ts +17 -0
  366. package/src/layout/strategies/grid.ts +247 -0
  367. package/src/layout/strategies/image.ts +342 -0
  368. package/src/layout/strategies/inline.ts +128 -0
  369. package/src/layout/strategies/table.ts +595 -0
  370. package/src/layout/table/cell_layout.ts +31 -0
  371. package/src/layout/table/diagnostics.ts +19 -0
  372. package/src/layout/text-run.ts +42 -0
  373. package/src/layout/utils/content-measurer.ts +117 -0
  374. package/src/layout/utils/display-utils.ts +24 -0
  375. package/src/layout/utils/floats.ts +98 -0
  376. package/src/layout/utils/gap-calculator.ts +167 -0
  377. package/src/layout/utils/inline-formatter.ts +31 -0
  378. package/src/layout/utils/inline-formatting.ts +9 -0
  379. package/src/layout/utils/margin.ts +140 -0
  380. package/src/layout/utils/node-math.ts +237 -0
  381. package/src/layout/utils/overflow.ts +14 -0
  382. package/src/layout/utils/sizing.ts +12 -0
  383. package/src/layout/utils/text-metrics.ts +361 -0
  384. package/src/logging/debug.ts +58 -0
  385. package/src/pdf/font/base14/widths-courier-bold.ts +159 -0
  386. package/src/pdf/font/base14/widths-courier.ts +159 -0
  387. package/src/pdf/font/base14/widths-helvetica-bold.ts +158 -0
  388. package/src/pdf/font/base14/widths-helvetica.ts +158 -0
  389. package/src/pdf/font/base14/widths-times-bold.ts +158 -0
  390. package/src/pdf/font/base14/widths-times-roman.ts +158 -0
  391. package/src/pdf/font/base14/widths-types.ts +25 -0
  392. package/src/pdf/font/base14-widths.ts +32 -0
  393. package/src/pdf/font/blur.ts +81 -0
  394. package/src/pdf/font/builtin-fonts.browser.ts +262 -0
  395. package/src/pdf/font/builtin-fonts.ts +126 -0
  396. package/src/pdf/font/composite-glyph-parser.ts +242 -0
  397. package/src/pdf/font/embedder.ts +395 -0
  398. package/src/pdf/font/font-config.ts +190 -0
  399. package/src/pdf/font/font-registry.ts +263 -0
  400. package/src/pdf/font/font-subset.ts +258 -0
  401. package/src/pdf/font/glyph-atlas-maxrects.ts +305 -0
  402. package/src/pdf/font/glyph-atlas-tuner.ts +98 -0
  403. package/src/pdf/font/glyph-atlas.ts +226 -0
  404. package/src/pdf/font/glyph-cache.ts +127 -0
  405. package/src/pdf/font/loca-reader.ts +109 -0
  406. package/src/pdf/font/managers/font-resource-manager.ts +73 -0
  407. package/src/pdf/font/managers/subset-resource-manager.ts +164 -0
  408. package/src/pdf/font/rasterizer.ts +270 -0
  409. package/src/pdf/font/resolvers/base-font-mapper.ts +77 -0
  410. package/src/pdf/font/resolvers/family-resolver.ts +33 -0
  411. package/src/pdf/font/resolvers/weight-style-applicator.ts +63 -0
  412. package/src/pdf/font/simple-glyph-parser.ts +289 -0
  413. package/src/pdf/font/to-unicode.ts +109 -0
  414. package/src/pdf/font/transformation-matrix.ts +136 -0
  415. package/src/pdf/font/ttf-cmap.ts +180 -0
  416. package/src/pdf/font/ttf-global-metrics.ts +58 -0
  417. package/src/pdf/font/ttf-glyf.ts +125 -0
  418. package/src/pdf/font/ttf-glyph-metrics.ts +43 -0
  419. package/src/pdf/font/ttf-lite.ts +269 -0
  420. package/src/pdf/font/ttf-table-parser.ts +132 -0
  421. package/src/pdf/font/ttf-table-provider.ts +61 -0
  422. package/src/pdf/font/widths.ts +79 -0
  423. package/src/pdf/font-subset/font-registry.ts +127 -0
  424. package/src/pdf/header-footer-layout.ts +153 -0
  425. package/src/pdf/header-footer-painter.ts +209 -0
  426. package/src/pdf/header-footer-renderer.ts +357 -0
  427. package/src/pdf/header-footer-tokens.ts +55 -0
  428. package/src/pdf/header-footer.ts +25 -0
  429. package/src/pdf/layout-tree-builder.ts +261 -0
  430. package/src/pdf/page-painter.ts +241 -0
  431. package/src/pdf/pagination.ts +155 -0
  432. package/src/pdf/primitives/pdf-builder.ts +378 -0
  433. package/src/pdf/primitives/pdf-bytes.ts +40 -0
  434. package/src/pdf/primitives/pdf-document.ts +108 -0
  435. package/src/pdf/primitives/pdf-reference-manager.ts +47 -0
  436. package/src/pdf/primitives/pdf-resource-registries.ts +255 -0
  437. package/src/pdf/primitives/pdf-serializers.ts +194 -0
  438. package/src/pdf/primitives/pdf-types.ts +73 -0
  439. package/src/pdf/render.ts +210 -0
  440. package/src/pdf/renderer/box-painter.ts +236 -0
  441. package/src/pdf/renderer/page-paint.ts +102 -0
  442. package/src/pdf/renderer/paint-box-shadows.ts +218 -0
  443. package/src/pdf/renderer/radius.ts +58 -0
  444. package/src/pdf/renderers/graphics-state-manager.ts +40 -0
  445. package/src/pdf/renderers/image-renderer.ts +127 -0
  446. package/src/pdf/renderers/radius-utils.ts +80 -0
  447. package/src/pdf/renderers/rectangle-renderer.ts +129 -0
  448. package/src/pdf/renderers/rounded-rect-path.ts +120 -0
  449. package/src/pdf/renderers/shape-renderer.ts +563 -0
  450. package/src/pdf/renderers/shape-utils.ts +194 -0
  451. package/src/pdf/renderers/text-decoration-renderer.ts +313 -0
  452. package/src/pdf/renderers/text-encoder.ts +41 -0
  453. package/src/pdf/renderers/text-font-resolver.ts +75 -0
  454. package/src/pdf/renderers/text-renderer-utils.ts +28 -0
  455. package/src/pdf/renderers/text-renderer.ts +391 -0
  456. package/src/pdf/renderers/text-shadow-renderer.ts +300 -0
  457. package/src/pdf/shading/gradient-service.ts +525 -0
  458. package/src/pdf/shading/index.ts +1 -0
  459. package/src/pdf/stacking/build-stacking-contexts.ts +93 -0
  460. package/src/pdf/stacking/resolve-paint-order.ts +157 -0
  461. package/src/pdf/stacking/types.ts +40 -0
  462. package/src/pdf/svg/aspect-ratio.ts +81 -0
  463. package/src/pdf/svg/coordinate-mapper.ts +81 -0
  464. package/src/pdf/svg/geometry-builder.ts +45 -0
  465. package/src/pdf/svg/render-svg.ts +296 -0
  466. package/src/pdf/svg/shape-renderer.ts +463 -0
  467. package/src/pdf/svg/style-computer.ts +246 -0
  468. package/src/pdf/transform-adapter.ts +26 -0
  469. package/src/pdf/types.ts +377 -0
  470. package/src/pdf/utils/background-layer-resolver.ts +439 -0
  471. package/src/pdf/utils/background-tiles.ts +192 -0
  472. package/src/pdf/utils/border-dashes.ts +109 -0
  473. package/src/pdf/utils/border-radius-utils.ts +86 -0
  474. package/src/pdf/utils/box-dimensions-utils.ts +47 -0
  475. package/src/pdf/utils/clip-path-resolver.ts +50 -0
  476. package/src/pdf/utils/clipping-path-builder.ts +190 -0
  477. package/src/pdf/utils/color-utils.ts +102 -0
  478. package/src/pdf/utils/coordinate-transformer.ts +30 -0
  479. package/src/pdf/utils/drop-shadow-raster.ts +233 -0
  480. package/src/pdf/utils/encoding.ts +98 -0
  481. package/src/pdf/utils/glyph-atlas-registrar.ts +13 -0
  482. package/src/pdf/utils/glyph-run-renderer.ts +129 -0
  483. package/src/pdf/utils/image-command-partitioner.ts +28 -0
  484. package/src/pdf/utils/image-matrix-builder.ts +31 -0
  485. package/src/pdf/utils/image-utils.ts +26 -0
  486. package/src/pdf/utils/list-utils.ts +194 -0
  487. package/src/pdf/utils/node-text-run-factory.ts +202 -0
  488. package/src/pdf/utils/page-resource-registrar.ts +46 -0
  489. package/src/pdf/utils/result-combiner.ts +102 -0
  490. package/src/pdf/utils/shadow-utils.ts +127 -0
  491. package/src/pdf/utils/text-alignment-resolver.ts +76 -0
  492. package/src/pdf/utils/text-decoration-utils.ts +64 -0
  493. package/src/pdf/utils/text-layout-adjuster.ts +185 -0
  494. package/src/pdf/utils/text-utils.ts +193 -0
  495. package/src/pdf/utils/transform-scope-manager.ts +69 -0
  496. package/src/render/offset.ts +170 -0
  497. package/src/shim/empty.ts +2 -0
  498. package/src/shim/fs-empty.ts +5 -0
  499. package/src/shim/url-empty.ts +7 -0
  500. package/src/shim/zlib-empty.ts +9 -0
  501. package/src/style/shorthands/index.ts +19 -0
  502. package/src/style/ua/defaults.ts +69 -0
  503. package/src/svg/index.ts +4 -0
  504. package/src/svg/parser-registry.ts +71 -0
  505. package/src/svg/parser.ts +486 -0
  506. package/src/svg/path-data.ts +515 -0
  507. package/src/svg/types.ts +194 -0
  508. package/src/text/line-breaker.ts +321 -0
  509. package/src/text/text-transform.ts +43 -0
  510. package/src/text/text.ts +33 -0
  511. package/src/transform/css-parser.ts +95 -0
  512. package/src/types/fonts.ts +62 -0
  513. package/src/types/public.ts +19 -0
  514. package/src/units/page-utils.ts +58 -0
  515. package/src/units/units.ts +50 -0
  516. package/src/utils/base64.ts +24 -0
  517. package/test-output.txt +79 -0
  518. package/tests/css/background-parser.spec.ts +14 -0
  519. package/tests/css/clip-path-parser.spec.ts +66 -0
  520. package/tests/environment/path-resolution.spec.ts +104 -0
  521. package/tests/helpers/ai-layout-diagnostics.ts +141 -0
  522. package/tests/helpers/render-utils.ts +52 -0
  523. package/tests/helpers/text-geometry.ts +56 -0
  524. package/tests/layout/custom-properties.test.ts +38 -0
  525. package/tests/layout/gap-calculator.spec.ts +196 -0
  526. package/tests/layout/inline-background-alignment.spec.ts +93 -0
  527. package/tests/layout/inline-fragments.spec.ts +26 -0
  528. package/tests/layout/run-placer-baseline.spec.ts +108 -0
  529. package/tests/pdf/alignments.spec.ts +26 -0
  530. package/tests/pdf/background-clip.spec.ts +57 -0
  531. package/tests/pdf/background-repeat-space-round.spec.ts +35 -0
  532. package/tests/pdf/background-repeat.spec.ts +137 -0
  533. package/tests/pdf/border-radius.spec.ts +151 -0
  534. package/tests/pdf/clip-path.spec.ts +92 -0
  535. package/tests/pdf/radial-gradient.spec.ts +50 -0
  536. package/tests/pdf/svg-stroke-dash.spec.ts +81 -0
  537. package/tests/pdf/text-transform-matrix.spec.ts +43 -0
  538. package/tsconfig.json +17 -0
  539. package/types/fonts.js +10 -0
  540. package/vitest.config.ts +9 -0
package/docs/AGENTS.md ADDED
@@ -0,0 +1,288 @@
1
+ # AGENTS.md — Project Rules for Coding Agents
2
+
3
+ > This document defines how autonomous coding agents should work in this repository:
4
+ > goals, constraints, folder structure, coding style, tests, error handling, and
5
+ > what you *must* do before opening a PR.
6
+
7
+ ---
8
+
9
+ ## 1) Mission & Scope
10
+
11
+ - **Mission:** Convert **HTML + CSS** into **deterministic PDF** bytes via a clean pipeline:
12
+ `HTML → DOM → CSSOM → Cascade → StyledTree → Layout (+pagination) → DisplayList → PDF`.
13
+ - **Out of scope:** Executing JavaScript from HTML, fetching the open internet beyond allowed inputs,
14
+ adding heavy dependencies without explicit instructions, or breaking determinism.
15
+
16
+ ---
17
+
18
+ ## 2) Repository Layout (authoritative)
19
+
20
+ Use and keep these boundaries stable:
21
+
22
+ ```
23
+ /src/core.ts # Core exports and main types
24
+ /src/html-to-pdf.ts # Main HTML to PDF conversion pipeline
25
+ /src/index.ts # Public API entry point
26
+ /src/html/ # HTML parsing and DOM conversion (using linkedom)
27
+ /src/css/ # CSS parsing, cascade, shorthands, specificity
28
+ /src/layout/ # Layout computation (block/inline layout, positioning)
29
+ /src/dom/ # DOM node representation and manipulation
30
+ /src/pdf/ # PDF generation, rendering, and primitives
31
+ /src/fonts/ # Font handling, embedding, subsetting, metrics
32
+ /src/image/ # Image decoding (PNG, JPEG, WebP), processing
33
+ /src/svg/ # SVG parsing and rendering support
34
+ /src/assets/ # Built-in assets (fonts, images)
35
+ /src/compression/ # Data compression utilities (deflate, brotli)
36
+ /src/config/ # Configuration interfaces
37
+ /src/debug/ # Debugging and audit utilities
38
+ /src/geometry/ # Geometric calculations (boxes, matrices)
39
+ /src/logging/ # Logging utilities
40
+ /src/orchestrator/ # Pipeline coordination
41
+ /src/paint-order/ # Paint order management
42
+ /src/render/ # Render tree operations and transformations
43
+ /src/style/ # Style computation and inheritance
44
+ /src/text/ # Text processing and line breaking
45
+ /src/transform/ # Transformation utilities
46
+ /src/types/ # Type definitions
47
+ /src/units/ # Unit conversion and page utilities
48
+ /tests/helpers/ # Test utilities and helpers
49
+ /tests/layout/ # Layout-specific tests
50
+ /tests/pdf/ # PDF-specific tests
51
+ /scripts/ # Development scripts and utilities
52
+ /playground/ # Interactive development server
53
+ /playground/public/examples/ # HTML examples for testing
54
+ /examples/ # Example files (if any)
55
+ ```
56
+
57
+ Do **not** restructure without updating this file and the README.
58
+
59
+ ---
60
+
61
+ ## 3) Pipeline Contracts (inputs/outputs)
62
+
63
+ ### 3.1 Input Loader
64
+ - **In:** `RenderHtmlOptions` with HTML string, CSS string, viewport/page dimensions, margins, font config
65
+ - **Out:** `PreparedRender` with layout root, render tree, and page size in points
66
+ - **Errors:** `E_HTML_EMPTY`, `E_FETCH_FAILED`
67
+
68
+ ### 3.2 HTML → DOM
69
+ - **Library:** Uses linkedom for HTML parsing (no JS execution)
70
+ - **Rules:** Preserve whitespace where CSS `white-space` requires; normalize HTML fragments to full documents
71
+ - **Error:** `E_HTML_SYNTAX` (recover if possible; warn + continue).
72
+
73
+ ### 3.3 CSS Resolution
74
+ - Sources: `<style>`, `style=""` attributes, linked styles, UA styles.
75
+ - **Ordering:** UA < author < inline, specificity, `!important`.
76
+ - **Minimum selectors:** type/class/id, **descendant `A B`**, **child `A > B`**.
77
+ - **Shorthands:** border, margin, padding, background, font, etc.
78
+ - **@font-face:** Support for font loading and embedding from CSS
79
+
80
+ ### 3.4 Style Computation (Cascade)
81
+ - **Out:** DOM nodes with computed styles attached
82
+ - **Normalize:** units (px internally), shorthands → longhands, inheritance, font face definitions
83
+
84
+ ### 3.5 Layout & Pagination
85
+ - Flow layout, line boxes, absolute/fixed positioning, page fragments.
86
+ - **Stacking contexts & z-index:** negative < 0 < positive; follow paint order rules.
87
+ - **Recoverable overflow:** report `E_LAYOUT_OVERFLOW` (warn) and continue.
88
+
89
+ ### 3.6 Render Tree Construction
90
+ - **Order:** backgrounds → borders → text → decorations → images/shadows.
91
+ - Generate **deterministic** render tree per page with proper offsets and margins applied.
92
+
93
+ ### 3.7 PDF Writer
94
+ - Embed/subset fonts; compress streams; valid xref; metadata/XMP if present.
95
+ - **Out:** `Uint8Array` (PDF).
96
+ - **No partial PDF** on fatal errors.
97
+
98
+ ---
99
+
100
+ ## 4) Determinism & Seeds
101
+
102
+ - Internal units = **px**. Convert `px → pt` only in PDF writer (default `1px = 0.75pt`).
103
+ - When `seed` is provided, **same input ⇒ same output bytes**.
104
+ - Do not include timestamps/volatile IDs unless explicitly normalized.
105
+
106
+ ---
107
+
108
+ ## 5) Fonts & Text
109
+
110
+ - Font handling via FontEmbedder with support for TTF, WOFF, and WOFF2 formats
111
+ - Always subset embedded fonts; keep cmap/metrics consistent.
112
+ - Support for @font-face rules with font loading from URLs or local files
113
+ - Provide sane fallbacks for missing glyphs.
114
+ - Respect normalized font-weight steps (100..900); snap non-integer weights to nearest step.
115
+ - Font loading supports data URIs, HTTP URLs, and local file paths
116
+
117
+ ---
118
+
119
+ ## 6) Colors, Backgrounds & Shadows
120
+
121
+ - Work in **sRGB** internally; writer maps to DeviceRGB/ICC.
122
+ - Background shorthand may include **colors**, **images (url(...))**, and **linear-gradients**.
123
+ - `box-shadow` layers supported; `none` disables.
124
+
125
+ ---
126
+
127
+ ## 7) CSS Conventions & Notable Rules
128
+
129
+ - `z-index`: accepts **integer** values or `auto`. Non-integers (e.g., `"2.0"`) are ignored.
130
+ - Shorthands must expand correctly (border, margin/padding, background, font).
131
+ - **Selectors supported:** tag names, `#id`, `.class`, `[attr]`, `:first-child`, `:last-child`, `:nth-child`, `:not()`, `:root`, descendant (`A B`), child (`A > B`), adjacent sibling (`A + B`), and general sibling (`A ~ B`) combinators
132
+ - **Display values:** `block`, `inline`, `inline-block`, `flex`, `inline-flex`, `grid`, `inline-grid`, `table`, `inline-table`, `table-row-group`, `table-header-group`, `table-footer-group`, `table-row`, `table-cell`, `table-caption`, `list-item`, `none`, `flow-root`
133
+ - **Position values:** `static`, `relative`, `absolute`, `fixed`, `sticky`
134
+ - **Float values:** `none`, `left`, `right`, `inline-start`, `inline-end`
135
+ - **Table displays for `table`, `tbody/thead/tfoot`, `tr`, `td/th` are forced to canonical display types when overridden improperly.
136
+ - Defaults approximate UA styles (headings, paragraphs, lists, inline elements, tables, etc.).
137
+ - **CSS Variables:** Supported via `--custom-property` syntax and `var()` function with fallback support. Variables are inherited and resolved at computed style time.
138
+
139
+ ---
140
+
141
+ ## 8) Error Policy
142
+
143
+ - Prefer **warn and continue** (collect `warnings: string[]`) when safe.
144
+ - Fatal errors have stable codes `E_*` and never produce partial PDFs.
145
+ - All thrown errors must include: `code`, brief `message`, and optional `details`.
146
+
147
+ ## 8.5) Logging & Debugging
148
+
149
+ - **Log levels:** `trace`, `debug`, `info`, `warn`, `error` (in increasing order of severity)
150
+ - **Log categories:** `parse`, `style`, `layout`, `paint`, `font`, `encoding`, `pdf` (case-insensitive)
151
+ - **Debug configuration:** Use `configureDebug({ level: LogLevel, cats: string[] })` to set runtime logging
152
+ - **Playground debugging:** Use `--debug-level` and `--debug-cats` flags with `npm run playground:render`
153
+ - **Log output:** Colored console output with level and category prefixes for easy identification
154
+
155
+ ---
156
+
157
+ ## 9) Tooling & Scripts
158
+
159
+ **Do not** reinvent commands; use these NPM scripts:
160
+
161
+ ```jsonc
162
+ {
163
+ "scripts": {
164
+ "build": "tsc",
165
+ "start": "node ./dist/index.js",
166
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
167
+ "lint": "eslint src tests --ext .ts,.js",
168
+ "test": "vitest run",
169
+ "playground": "tsx playground/server.ts",
170
+ "playground:render": "tsx scripts/render-playground-example.ts",
171
+ "validate": "npm run lint && npm test"
172
+ }
173
+ }
174
+ ```
175
+
176
+ **Note:** Run `npm run build` before testing to ensure TypeScript compilation succeeds.
177
+
178
+ ---
179
+
180
+ ## 10) Coding Style
181
+
182
+ - Language: **TypeScript** (ES modules).
183
+ - Lint/format: **ESLint + Prettier**; zero warnings on CI.
184
+ - Logging: use the provided logger; avoid raw `console.log` in src.
185
+ - Keep modules **SRP** (Single Responsibility Principle). Split big functions.
186
+
187
+ ---
188
+
189
+ ## 10.5) Development Workflow
190
+
191
+ - **Playground:** Use `npm run playground` to start interactive development server
192
+ - Access at `http://localhost:3000` (or configured port) for visual testing
193
+ - Hot reload for rapid iteration on HTML/CSS inputs
194
+ - Render specific examples with `npm run playground:render`
195
+ - Playground render supports command-line options:
196
+ - `npm run playground:render [example-path]` - Render a specific example from playground/public/examples/
197
+ - `npm run playground:render -- --debug-level debug` - Enable debug logging
198
+ - `npm run playground:render -- --debug-cats layout,pdf` - Enable specific debug categories (comma-separated)
199
+ - `npm run playground:render -- --page-width 800` - Set a custom page width in pixels
200
+ - `npm run playground:render -- --page-height 600` - Set a custom page height in pixels
201
+ - `npm run playground:render -- --margins "50"` - Set uniform margins (50px)
202
+ - `npm run playground:render -- --margins "20,40"` - Set vertical (20px) and horizontal (40px) margins
203
+ - `npm run playground:render -- --margins "20,30,40,50"` - Set top, right, bottom, and left margins individually
204
+ - Output PDFs are saved to `playground/exports/` directory
205
+
206
+ - **Scripts:** Development utilities in `/scripts/` directory
207
+ - TypeScript scripts run with `tsx` for direct execution without compilation
208
+ - May write output files for debugging/validation purposes
209
+
210
+ - **Build & Test Cycle:**
211
+ 1. Make changes in `/src/`
212
+ 2. Run `npm run build` to compile TypeScript
213
+ 3. Run `npm test` for unit and e2e tests
214
+ 4. Use playground for visual/manual verification
215
+ 5. Run `npm run validate` before committing (lint + test)
216
+
217
+ ---
218
+
219
+ ## 11) Tests: What You Must Cover
220
+
221
+ - **Unit:** CSS parsing (shorthands/longhands), specificity, cascade, layout pieces, render tree construction, PDF primitives.
222
+ - **Layout tests:** Inline fragments, text alignment, positioning, flexbox/grid (if implemented)
223
+ - **PDF tests:** Alignments, header/footer rendering, page breaks, font embedding
224
+ - **E2E:**
225
+ - z-index negative vs zero/positive (3+ overlapping elements).
226
+ - Page breaks: `page-break-*` / `break-inside: avoid`.
227
+ - Fonts: accents/symbols, embedding + subset, widths/metrics accuracy.
228
+ - Images: PNG/JPEG/WebP with/without alpha; scaling & `object-fit`.
229
+ - Selectors: `A B` and `A > B` with specificity ties.
230
+ - Determinism: snapshot binary with `seed=42`.
231
+
232
+ A PR **must** add/adjust tests that reproduce any bug or validate a new feature in the appropriate test directory (`/tests/helpers/`, `/tests/layout/`, or `/tests/pdf/`).
233
+
234
+ ---
235
+
236
+ ## 12) PR & Commits
237
+
238
+ - One focused change per PR.
239
+ - Conventional commits: `feat(...)`, `fix(...)`, `test(...)`, `refactor(...)`, etc.
240
+ - Update `CHANGELOG.md` and, if relevant, this `AGENTS.md`.
241
+ - CI requirement: `npm run validate` **must pass**.
242
+
243
+ ---
244
+
245
+ ## 13) Security & Supply Chain
246
+
247
+ - No runtime network fetches during tests except for controlled fixtures.
248
+ - No dynamic `eval`/Function constructors.
249
+ - Keep dependencies minimal; justify any new runtime dep in PR description.
250
+
251
+ ---
252
+
253
+ ## 14) Inputs & Artifacts
254
+
255
+ - **Inputs:** `RenderHtmlOptions` with HTML string, CSS string, viewport/page dimensions, margins, font config, resource base directory, header/footer HTML
256
+ - **Artifacts:** PDF bytes (`Uint8Array`) + metrics (timings, page count) + warnings.
257
+ - Never write files in library code; CLIs in `/scripts/` may write to disk.
258
+
259
+ ---
260
+
261
+ ## 15) Agent Checklists (must pass)
262
+
263
+ - [ ] `npm run validate` (lint + test) succeeded.
264
+ - [ ] Coverage ≥ 80% for changed modules.
265
+ - [ ] Deterministic snapshots unchanged (or re-baselined with reason).
266
+ - [ ] Added/updated e2e demonstrating the change.
267
+ - [ ] No stray logs; no partial PDF on fatal paths.
268
+ - [ ] Documentation (README/AGENTS) updated if behavior changed.
269
+
270
+ ---
271
+
272
+ ## 16) Glossary
273
+
274
+ - **StyledTree:** DOM nodes decorated with computed CSS.
275
+ - **DisplayList:** Ordered painting operations per page.
276
+ - **Deterministic:** Same inputs + same seed → identical PDF bytes.
277
+ - **RenderTree:** Tree structure representing the final layout with positioning and styling applied for PDF rendering
278
+ - **LayoutNode:** Internal representation of DOM elements with computed layout properties
279
+ - **FontEmbedder:** Component responsible for font loading, subsetting, and embedding in PDF output
280
+
281
+ ---
282
+
283
+ ## 17) Document Maintenance
284
+
285
+ - Version: `1.1.0`
286
+ - Last updated: 2025-11-26
287
+ - Editors: maintainers of this repo. Update alongside code changes that alter behavior.
288
+ - Keep synchronized with `package.json` scripts and actual repository structure.
@@ -0,0 +1,127 @@
1
+ # Background-Repeat Support Implementation Summary
2
+
3
+ ## Overview
4
+ Successfully implemented complete support for the CSS `background-repeat` property in the pagyra-js HTML-to-PDF converter. The implementation covers both inline `background-repeat` declarations and the property within the `background` shorthand.
5
+
6
+ ## Changes Made
7
+
8
+ ### 1. **Added `applyBackgroundRepeat` Function** (`src/css/parsers/background-parser.ts`)
9
+ - Created a new parser function that applies the `background-repeat` longhand property to background layers
10
+ - Validates the repeat value against the allowed keywords: `repeat`, `repeat-x`, `repeat-y`, `no-repeat`, `space`, `round`
11
+ - Applies to both image and gradient background layers
12
+ - Follows the same pattern as existing background property parsers (`applyBackgroundSize`, `applyBackgroundOrigin`)
13
+
14
+ ### 2. **Exported Parser Function** (`src/css/parsers/background-parser-extended.ts`)
15
+ - Imported `applyBackgroundRepeat` from the base parser
16
+ - Created wrapper function `applyBackgroundRepeatDecl` following naming conventions
17
+ - Made it available for registration
18
+
19
+ ### 3. **Registered the Parser** (`src/css/parsers/register-parsers.ts`)
20
+ - Added `applyBackgroundRepeatDecl` to imports
21
+ - Registered `background-repeat` property parser in `registerAllPropertyParsers()`
22
+ - Placed it logically alongside other background properties
23
+
24
+ ### 4. **Comprehensive Test Coverage** (`tests/pdf/background-repeat.spec.ts`)
25
+ - Created 11 test cases covering all functionality:
26
+ - All repeat modes: `repeat`, `no-repeat`, `repeat-x`, `repeat-y`, `space`, `round`
27
+ - Default behavior when not specified
28
+ - Parsing from background shorthand
29
+ - Application to gradients
30
+ - Property override scenarios
31
+ - Invalid value handling
32
+
33
+ ## Existing Infrastructure
34
+ The implementation leverages existing, robust infrastructure:
35
+
36
+ ### Type Definitions
37
+ - **`BackgroundRepeat`** type already defined in `src/css/background-types.ts`
38
+ - Supports all standard CSS values: `repeat`, `repeat-x`, `repeat-y`, `no-repeat`, `space`, `round`
39
+
40
+ ### Background Layer Storage
41
+ - **`ImageBackgroundLayer`** and **`GradientBackgroundLayer`** interfaces already include `repeat?` field
42
+ - PDF types (`BackgroundImage`, `GradientBackground`) already have `repeat` property
43
+
44
+ ### Rendering Logic
45
+ - **`computeBackgroundTileRects`** function (`src/pdf/utils/background-tiles.ts`) already handles all repeat modes
46
+ - Properly calculates tile positions for:
47
+ - `no-repeat`: Single tile
48
+ - `repeat`: Tiles in both directions
49
+ - `repeat-x`: Horizontal tiling only
50
+ - `repeat-y`: Vertical tiling only
51
+ - `space` and `round`: Treated as `repeat` with a warning (per spec notes)
52
+
53
+ ### Integration
54
+ - **`createBackgroundImage`** and **`createGradientBackground`** (`src/pdf/utils/background-layer-resolver.ts`)
55
+ - Already read `layer.repeat` and default to appropriate values
56
+ - Images default to `"repeat"`
57
+ - Gradients default to `"no-repeat"`
58
+
59
+ ## Testing Results
60
+ ✅ All 11 new tests passing
61
+ ✅ All existing tests still passing
62
+ ✅ No regressions introduced
63
+
64
+ ## Demonstration
65
+ The feature can be demonstrated using the existing example file:
66
+ `playground/public/examples/background-repeat-showcase.html`
67
+
68
+ This file showcases:
69
+ - `background-repeat: repeat` (default tiling behavior)
70
+ - `background-repeat: no-repeat` (single image, centered)
71
+ - `background-repeat: repeat-x` (horizontal tiling)
72
+ - `background-repeat: repeat-y` (vertical tiling)
73
+
74
+ ## Compliance with AGENTS.md
75
+ ✅ Single Responsibility Principle maintained
76
+ ✅ TypeScript with proper type safety
77
+ ✅ Tests added with ≥80% coverage
78
+ ✅ No breaking changes
79
+ ✅ Follows existing code patterns
80
+ ✅ Build succeeds: `npm run build` ✓
81
+ ✅ Tests pass: `npm test` ✓
82
+
83
+ ## Usage Examples
84
+
85
+ ### Inline Property
86
+ ```html
87
+ <div style="background-image: url(image.png); background-repeat: no-repeat;">
88
+ Content
89
+ </div>
90
+ ```
91
+
92
+ ### Background Shorthand
93
+ ```html
94
+ <div style="background: url(image.png) repeat-x;">
95
+ Content
96
+ </div>
97
+ ```
98
+
99
+ ### With Gradients
100
+ ```html
101
+ <div style="background-image: linear-gradient(red, blue); background-repeat: no-repeat;">
102
+ Content
103
+ </div>
104
+ ```
105
+
106
+ ### CSS Rules
107
+ ```css
108
+ .pattern {
109
+ background-image: url(tile.png);
110
+ background-repeat: repeat;
111
+ background-size: 50px 50px;
112
+ }
113
+ ```
114
+
115
+ ## Notes
116
+ - The `space` and `round` values are parsed and stored correctly, but render as `repeat` with a warning (as noted in existing code)
117
+ - This is consistent with the current implementation for gradients
118
+ - Full `space` and `round` rendering could be added in a future enhancement
119
+
120
+ ## Files Modified
121
+ 1. `src/css/parsers/background-parser.ts` - Added core parser function
122
+ 2. `src/css/parsers/background-parser-extended.ts` - Exported wrapper function
123
+ 3. `src/css/parsers/register-parsers.ts` - Registered the parser
124
+ 4. `tests/pdf/background-repeat.spec.ts` - Added comprehensive tests (NEW)
125
+
126
+ ## Conclusion
127
+ The `background-repeat` property is now fully supported for HTML to PDF conversion, enabling precise control over how background images and gradients tile within elements. The implementation is complete, well-tested, and ready for use.
@@ -0,0 +1,127 @@
1
+ # Quick Reference: Background-Repeat Property
2
+
3
+ ## Property Support
4
+ The `background-repeat` CSS property is fully supported for controlling how background images and gradients tile.
5
+
6
+ ## Syntax
7
+ ```css
8
+ background-repeat: value;
9
+ ```
10
+
11
+ ## Supported Values
12
+ | Value | Description | Support Status |
13
+ |-------|-------------|----------------|
14
+ | `repeat` | Tiles the image in both directions (default for images) | ✅ Full |
15
+ | `repeat-x` | Tiles the image horizontally only | ✅ Full |
16
+ | `repeat-y` | Tiles the image vertically only | ✅ Full |
17
+ | `no-repeat` | Displays the image once (default for gradients) | ✅ Full |
18
+ | `space` | Tiles with spacing to fit container | ⚠️ Renders as `repeat` (with warning) |
19
+ | `round` | Tiles and scales to fit container | ⚠️ Renders as `repeat` (with warning) |
20
+
21
+ ## Usage Scenarios
22
+
23
+ ### 1. As an Inline Property
24
+ ```html
25
+ <div style="background-image: url(pattern.png); background-repeat: repeat-x;">
26
+ Horizontal pattern
27
+ </div>
28
+ ```
29
+
30
+ ### 2. Within Background Shorthand
31
+ ```html
32
+ <div style="background: url(tile.png) no-repeat center;">
33
+ Centered image, no tiling
34
+ </div>
35
+ ```
36
+
37
+ ### 3. In External/Internal CSS
38
+ ```html
39
+ <style>
40
+ .tiled-background {
41
+ background-image: url(tile.png);
42
+ background-repeat: repeat;
43
+ background-size: 100px 100px;
44
+ }
45
+ </style>
46
+ <div class="tiled-background">Content</div>
47
+ ```
48
+
49
+ ### 4. With Gradients
50
+ ```html
51
+ <div style="background-image: linear-gradient(to right, red, blue); background-repeat: no-repeat;">
52
+ Single gradient
53
+ </div>
54
+ ```
55
+
56
+ ### 5. Property Override
57
+ ```html
58
+ <!-- The background-repeat property will override the shorthand -->
59
+ <div style="background: url(img.png) repeat; background-repeat: no-repeat;">
60
+ Override example
61
+ </div>
62
+ ```
63
+
64
+ ## Advanced Examples
65
+
66
+ ### Tiled Pattern with Size Control
67
+ ```css
68
+ .pattern {
69
+ background-image: url(small-tile.png);
70
+ background-repeat: repeat;
71
+ background-size: 50px 50px;
72
+ }
73
+ ```
74
+
75
+ ### Horizontal Banner
76
+ ```css
77
+ .banner {
78
+ background-image: url(banner-pattern.png);
79
+ background-repeat: repeat-x;
80
+ background-position: top center;
81
+ }
82
+ ```
83
+
84
+ ### Vertical Sidebar
85
+ ```css
86
+ .sidebar {
87
+ background-image: url(vertical-pattern.png);
88
+ background-repeat: repeat-y;
89
+ background-position: left center;
90
+ }
91
+ ```
92
+
93
+ ### Single Positioned Image
94
+ ```css
95
+ .logo-watermark {
96
+ background-image: url(logo.png);
97
+ background-repeat: no-repeat;
98
+ background-position: bottom right;
99
+ background-size: 100px auto;
100
+ }
101
+ ```
102
+
103
+ ## Default Behavior
104
+ - **Images**: Default to `repeat` if not specified
105
+ - **Gradients**: Default to `no-repeat` if not specified
106
+
107
+ ## Property Cascade
108
+ The `background-repeat` property follows standard CSS cascade rules:
109
+ 1. Inline styles have highest specificity
110
+ 2. Later declarations override earlier ones
111
+ 3. Properties override shorthand when declared after
112
+
113
+ ## Combining with Other Properties
114
+ ```css
115
+ .complex-background {
116
+ background-image: url(texture.png);
117
+ background-repeat: repeat;
118
+ background-size: 80px 80px;
119
+ background-position: center;
120
+ background-origin: padding-box;
121
+ }
122
+ ```
123
+
124
+ ## Notes
125
+ - The `space` and `round` values are accepted but currently render as `repeat` with a console warning
126
+ - Full implementation of `space` and `round` spacing algorithms may be added in future versions
127
+ - Background repeat works seamlessly with other background properties