blitz-pdf 0.0.0-stage → 0.1.0

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 (370) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +355 -2
  3. package/THIRD_PARTY_NOTICES.md +25 -0
  4. package/assets/icon.svg +4 -0
  5. package/dist/api.d.ts +7 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +46 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/assets.d.ts +7 -0
  10. package/dist/assets.d.ts.map +1 -0
  11. package/dist/assets.js +52 -0
  12. package/dist/assets.js.map +1 -0
  13. package/dist/browser.d.ts +3 -0
  14. package/dist/browser.d.ts.map +1 -0
  15. package/dist/browser.js +3 -0
  16. package/dist/browser.js.map +1 -0
  17. package/dist/node.d.ts +3 -0
  18. package/dist/node.d.ts.map +1 -0
  19. package/dist/node.js +10 -0
  20. package/dist/node.js.map +1 -0
  21. package/dist/options.d.ts +24 -0
  22. package/dist/options.d.ts.map +1 -0
  23. package/dist/options.js +135 -0
  24. package/dist/options.js.map +1 -0
  25. package/dist/types.d.ts +51 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/types.js +2 -0
  28. package/dist/types.js.map +1 -0
  29. package/examples/bun.ts +8 -0
  30. package/examples/german-invoice/README.md +70 -0
  31. package/examples/german-invoice/data.mjs +83 -0
  32. package/examples/german-invoice/invoice.css +59 -0
  33. package/examples/german-invoice/template.mjs +49 -0
  34. package/examples/german-invoice.mjs +20 -0
  35. package/examples/invoice.html +29 -0
  36. package/examples/node.mjs +8 -0
  37. package/examples/pagination.html +40 -0
  38. package/examples/pagination.mjs +8 -0
  39. package/licenses/DejaVu.txt +187 -0
  40. package/licenses/RUST_DEPENDENCIES.txt +11577 -0
  41. package/package.json +89 -4
  42. package/src/api.ts +44 -0
  43. package/src/assets.ts +43 -0
  44. package/src/browser.ts +6 -0
  45. package/src/node.ts +12 -0
  46. package/src/options.ts +101 -0
  47. package/src/types.ts +49 -0
  48. package/vendor/README.md +17 -0
  49. package/vendor/stylo/.cargo-ok +1 -0
  50. package/vendor/stylo/.cargo_vcs_info.json +6 -0
  51. package/vendor/stylo/Cargo.lock +1485 -0
  52. package/vendor/stylo/Cargo.toml +274 -0
  53. package/vendor/stylo/LICENSE +373 -0
  54. package/vendor/stylo/README.md +6 -0
  55. package/vendor/stylo/applicable_declarations.rs +328 -0
  56. package/vendor/stylo/author_styles.rs +79 -0
  57. package/vendor/stylo/bezier.rs +176 -0
  58. package/vendor/stylo/bloom.rs +414 -0
  59. package/vendor/stylo/build.rs +91 -0
  60. package/vendor/stylo/build_gecko.rs +393 -0
  61. package/vendor/stylo/color/color_function.rs +601 -0
  62. package/vendor/stylo/color/component.rs +207 -0
  63. package/vendor/stylo/color/convert.rs +935 -0
  64. package/vendor/stylo/color/gamut/raytrace.rs +265 -0
  65. package/vendor/stylo/color/gamut.rs +227 -0
  66. package/vendor/stylo/color/mix.rs +645 -0
  67. package/vendor/stylo/color/mod.rs +750 -0
  68. package/vendor/stylo/color/parsing.rs +770 -0
  69. package/vendor/stylo/color/to_css.rs +297 -0
  70. package/vendor/stylo/context.rs +716 -0
  71. package/vendor/stylo/counter_style/mod.rs +754 -0
  72. package/vendor/stylo/counter_style/predefined.rs +61 -0
  73. package/vendor/stylo/counter_style/update_predefined.py +35 -0
  74. package/vendor/stylo/custom_properties.rs +2023 -0
  75. package/vendor/stylo/custom_properties_map.rs +220 -0
  76. package/vendor/stylo/data.rs +693 -0
  77. package/vendor/stylo/device/gecko.rs +486 -0
  78. package/vendor/stylo/device/mod.rs +304 -0
  79. package/vendor/stylo/device/servo.rs +507 -0
  80. package/vendor/stylo/dom.rs +1164 -0
  81. package/vendor/stylo/dom_apis.rs +937 -0
  82. package/vendor/stylo/driver.rs +172 -0
  83. package/vendor/stylo/error_reporting.rs +484 -0
  84. package/vendor/stylo/font_face.rs +558 -0
  85. package/vendor/stylo/font_metrics.rs +124 -0
  86. package/vendor/stylo/gecko/anon_boxes.toml +113 -0
  87. package/vendor/stylo/gecko/arc_types.rs +211 -0
  88. package/vendor/stylo/gecko/conversions.rs +59 -0
  89. package/vendor/stylo/gecko/data.rs +222 -0
  90. package/vendor/stylo/gecko/media_features.rs +971 -0
  91. package/vendor/stylo/gecko/mod.rs +20 -0
  92. package/vendor/stylo/gecko/non_ts_pseudo_class_list.rs +119 -0
  93. package/vendor/stylo/gecko/pseudo_element.rs +640 -0
  94. package/vendor/stylo/gecko/pseudo_element_definition.mako.rs +298 -0
  95. package/vendor/stylo/gecko/pseudo_elements.py +137 -0
  96. package/vendor/stylo/gecko/pseudo_elements.toml +197 -0
  97. package/vendor/stylo/gecko/regen_pseudo_elements.py +33 -0
  98. package/vendor/stylo/gecko/restyle_damage.rs +127 -0
  99. package/vendor/stylo/gecko/selector_parser.rs +627 -0
  100. package/vendor/stylo/gecko/snapshot.rs +202 -0
  101. package/vendor/stylo/gecko/snapshot_helpers.rs +334 -0
  102. package/vendor/stylo/gecko/traversal.rs +52 -0
  103. package/vendor/stylo/gecko/wrapper.rs +2258 -0
  104. package/vendor/stylo/gecko_bindings/mod.rs +34 -0
  105. package/vendor/stylo/gecko_bindings/sugar/mod.rs +12 -0
  106. package/vendor/stylo/gecko_bindings/sugar/ns_com_ptr.rs +15 -0
  107. package/vendor/stylo/gecko_bindings/sugar/ns_compatibility.rs +19 -0
  108. package/vendor/stylo/gecko_bindings/sugar/ns_style_auto_array.rs +111 -0
  109. package/vendor/stylo/gecko_bindings/sugar/origin_flags.rs +31 -0
  110. package/vendor/stylo/gecko_bindings/sugar/ownership.rs +70 -0
  111. package/vendor/stylo/gecko_bindings/sugar/refptr.rs +299 -0
  112. package/vendor/stylo/gecko_string_cache/mod.rs +543 -0
  113. package/vendor/stylo/gecko_string_cache/namespace.rs +106 -0
  114. package/vendor/stylo/global_style_data.rs +224 -0
  115. package/vendor/stylo/invalidation/element/document_state.rs +156 -0
  116. package/vendor/stylo/invalidation/element/element_wrapper.rs +432 -0
  117. package/vendor/stylo/invalidation/element/invalidation_map.rs +1631 -0
  118. package/vendor/stylo/invalidation/element/invalidator.rs +1470 -0
  119. package/vendor/stylo/invalidation/element/mod.rs +13 -0
  120. package/vendor/stylo/invalidation/element/relative_selector.rs +1399 -0
  121. package/vendor/stylo/invalidation/element/restyle_hints.rs +226 -0
  122. package/vendor/stylo/invalidation/element/state_and_attributes.rs +756 -0
  123. package/vendor/stylo/invalidation/media_queries.rs +144 -0
  124. package/vendor/stylo/invalidation/mod.rs +10 -0
  125. package/vendor/stylo/invalidation/stylesheets.rs +745 -0
  126. package/vendor/stylo/invalidation/viewport_units.rs +71 -0
  127. package/vendor/stylo/lib.rs +336 -0
  128. package/vendor/stylo/logical_geometry.rs +1684 -0
  129. package/vendor/stylo/macros.rs +70 -0
  130. package/vendor/stylo/matching.rs +1226 -0
  131. package/vendor/stylo/media_queries/media_list.rs +168 -0
  132. package/vendor/stylo/media_queries/media_query.rs +190 -0
  133. package/vendor/stylo/media_queries/mod.rs +13 -0
  134. package/vendor/stylo/parallel.rs +205 -0
  135. package/vendor/stylo/parser.rs +276 -0
  136. package/vendor/stylo/piecewise_linear.rs +282 -0
  137. package/vendor/stylo/prefs.rs +33 -0
  138. package/vendor/stylo/properties/build.py +119 -0
  139. package/vendor/stylo/properties/cascade.rs +2704 -0
  140. package/vendor/stylo/properties/computed_value_flags.rs +206 -0
  141. package/vendor/stylo/properties/counted_unknown_properties.py +104 -0
  142. package/vendor/stylo/properties/counter_style_descriptors.toml +45 -0
  143. package/vendor/stylo/properties/data.py +1375 -0
  144. package/vendor/stylo/properties/declaration_block.rs +1788 -0
  145. package/vendor/stylo/properties/font_face_descriptors.toml +50 -0
  146. package/vendor/stylo/properties/gecko.mako.rs +1555 -0
  147. package/vendor/stylo/properties/helpers/animated_properties.mako.rs +800 -0
  148. package/vendor/stylo/properties/helpers.mako.rs +812 -0
  149. package/vendor/stylo/properties/longhands.toml +4305 -0
  150. package/vendor/stylo/properties/mod.rs +1857 -0
  151. package/vendor/stylo/properties/properties.html.mako +31 -0
  152. package/vendor/stylo/properties/properties.mako.rs +3103 -0
  153. package/vendor/stylo/properties/property_descriptors.toml +18 -0
  154. package/vendor/stylo/properties/shorthands.rs +4241 -0
  155. package/vendor/stylo/properties/shorthands.toml +575 -0
  156. package/vendor/stylo/properties/vendored_python/mako-1.3.10-py3-none-any.whl +0 -0
  157. package/vendor/stylo/properties/vendored_python/markupsafe/LICENSE.txt +28 -0
  158. package/vendor/stylo/properties/vendored_python/markupsafe/__init__.py +384 -0
  159. package/vendor/stylo/properties/vendored_python/toml-0.10.2-py2.py3-none-any.whl +0 -0
  160. package/vendor/stylo/properties/view_transition_descriptors.toml +11 -0
  161. package/vendor/stylo/properties_and_values/mod.rs +12 -0
  162. package/vendor/stylo/properties_and_values/registry.rs +65 -0
  163. package/vendor/stylo/properties_and_values/rule.rs +331 -0
  164. package/vendor/stylo/properties_and_values/syntax/ascii.rs +60 -0
  165. package/vendor/stylo/properties_and_values/syntax/data_type.rs +146 -0
  166. package/vendor/stylo/properties_and_values/syntax/mod.rs +437 -0
  167. package/vendor/stylo/properties_and_values/value.rs +758 -0
  168. package/vendor/stylo/queries/condition.rs +996 -0
  169. package/vendor/stylo/queries/feature.rs +199 -0
  170. package/vendor/stylo/queries/feature_expression.rs +1170 -0
  171. package/vendor/stylo/queries/mod.rs +19 -0
  172. package/vendor/stylo/queries/values.rs +46 -0
  173. package/vendor/stylo/rule_cache.rs +267 -0
  174. package/vendor/stylo/rule_collector.rs +554 -0
  175. package/vendor/stylo/rule_tree/core.rs +787 -0
  176. package/vendor/stylo/rule_tree/level.rs +396 -0
  177. package/vendor/stylo/rule_tree/map.rs +201 -0
  178. package/vendor/stylo/rule_tree/mod.rs +427 -0
  179. package/vendor/stylo/rule_tree/source.rs +80 -0
  180. package/vendor/stylo/rule_tree/unsafe_box.rs +78 -0
  181. package/vendor/stylo/scoped_tls.rs +80 -0
  182. package/vendor/stylo/selector_map.rs +1050 -0
  183. package/vendor/stylo/selector_parser.rs +305 -0
  184. package/vendor/stylo/servo/animation.rs +1922 -0
  185. package/vendor/stylo/servo/attr.rs +714 -0
  186. package/vendor/stylo/servo/encoding_support.rs +81 -0
  187. package/vendor/stylo/servo/media_features.rs +254 -0
  188. package/vendor/stylo/servo/mod.rs +16 -0
  189. package/vendor/stylo/servo/restyle_damage.rs +215 -0
  190. package/vendor/stylo/servo/selector_parser.rs +1036 -0
  191. package/vendor/stylo/servo/shadow_parts.rs +207 -0
  192. package/vendor/stylo/shared_lock.rs +271 -0
  193. package/vendor/stylo/sharing/checks.rs +281 -0
  194. package/vendor/stylo/sharing/mod.rs +1000 -0
  195. package/vendor/stylo/simple_buckets_map.rs +52 -0
  196. package/vendor/stylo/str.rs +168 -0
  197. package/vendor/stylo/style_adjuster.rs +1086 -0
  198. package/vendor/stylo/style_resolver.rs +658 -0
  199. package/vendor/stylo/stylesheet_set.rs +658 -0
  200. package/vendor/stylo/stylesheets/appearance_base_rule.rs +51 -0
  201. package/vendor/stylo/stylesheets/container_rule.rs +769 -0
  202. package/vendor/stylo/stylesheets/counter_style_rule.rs +7 -0
  203. package/vendor/stylo/stylesheets/document_rule.rs +272 -0
  204. package/vendor/stylo/stylesheets/font_face_rule.rs +7 -0
  205. package/vendor/stylo/stylesheets/font_feature_values_rule.rs +481 -0
  206. package/vendor/stylo/stylesheets/font_palette_values_rule.rs +304 -0
  207. package/vendor/stylo/stylesheets/import_rule.rs +259 -0
  208. package/vendor/stylo/stylesheets/keyframes_rule.rs +733 -0
  209. package/vendor/stylo/stylesheets/layer_rule.rs +221 -0
  210. package/vendor/stylo/stylesheets/loader.rs +29 -0
  211. package/vendor/stylo/stylesheets/margin_rule.rs +190 -0
  212. package/vendor/stylo/stylesheets/media_rule.rs +191 -0
  213. package/vendor/stylo/stylesheets/mod.rs +918 -0
  214. package/vendor/stylo/stylesheets/namespace_rule.rs +43 -0
  215. package/vendor/stylo/stylesheets/nested_declarations_rule.rs +51 -0
  216. package/vendor/stylo/stylesheets/origin.rs +249 -0
  217. package/vendor/stylo/stylesheets/page_rule.rs +354 -0
  218. package/vendor/stylo/stylesheets/position_try_rule.rs +68 -0
  219. package/vendor/stylo/stylesheets/property_rule.rs +5 -0
  220. package/vendor/stylo/stylesheets/rule_list.rs +167 -0
  221. package/vendor/stylo/stylesheets/rule_parser.rs +1189 -0
  222. package/vendor/stylo/stylesheets/rules_iterator.rs +397 -0
  223. package/vendor/stylo/stylesheets/scope_rule.rs +511 -0
  224. package/vendor/stylo/stylesheets/starting_style_rule.rs +54 -0
  225. package/vendor/stylo/stylesheets/style_rule.rs +80 -0
  226. package/vendor/stylo/stylesheets/stylesheet.rs +570 -0
  227. package/vendor/stylo/stylesheets/supports_rule.rs +486 -0
  228. package/vendor/stylo/stylesheets/view_transition_rule.rs +81 -0
  229. package/vendor/stylo/stylist.rs +5076 -0
  230. package/vendor/stylo/thread_state.rs +87 -0
  231. package/vendor/stylo/traversal.rs +765 -0
  232. package/vendor/stylo/traversal_flags.rs +68 -0
  233. package/vendor/stylo/typed_om/mod.rs +981 -0
  234. package/vendor/stylo/typed_om/numeric.rs +128 -0
  235. package/vendor/stylo/typed_om/numeric_declaration.rs +93 -0
  236. package/vendor/stylo/typed_om/numeric_type.rs +640 -0
  237. package/vendor/stylo/typed_om/sum_value.rs +426 -0
  238. package/vendor/stylo/url/gecko.rs +367 -0
  239. package/vendor/stylo/url/mod.rs +71 -0
  240. package/vendor/stylo/url/servo.rs +239 -0
  241. package/vendor/stylo/use_counters/mod.rs +137 -0
  242. package/vendor/stylo/values/animated/color.rs +103 -0
  243. package/vendor/stylo/values/animated/effects.rs +26 -0
  244. package/vendor/stylo/values/animated/font.rs +37 -0
  245. package/vendor/stylo/values/animated/grid.rs +161 -0
  246. package/vendor/stylo/values/animated/lists.rs +141 -0
  247. package/vendor/stylo/values/animated/mod.rs +550 -0
  248. package/vendor/stylo/values/animated/svg.rs +46 -0
  249. package/vendor/stylo/values/animated/text.rs +58 -0
  250. package/vendor/stylo/values/animated/transform.rs +1592 -0
  251. package/vendor/stylo/values/computed/align.rs +90 -0
  252. package/vendor/stylo/values/computed/angle.rs +130 -0
  253. package/vendor/stylo/values/computed/animation.rs +124 -0
  254. package/vendor/stylo/values/computed/background.rs +13 -0
  255. package/vendor/stylo/values/computed/basic_shape.rs +267 -0
  256. package/vendor/stylo/values/computed/border.rs +163 -0
  257. package/vendor/stylo/values/computed/box.rs +267 -0
  258. package/vendor/stylo/values/computed/calc.rs +334 -0
  259. package/vendor/stylo/values/computed/color.rs +161 -0
  260. package/vendor/stylo/values/computed/column.rs +11 -0
  261. package/vendor/stylo/values/computed/corner_shape.rs +155 -0
  262. package/vendor/stylo/values/computed/counters.rs +26 -0
  263. package/vendor/stylo/values/computed/easing.rs +109 -0
  264. package/vendor/stylo/values/computed/effects.rs +30 -0
  265. package/vendor/stylo/values/computed/flex.rs +19 -0
  266. package/vendor/stylo/values/computed/font.rs +1517 -0
  267. package/vendor/stylo/values/computed/image.rs +273 -0
  268. package/vendor/stylo/values/computed/length.rs +576 -0
  269. package/vendor/stylo/values/computed/length_percentage.rs +1055 -0
  270. package/vendor/stylo/values/computed/list.rs +16 -0
  271. package/vendor/stylo/values/computed/mod.rs +1141 -0
  272. package/vendor/stylo/values/computed/motion.rs +73 -0
  273. package/vendor/stylo/values/computed/outline.rs +7 -0
  274. package/vendor/stylo/values/computed/page.rs +77 -0
  275. package/vendor/stylo/values/computed/param.rs +9 -0
  276. package/vendor/stylo/values/computed/percentage.rs +143 -0
  277. package/vendor/stylo/values/computed/position.rs +273 -0
  278. package/vendor/stylo/values/computed/ratio.rs +88 -0
  279. package/vendor/stylo/values/computed/rect.rs +19 -0
  280. package/vendor/stylo/values/computed/resolution.rs +76 -0
  281. package/vendor/stylo/values/computed/svg.rs +66 -0
  282. package/vendor/stylo/values/computed/table.rs +7 -0
  283. package/vendor/stylo/values/computed/text.rs +199 -0
  284. package/vendor/stylo/values/computed/time.rs +83 -0
  285. package/vendor/stylo/values/computed/transform.rs +559 -0
  286. package/vendor/stylo/values/computed/tree_counting.rs +30 -0
  287. package/vendor/stylo/values/computed/ui.rs +23 -0
  288. package/vendor/stylo/values/computed/url.rs +12 -0
  289. package/vendor/stylo/values/distance.rs +139 -0
  290. package/vendor/stylo/values/generics/animation.rs +363 -0
  291. package/vendor/stylo/values/generics/background.rs +65 -0
  292. package/vendor/stylo/values/generics/basic_shape.rs +1389 -0
  293. package/vendor/stylo/values/generics/border.rs +303 -0
  294. package/vendor/stylo/values/generics/box.rs +552 -0
  295. package/vendor/stylo/values/generics/calc.rs +2986 -0
  296. package/vendor/stylo/values/generics/color.rs +318 -0
  297. package/vendor/stylo/values/generics/column.rs +44 -0
  298. package/vendor/stylo/values/generics/counters.rs +320 -0
  299. package/vendor/stylo/values/generics/easing.rs +132 -0
  300. package/vendor/stylo/values/generics/effects.rs +131 -0
  301. package/vendor/stylo/values/generics/flex.rs +34 -0
  302. package/vendor/stylo/values/generics/font.rs +376 -0
  303. package/vendor/stylo/values/generics/grid.rs +962 -0
  304. package/vendor/stylo/values/generics/image.rs +653 -0
  305. package/vendor/stylo/values/generics/length.rs +656 -0
  306. package/vendor/stylo/values/generics/mod.rs +303 -0
  307. package/vendor/stylo/values/generics/motion.rs +274 -0
  308. package/vendor/stylo/values/generics/page.rs +167 -0
  309. package/vendor/stylo/values/generics/position.rs +669 -0
  310. package/vendor/stylo/values/generics/ratio.rs +88 -0
  311. package/vendor/stylo/values/generics/rect.rs +147 -0
  312. package/vendor/stylo/values/generics/size.rs +102 -0
  313. package/vendor/stylo/values/generics/svg.rs +226 -0
  314. package/vendor/stylo/values/generics/text.rs +268 -0
  315. package/vendor/stylo/values/generics/transform.rs +1157 -0
  316. package/vendor/stylo/values/generics/ui.rs +147 -0
  317. package/vendor/stylo/values/generics/url.rs +51 -0
  318. package/vendor/stylo/values/mod.rs +820 -0
  319. package/vendor/stylo/values/resolved/animation.rs +33 -0
  320. package/vendor/stylo/values/resolved/color.rs +53 -0
  321. package/vendor/stylo/values/resolved/counters.rs +45 -0
  322. package/vendor/stylo/values/resolved/mod.rs +316 -0
  323. package/vendor/stylo/values/specified/align.rs +711 -0
  324. package/vendor/stylo/values/specified/angle.rs +407 -0
  325. package/vendor/stylo/values/specified/animation.rs +921 -0
  326. package/vendor/stylo/values/specified/background.rs +270 -0
  327. package/vendor/stylo/values/specified/basic_shape.rs +986 -0
  328. package/vendor/stylo/values/specified/border.rs +430 -0
  329. package/vendor/stylo/values/specified/box.rs +2231 -0
  330. package/vendor/stylo/values/specified/calc.rs +1657 -0
  331. package/vendor/stylo/values/specified/color.rs +1210 -0
  332. package/vendor/stylo/values/specified/column.rs +11 -0
  333. package/vendor/stylo/values/specified/corner_shape.rs +152 -0
  334. package/vendor/stylo/values/specified/counters.rs +242 -0
  335. package/vendor/stylo/values/specified/easing.rs +225 -0
  336. package/vendor/stylo/values/specified/effects.rs +421 -0
  337. package/vendor/stylo/values/specified/flex.rs +42 -0
  338. package/vendor/stylo/values/specified/font.rs +2103 -0
  339. package/vendor/stylo/values/specified/frequency.rs +39 -0
  340. package/vendor/stylo/values/specified/grid.rs +407 -0
  341. package/vendor/stylo/values/specified/image.rs +1385 -0
  342. package/vendor/stylo/values/specified/intersection_observer.rs +80 -0
  343. package/vendor/stylo/values/specified/length.rs +2024 -0
  344. package/vendor/stylo/values/specified/list.rs +190 -0
  345. package/vendor/stylo/values/specified/mod.rs +531 -0
  346. package/vendor/stylo/values/specified/motion.rs +316 -0
  347. package/vendor/stylo/values/specified/number.rs +603 -0
  348. package/vendor/stylo/values/specified/outline.rs +69 -0
  349. package/vendor/stylo/values/specified/page.rs +94 -0
  350. package/vendor/stylo/values/specified/param.rs +121 -0
  351. package/vendor/stylo/values/specified/percentage.rs +364 -0
  352. package/vendor/stylo/values/specified/position.rs +2247 -0
  353. package/vendor/stylo/values/specified/ratio.rs +29 -0
  354. package/vendor/stylo/values/specified/rect.rs +28 -0
  355. package/vendor/stylo/values/specified/resolution.rs +237 -0
  356. package/vendor/stylo/values/specified/source_size_list.rs +135 -0
  357. package/vendor/stylo/values/specified/svg.rs +427 -0
  358. package/vendor/stylo/values/specified/svg_path.rs +1115 -0
  359. package/vendor/stylo/values/specified/table.rs +38 -0
  360. package/vendor/stylo/values/specified/text.rs +1561 -0
  361. package/vendor/stylo/values/specified/time.rs +313 -0
  362. package/vendor/stylo/values/specified/transform.rs +599 -0
  363. package/vendor/stylo/values/specified/tree_counting.rs +32 -0
  364. package/vendor/stylo/values/specified/ui.rs +344 -0
  365. package/vendor/stylo/values/specified/url.rs +12 -0
  366. package/vendor/stylo/values/tagged_numeric.rs +253 -0
  367. package/wasm/blitz_pdf.d.ts +67 -0
  368. package/wasm/blitz_pdf.js +699 -0
  369. package/wasm/blitz_pdf_bg.wasm +0 -0
  370. package/wasm/blitz_pdf_bg.wasm.d.ts +20 -0
@@ -0,0 +1,1684 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ //! Geometry in flow-relative space.
6
+
7
+ use crate::derives::*;
8
+ use crate::properties::style_structs;
9
+ use euclid::default::{Point2D, Rect, SideOffsets2D, Size2D};
10
+ use euclid::num::Zero;
11
+ use std::cmp::{max, min};
12
+ use std::fmt::{self, Debug, Error, Formatter};
13
+ use std::ops::{Add, Sub};
14
+
15
+ pub enum BlockFlowDirection {
16
+ TopToBottom,
17
+ RightToLeft,
18
+ LeftToRight,
19
+ }
20
+
21
+ pub enum InlineBaseDirection {
22
+ LeftToRight,
23
+ RightToLeft,
24
+ }
25
+
26
+ /// The writing-mode property (different from the WritingMode enum).
27
+ /// https://drafts.csswg.org/css-writing-modes/#block-flow
28
+ /// Aliases come from https://drafts.csswg.org/css-writing-modes-4/#svg-writing-mode
29
+ #[allow(missing_docs)]
30
+ #[derive(
31
+ Clone,
32
+ Copy,
33
+ Debug,
34
+ Eq,
35
+ FromPrimitive,
36
+ MallocSizeOf,
37
+ Parse,
38
+ PartialEq,
39
+ SpecifiedValueInfo,
40
+ ToComputedValue,
41
+ ToCss,
42
+ ToResolvedValue,
43
+ ToShmem,
44
+ ToTyped,
45
+ )]
46
+ #[repr(u8)]
47
+ pub enum WritingModeProperty {
48
+ #[parse(aliases = "lr,lr-tb,rl,rl-tb")]
49
+ HorizontalTb,
50
+ #[parse(aliases = "tb,tb-rl")]
51
+ VerticalRl,
52
+ VerticalLr,
53
+ #[cfg(feature = "gecko")]
54
+ SidewaysRl,
55
+ #[cfg(feature = "gecko")]
56
+ SidewaysLr,
57
+ }
58
+
59
+ // TODO: improve the readability of the WritingMode serialization, refer to the Debug:fmt()
60
+ #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Serialize)]
61
+ #[repr(C)]
62
+ pub struct WritingMode(u8);
63
+ bitflags!(
64
+ impl WritingMode: u8 {
65
+ /// A vertical writing mode; writing-mode is vertical-rl,
66
+ /// vertical-lr, sideways-lr, or sideways-rl.
67
+ const VERTICAL = 1 << 0;
68
+ /// The inline flow direction is reversed against the physical
69
+ /// direction (i.e. right-to-left or bottom-to-top); writing-mode is
70
+ /// sideways-lr or direction is rtl (but not both).
71
+ ///
72
+ /// (This bit can be derived from the others, but we store it for
73
+ /// convenience.)
74
+ const INLINE_REVERSED = 1 << 1;
75
+ /// A vertical writing mode whose block progression direction is left-
76
+ /// to-right; writing-mode is vertical-lr or sideways-lr.
77
+ ///
78
+ /// Never set without VERTICAL.
79
+ const VERTICAL_LR = 1 << 2;
80
+ /// The line-over/line-under sides are inverted with respect to the
81
+ /// block-start/block-end edge; writing-mode is vertical-lr.
82
+ ///
83
+ /// Never set without VERTICAL and VERTICAL_LR.
84
+ const LINE_INVERTED = 1 << 3;
85
+ /// direction is rtl.
86
+ const RTL = 1 << 4;
87
+ /// All text within a vertical writing mode is displayed sideways
88
+ /// and runs top-to-bottom or bottom-to-top; set in these cases:
89
+ ///
90
+ /// * writing-mode: sideways-rl;
91
+ /// * writing-mode: sideways-lr;
92
+ ///
93
+ /// Never set without VERTICAL.
94
+ const VERTICAL_SIDEWAYS = 1 << 5;
95
+ /// Similar to VERTICAL_SIDEWAYS, but is set via text-orientation;
96
+ /// set in these cases:
97
+ ///
98
+ /// * writing-mode: vertical-rl; text-orientation: sideways;
99
+ /// * writing-mode: vertical-lr; text-orientation: sideways;
100
+ ///
101
+ /// Never set without VERTICAL.
102
+ const TEXT_SIDEWAYS = 1 << 6;
103
+ /// Horizontal text within a vertical writing mode is displayed with each
104
+ /// glyph upright; set in these cases:
105
+ ///
106
+ /// * writing-mode: vertical-rl; text-orientation: upright;
107
+ /// * writing-mode: vertical-lr: text-orientation: upright;
108
+ ///
109
+ /// Never set without VERTICAL.
110
+ const UPRIGHT = 1 << 7;
111
+ /// Writing mode combinations that can be specified in CSS.
112
+ ///
113
+ /// * writing-mode: horizontal-tb;
114
+ const WRITING_MODE_HORIZONTAL_TB = 0;
115
+ /// * writing-mode: vertical_rl;
116
+ const WRITING_MODE_VERTICAL_RL = WritingMode::VERTICAL.bits();
117
+ /// * writing-mode: vertical-lr;
118
+ const WRITING_MODE_VERTICAL_LR = WritingMode::VERTICAL.bits() |
119
+ WritingMode::VERTICAL_LR.bits() |
120
+ WritingMode::LINE_INVERTED.bits();
121
+ /// * writing-mode: sideways-rl;
122
+ const WRITING_MODE_SIDEWAYS_RL = WritingMode::VERTICAL.bits() |
123
+ WritingMode::VERTICAL_SIDEWAYS.bits();
124
+ /// * writing-mode: sideways-lr;
125
+ const WRITING_MODE_SIDEWAYS_LR = WritingMode::VERTICAL.bits() |
126
+ WritingMode::VERTICAL_LR.bits() |
127
+ WritingMode::VERTICAL_SIDEWAYS.bits();
128
+ }
129
+ );
130
+
131
+ impl WritingMode {
132
+ /// Return a WritingMode bitflags from the relevant CSS properties.
133
+ pub fn new(inheritedbox_style: &style_structs::InheritedBox) -> Self {
134
+ use crate::properties::longhands::direction::computed_value::T as Direction;
135
+
136
+ let mut flags = WritingMode::empty();
137
+
138
+ let direction = inheritedbox_style.clone_direction();
139
+ let writing_mode = inheritedbox_style.clone_writing_mode();
140
+
141
+ match direction {
142
+ Direction::Ltr => {},
143
+ Direction::Rtl => {
144
+ flags.insert(WritingMode::RTL);
145
+ },
146
+ }
147
+
148
+ match writing_mode {
149
+ WritingModeProperty::HorizontalTb => {
150
+ if direction == Direction::Rtl {
151
+ flags.insert(WritingMode::INLINE_REVERSED);
152
+ }
153
+ },
154
+ WritingModeProperty::VerticalRl => {
155
+ flags.insert(WritingMode::WRITING_MODE_VERTICAL_RL);
156
+ if direction == Direction::Rtl {
157
+ flags.insert(WritingMode::INLINE_REVERSED);
158
+ }
159
+ },
160
+ WritingModeProperty::VerticalLr => {
161
+ flags.insert(WritingMode::WRITING_MODE_VERTICAL_LR);
162
+ if direction == Direction::Rtl {
163
+ flags.insert(WritingMode::INLINE_REVERSED);
164
+ }
165
+ },
166
+ #[cfg(feature = "gecko")]
167
+ WritingModeProperty::SidewaysRl => {
168
+ flags.insert(WritingMode::WRITING_MODE_SIDEWAYS_RL);
169
+ if direction == Direction::Rtl {
170
+ flags.insert(WritingMode::INLINE_REVERSED);
171
+ }
172
+ },
173
+ #[cfg(feature = "gecko")]
174
+ WritingModeProperty::SidewaysLr => {
175
+ flags.insert(WritingMode::WRITING_MODE_SIDEWAYS_LR);
176
+ if direction == Direction::Ltr {
177
+ flags.insert(WritingMode::INLINE_REVERSED);
178
+ }
179
+ },
180
+ }
181
+
182
+ #[cfg(feature = "gecko")]
183
+ {
184
+ use crate::properties::longhands::text_orientation::computed_value::T as TextOrientation;
185
+
186
+ // text-orientation only has an effect for vertical-rl and
187
+ // vertical-lr values of writing-mode.
188
+ match writing_mode {
189
+ WritingModeProperty::VerticalRl | WritingModeProperty::VerticalLr => {
190
+ match inheritedbox_style.clone_text_orientation() {
191
+ TextOrientation::Mixed => {},
192
+ TextOrientation::Upright => {
193
+ flags.insert(WritingMode::UPRIGHT);
194
+
195
+ // https://drafts.csswg.org/css-writing-modes-3/#valdef-text-orientation-upright:
196
+ //
197
+ // > This value causes the used value of direction
198
+ // > to be ltr, and for the purposes of bidi
199
+ // > reordering, causes all characters to be treated
200
+ // > as strong LTR.
201
+ flags.remove(WritingMode::RTL);
202
+ flags.remove(WritingMode::INLINE_REVERSED);
203
+ },
204
+ TextOrientation::Sideways => {
205
+ flags.insert(WritingMode::TEXT_SIDEWAYS);
206
+ },
207
+ }
208
+ },
209
+ _ => {},
210
+ }
211
+ }
212
+
213
+ flags
214
+ }
215
+
216
+ /// Returns the `horizontal-tb` value.
217
+ pub fn horizontal_tb() -> Self {
218
+ Self::empty()
219
+ }
220
+
221
+ #[inline]
222
+ pub fn is_vertical(&self) -> bool {
223
+ self.intersects(WritingMode::VERTICAL)
224
+ }
225
+
226
+ #[inline]
227
+ pub fn is_vertical_rl(&self) -> bool {
228
+ self.is_vertical() && !self.is_vertical_lr()
229
+ }
230
+
231
+ #[inline]
232
+ pub fn is_horizontal(&self) -> bool {
233
+ !self.is_vertical()
234
+ }
235
+
236
+ /// Assuming .is_vertical(), does the block direction go left to right?
237
+ #[inline]
238
+ pub fn is_vertical_lr(&self) -> bool {
239
+ self.intersects(WritingMode::VERTICAL_LR)
240
+ }
241
+
242
+ /// Assuming .is_vertical(), does the inline direction go top to bottom?
243
+ #[inline]
244
+ pub fn is_inline_tb(&self) -> bool {
245
+ // https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
246
+ !self.intersects(WritingMode::INLINE_REVERSED)
247
+ }
248
+
249
+ #[inline]
250
+ pub fn is_bidi_ltr(&self) -> bool {
251
+ !self.intersects(WritingMode::RTL)
252
+ }
253
+
254
+ #[inline]
255
+ pub fn is_sideways(&self) -> bool {
256
+ self.intersects(WritingMode::VERTICAL_SIDEWAYS | WritingMode::TEXT_SIDEWAYS)
257
+ }
258
+
259
+ #[inline]
260
+ pub fn is_upright(&self) -> bool {
261
+ self.intersects(WritingMode::UPRIGHT)
262
+ }
263
+
264
+ /// https://drafts.csswg.org/css-writing-modes/#logical-to-physical
265
+ ///
266
+ /// | Return | line-left is… | line-right is… |
267
+ /// |---------|---------------|----------------|
268
+ /// | `true` | inline-start | inline-end |
269
+ /// | `false` | inline-end | inline-start |
270
+ #[inline]
271
+ pub fn line_left_is_inline_start(&self) -> bool {
272
+ // https://drafts.csswg.org/css-writing-modes/#inline-start
273
+ // “For boxes with a used direction value of ltr, this means the line-left side.
274
+ // For boxes with a used direction value of rtl, this means the line-right side.”
275
+ self.is_bidi_ltr()
276
+ }
277
+
278
+ #[inline]
279
+ pub fn inline_start_physical_side(&self) -> PhysicalSide {
280
+ match (self.is_vertical(), self.is_inline_tb(), self.is_bidi_ltr()) {
281
+ (false, _, true) => PhysicalSide::Left,
282
+ (false, _, false) => PhysicalSide::Right,
283
+ (true, true, _) => PhysicalSide::Top,
284
+ (true, false, _) => PhysicalSide::Bottom,
285
+ }
286
+ }
287
+
288
+ #[inline]
289
+ pub fn inline_end_physical_side(&self) -> PhysicalSide {
290
+ match (self.is_vertical(), self.is_inline_tb(), self.is_bidi_ltr()) {
291
+ (false, _, true) => PhysicalSide::Right,
292
+ (false, _, false) => PhysicalSide::Left,
293
+ (true, true, _) => PhysicalSide::Bottom,
294
+ (true, false, _) => PhysicalSide::Top,
295
+ }
296
+ }
297
+
298
+ #[inline]
299
+ pub fn block_start_physical_side(&self) -> PhysicalSide {
300
+ match (self.is_vertical(), self.is_vertical_lr()) {
301
+ (false, _) => PhysicalSide::Top,
302
+ (true, true) => PhysicalSide::Left,
303
+ (true, false) => PhysicalSide::Right,
304
+ }
305
+ }
306
+
307
+ #[inline]
308
+ pub fn block_end_physical_side(&self) -> PhysicalSide {
309
+ match (self.is_vertical(), self.is_vertical_lr()) {
310
+ (false, _) => PhysicalSide::Bottom,
311
+ (true, true) => PhysicalSide::Right,
312
+ (true, false) => PhysicalSide::Left,
313
+ }
314
+ }
315
+
316
+ /// Given a physical side, flips the start on that axis, and returns the corresponding
317
+ /// physical side.
318
+ #[inline]
319
+ pub fn flipped_start_side(&self, side: PhysicalSide) -> PhysicalSide {
320
+ let bs = self.block_start_physical_side();
321
+ if side == bs {
322
+ return self.inline_start_physical_side();
323
+ }
324
+ let be = self.block_end_physical_side();
325
+ if side == be {
326
+ return self.inline_end_physical_side();
327
+ }
328
+ if side == self.inline_start_physical_side() {
329
+ return bs;
330
+ }
331
+ debug_assert_eq!(side, self.inline_end_physical_side());
332
+ be
333
+ }
334
+
335
+ #[inline]
336
+ pub fn start_start_physical_corner(&self) -> PhysicalCorner {
337
+ PhysicalCorner::from_sides(
338
+ self.block_start_physical_side(),
339
+ self.inline_start_physical_side(),
340
+ )
341
+ }
342
+
343
+ #[inline]
344
+ pub fn start_end_physical_corner(&self) -> PhysicalCorner {
345
+ PhysicalCorner::from_sides(
346
+ self.block_start_physical_side(),
347
+ self.inline_end_physical_side(),
348
+ )
349
+ }
350
+
351
+ #[inline]
352
+ pub fn end_start_physical_corner(&self) -> PhysicalCorner {
353
+ PhysicalCorner::from_sides(
354
+ self.block_end_physical_side(),
355
+ self.inline_start_physical_side(),
356
+ )
357
+ }
358
+
359
+ #[inline]
360
+ pub fn end_end_physical_corner(&self) -> PhysicalCorner {
361
+ PhysicalCorner::from_sides(
362
+ self.block_end_physical_side(),
363
+ self.inline_end_physical_side(),
364
+ )
365
+ }
366
+
367
+ #[inline]
368
+ pub fn block_flow_direction(&self) -> BlockFlowDirection {
369
+ match (self.is_vertical(), self.is_vertical_lr()) {
370
+ (false, _) => BlockFlowDirection::TopToBottom,
371
+ (true, true) => BlockFlowDirection::LeftToRight,
372
+ (true, false) => BlockFlowDirection::RightToLeft,
373
+ }
374
+ }
375
+
376
+ #[inline]
377
+ pub fn inline_base_direction(&self) -> InlineBaseDirection {
378
+ if self.intersects(WritingMode::RTL) {
379
+ InlineBaseDirection::RightToLeft
380
+ } else {
381
+ InlineBaseDirection::LeftToRight
382
+ }
383
+ }
384
+
385
+ #[inline]
386
+ /// Is the text layout vertical?
387
+ pub fn is_text_vertical(&self) -> bool {
388
+ self.is_vertical() && !self.is_sideways()
389
+ }
390
+ }
391
+
392
+ impl fmt::Display for WritingMode {
393
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
394
+ if self.is_vertical() {
395
+ write!(formatter, "V")?;
396
+ if self.is_vertical_lr() {
397
+ write!(formatter, " LR")?;
398
+ } else {
399
+ write!(formatter, " RL")?;
400
+ }
401
+ if self.is_sideways() {
402
+ write!(formatter, " Sideways")?;
403
+ }
404
+ if self.intersects(WritingMode::LINE_INVERTED) {
405
+ write!(formatter, " Inverted")?;
406
+ }
407
+ } else {
408
+ write!(formatter, "H")?;
409
+ }
410
+ if self.is_bidi_ltr() {
411
+ write!(formatter, " LTR")
412
+ } else {
413
+ write!(formatter, " RTL")
414
+ }
415
+ }
416
+ }
417
+
418
+ /// Wherever logical geometry is used, the writing mode is known based on context:
419
+ /// every method takes a `mode` parameter.
420
+ /// However, this context is easy to get wrong.
421
+ /// In debug builds only, logical geometry objects store their writing mode
422
+ /// (in addition to taking it as a parameter to methods) and check it.
423
+ /// In non-debug builds, make this storage zero-size and the checks no-ops.
424
+ #[cfg(not(debug_assertions))]
425
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
426
+ struct DebugWritingMode;
427
+
428
+ #[cfg(debug_assertions)]
429
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
430
+ struct DebugWritingMode {
431
+ mode: WritingMode,
432
+ }
433
+
434
+ #[cfg(not(debug_assertions))]
435
+ impl DebugWritingMode {
436
+ #[inline]
437
+ fn check(&self, _other: WritingMode) {}
438
+
439
+ #[inline]
440
+ fn check_debug(&self, _other: DebugWritingMode) {}
441
+
442
+ #[inline]
443
+ fn new(_mode: WritingMode) -> DebugWritingMode {
444
+ DebugWritingMode
445
+ }
446
+ }
447
+
448
+ #[cfg(debug_assertions)]
449
+ impl DebugWritingMode {
450
+ #[inline]
451
+ fn check(&self, other: WritingMode) {
452
+ assert_eq!(self.mode, other)
453
+ }
454
+
455
+ #[inline]
456
+ fn check_debug(&self, other: DebugWritingMode) {
457
+ assert_eq!(self.mode, other.mode)
458
+ }
459
+
460
+ #[inline]
461
+ fn new(mode: WritingMode) -> DebugWritingMode {
462
+ DebugWritingMode { mode }
463
+ }
464
+ }
465
+
466
+ impl Debug for DebugWritingMode {
467
+ #[cfg(not(debug_assertions))]
468
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
469
+ write!(formatter, "?")
470
+ }
471
+
472
+ #[cfg(debug_assertions)]
473
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
474
+ write!(formatter, "{}", self.mode)
475
+ }
476
+ }
477
+
478
+ // Used to specify the logical direction.
479
+ #[derive(Clone, Copy, Debug, PartialEq, Serialize)]
480
+ pub enum Direction {
481
+ Inline,
482
+ Block,
483
+ }
484
+
485
+ /// A 2D size in flow-relative dimensions
486
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
487
+ pub struct LogicalSize<T> {
488
+ pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure
489
+ pub block: T, // block-size, a.k.a. logical height, a.k.a. extent
490
+ debug_writing_mode: DebugWritingMode,
491
+ }
492
+
493
+ impl<T: Debug> Debug for LogicalSize<T> {
494
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
495
+ write!(
496
+ formatter,
497
+ "LogicalSize({:?}, i{:?}×b{:?})",
498
+ self.debug_writing_mode, self.inline, self.block
499
+ )
500
+ }
501
+ }
502
+
503
+ // Can not implement the Zero trait: its zero() method does not have the `mode` parameter.
504
+ impl<T: Zero> LogicalSize<T> {
505
+ #[inline]
506
+ pub fn zero(mode: WritingMode) -> LogicalSize<T> {
507
+ LogicalSize {
508
+ inline: Zero::zero(),
509
+ block: Zero::zero(),
510
+ debug_writing_mode: DebugWritingMode::new(mode),
511
+ }
512
+ }
513
+ }
514
+
515
+ impl<T> LogicalSize<T> {
516
+ #[inline]
517
+ pub fn new(mode: WritingMode, inline: T, block: T) -> LogicalSize<T> {
518
+ LogicalSize {
519
+ inline,
520
+ block,
521
+ debug_writing_mode: DebugWritingMode::new(mode),
522
+ }
523
+ }
524
+
525
+ #[inline]
526
+ pub fn from_physical(mode: WritingMode, size: Size2D<T>) -> LogicalSize<T> {
527
+ if mode.is_vertical() {
528
+ LogicalSize::new(mode, size.height, size.width)
529
+ } else {
530
+ LogicalSize::new(mode, size.width, size.height)
531
+ }
532
+ }
533
+ }
534
+
535
+ impl<T: Clone> LogicalSize<T> {
536
+ #[inline]
537
+ pub fn width(&self, mode: WritingMode) -> T {
538
+ self.debug_writing_mode.check(mode);
539
+ if mode.is_vertical() {
540
+ self.block.clone()
541
+ } else {
542
+ self.inline.clone()
543
+ }
544
+ }
545
+
546
+ #[inline]
547
+ pub fn set_width(&mut self, mode: WritingMode, width: T) {
548
+ self.debug_writing_mode.check(mode);
549
+ if mode.is_vertical() {
550
+ self.block = width
551
+ } else {
552
+ self.inline = width
553
+ }
554
+ }
555
+
556
+ #[inline]
557
+ pub fn height(&self, mode: WritingMode) -> T {
558
+ self.debug_writing_mode.check(mode);
559
+ if mode.is_vertical() {
560
+ self.inline.clone()
561
+ } else {
562
+ self.block.clone()
563
+ }
564
+ }
565
+
566
+ #[inline]
567
+ pub fn set_height(&mut self, mode: WritingMode, height: T) {
568
+ self.debug_writing_mode.check(mode);
569
+ if mode.is_vertical() {
570
+ self.inline = height
571
+ } else {
572
+ self.block = height
573
+ }
574
+ }
575
+
576
+ #[inline]
577
+ pub fn to_physical(&self, mode: WritingMode) -> Size2D<T> {
578
+ self.debug_writing_mode.check(mode);
579
+ if mode.is_vertical() {
580
+ Size2D::new(self.block.clone(), self.inline.clone())
581
+ } else {
582
+ Size2D::new(self.inline.clone(), self.block.clone())
583
+ }
584
+ }
585
+
586
+ #[inline]
587
+ pub fn convert(&self, mode_from: WritingMode, mode_to: WritingMode) -> LogicalSize<T> {
588
+ if mode_from == mode_to {
589
+ self.debug_writing_mode.check(mode_from);
590
+ self.clone()
591
+ } else {
592
+ LogicalSize::from_physical(mode_to, self.to_physical(mode_from))
593
+ }
594
+ }
595
+ }
596
+
597
+ impl<T: Add<T, Output = T>> Add for LogicalSize<T> {
598
+ type Output = LogicalSize<T>;
599
+
600
+ #[inline]
601
+ fn add(self, other: LogicalSize<T>) -> LogicalSize<T> {
602
+ self.debug_writing_mode
603
+ .check_debug(other.debug_writing_mode);
604
+ LogicalSize {
605
+ debug_writing_mode: self.debug_writing_mode,
606
+ inline: self.inline + other.inline,
607
+ block: self.block + other.block,
608
+ }
609
+ }
610
+ }
611
+
612
+ impl<T: Sub<T, Output = T>> Sub for LogicalSize<T> {
613
+ type Output = LogicalSize<T>;
614
+
615
+ #[inline]
616
+ fn sub(self, other: LogicalSize<T>) -> LogicalSize<T> {
617
+ self.debug_writing_mode
618
+ .check_debug(other.debug_writing_mode);
619
+ LogicalSize {
620
+ debug_writing_mode: self.debug_writing_mode,
621
+ inline: self.inline - other.inline,
622
+ block: self.block - other.block,
623
+ }
624
+ }
625
+ }
626
+
627
+ /// A 2D point in flow-relative dimensions
628
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
629
+ pub struct LogicalPoint<T> {
630
+ /// inline-axis coordinate
631
+ pub i: T,
632
+ /// block-axis coordinate
633
+ pub b: T,
634
+ debug_writing_mode: DebugWritingMode,
635
+ }
636
+
637
+ impl<T: Debug> Debug for LogicalPoint<T> {
638
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
639
+ write!(
640
+ formatter,
641
+ "LogicalPoint({:?} (i{:?}, b{:?}))",
642
+ self.debug_writing_mode, self.i, self.b
643
+ )
644
+ }
645
+ }
646
+
647
+ // Can not implement the Zero trait: its zero() method does not have the `mode` parameter.
648
+ impl<T: Zero> LogicalPoint<T> {
649
+ #[inline]
650
+ pub fn zero(mode: WritingMode) -> LogicalPoint<T> {
651
+ LogicalPoint {
652
+ i: Zero::zero(),
653
+ b: Zero::zero(),
654
+ debug_writing_mode: DebugWritingMode::new(mode),
655
+ }
656
+ }
657
+ }
658
+
659
+ impl<T: Copy> LogicalPoint<T> {
660
+ #[inline]
661
+ pub fn new(mode: WritingMode, i: T, b: T) -> LogicalPoint<T> {
662
+ LogicalPoint {
663
+ i,
664
+ b,
665
+ debug_writing_mode: DebugWritingMode::new(mode),
666
+ }
667
+ }
668
+ }
669
+
670
+ impl<T: Copy + Sub<T, Output = T>> LogicalPoint<T> {
671
+ #[inline]
672
+ pub fn from_physical(
673
+ mode: WritingMode,
674
+ point: Point2D<T>,
675
+ container_size: Size2D<T>,
676
+ ) -> LogicalPoint<T> {
677
+ if mode.is_vertical() {
678
+ LogicalPoint {
679
+ i: if mode.is_inline_tb() {
680
+ point.y
681
+ } else {
682
+ container_size.height - point.y
683
+ },
684
+ b: if mode.is_vertical_lr() {
685
+ point.x
686
+ } else {
687
+ container_size.width - point.x
688
+ },
689
+ debug_writing_mode: DebugWritingMode::new(mode),
690
+ }
691
+ } else {
692
+ LogicalPoint {
693
+ i: if mode.is_bidi_ltr() {
694
+ point.x
695
+ } else {
696
+ container_size.width - point.x
697
+ },
698
+ b: point.y,
699
+ debug_writing_mode: DebugWritingMode::new(mode),
700
+ }
701
+ }
702
+ }
703
+
704
+ #[inline]
705
+ pub fn x(&self, mode: WritingMode, container_size: Size2D<T>) -> T {
706
+ self.debug_writing_mode.check(mode);
707
+ if mode.is_vertical() {
708
+ if mode.is_vertical_lr() {
709
+ self.b
710
+ } else {
711
+ container_size.width - self.b
712
+ }
713
+ } else if mode.is_bidi_ltr() {
714
+ self.i
715
+ } else {
716
+ container_size.width - self.i
717
+ }
718
+ }
719
+
720
+ #[inline]
721
+ pub fn set_x(&mut self, mode: WritingMode, x: T, container_size: Size2D<T>) {
722
+ self.debug_writing_mode.check(mode);
723
+ if mode.is_vertical() {
724
+ self.b = if mode.is_vertical_lr() {
725
+ x
726
+ } else {
727
+ container_size.width - x
728
+ }
729
+ } else {
730
+ self.i = if mode.is_bidi_ltr() {
731
+ x
732
+ } else {
733
+ container_size.width - x
734
+ }
735
+ }
736
+ }
737
+
738
+ #[inline]
739
+ pub fn y(&self, mode: WritingMode, container_size: Size2D<T>) -> T {
740
+ self.debug_writing_mode.check(mode);
741
+ if mode.is_vertical() {
742
+ if mode.is_inline_tb() {
743
+ self.i
744
+ } else {
745
+ container_size.height - self.i
746
+ }
747
+ } else {
748
+ self.b
749
+ }
750
+ }
751
+
752
+ #[inline]
753
+ pub fn set_y(&mut self, mode: WritingMode, y: T, container_size: Size2D<T>) {
754
+ self.debug_writing_mode.check(mode);
755
+ if mode.is_vertical() {
756
+ self.i = if mode.is_inline_tb() {
757
+ y
758
+ } else {
759
+ container_size.height - y
760
+ }
761
+ } else {
762
+ self.b = y
763
+ }
764
+ }
765
+
766
+ #[inline]
767
+ pub fn to_physical(&self, mode: WritingMode, container_size: Size2D<T>) -> Point2D<T> {
768
+ self.debug_writing_mode.check(mode);
769
+ if mode.is_vertical() {
770
+ Point2D::new(
771
+ if mode.is_vertical_lr() {
772
+ self.b
773
+ } else {
774
+ container_size.width - self.b
775
+ },
776
+ if mode.is_inline_tb() {
777
+ self.i
778
+ } else {
779
+ container_size.height - self.i
780
+ },
781
+ )
782
+ } else {
783
+ Point2D::new(
784
+ if mode.is_bidi_ltr() {
785
+ self.i
786
+ } else {
787
+ container_size.width - self.i
788
+ },
789
+ self.b,
790
+ )
791
+ }
792
+ }
793
+
794
+ #[inline]
795
+ pub fn convert(
796
+ &self,
797
+ mode_from: WritingMode,
798
+ mode_to: WritingMode,
799
+ container_size: Size2D<T>,
800
+ ) -> LogicalPoint<T> {
801
+ if mode_from == mode_to {
802
+ self.debug_writing_mode.check(mode_from);
803
+ *self
804
+ } else {
805
+ LogicalPoint::from_physical(
806
+ mode_to,
807
+ self.to_physical(mode_from, container_size),
808
+ container_size,
809
+ )
810
+ }
811
+ }
812
+ }
813
+
814
+ impl<T: Copy + Add<T, Output = T>> LogicalPoint<T> {
815
+ /// This doesn’t really makes sense,
816
+ /// but happens when dealing with multiple origins.
817
+ #[inline]
818
+ pub fn add_point(&self, other: &LogicalPoint<T>) -> LogicalPoint<T> {
819
+ self.debug_writing_mode
820
+ .check_debug(other.debug_writing_mode);
821
+ LogicalPoint {
822
+ debug_writing_mode: self.debug_writing_mode,
823
+ i: self.i + other.i,
824
+ b: self.b + other.b,
825
+ }
826
+ }
827
+ }
828
+
829
+ impl<T: Copy + Add<T, Output = T>> Add<LogicalSize<T>> for LogicalPoint<T> {
830
+ type Output = LogicalPoint<T>;
831
+
832
+ #[inline]
833
+ fn add(self, other: LogicalSize<T>) -> LogicalPoint<T> {
834
+ self.debug_writing_mode
835
+ .check_debug(other.debug_writing_mode);
836
+ LogicalPoint {
837
+ debug_writing_mode: self.debug_writing_mode,
838
+ i: self.i + other.inline,
839
+ b: self.b + other.block,
840
+ }
841
+ }
842
+ }
843
+
844
+ impl<T: Copy + Sub<T, Output = T>> Sub<LogicalSize<T>> for LogicalPoint<T> {
845
+ type Output = LogicalPoint<T>;
846
+
847
+ #[inline]
848
+ fn sub(self, other: LogicalSize<T>) -> LogicalPoint<T> {
849
+ self.debug_writing_mode
850
+ .check_debug(other.debug_writing_mode);
851
+ LogicalPoint {
852
+ debug_writing_mode: self.debug_writing_mode,
853
+ i: self.i - other.inline,
854
+ b: self.b - other.block,
855
+ }
856
+ }
857
+ }
858
+
859
+ /// A "margin" in flow-relative dimensions
860
+ /// Represents the four sides of the margins, borders, or padding of a CSS box,
861
+ /// or a combination of those.
862
+ /// A positive "margin" can be added to a rectangle to obtain a bigger rectangle.
863
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
864
+ pub struct LogicalMargin<T> {
865
+ pub block_start: T,
866
+ pub inline_end: T,
867
+ pub block_end: T,
868
+ pub inline_start: T,
869
+ debug_writing_mode: DebugWritingMode,
870
+ }
871
+
872
+ impl<T: Debug> Debug for LogicalMargin<T> {
873
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
874
+ let writing_mode_string = if cfg!(debug_assertions) {
875
+ format!("{:?}, ", self.debug_writing_mode)
876
+ } else {
877
+ "".to_owned()
878
+ };
879
+
880
+ write!(
881
+ formatter,
882
+ "LogicalMargin({}i:{:?}..{:?} b:{:?}..{:?})",
883
+ writing_mode_string,
884
+ self.inline_start,
885
+ self.inline_end,
886
+ self.block_start,
887
+ self.block_end
888
+ )
889
+ }
890
+ }
891
+
892
+ impl<T: Zero> LogicalMargin<T> {
893
+ #[inline]
894
+ pub fn zero(mode: WritingMode) -> LogicalMargin<T> {
895
+ LogicalMargin {
896
+ block_start: Zero::zero(),
897
+ inline_end: Zero::zero(),
898
+ block_end: Zero::zero(),
899
+ inline_start: Zero::zero(),
900
+ debug_writing_mode: DebugWritingMode::new(mode),
901
+ }
902
+ }
903
+ }
904
+
905
+ impl<T> LogicalMargin<T> {
906
+ #[inline]
907
+ pub fn new(
908
+ mode: WritingMode,
909
+ block_start: T,
910
+ inline_end: T,
911
+ block_end: T,
912
+ inline_start: T,
913
+ ) -> LogicalMargin<T> {
914
+ LogicalMargin {
915
+ block_start,
916
+ inline_end,
917
+ block_end,
918
+ inline_start,
919
+ debug_writing_mode: DebugWritingMode::new(mode),
920
+ }
921
+ }
922
+
923
+ #[inline]
924
+ pub fn from_physical(mode: WritingMode, offsets: SideOffsets2D<T>) -> LogicalMargin<T> {
925
+ let block_start;
926
+ let inline_end;
927
+ let block_end;
928
+ let inline_start;
929
+ if mode.is_vertical() {
930
+ if mode.is_vertical_lr() {
931
+ block_start = offsets.left;
932
+ block_end = offsets.right;
933
+ } else {
934
+ block_start = offsets.right;
935
+ block_end = offsets.left;
936
+ }
937
+ if mode.is_inline_tb() {
938
+ inline_start = offsets.top;
939
+ inline_end = offsets.bottom;
940
+ } else {
941
+ inline_start = offsets.bottom;
942
+ inline_end = offsets.top;
943
+ }
944
+ } else {
945
+ block_start = offsets.top;
946
+ block_end = offsets.bottom;
947
+ if mode.is_bidi_ltr() {
948
+ inline_start = offsets.left;
949
+ inline_end = offsets.right;
950
+ } else {
951
+ inline_start = offsets.right;
952
+ inline_end = offsets.left;
953
+ }
954
+ }
955
+ LogicalMargin::new(mode, block_start, inline_end, block_end, inline_start)
956
+ }
957
+ }
958
+
959
+ impl<T: Clone> LogicalMargin<T> {
960
+ #[inline]
961
+ pub fn new_all_same(mode: WritingMode, value: T) -> LogicalMargin<T> {
962
+ LogicalMargin::new(mode, value.clone(), value.clone(), value.clone(), value)
963
+ }
964
+
965
+ #[inline]
966
+ pub fn top(&self, mode: WritingMode) -> T {
967
+ self.debug_writing_mode.check(mode);
968
+ if mode.is_vertical() {
969
+ if mode.is_inline_tb() {
970
+ self.inline_start.clone()
971
+ } else {
972
+ self.inline_end.clone()
973
+ }
974
+ } else {
975
+ self.block_start.clone()
976
+ }
977
+ }
978
+
979
+ #[inline]
980
+ pub fn set_top(&mut self, mode: WritingMode, top: T) {
981
+ self.debug_writing_mode.check(mode);
982
+ if mode.is_vertical() {
983
+ if mode.is_inline_tb() {
984
+ self.inline_start = top
985
+ } else {
986
+ self.inline_end = top
987
+ }
988
+ } else {
989
+ self.block_start = top
990
+ }
991
+ }
992
+
993
+ #[inline]
994
+ pub fn right(&self, mode: WritingMode) -> T {
995
+ self.debug_writing_mode.check(mode);
996
+ if mode.is_vertical() {
997
+ if mode.is_vertical_lr() {
998
+ self.block_end.clone()
999
+ } else {
1000
+ self.block_start.clone()
1001
+ }
1002
+ } else if mode.is_bidi_ltr() {
1003
+ self.inline_end.clone()
1004
+ } else {
1005
+ self.inline_start.clone()
1006
+ }
1007
+ }
1008
+
1009
+ #[inline]
1010
+ pub fn set_right(&mut self, mode: WritingMode, right: T) {
1011
+ self.debug_writing_mode.check(mode);
1012
+ if mode.is_vertical() {
1013
+ if mode.is_vertical_lr() {
1014
+ self.block_end = right
1015
+ } else {
1016
+ self.block_start = right
1017
+ }
1018
+ } else if mode.is_bidi_ltr() {
1019
+ self.inline_end = right
1020
+ } else {
1021
+ self.inline_start = right
1022
+ }
1023
+ }
1024
+
1025
+ #[inline]
1026
+ pub fn bottom(&self, mode: WritingMode) -> T {
1027
+ self.debug_writing_mode.check(mode);
1028
+ if mode.is_vertical() {
1029
+ if mode.is_inline_tb() {
1030
+ self.inline_end.clone()
1031
+ } else {
1032
+ self.inline_start.clone()
1033
+ }
1034
+ } else {
1035
+ self.block_end.clone()
1036
+ }
1037
+ }
1038
+
1039
+ #[inline]
1040
+ pub fn set_bottom(&mut self, mode: WritingMode, bottom: T) {
1041
+ self.debug_writing_mode.check(mode);
1042
+ if mode.is_vertical() {
1043
+ if mode.is_inline_tb() {
1044
+ self.inline_end = bottom
1045
+ } else {
1046
+ self.inline_start = bottom
1047
+ }
1048
+ } else {
1049
+ self.block_end = bottom
1050
+ }
1051
+ }
1052
+
1053
+ #[inline]
1054
+ pub fn left(&self, mode: WritingMode) -> T {
1055
+ self.debug_writing_mode.check(mode);
1056
+ if mode.is_vertical() {
1057
+ if mode.is_vertical_lr() {
1058
+ self.block_start.clone()
1059
+ } else {
1060
+ self.block_end.clone()
1061
+ }
1062
+ } else if mode.is_bidi_ltr() {
1063
+ self.inline_start.clone()
1064
+ } else {
1065
+ self.inline_end.clone()
1066
+ }
1067
+ }
1068
+
1069
+ #[inline]
1070
+ pub fn set_left(&mut self, mode: WritingMode, left: T) {
1071
+ self.debug_writing_mode.check(mode);
1072
+ if mode.is_vertical() {
1073
+ if mode.is_vertical_lr() {
1074
+ self.block_start = left
1075
+ } else {
1076
+ self.block_end = left
1077
+ }
1078
+ } else if mode.is_bidi_ltr() {
1079
+ self.inline_start = left
1080
+ } else {
1081
+ self.inline_end = left
1082
+ }
1083
+ }
1084
+
1085
+ #[inline]
1086
+ pub fn to_physical(&self, mode: WritingMode) -> SideOffsets2D<T> {
1087
+ self.debug_writing_mode.check(mode);
1088
+ let top;
1089
+ let right;
1090
+ let bottom;
1091
+ let left;
1092
+ if mode.is_vertical() {
1093
+ if mode.is_vertical_lr() {
1094
+ left = self.block_start.clone();
1095
+ right = self.block_end.clone();
1096
+ } else {
1097
+ right = self.block_start.clone();
1098
+ left = self.block_end.clone();
1099
+ }
1100
+ if mode.is_inline_tb() {
1101
+ top = self.inline_start.clone();
1102
+ bottom = self.inline_end.clone();
1103
+ } else {
1104
+ bottom = self.inline_start.clone();
1105
+ top = self.inline_end.clone();
1106
+ }
1107
+ } else {
1108
+ top = self.block_start.clone();
1109
+ bottom = self.block_end.clone();
1110
+ if mode.is_bidi_ltr() {
1111
+ left = self.inline_start.clone();
1112
+ right = self.inline_end.clone();
1113
+ } else {
1114
+ right = self.inline_start.clone();
1115
+ left = self.inline_end.clone();
1116
+ }
1117
+ }
1118
+ SideOffsets2D::new(top, right, bottom, left)
1119
+ }
1120
+
1121
+ #[inline]
1122
+ pub fn convert(&self, mode_from: WritingMode, mode_to: WritingMode) -> LogicalMargin<T> {
1123
+ if mode_from == mode_to {
1124
+ self.debug_writing_mode.check(mode_from);
1125
+ self.clone()
1126
+ } else {
1127
+ LogicalMargin::from_physical(mode_to, self.to_physical(mode_from))
1128
+ }
1129
+ }
1130
+ }
1131
+
1132
+ impl<T: PartialEq + Zero> LogicalMargin<T> {
1133
+ #[inline]
1134
+ pub fn is_zero(&self) -> bool {
1135
+ self.block_start == Zero::zero()
1136
+ && self.inline_end == Zero::zero()
1137
+ && self.block_end == Zero::zero()
1138
+ && self.inline_start == Zero::zero()
1139
+ }
1140
+ }
1141
+
1142
+ impl<T: Copy + Add<T, Output = T>> LogicalMargin<T> {
1143
+ #[inline]
1144
+ pub fn inline_start_end(&self) -> T {
1145
+ self.inline_start + self.inline_end
1146
+ }
1147
+
1148
+ #[inline]
1149
+ pub fn block_start_end(&self) -> T {
1150
+ self.block_start + self.block_end
1151
+ }
1152
+
1153
+ #[inline]
1154
+ pub fn start_end(&self, direction: Direction) -> T {
1155
+ match direction {
1156
+ Direction::Inline => self.inline_start + self.inline_end,
1157
+ Direction::Block => self.block_start + self.block_end,
1158
+ }
1159
+ }
1160
+
1161
+ #[inline]
1162
+ pub fn top_bottom(&self, mode: WritingMode) -> T {
1163
+ self.debug_writing_mode.check(mode);
1164
+ if mode.is_vertical() {
1165
+ self.inline_start_end()
1166
+ } else {
1167
+ self.block_start_end()
1168
+ }
1169
+ }
1170
+
1171
+ #[inline]
1172
+ pub fn left_right(&self, mode: WritingMode) -> T {
1173
+ self.debug_writing_mode.check(mode);
1174
+ if mode.is_vertical() {
1175
+ self.block_start_end()
1176
+ } else {
1177
+ self.inline_start_end()
1178
+ }
1179
+ }
1180
+ }
1181
+
1182
+ impl<T: Add<T, Output = T>> Add for LogicalMargin<T> {
1183
+ type Output = LogicalMargin<T>;
1184
+
1185
+ #[inline]
1186
+ fn add(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
1187
+ self.debug_writing_mode
1188
+ .check_debug(other.debug_writing_mode);
1189
+ LogicalMargin {
1190
+ debug_writing_mode: self.debug_writing_mode,
1191
+ block_start: self.block_start + other.block_start,
1192
+ inline_end: self.inline_end + other.inline_end,
1193
+ block_end: self.block_end + other.block_end,
1194
+ inline_start: self.inline_start + other.inline_start,
1195
+ }
1196
+ }
1197
+ }
1198
+
1199
+ impl<T: Sub<T, Output = T>> Sub for LogicalMargin<T> {
1200
+ type Output = LogicalMargin<T>;
1201
+
1202
+ #[inline]
1203
+ fn sub(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
1204
+ self.debug_writing_mode
1205
+ .check_debug(other.debug_writing_mode);
1206
+ LogicalMargin {
1207
+ debug_writing_mode: self.debug_writing_mode,
1208
+ block_start: self.block_start - other.block_start,
1209
+ inline_end: self.inline_end - other.inline_end,
1210
+ block_end: self.block_end - other.block_end,
1211
+ inline_start: self.inline_start - other.inline_start,
1212
+ }
1213
+ }
1214
+ }
1215
+
1216
+ /// A rectangle in flow-relative dimensions
1217
+ #[derive(Clone, Copy, Eq, PartialEq, Serialize)]
1218
+ pub struct LogicalRect<T> {
1219
+ pub start: LogicalPoint<T>,
1220
+ pub size: LogicalSize<T>,
1221
+ debug_writing_mode: DebugWritingMode,
1222
+ }
1223
+
1224
+ impl<T: Debug> Debug for LogicalRect<T> {
1225
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
1226
+ let writing_mode_string = if cfg!(debug_assertions) {
1227
+ format!("{:?}, ", self.debug_writing_mode)
1228
+ } else {
1229
+ "".to_owned()
1230
+ };
1231
+
1232
+ write!(
1233
+ formatter,
1234
+ "LogicalRect({}i{:?}×b{:?}, @ (i{:?},b{:?}))",
1235
+ writing_mode_string, self.size.inline, self.size.block, self.start.i, self.start.b
1236
+ )
1237
+ }
1238
+ }
1239
+
1240
+ impl<T: Zero> LogicalRect<T> {
1241
+ #[inline]
1242
+ pub fn zero(mode: WritingMode) -> LogicalRect<T> {
1243
+ LogicalRect {
1244
+ start: LogicalPoint::zero(mode),
1245
+ size: LogicalSize::zero(mode),
1246
+ debug_writing_mode: DebugWritingMode::new(mode),
1247
+ }
1248
+ }
1249
+ }
1250
+
1251
+ impl<T: Copy> LogicalRect<T> {
1252
+ #[inline]
1253
+ pub fn new(
1254
+ mode: WritingMode,
1255
+ inline_start: T,
1256
+ block_start: T,
1257
+ inline: T,
1258
+ block: T,
1259
+ ) -> LogicalRect<T> {
1260
+ LogicalRect {
1261
+ start: LogicalPoint::new(mode, inline_start, block_start),
1262
+ size: LogicalSize::new(mode, inline, block),
1263
+ debug_writing_mode: DebugWritingMode::new(mode),
1264
+ }
1265
+ }
1266
+
1267
+ #[inline]
1268
+ pub fn from_point_size(
1269
+ mode: WritingMode,
1270
+ start: LogicalPoint<T>,
1271
+ size: LogicalSize<T>,
1272
+ ) -> LogicalRect<T> {
1273
+ start.debug_writing_mode.check(mode);
1274
+ size.debug_writing_mode.check(mode);
1275
+ LogicalRect {
1276
+ start,
1277
+ size,
1278
+ debug_writing_mode: DebugWritingMode::new(mode),
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ impl<T: Copy + Add<T, Output = T> + Sub<T, Output = T>> LogicalRect<T> {
1284
+ #[inline]
1285
+ pub fn from_physical(
1286
+ mode: WritingMode,
1287
+ rect: Rect<T>,
1288
+ container_size: Size2D<T>,
1289
+ ) -> LogicalRect<T> {
1290
+ let inline_start;
1291
+ let block_start;
1292
+ let inline;
1293
+ let block;
1294
+ if mode.is_vertical() {
1295
+ inline = rect.size.height;
1296
+ block = rect.size.width;
1297
+ if mode.is_vertical_lr() {
1298
+ block_start = rect.origin.x;
1299
+ } else {
1300
+ block_start = container_size.width - (rect.origin.x + rect.size.width);
1301
+ }
1302
+ if mode.is_inline_tb() {
1303
+ inline_start = rect.origin.y;
1304
+ } else {
1305
+ inline_start = container_size.height - (rect.origin.y + rect.size.height);
1306
+ }
1307
+ } else {
1308
+ inline = rect.size.width;
1309
+ block = rect.size.height;
1310
+ block_start = rect.origin.y;
1311
+ if mode.is_bidi_ltr() {
1312
+ inline_start = rect.origin.x;
1313
+ } else {
1314
+ inline_start = container_size.width - (rect.origin.x + rect.size.width);
1315
+ }
1316
+ }
1317
+ LogicalRect {
1318
+ start: LogicalPoint::new(mode, inline_start, block_start),
1319
+ size: LogicalSize::new(mode, inline, block),
1320
+ debug_writing_mode: DebugWritingMode::new(mode),
1321
+ }
1322
+ }
1323
+
1324
+ #[inline]
1325
+ pub fn inline_end(&self) -> T {
1326
+ self.start.i + self.size.inline
1327
+ }
1328
+
1329
+ #[inline]
1330
+ pub fn block_end(&self) -> T {
1331
+ self.start.b + self.size.block
1332
+ }
1333
+
1334
+ #[inline]
1335
+ pub fn to_physical(&self, mode: WritingMode, container_size: Size2D<T>) -> Rect<T> {
1336
+ self.debug_writing_mode.check(mode);
1337
+ let x;
1338
+ let y;
1339
+ let width;
1340
+ let height;
1341
+ if mode.is_vertical() {
1342
+ width = self.size.block;
1343
+ height = self.size.inline;
1344
+ if mode.is_vertical_lr() {
1345
+ x = self.start.b;
1346
+ } else {
1347
+ x = container_size.width - self.block_end();
1348
+ }
1349
+ if mode.is_inline_tb() {
1350
+ y = self.start.i;
1351
+ } else {
1352
+ y = container_size.height - self.inline_end();
1353
+ }
1354
+ } else {
1355
+ width = self.size.inline;
1356
+ height = self.size.block;
1357
+ y = self.start.b;
1358
+ if mode.is_bidi_ltr() {
1359
+ x = self.start.i;
1360
+ } else {
1361
+ x = container_size.width - self.inline_end();
1362
+ }
1363
+ }
1364
+ Rect {
1365
+ origin: Point2D::new(x, y),
1366
+ size: Size2D::new(width, height),
1367
+ }
1368
+ }
1369
+
1370
+ #[inline]
1371
+ pub fn convert(
1372
+ &self,
1373
+ mode_from: WritingMode,
1374
+ mode_to: WritingMode,
1375
+ container_size: Size2D<T>,
1376
+ ) -> LogicalRect<T> {
1377
+ if mode_from == mode_to {
1378
+ self.debug_writing_mode.check(mode_from);
1379
+ *self
1380
+ } else {
1381
+ LogicalRect::from_physical(
1382
+ mode_to,
1383
+ self.to_physical(mode_from, container_size),
1384
+ container_size,
1385
+ )
1386
+ }
1387
+ }
1388
+
1389
+ pub fn translate_by_size(&self, offset: LogicalSize<T>) -> LogicalRect<T> {
1390
+ LogicalRect {
1391
+ start: self.start + offset,
1392
+ ..*self
1393
+ }
1394
+ }
1395
+
1396
+ pub fn translate(&self, offset: &LogicalPoint<T>) -> LogicalRect<T> {
1397
+ LogicalRect {
1398
+ start: self.start
1399
+ + LogicalSize {
1400
+ inline: offset.i,
1401
+ block: offset.b,
1402
+ debug_writing_mode: offset.debug_writing_mode,
1403
+ },
1404
+ size: self.size,
1405
+ debug_writing_mode: self.debug_writing_mode,
1406
+ }
1407
+ }
1408
+ }
1409
+
1410
+ impl<T: Copy + Ord + Add<T, Output = T> + Sub<T, Output = T>> LogicalRect<T> {
1411
+ #[inline]
1412
+ pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> {
1413
+ self.debug_writing_mode
1414
+ .check_debug(other.debug_writing_mode);
1415
+
1416
+ let inline_start = min(self.start.i, other.start.i);
1417
+ let block_start = min(self.start.b, other.start.b);
1418
+ LogicalRect {
1419
+ start: LogicalPoint {
1420
+ i: inline_start,
1421
+ b: block_start,
1422
+ debug_writing_mode: self.debug_writing_mode,
1423
+ },
1424
+ size: LogicalSize {
1425
+ inline: max(self.inline_end(), other.inline_end()) - inline_start,
1426
+ block: max(self.block_end(), other.block_end()) - block_start,
1427
+ debug_writing_mode: self.debug_writing_mode,
1428
+ },
1429
+ debug_writing_mode: self.debug_writing_mode,
1430
+ }
1431
+ }
1432
+ }
1433
+
1434
+ impl<T: Copy + Add<T, Output = T> + Sub<T, Output = T>> Add<LogicalMargin<T>> for LogicalRect<T> {
1435
+ type Output = LogicalRect<T>;
1436
+
1437
+ #[inline]
1438
+ fn add(self, other: LogicalMargin<T>) -> LogicalRect<T> {
1439
+ self.debug_writing_mode
1440
+ .check_debug(other.debug_writing_mode);
1441
+ LogicalRect {
1442
+ start: LogicalPoint {
1443
+ // Growing a rectangle on the start side means pushing its
1444
+ // start point on the negative direction.
1445
+ i: self.start.i - other.inline_start,
1446
+ b: self.start.b - other.block_start,
1447
+ debug_writing_mode: self.debug_writing_mode,
1448
+ },
1449
+ size: LogicalSize {
1450
+ inline: self.size.inline + other.inline_start_end(),
1451
+ block: self.size.block + other.block_start_end(),
1452
+ debug_writing_mode: self.debug_writing_mode,
1453
+ },
1454
+ debug_writing_mode: self.debug_writing_mode,
1455
+ }
1456
+ }
1457
+ }
1458
+
1459
+ impl<T: Copy + Add<T, Output = T> + Sub<T, Output = T>> Sub<LogicalMargin<T>> for LogicalRect<T> {
1460
+ type Output = LogicalRect<T>;
1461
+
1462
+ #[inline]
1463
+ fn sub(self, other: LogicalMargin<T>) -> LogicalRect<T> {
1464
+ self.debug_writing_mode
1465
+ .check_debug(other.debug_writing_mode);
1466
+ LogicalRect {
1467
+ start: LogicalPoint {
1468
+ // Shrinking a rectangle on the start side means pushing its
1469
+ // start point on the positive direction.
1470
+ i: self.start.i + other.inline_start,
1471
+ b: self.start.b + other.block_start,
1472
+ debug_writing_mode: self.debug_writing_mode,
1473
+ },
1474
+ size: LogicalSize {
1475
+ inline: self.size.inline - other.inline_start_end(),
1476
+ block: self.size.block - other.block_start_end(),
1477
+ debug_writing_mode: self.debug_writing_mode,
1478
+ },
1479
+ debug_writing_mode: self.debug_writing_mode,
1480
+ }
1481
+ }
1482
+ }
1483
+
1484
+ #[derive(Clone, Copy, Debug, PartialEq)]
1485
+ #[repr(u8)]
1486
+ pub enum LogicalAxis {
1487
+ Block = 0,
1488
+ Inline,
1489
+ }
1490
+
1491
+ impl LogicalAxis {
1492
+ #[inline]
1493
+ pub fn to_physical(self, wm: WritingMode) -> PhysicalAxis {
1494
+ if wm.is_horizontal() == (self == Self::Inline) {
1495
+ PhysicalAxis::Horizontal
1496
+ } else {
1497
+ PhysicalAxis::Vertical
1498
+ }
1499
+ }
1500
+ }
1501
+
1502
+ #[derive(Clone, Copy, Debug, PartialEq)]
1503
+ #[repr(u8)]
1504
+ pub enum LogicalSide {
1505
+ BlockStart = 0,
1506
+ BlockEnd,
1507
+ InlineStart,
1508
+ InlineEnd,
1509
+ }
1510
+
1511
+ impl LogicalSide {
1512
+ fn is_block(self) -> bool {
1513
+ matches!(self, Self::BlockStart | Self::BlockEnd)
1514
+ }
1515
+
1516
+ #[inline]
1517
+ pub fn to_physical(self, wm: WritingMode) -> PhysicalSide {
1518
+ // Block mapping depends only on vertical+vertical-lr
1519
+ static BLOCK_MAPPING: [[PhysicalSide; 2]; 4] = [
1520
+ [PhysicalSide::Top, PhysicalSide::Bottom], // horizontal-tb
1521
+ [PhysicalSide::Right, PhysicalSide::Left], // vertical-rl
1522
+ [PhysicalSide::Bottom, PhysicalSide::Top], // (horizontal-bt)
1523
+ [PhysicalSide::Left, PhysicalSide::Right], // vertical-lr
1524
+ ];
1525
+
1526
+ if self.is_block() {
1527
+ let vertical = wm.is_vertical();
1528
+ let lr = wm.is_vertical_lr();
1529
+ let index = (vertical as usize) | ((lr as usize) << 1);
1530
+ return BLOCK_MAPPING[index][self as usize];
1531
+ }
1532
+
1533
+ // start = 0, end = 1
1534
+ let edge = self as usize - 2;
1535
+ // Inline axis sides depend on all three of writing-mode, text-orientation and direction,
1536
+ // which are encoded in the VERTICAL, INLINE_REVERSED, VERTICAL_LR and LINE_INVERTED bits.
1537
+ //
1538
+ // bit 0 = the VERTICAL value
1539
+ // bit 1 = the INLINE_REVERSED value
1540
+ // bit 2 = the VERTICAL_LR value
1541
+ // bit 3 = the LINE_INVERTED value
1542
+ //
1543
+ // Note that not all of these combinations can actually be specified via CSS: there is no
1544
+ // horizontal-bt writing-mode, and no text-orientation value that produces "inverted"
1545
+ // text. (The former 'sideways-left' value, no longer in the spec, would have produced
1546
+ // this in vertical-rl mode.)
1547
+ static INLINE_MAPPING: [[PhysicalSide; 2]; 16] = [
1548
+ [PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb ltr
1549
+ [PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl ltr
1550
+ [PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb rtl
1551
+ [PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl rtl
1552
+ [PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) (inverted) ltr
1553
+ [PhysicalSide::Top, PhysicalSide::Bottom], // sideways-lr rtl
1554
+ [PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) (inverted) rtl
1555
+ [PhysicalSide::Bottom, PhysicalSide::Top], // sideways-lr ltr
1556
+ [PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb (inverted) rtl
1557
+ [PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl (inverted) rtl
1558
+ [PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb (inverted) ltr
1559
+ [PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl (inverted) ltr
1560
+ [PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) ltr
1561
+ [PhysicalSide::Top, PhysicalSide::Bottom], // vertical-lr ltr
1562
+ [PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) rtl
1563
+ [PhysicalSide::Bottom, PhysicalSide::Top], // vertical-lr rtl
1564
+ ];
1565
+
1566
+ debug_assert!(
1567
+ WritingMode::VERTICAL.bits() == 0x01
1568
+ && WritingMode::INLINE_REVERSED.bits() == 0x02
1569
+ && WritingMode::VERTICAL_LR.bits() == 0x04
1570
+ && WritingMode::LINE_INVERTED.bits() == 0x08
1571
+ );
1572
+ let index = (wm.bits() & 0xF) as usize;
1573
+ INLINE_MAPPING[index][edge]
1574
+ }
1575
+ }
1576
+
1577
+ #[derive(Clone, Copy, Debug, PartialEq)]
1578
+ #[repr(u8)]
1579
+ pub enum LogicalCorner {
1580
+ StartStart = 0,
1581
+ StartEnd,
1582
+ EndStart,
1583
+ EndEnd,
1584
+ }
1585
+
1586
+ impl LogicalCorner {
1587
+ #[inline]
1588
+ pub fn to_physical(self, wm: WritingMode) -> PhysicalCorner {
1589
+ static CORNER_TO_SIDES: [[LogicalSide; 2]; 4] = [
1590
+ [LogicalSide::BlockStart, LogicalSide::InlineStart],
1591
+ [LogicalSide::BlockStart, LogicalSide::InlineEnd],
1592
+ [LogicalSide::BlockEnd, LogicalSide::InlineStart],
1593
+ [LogicalSide::BlockEnd, LogicalSide::InlineEnd],
1594
+ ];
1595
+
1596
+ let [block, inline] = CORNER_TO_SIDES[self as usize];
1597
+ let block = block.to_physical(wm);
1598
+ let inline = inline.to_physical(wm);
1599
+ PhysicalCorner::from_sides(block, inline)
1600
+ }
1601
+ }
1602
+
1603
+ #[derive(Clone, Copy, Debug, PartialEq)]
1604
+ #[repr(u8)]
1605
+ pub enum PhysicalAxis {
1606
+ Vertical = 0,
1607
+ Horizontal,
1608
+ }
1609
+
1610
+ #[derive(Clone, Copy, Debug, PartialEq)]
1611
+ #[repr(u8)]
1612
+ pub enum PhysicalSide {
1613
+ Top = 0,
1614
+ Right,
1615
+ Bottom,
1616
+ Left,
1617
+ }
1618
+
1619
+ impl PhysicalSide {
1620
+ /// Returns whether one physical side is parallel to another.
1621
+ pub fn parallel_to(self, other: Self) -> bool {
1622
+ !self.orthogonal_to(other)
1623
+ }
1624
+
1625
+ /// Returns whether one physical side is orthogonal to another.
1626
+ pub fn orthogonal_to(self, other: Self) -> bool {
1627
+ matches!(self, Self::Top | Self::Bottom) != matches!(other, Self::Top | Self::Bottom)
1628
+ }
1629
+
1630
+ /// Returns the opposite side.
1631
+ pub fn opposite_side(self) -> Self {
1632
+ match self {
1633
+ Self::Top => Self::Bottom,
1634
+ Self::Right => Self::Left,
1635
+ Self::Bottom => Self::Top,
1636
+ Self::Left => Self::Right,
1637
+ }
1638
+ }
1639
+ }
1640
+
1641
+ #[derive(Clone, Copy, Debug, PartialEq)]
1642
+ #[repr(u8)]
1643
+ pub enum PhysicalCorner {
1644
+ TopLeft = 0,
1645
+ TopRight,
1646
+ BottomRight,
1647
+ BottomLeft,
1648
+ }
1649
+
1650
+ impl PhysicalCorner {
1651
+ fn from_sides(a: PhysicalSide, b: PhysicalSide) -> Self {
1652
+ debug_assert!(a.orthogonal_to(b), "Sides should be orthogonal");
1653
+ // Only some of these are possible, since we expect only orthogonal values. If the two
1654
+ // sides were to be parallel, we fall back to returning TopLeft.
1655
+ const IMPOSSIBLE: PhysicalCorner = PhysicalCorner::TopLeft;
1656
+ static SIDES_TO_CORNER: [[PhysicalCorner; 4]; 4] = [
1657
+ [
1658
+ IMPOSSIBLE,
1659
+ PhysicalCorner::TopRight,
1660
+ IMPOSSIBLE,
1661
+ PhysicalCorner::TopLeft,
1662
+ ],
1663
+ [
1664
+ PhysicalCorner::TopRight,
1665
+ IMPOSSIBLE,
1666
+ PhysicalCorner::BottomRight,
1667
+ IMPOSSIBLE,
1668
+ ],
1669
+ [
1670
+ IMPOSSIBLE,
1671
+ PhysicalCorner::BottomRight,
1672
+ IMPOSSIBLE,
1673
+ PhysicalCorner::BottomLeft,
1674
+ ],
1675
+ [
1676
+ PhysicalCorner::TopLeft,
1677
+ IMPOSSIBLE,
1678
+ PhysicalCorner::BottomLeft,
1679
+ IMPOSSIBLE,
1680
+ ],
1681
+ ];
1682
+ SIDES_TO_CORNER[a as usize][b as usize]
1683
+ }
1684
+ }