Skip to main content

fop_core/properties/
initial_values.rs

1//! Initial (default) values for all XSL-FO properties
2//!
3//! This module provides initial values for all 295 properties as defined in the
4//! XSL-FO 1.1 specification (<http://www.w3.org/TR/xsl11/>).
5//!
6//! The initial value is used when:
7//! - Property is not explicitly set
8//! - Property is not inherited
9//! - No parent to inherit from
10
11#![allow(dead_code)] // Many enum constants are placeholders for future property support
12
13use crate::properties::{PropertyId, PropertyValue};
14use fop_types::{Color, Length};
15use std::borrow::Cow;
16
17// Enumeration constants (matching Apache FOP Constants.java)
18// These represent the values for enumerated properties
19
20// Common enum values
21const EN_AUTO: u16 = 9;
22const EN_NONE: u16 = 86;
23const EN_NORMAL: u16 = 87;
24const EN_VISIBLE: u16 = 136;
25const EN_HIDDEN: u16 = 57;
26const EN_COLLAPSE: u16 = 26;
27const EN_SEPARATE: u16 = 120;
28
29// Text alignment
30const EN_START: u16 = 126;
31const EN_CENTER: u16 = 23;
32const EN_END: u16 = 39;
33const EN_JUSTIFY: u16 = 70;
34const EN_LEFT: u16 = 72;
35const EN_RIGHT: u16 = 113;
36
37// Border styles
38const EN_SOLID: u16 = 123;
39const EN_DASHED: u16 = 31;
40const EN_DOTTED: u16 = 36;
41const EN_DOUBLE: u16 = 37;
42const EN_GROOVE: u16 = 55;
43const EN_RIDGE: u16 = 114;
44const EN_INSET: u16 = 67;
45const EN_OUTSET: u16 = 93;
46
47// Display/position
48const EN_BLOCK: u16 = 18;
49const EN_INLINE: u16 = 65;
50const EN_STATIC: u16 = 127;
51const EN_RELATIVE: u16 = 109;
52const EN_ABSOLUTE: u16 = 1;
53const EN_FIXED: u16 = 51;
54
55// Keep/break
56const EN_ALWAYS: u16 = 7;
57const EN_AVOID: u16 = 11;
58
59// Direction
60const EN_LTR: u16 = 75;
61const EN_RTL: u16 = 116;
62
63// Writing mode
64const EN_LR_TB: u16 = 74;
65const EN_RL_TB: u16 = 115;
66const EN_TB_RL: u16 = 131;
67
68// Font style
69const EN_ITALIC: u16 = 68;
70const EN_OBLIQUE: u16 = 90;
71
72// Font weight
73const EN_BOLD: u16 = 19;
74const EN_BOLDER: u16 = 20;
75const EN_LIGHTER: u16 = 73;
76const EN_100: u16 = 141;
77const EN_200: u16 = 142;
78const EN_300: u16 = 143;
79const EN_400: u16 = 144;
80const EN_500: u16 = 145;
81const EN_600: u16 = 146;
82const EN_700: u16 = 147;
83const EN_800: u16 = 148;
84const EN_900: u16 = 149;
85
86// Font variant
87const EN_SMALL_CAPS: u16 = 122;
88
89// Text decoration
90const EN_UNDERLINE: u16 = 134;
91const EN_OVERLINE: u16 = 94;
92const EN_LINE_THROUGH: u16 = 76;
93const EN_BLINK: u16 = 17;
94
95// Text transform
96const EN_CAPITALIZE: u16 = 22;
97const EN_UPPERCASE: u16 = 135;
98const EN_LOWERCASE: u16 = 77;
99
100// Overflow
101const EN_SCROLL: u16 = 119;
102const EN_ERROR_IF_OVERFLOW: u16 = 42;
103
104// Empty cells
105const EN_SHOW: u16 = 121;
106const EN_HIDE: u16 = 58;
107
108// Caption side
109const EN_BEFORE: u16 = 13;
110const EN_AFTER: u16 = 3;
111const EN_TOP: u16 = 133;
112const EN_BOTTOM: u16 = 20;
113
114// Table layout
115const EN_AUTO_LAYOUT: u16 = 9; // Same as EN_AUTO
116
117// Vertical align
118const EN_BASELINE: u16 = 12;
119const EN_MIDDLE: u16 = 81;
120const EN_SUB: u16 = 128;
121const EN_SUPER: u16 = 129;
122const EN_TEXT_TOP: u16 = 132;
123const EN_TEXT_BOTTOM: u16 = 130;
124
125// Display align
126const EN_DISTRIBUTE: u16 = 34;
127
128// Dominant baseline
129const EN_ALPHABETIC: u16 = 6;
130const EN_IDEOGRAPHIC: u16 = 59;
131const EN_HANGING: u16 = 56;
132const EN_MATHEMATICAL: u16 = 79;
133
134// White space
135const EN_PRE: u16 = 100;
136const EN_NOWRAP: u16 = 88;
137const EN_PRE_WRAP: u16 = 101;
138const EN_PRE_LINE: u16 = 99;
139
140// Wrap option
141const EN_WRAP: u16 = 139;
142const EN_NO_WRAP: u16 = 88;
143
144// Hyphenate
145const EN_TRUE: u16 = 134;
146const EN_FALSE: u16 = 48;
147
148// Span
149const EN_ALL: u16 = 5;
150
151// Clear
152const EN_BOTH: u16 = 19;
153
154// Float
155const EN_INSIDE: u16 = 68;
156const EN_OUTSIDE: u16 = 95;
157
158// Leader pattern
159const EN_SPACE: u16 = 124;
160const EN_RULE: u16 = 117;
161const EN_DOTS: u16 = 35;
162const EN_USE_CONTENT: u16 = 137;
163
164// Odd or even
165const EN_ODD: u16 = 89;
166const EN_EVEN: u16 = 43;
167const EN_ANY: u16 = 8;
168
169// Page position
170const EN_FIRST: u16 = 50;
171const EN_LAST: u16 = 71;
172const EN_REST: u16 = 112;
173
174// Blank or not blank
175const EN_BLANK: u16 = 16;
176const EN_NOT_BLANK: u16 = 85;
177
178// Column count
179const EN_COLUMN: u16 = 28;
180
181// Page break
182const EN_PAGE: u16 = 96;
183
184// Force page count
185const EN_NO_FORCE: u16 = 84;
186const EN_EVEN_PAGE: u16 = 44;
187const EN_ODD_PAGE: u16 = 91;
188
189// Precedence
190const EN_FORCE: u16 = 53;
191
192// Unicode bidi
193const EN_EMBED: u16 = 38;
194const EN_BIDI_OVERRIDE: u16 = 15;
195
196// Treat as word space
197const EN_IGNORE_IF_BEFORE_LINEFEED: u16 = 62;
198const EN_IGNORE_IF_AFTER_LINEFEED: u16 = 61;
199const EN_IGNORE_IF_SURROUNDING_LINEFEED: u16 = 63;
200const EN_PRESERVE: u16 = 102;
201const EN_IGNORE: u16 = 60;
202
203// Line stacking strategy
204const EN_LINE_HEIGHT: u16 = 75;
205const EN_FONT_HEIGHT: u16 = 52;
206const EN_MAX_HEIGHT: u16 = 80;
207
208// Line height shift adjustment
209const EN_CONSIDER_SHIFTS: u16 = 30;
210const EN_DISREGARD_SHIFTS: u16 = 33;
211
212// Alignment adjust
213const EN_CENTRAL: u16 = 24;
214
215// Alignment baseline
216const EN_BEFORE_EDGE: u16 = 14;
217const EN_TEXT_BEFORE_EDGE: u16 = 130;
218const EN_AFTER_EDGE: u16 = 4;
219const EN_TEXT_AFTER_EDGE: u16 = 132;
220
221// Leader alignment
222const EN_REFERENCE_AREA: u16 = 108;
223
224// Scaling
225const EN_UNIFORM: u16 = 134;
226const EN_NON_UNIFORM: u16 = 86;
227
228// Rendering intent
229const EN_PERCEPTUAL: u16 = 98;
230const EN_RELATIVE_COLORIMETRIC: u16 = 110;
231const EN_SATURATION: u16 = 118;
232const EN_ABSOLUTE_COLORIMETRIC: u16 = 2;
233
234// Retrieve boundary
235const EN_PAGE_SEQUENCE: u16 = 97;
236const EN_DOCUMENT: u16 = 34;
237
238// Retrieve position
239const EN_FIRST_STARTING_WITHIN_PAGE: u16 = 54;
240const EN_FIRST_INCLUDING_CARRYOVER: u16 = 49;
241const EN_LAST_STARTING_WITHIN_PAGE: u16 = 71;
242const EN_LAST_ENDING_WITHIN_PAGE: u16 = 70;
243
244// Font selection strategy
245const EN_AUTO_SELECT: u16 = 10;
246const EN_CHARACTER_BY_CHARACTER: u16 = 25;
247
248// Media usage
249const EN_AUTO_MEDIA_USAGE: u16 = 9;
250const EN_PAGINATE: u16 = 97;
251const EN_BOUNDED_IN_ONE_DIMENSION: u16 = 21;
252const EN_UNBOUNDED: u16 = 134;
253
254// Intrusion displace
255const EN_NONE_DISPLACE: u16 = 86;
256
257// Active state
258const EN_LINK: u16 = 75;
259const EN_VISITED: u16 = 138;
260const EN_ACTIVE: u16 = 0;
261const EN_HOVER: u16 = 58;
262const EN_FOCUS: u16 = 53;
263
264// Auto restore
265const EN_NO_AUTO_RESTORE: u16 = 83;
266
267// Indicate destination
268const EN_INDICATE_DESTINATION_TRUE: u16 = 134;
269
270// Show destination
271const EN_REPLACE: u16 = 111;
272const EN_NEW: u16 = 82;
273
274// Destination placement offset
275// Uses length, default 0pt
276
277// Target presentation context
278const EN_USE_TARGET_PROCESSING_CONTEXT: u16 = 137;
279
280// Target processing context
281const EN_DOCUMENT_ROOT: u16 = 35;
282
283// Change bar placement
284const EN_ALTERNATE: u16 = 7;
285
286// Intrinsic scale value
287// Uses percentage, default 100%
288
289// Page citation strategy
290const EN_NORMAL_CITATION: u16 = 87;
291const EN_ALL_CITATION: u16 = 5;
292
293// Page number treatment
294const EN_LINK_COMBINE: u16 = 75;
295const EN_NO_LINK: u16 = 83;
296
297// Merge sequential page numbers
298const EN_MERGE: u16 = 80;
299const EN_LEAVE_SEPARATE: u16 = 72;
300
301// Get the initial value for any property
302///
303/// Returns the default value as specified in XSL-FO 1.1 specification.
304/// Reference: <http://www.w3.org/TR/xsl11/>
305pub fn get_initial_value(property_id: PropertyId) -> PropertyValue {
306    match property_id {
307        // ===== COMMON TEXT PROPERTIES =====
308
309        // color: black (inherited)
310        PropertyId::Color => PropertyValue::Color(Color::BLACK),
311
312        // font-family: serif (inherited)
313        PropertyId::FontFamily => PropertyValue::String(Cow::Borrowed("serif")),
314
315        // font-size: 12pt (inherited)
316        PropertyId::FontSize => PropertyValue::Length(Length::from_pt(12.0)),
317
318        // font-style: normal (inherited)
319        PropertyId::FontStyle => PropertyValue::Enum(EN_NORMAL),
320
321        // font-weight: normal (inherited)
322        PropertyId::FontWeight => PropertyValue::Enum(EN_NORMAL),
323
324        // font-variant: normal (inherited)
325        PropertyId::FontVariant => PropertyValue::Enum(EN_NORMAL),
326
327        // font-stretch: normal (inherited)
328        PropertyId::FontStretch => PropertyValue::Enum(EN_NORMAL),
329
330        // font-size-adjust: none (inherited)
331        PropertyId::FontSizeAdjust => PropertyValue::None,
332
333        // font-selection-strategy: auto (inherited)
334        PropertyId::FontSelectionStrategy => PropertyValue::Enum(EN_AUTO),
335
336        // font: shorthand, should not have initial value
337        PropertyId::Font => PropertyValue::Auto,
338
339        // ===== TEXT PROPERTIES =====
340
341        // text-align: start (inherited)
342        PropertyId::TextAlign => PropertyValue::Enum(EN_START),
343
344        // text-align-last: start (inherited)
345        PropertyId::TextAlignLast => PropertyValue::Enum(EN_START),
346
347        // text-indent: 0pt (inherited)
348        PropertyId::TextIndent => PropertyValue::Length(Length::ZERO),
349
350        // text-decoration: none (not inherited)
351        PropertyId::TextDecoration => PropertyValue::None,
352
353        // text-transform: none (inherited)
354        PropertyId::TextTransform => PropertyValue::Enum(EN_NONE),
355
356        // text-shadow: none (inherited)
357        PropertyId::TextShadow => PropertyValue::None,
358
359        // line-height: normal (inherited)
360        PropertyId::LineHeight => PropertyValue::Enum(EN_NORMAL),
361
362        // letter-spacing: normal (inherited)
363        PropertyId::LetterSpacing => PropertyValue::Enum(EN_NORMAL),
364
365        // word-spacing: normal (inherited)
366        PropertyId::WordSpacing => PropertyValue::Enum(EN_NORMAL),
367
368        // white-space: normal (inherited)
369        PropertyId::WhiteSpace => PropertyValue::Enum(EN_NORMAL),
370
371        // white-space-collapse: true (inherited)
372        PropertyId::WhiteSpaceCollapse => PropertyValue::Enum(EN_TRUE),
373
374        // white-space-treatment: ignore-if-surrounding-linefeed (inherited)
375        PropertyId::WhiteSpaceTreatment => PropertyValue::Enum(EN_IGNORE_IF_SURROUNDING_LINEFEED),
376
377        // linefeed-treatment: treat-as-space (inherited)
378        PropertyId::LinefeedTreatment => PropertyValue::Enum(EN_IGNORE),
379
380        // wrap-option: wrap (inherited)
381        PropertyId::WrapOption => PropertyValue::Enum(EN_WRAP),
382
383        // ===== MARGIN PROPERTIES (all 0pt) =====
384        PropertyId::MarginTop
385        | PropertyId::MarginRight
386        | PropertyId::MarginBottom
387        | PropertyId::MarginLeft => PropertyValue::Length(Length::ZERO),
388
389        // margin: shorthand
390        PropertyId::Margin => PropertyValue::Auto,
391
392        // ===== PADDING PROPERTIES (all 0pt) =====
393        PropertyId::PaddingTop
394        | PropertyId::PaddingRight
395        | PropertyId::PaddingBottom
396        | PropertyId::PaddingLeft
397        | PropertyId::PaddingBefore
398        | PropertyId::PaddingAfter
399        | PropertyId::PaddingStart
400        | PropertyId::PaddingEnd => PropertyValue::Length(Length::ZERO),
401
402        // padding: shorthand
403        PropertyId::Padding => PropertyValue::Auto,
404
405        // ===== BORDER WIDTH PROPERTIES =====
406        PropertyId::BorderTopWidth
407        | PropertyId::BorderRightWidth
408        | PropertyId::BorderBottomWidth
409        | PropertyId::BorderLeftWidth
410        | PropertyId::BorderBeforeWidth
411        | PropertyId::BorderAfterWidth
412        | PropertyId::BorderStartWidth
413        | PropertyId::BorderEndWidth => {
414            // medium = 1pt
415            PropertyValue::Length(Length::from_pt(1.0))
416        }
417
418        // border-width: shorthand
419        PropertyId::BorderWidth => PropertyValue::Auto,
420
421        // ===== BORDER STYLE PROPERTIES =====
422        PropertyId::BorderTopStyle
423        | PropertyId::BorderRightStyle
424        | PropertyId::BorderBottomStyle
425        | PropertyId::BorderLeftStyle
426        | PropertyId::BorderBeforeStyle
427        | PropertyId::BorderAfterStyle
428        | PropertyId::BorderStartStyle
429        | PropertyId::BorderEndStyle => PropertyValue::Enum(EN_NONE),
430
431        // border-style: shorthand
432        PropertyId::BorderStyle => PropertyValue::Auto,
433
434        // ===== BORDER COLOR PROPERTIES =====
435        PropertyId::BorderTopColor
436        | PropertyId::BorderRightColor
437        | PropertyId::BorderBottomColor
438        | PropertyId::BorderLeftColor
439        | PropertyId::BorderBeforeColor
440        | PropertyId::BorderAfterColor
441        | PropertyId::BorderStartColor
442        | PropertyId::BorderEndColor => {
443            // Initial value is the value of the 'color' property
444            PropertyValue::Color(Color::BLACK)
445        }
446
447        // border-color: shorthand
448        PropertyId::BorderColor => PropertyValue::Auto,
449
450        // Border shorthands
451        PropertyId::Border
452        | PropertyId::BorderTop
453        | PropertyId::BorderRight
454        | PropertyId::BorderBottom
455        | PropertyId::BorderLeft => PropertyValue::Auto,
456
457        // ===== BORDER PRECEDENCE =====
458        PropertyId::BorderBeforePrecedence
459        | PropertyId::BorderAfterPrecedence
460        | PropertyId::BorderStartPrecedence
461        | PropertyId::BorderEndPrecedence => PropertyValue::Enum(EN_NONE),
462
463        // ===== BORDER RADIUS (FOP extensions, all 0pt) =====
464        PropertyId::XBorderBeforeRadiusStart
465        | PropertyId::XBorderBeforeRadiusEnd
466        | PropertyId::XBorderAfterRadiusStart
467        | PropertyId::XBorderAfterRadiusEnd
468        | PropertyId::XBorderStartRadiusBefore
469        | PropertyId::XBorderStartRadiusAfter
470        | PropertyId::XBorderEndRadiusBefore
471        | PropertyId::XBorderEndRadiusAfter
472        | PropertyId::XBorderBeforeStartRadius
473        | PropertyId::XBorderBeforeEndRadius
474        | PropertyId::XBorderAfterStartRadius
475        | PropertyId::XBorderAfterEndRadius => PropertyValue::Length(Length::ZERO),
476
477        PropertyId::XBorderRadius => PropertyValue::Auto,
478
479        // ===== SPACE PROPERTIES =====
480        PropertyId::SpaceBefore
481        | PropertyId::SpaceAfter
482        | PropertyId::SpaceStart
483        | PropertyId::SpaceEnd => {
484            // Space properties are compound, default to 0pt
485            PropertyValue::Length(Length::ZERO)
486        }
487
488        // ===== INDENT PROPERTIES =====
489
490        // start-indent: 0pt (not inherited)
491        PropertyId::StartIndent => PropertyValue::Length(Length::ZERO),
492
493        // end-indent: 0pt (not inherited)
494        PropertyId::EndIndent => PropertyValue::Length(Length::ZERO),
495
496        // last-line-end-indent: 0pt (inherited)
497        PropertyId::LastLineEndIndent => PropertyValue::Length(Length::ZERO),
498
499        // ===== POSITION PROPERTIES =====
500
501        // position: static (not inherited)
502        PropertyId::Position => PropertyValue::Enum(EN_STATIC),
503
504        // absolute-position: auto (not inherited)
505        PropertyId::AbsolutePosition => PropertyValue::Enum(EN_AUTO),
506
507        // relative-position: static (not inherited)
508        PropertyId::RelativePosition => PropertyValue::Enum(EN_STATIC),
509
510        // top, right, bottom, left: auto (not inherited)
511        PropertyId::Top | PropertyId::Right | PropertyId::Bottom | PropertyId::Left => {
512            PropertyValue::Auto
513        }
514
515        // ===== DIMENSION PROPERTIES =====
516
517        // width: auto (not inherited)
518        PropertyId::Width => PropertyValue::Auto,
519
520        // height: auto (not inherited)
521        PropertyId::Height => PropertyValue::Auto,
522
523        // min-width: 0pt (not inherited)
524        PropertyId::MinWidth => PropertyValue::Length(Length::ZERO),
525
526        // min-height: 0pt (not inherited)
527        PropertyId::MinHeight => PropertyValue::Length(Length::ZERO),
528
529        // max-width: none (not inherited)
530        PropertyId::MaxWidth => PropertyValue::None,
531
532        // max-height: none (not inherited)
533        PropertyId::MaxHeight => PropertyValue::None,
534
535        // inline-progression-dimension: auto (not inherited)
536        PropertyId::InlineProgressionDimension => PropertyValue::Auto,
537
538        // block-progression-dimension: auto (not inherited)
539        PropertyId::BlockProgressionDimension => PropertyValue::Auto,
540
541        // content-width: auto (not inherited)
542        PropertyId::ContentWidth => PropertyValue::Auto,
543
544        // content-height: auto (not inherited)
545        PropertyId::ContentHeight => PropertyValue::Auto,
546
547        // ===== TABLE PROPERTIES =====
548
549        // table-layout: auto (not inherited)
550        PropertyId::TableLayout => PropertyValue::Enum(EN_AUTO),
551
552        // border-collapse: separate (inherited)
553        PropertyId::BorderCollapse => PropertyValue::Enum(EN_SEPARATE),
554
555        // border-spacing: 0pt (inherited)
556        PropertyId::BorderSpacing => PropertyValue::Length(Length::ZERO),
557
558        // border-separation: 0pt (not inherited)
559        PropertyId::BorderSeparation => PropertyValue::Length(Length::ZERO),
560
561        // caption-side: before (inherited)
562        PropertyId::CaptionSide => PropertyValue::Enum(EN_BEFORE),
563
564        // empty-cells: show (inherited)
565        PropertyId::EmptyCells => PropertyValue::Enum(EN_SHOW),
566
567        // table-omit-footer-at-break: false (not inherited)
568        PropertyId::TableOmitFooterAtBreak => PropertyValue::Enum(EN_FALSE),
569
570        // table-omit-header-at-break: false (not inherited)
571        PropertyId::TableOmitHeaderAtBreak => PropertyValue::Enum(EN_FALSE),
572
573        // column-width: auto (not inherited)
574        PropertyId::ColumnWidth => PropertyValue::Auto,
575
576        // column-number: auto (not inherited)
577        PropertyId::ColumnNumber => PropertyValue::Auto,
578
579        // column-count: 1 (not inherited)
580        PropertyId::ColumnCount => PropertyValue::Integer(1),
581
582        // column-gap: 12pt (not inherited)
583        PropertyId::ColumnGap => PropertyValue::Length(Length::from_pt(12.0)),
584
585        // number-columns-repeated: 1 (not inherited)
586        PropertyId::NumberColumnsRepeated => PropertyValue::Integer(1),
587
588        // number-columns-spanned: 1 (not inherited)
589        PropertyId::NumberColumnsSpanned => PropertyValue::Integer(1),
590
591        // number-rows-spanned: 1 (not inherited)
592        PropertyId::NumberRowsSpanned => PropertyValue::Integer(1),
593
594        // starts-row: false (not inherited)
595        PropertyId::StartsRow => PropertyValue::Enum(EN_FALSE),
596
597        // ends-row: false (not inherited)
598        PropertyId::EndsRow => PropertyValue::Enum(EN_FALSE),
599
600        // ===== PAGE PROPERTIES =====
601
602        // page-width: auto (not inherited)
603        PropertyId::PageWidth => PropertyValue::Auto,
604
605        // page-height: auto (not inherited)
606        PropertyId::PageHeight => PropertyValue::Auto,
607
608        // extent: 0pt (not inherited)
609        PropertyId::Extent => PropertyValue::Length(Length::ZERO),
610
611        // precedence: false (not inherited)
612        PropertyId::Precedence => PropertyValue::Enum(EN_FALSE),
613
614        // region-name: empty string (not inherited)
615        PropertyId::RegionName => PropertyValue::String(Cow::Borrowed("")),
616
617        // region-name-reference: empty string (not inherited)
618        PropertyId::RegionNameReference => PropertyValue::String(Cow::Borrowed("")),
619
620        // flow-name: empty string (not inherited)
621        PropertyId::FlowName => PropertyValue::String(Cow::Borrowed("")),
622
623        // flow-name-reference: empty string (not inherited)
624        PropertyId::FlowNameReference => PropertyValue::String(Cow::Borrowed("")),
625
626        // flow-map-name: empty string (not inherited)
627        PropertyId::FlowMapName => PropertyValue::String(Cow::Borrowed("")),
628
629        // flow-map-reference: empty string (not inherited)
630        PropertyId::FlowMapReference => PropertyValue::String(Cow::Borrowed("")),
631
632        // master-name: empty string (not inherited)
633        PropertyId::MasterName => PropertyValue::String(Cow::Borrowed("")),
634
635        // master-reference: empty string (not inherited)
636        PropertyId::MasterReference => PropertyValue::String(Cow::Borrowed("")),
637
638        // reference-orientation: 0 (inherited)
639        PropertyId::ReferenceOrientation => PropertyValue::Integer(0),
640
641        // writing-mode: lr-tb (inherited)
642        PropertyId::WritingMode => PropertyValue::Enum(EN_LR_TB),
643
644        // ===== KEEP AND BREAK PROPERTIES =====
645
646        // keep-together: auto (not inherited)
647        PropertyId::KeepTogether => PropertyValue::Enum(EN_AUTO),
648
649        // keep-with-next: auto (not inherited)
650        PropertyId::KeepWithNext => PropertyValue::Enum(EN_AUTO),
651
652        // keep-with-previous: auto (not inherited)
653        PropertyId::KeepWithPrevious => PropertyValue::Enum(EN_AUTO),
654
655        // break-before: auto (not inherited)
656        PropertyId::BreakBefore => PropertyValue::Enum(EN_AUTO),
657
658        // break-after: auto (not inherited)
659        PropertyId::BreakAfter => PropertyValue::Enum(EN_AUTO),
660
661        // page-break-before: auto (not inherited)
662        PropertyId::PageBreakBefore => PropertyValue::Enum(EN_AUTO),
663
664        // page-break-after: auto (not inherited)
665        PropertyId::PageBreakAfter => PropertyValue::Enum(EN_AUTO),
666
667        // page-break-inside: auto (not inherited)
668        PropertyId::PageBreakInside => PropertyValue::Enum(EN_AUTO),
669
670        // orphans: 2 (inherited)
671        PropertyId::Orphans => PropertyValue::Integer(2),
672
673        // widows: 2 (inherited)
674        PropertyId::Widows => PropertyValue::Integer(2),
675
676        // ===== BACKGROUND PROPERTIES =====
677
678        // background-color: transparent (not inherited)
679        PropertyId::BackgroundColor => PropertyValue::Color(Color::TRANSPARENT),
680
681        // background-image: none (not inherited)
682        PropertyId::BackgroundImage => PropertyValue::None,
683
684        // background-repeat: repeat (not inherited)
685        PropertyId::BackgroundRepeat => PropertyValue::Enum(EN_NORMAL),
686
687        // background-attachment: scroll (not inherited)
688        PropertyId::BackgroundAttachment => PropertyValue::Enum(EN_SCROLL),
689
690        // background-position: 0% 0% (not inherited)
691        PropertyId::BackgroundPosition => PropertyValue::Auto,
692
693        // background-position-horizontal: 0% (not inherited)
694        PropertyId::BackgroundPositionHorizontal => PropertyValue::Length(Length::ZERO),
695
696        // background-position-vertical: 0% (not inherited)
697        PropertyId::BackgroundPositionVertical => PropertyValue::Length(Length::ZERO),
698
699        // background: shorthand
700        PropertyId::Background => PropertyValue::Auto,
701
702        // ===== DISPLAY AND VISIBILITY =====
703
704        // visibility: visible (inherited)
705        PropertyId::Visibility => PropertyValue::Enum(EN_VISIBLE),
706
707        // overflow: visible (not inherited)
708        PropertyId::Overflow => PropertyValue::Enum(EN_VISIBLE),
709
710        // clip: auto (not inherited)
711        PropertyId::Clip => PropertyValue::Auto,
712
713        // display-align: auto (not inherited)
714        PropertyId::DisplayAlign => PropertyValue::Enum(EN_AUTO),
715
716        // ===== BASELINE PROPERTIES =====
717
718        // baseline-shift: baseline (not inherited)
719        PropertyId::BaselineShift => PropertyValue::Enum(EN_BASELINE),
720
721        // dominant-baseline: auto (not inherited)
722        PropertyId::DominantBaseline => PropertyValue::Enum(EN_AUTO),
723
724        // alignment-baseline: baseline (not inherited)
725        PropertyId::AlignmentBaseline => PropertyValue::Enum(EN_BASELINE),
726
727        // alignment-adjust: auto (not inherited)
728        PropertyId::AlignmentAdjust => PropertyValue::Enum(EN_AUTO),
729
730        // vertical-align: baseline (not inherited)
731        PropertyId::VerticalAlign => PropertyValue::Enum(EN_BASELINE),
732
733        // ===== LINE HEIGHT AND STACKING =====
734
735        // line-height-shift-adjustment: consider-shifts (inherited)
736        PropertyId::LineHeightShiftAdjustment => PropertyValue::Enum(EN_CONSIDER_SHIFTS),
737
738        // line-stacking-strategy: line-height (inherited)
739        PropertyId::LineStackingStrategy => PropertyValue::Enum(EN_LINE_HEIGHT),
740
741        // text-altitude: use-font-metrics (not inherited)
742        PropertyId::TextAltitude => PropertyValue::Enum(EN_AUTO),
743
744        // text-depth: use-font-metrics (not inherited)
745        PropertyId::TextDepth => PropertyValue::Enum(EN_AUTO),
746
747        // ===== DIRECTION AND UNICODE =====
748
749        // direction: ltr (inherited)
750        PropertyId::Direction => PropertyValue::Enum(EN_LTR),
751
752        // unicode-bidi: normal (not inherited)
753        PropertyId::UnicodeBidi => PropertyValue::Enum(EN_NORMAL),
754
755        // ===== HYPHENATION PROPERTIES =====
756
757        // hyphenate: false (inherited)
758        PropertyId::Hyphenate => PropertyValue::Enum(EN_FALSE),
759
760        // hyphenation-character: "-" (inherited)
761        PropertyId::HyphenationCharacter => PropertyValue::String(Cow::Borrowed("-")),
762
763        // hyphenation-push-character-count: 2 (inherited)
764        PropertyId::HyphenationPushCharacterCount => PropertyValue::Integer(2),
765
766        // hyphenation-remain-character-count: 2 (inherited)
767        PropertyId::HyphenationRemainCharacterCount => PropertyValue::Integer(2),
768
769        // hyphenation-ladder-count: no-limit (inherited)
770        PropertyId::HyphenationLadderCount => PropertyValue::Enum(EN_AUTO),
771
772        // hyphenation-keep: auto (inherited)
773        PropertyId::HyphenationKeep => PropertyValue::Enum(EN_AUTO),
774
775        // ===== LEADER PROPERTIES =====
776
777        // leader-pattern: space (not inherited)
778        PropertyId::LeaderPattern => PropertyValue::Enum(EN_SPACE),
779
780        // leader-pattern-width: use-font-metrics (not inherited)
781        PropertyId::LeaderPatternWidth => PropertyValue::Enum(EN_AUTO),
782
783        // leader-length: 0pt (not inherited)
784        PropertyId::LeaderLength => PropertyValue::Length(Length::ZERO),
785
786        // leader-alignment: none (not inherited)
787        PropertyId::LeaderAlignment => PropertyValue::Enum(EN_NONE),
788
789        // rule-style: solid (not inherited)
790        PropertyId::RuleStyle => PropertyValue::Enum(EN_SOLID),
791
792        // rule-thickness: 1pt (not inherited)
793        PropertyId::RuleThickness => PropertyValue::Length(Length::from_pt(1.0)),
794
795        // ===== FLOAT AND CLEAR =====
796
797        // float: none (not inherited)
798        PropertyId::Float => PropertyValue::Enum(EN_NONE),
799
800        // clear: none (not inherited)
801        PropertyId::Clear => PropertyValue::Enum(EN_NONE),
802
803        // intrusion-displace: none (not inherited)
804        PropertyId::IntrusionDisplace => PropertyValue::Enum(EN_NONE),
805
806        // ===== LIST PROPERTIES =====
807
808        // provisional-distance-between-starts: 24pt (inherited)
809        PropertyId::ProvisionalDistanceBetweenStarts => {
810            PropertyValue::Length(Length::from_pt(24.0))
811        }
812
813        // provisional-label-separation: 6pt (inherited)
814        PropertyId::ProvisionalLabelSeparation => PropertyValue::Length(Length::from_pt(6.0)),
815
816        // ===== MARKER PROPERTIES =====
817
818        // marker-class-name: empty string (not inherited)
819        PropertyId::MarkerClassName => PropertyValue::String(Cow::Borrowed("")),
820
821        // retrieve-class-name: empty string (not inherited)
822        PropertyId::RetrieveClassName => PropertyValue::String(Cow::Borrowed("")),
823
824        // retrieve-position: first-starting-within-page (not inherited)
825        PropertyId::RetrievePosition => PropertyValue::Enum(EN_FIRST_STARTING_WITHIN_PAGE),
826
827        // retrieve-boundary: page-sequence (not inherited)
828        PropertyId::RetrieveBoundary => PropertyValue::Enum(EN_PAGE_SEQUENCE),
829
830        // retrieve-position-within-table: first-starting (not inherited)
831        PropertyId::RetrievePositionWithinTable => PropertyValue::Enum(EN_FIRST),
832
833        // retrieve-boundary-within-table: table (not inherited)
834        PropertyId::RetrieveBoundaryWithinTable => PropertyValue::Enum(EN_AUTO),
835
836        // ===== PAGE NUMBER PROPERTIES =====
837
838        // initial-page-number: auto (not inherited)
839        PropertyId::InitialPageNumber => PropertyValue::Enum(EN_AUTO),
840
841        // force-page-count: auto (not inherited)
842        PropertyId::ForcePageCount => PropertyValue::Enum(EN_AUTO),
843
844        // format: "1" (not inherited)
845        PropertyId::Format => PropertyValue::String(Cow::Borrowed("1")),
846
847        // letter-value: auto (not inherited)
848        PropertyId::LetterValue => PropertyValue::Enum(EN_AUTO),
849
850        // grouping-separator: no separator (not inherited)
851        PropertyId::GroupingSeparator => PropertyValue::String(Cow::Borrowed("")),
852
853        // grouping-size: 0 (not inherited)
854        PropertyId::GroupingSize => PropertyValue::Integer(0),
855
856        // page-position: any (not inherited)
857        PropertyId::PagePosition => PropertyValue::Enum(EN_ANY),
858
859        // odd-or-even: any (not inherited)
860        PropertyId::OddOrEven => PropertyValue::Enum(EN_ANY),
861
862        // blank-or-not-blank: any (not inherited)
863        PropertyId::BlankOrNotBlank => PropertyValue::Enum(EN_ANY),
864
865        // ===== LINK AND DESTINATION PROPERTIES =====
866
867        // external-destination: empty string (not inherited)
868        PropertyId::ExternalDestination => PropertyValue::String(Cow::Borrowed("")),
869
870        // internal-destination: empty string (not inherited)
871        PropertyId::InternalDestination => PropertyValue::String(Cow::Borrowed("")),
872
873        // indicate-destination: false (not inherited)
874        PropertyId::IndicateDestination => PropertyValue::Enum(EN_FALSE),
875
876        // show-destination: replace (not inherited)
877        PropertyId::ShowDestination => PropertyValue::Enum(EN_REPLACE),
878
879        // destination-placement-offset: 0pt (not inherited)
880        PropertyId::DestinationPlacementOffset => PropertyValue::Length(Length::ZERO),
881
882        // target-presentation-context: use-target-processing-context (not inherited)
883        PropertyId::TargetPresentationContext => {
884            PropertyValue::Enum(EN_USE_TARGET_PROCESSING_CONTEXT)
885        }
886
887        // target-processing-context: document-root (not inherited)
888        PropertyId::TargetProcessingContext => PropertyValue::Enum(EN_DOCUMENT_ROOT),
889
890        // target-stylesheet: use-normal-stylesheet (not inherited)
891        PropertyId::TargetStylesheet => PropertyValue::Enum(EN_AUTO),
892
893        // ===== IDENTIFIER PROPERTIES =====
894
895        // id: empty string (not inherited)
896        PropertyId::Id => PropertyValue::String(Cow::Borrowed("")),
897
898        // ref-id: empty string (not inherited)
899        PropertyId::RefId => PropertyValue::String(Cow::Borrowed("")),
900
901        // ref-index-key: empty string (not inherited)
902        PropertyId::RefIndexKey => PropertyValue::String(Cow::Borrowed("")),
903
904        // ===== INDEX PROPERTIES (XSL 1.1) =====
905
906        // index-class: empty string (not inherited)
907        PropertyId::IndexClass => PropertyValue::String(Cow::Borrowed("")),
908
909        // index-key: empty string (not inherited)
910        PropertyId::IndexKey => PropertyValue::String(Cow::Borrowed("")),
911
912        // merge-pages-across-index-key-references: merge (not inherited)
913        PropertyId::MergePagesAcrossIndexKeyReferences => PropertyValue::Enum(EN_MERGE),
914
915        // merge-ranges-across-index-key-references: merge (not inherited)
916        PropertyId::MergeRangesAcrossIndexKeyReferences => PropertyValue::Enum(EN_MERGE),
917
918        // merge-sequential-page-numbers: merge (not inherited)
919        PropertyId::MergeSequentialPageNumbers => PropertyValue::Enum(EN_MERGE),
920
921        // page-number-treatment: link (not inherited)
922        PropertyId::PageNumberTreatment => PropertyValue::Enum(EN_LINK),
923
924        // page-citation-strategy: normal (not inherited)
925        PropertyId::PageCitationStrategy => PropertyValue::Enum(EN_NORMAL),
926
927        // ===== CHANGE BAR PROPERTIES (XSL 1.1) =====
928
929        // change-bar-class: empty string (not inherited)
930        PropertyId::ChangeBarClass => PropertyValue::String(Cow::Borrowed("")),
931
932        // change-bar-color: black (not inherited)
933        PropertyId::ChangeBarColor => PropertyValue::Color(Color::BLACK),
934
935        // change-bar-offset: 6pt (not inherited)
936        PropertyId::ChangeBarOffset => PropertyValue::Length(Length::from_pt(6.0)),
937
938        // change-bar-placement: start (not inherited)
939        PropertyId::ChangeBarPlacement => PropertyValue::Enum(EN_START),
940
941        // change-bar-style: solid (not inherited)
942        PropertyId::ChangeBarStyle => PropertyValue::Enum(EN_SOLID),
943
944        // change-bar-width: 1pt (not inherited)
945        PropertyId::ChangeBarWidth => PropertyValue::Length(Length::from_pt(1.0)),
946
947        // ===== MULTI-PROPERTY PROPERTIES =====
948
949        // active-state: link (not inherited)
950        PropertyId::ActiveState => PropertyValue::Enum(EN_LINK),
951
952        // auto-restore: false (not inherited)
953        PropertyId::AutoRestore => PropertyValue::Enum(EN_FALSE),
954
955        // case-name: empty string (not inherited)
956        PropertyId::CaseName => PropertyValue::String(Cow::Borrowed("")),
957
958        // case-title: empty string (not inherited)
959        PropertyId::CaseTitle => PropertyValue::String(Cow::Borrowed("")),
960
961        // starting-state: show (not inherited)
962        PropertyId::StartingState => PropertyValue::Enum(EN_SHOW),
963
964        // switch-to: empty string (not inherited)
965        PropertyId::SwitchTo => PropertyValue::String(Cow::Borrowed("")),
966
967        // ===== MEDIA AND RENDERING =====
968
969        // media-usage: auto (not inherited)
970        PropertyId::MediaUsage => PropertyValue::Enum(EN_AUTO),
971
972        // rendering-intent: auto (not inherited)
973        PropertyId::RenderingIntent => PropertyValue::Enum(EN_AUTO),
974
975        // color-profile-name: empty string (not inherited)
976        PropertyId::ColorProfileName => PropertyValue::String(Cow::Borrowed("")),
977
978        // ===== SCALING PROPERTIES =====
979
980        // scaling: uniform (not inherited)
981        PropertyId::Scaling => PropertyValue::Enum(EN_UNIFORM),
982
983        // scaling-method: auto (not inherited)
984        PropertyId::ScalingMethod => PropertyValue::Enum(EN_AUTO),
985
986        // intrinsic-scale-value: 100% (not inherited)
987        PropertyId::IntrinsicScaleValue => PropertyValue::Integer(100),
988
989        // ===== GLYPH ORIENTATION =====
990
991        // glyph-orientation-horizontal: 0deg (inherited)
992        PropertyId::GlyphOrientationHorizontal => PropertyValue::Integer(0),
993
994        // glyph-orientation-vertical: auto (inherited)
995        PropertyId::GlyphOrientationVertical => PropertyValue::Enum(EN_AUTO),
996
997        // ===== SCORE SPACES =====
998
999        // score-spaces: true (inherited)
1000        PropertyId::ScoreSpaces => PropertyValue::Enum(EN_TRUE),
1001
1002        // suppress-at-line-break: auto (not inherited)
1003        PropertyId::SuppressAtLineBreak => PropertyValue::Enum(EN_AUTO),
1004
1005        // treat-as-word-space: auto (not inherited)
1006        PropertyId::TreatAsWordSpace => PropertyValue::Enum(EN_AUTO),
1007
1008        // ===== SPAN =====
1009
1010        // span: none (not inherited)
1011        PropertyId::Span => PropertyValue::Enum(EN_NONE),
1012
1013        // relative-align: before (inherited)
1014        PropertyId::RelativeAlign => PropertyValue::Enum(EN_BEFORE),
1015
1016        // ===== AURAL PROPERTIES (CSS2 aural properties) =====
1017
1018        // azimuth: center (inherited)
1019        PropertyId::Azimuth => PropertyValue::Enum(EN_CENTER),
1020
1021        // cue-after: none (not inherited)
1022        PropertyId::CueAfter => PropertyValue::None,
1023
1024        // cue-before: none (not inherited)
1025        PropertyId::CueBefore => PropertyValue::None,
1026
1027        // cue: shorthand
1028        PropertyId::Cue => PropertyValue::Auto,
1029
1030        // elevation: level (inherited)
1031        PropertyId::Elevation => PropertyValue::Enum(EN_AUTO),
1032
1033        // pause-after: 0ms (not inherited)
1034        PropertyId::PauseAfter => PropertyValue::Length(Length::ZERO),
1035
1036        // pause-before: 0ms (not inherited)
1037        PropertyId::PauseBefore => PropertyValue::Length(Length::ZERO),
1038
1039        // pause: shorthand
1040        PropertyId::Pause => PropertyValue::Auto,
1041
1042        // pitch: medium (inherited)
1043        PropertyId::Pitch => PropertyValue::Enum(EN_AUTO),
1044
1045        // pitch-range: 50 (inherited)
1046        PropertyId::PitchRange => PropertyValue::Integer(50),
1047
1048        // play-during: auto (not inherited)
1049        PropertyId::PlayDuring => PropertyValue::Enum(EN_AUTO),
1050
1051        // richness: 50 (inherited)
1052        PropertyId::Richness => PropertyValue::Integer(50),
1053
1054        // speak: normal (inherited)
1055        PropertyId::Speak => PropertyValue::Enum(EN_NORMAL),
1056
1057        // speak-header: once (inherited)
1058        PropertyId::SpeakHeader => PropertyValue::Enum(EN_AUTO),
1059
1060        // speak-numeral: continuous (inherited)
1061        PropertyId::SpeakNumeral => PropertyValue::Enum(EN_AUTO),
1062
1063        // speak-punctuation: none (inherited)
1064        PropertyId::SpeakPunctuation => PropertyValue::Enum(EN_NONE),
1065
1066        // speech-rate: medium (inherited)
1067        PropertyId::SpeechRate => PropertyValue::Enum(EN_AUTO),
1068
1069        // stress: 50 (inherited)
1070        PropertyId::Stress => PropertyValue::Integer(50),
1071
1072        // voice-family: depends on user agent (inherited)
1073        PropertyId::VoiceFamily => PropertyValue::String(Cow::Borrowed("")),
1074
1075        // volume: medium (inherited)
1076        PropertyId::Volume => PropertyValue::Enum(EN_AUTO),
1077
1078        // ===== MISCELLANEOUS STRING/CONTENT PROPERTIES =====
1079
1080        // character: empty (not inherited)
1081        PropertyId::Character => PropertyValue::String(Cow::Borrowed("")),
1082
1083        // content-type: auto (not inherited)
1084        PropertyId::ContentType => PropertyValue::Enum(EN_AUTO),
1085
1086        // country: none (inherited)
1087        PropertyId::Country => PropertyValue::None,
1088
1089        // language: none (inherited)
1090        PropertyId::Language => PropertyValue::None,
1091
1092        // script: none (inherited)
1093        PropertyId::Script => PropertyValue::None,
1094
1095        // src: empty string (not inherited)
1096        PropertyId::Src => PropertyValue::String(Cow::Borrowed("")),
1097
1098        // source-document: empty string (not inherited)
1099        PropertyId::SourceDocument => PropertyValue::String(Cow::Borrowed("")),
1100
1101        // role: empty string (not inherited)
1102        PropertyId::Role => PropertyValue::String(Cow::Borrowed("")),
1103
1104        // xml-lang: empty string (inherited)
1105        PropertyId::XmlLang => PropertyValue::String(Cow::Borrowed("")),
1106
1107        // ===== Z-INDEX =====
1108
1109        // z-index: auto (not inherited)
1110        PropertyId::ZIndex => PropertyValue::Auto,
1111
1112        // opacity: 1.0 (not inherited)
1113        PropertyId::Opacity => PropertyValue::Number(1.0),
1114
1115        // ===== SIZE (page size shorthand) =====
1116
1117        // size: auto (not inherited)
1118        PropertyId::Size => PropertyValue::Enum(EN_AUTO),
1119
1120        // ===== MAXIMUM REPEATS =====
1121
1122        // maximum-repeats: no-limit (not inherited)
1123        PropertyId::MaximumRepeats => PropertyValue::Enum(EN_AUTO),
1124
1125        // ===== FOP PROPRIETARY EXTENSIONS =====
1126
1127        // x-widow-content-limit: 0pt (inherited)
1128        PropertyId::XWidowContentLimit => PropertyValue::Length(Length::ZERO),
1129
1130        // x-orphan-content-limit: 0pt (inherited)
1131        PropertyId::XOrphanContentLimit => PropertyValue::Length(Length::ZERO),
1132
1133        // x-disable-column-balancing: false (not inherited)
1134        PropertyId::XDisableColumnBalancing => PropertyValue::Enum(EN_FALSE),
1135
1136        // x-alt-text: empty string (not inherited)
1137        PropertyId::XAltText => PropertyValue::String(Cow::Borrowed("")),
1138
1139        // x-xml-base: empty string (not inherited)
1140        PropertyId::XXmlBase => PropertyValue::String(Cow::Borrowed("")),
1141
1142        // x-number-conversion-features: empty string (not inherited)
1143        PropertyId::XNumberConversionFeatures => PropertyValue::String(Cow::Borrowed("")),
1144
1145        // x-header-column: false (not inherited)
1146        PropertyId::XHeaderColumn => PropertyValue::Enum(EN_FALSE),
1147
1148        // x-layer: empty string (not inherited)
1149        PropertyId::XLayer => PropertyValue::String(Cow::Borrowed("")),
1150
1151        // x-auto-toggle: select-first-fitting (not inherited)
1152        PropertyId::XAutoToggle => PropertyValue::Enum(EN_AUTO),
1153
1154        // x-background-image-width: auto (not inherited)
1155        PropertyId::XBackgroundImageWidth => PropertyValue::Auto,
1156
1157        // x-background-image-height: auto (not inherited)
1158        PropertyId::XBackgroundImageHeight => PropertyValue::Auto,
1159
1160        // x-abbreviation: empty string (not inherited)
1161        PropertyId::XAbbreviation => PropertyValue::String(Cow::Borrowed("")),
1162    }
1163}
1164
1165#[cfg(test)]
1166mod tests {
1167    use super::*;
1168
1169    #[test]
1170    fn test_initial_color() {
1171        let value = get_initial_value(PropertyId::Color);
1172        assert_eq!(value.as_color(), Some(Color::BLACK));
1173    }
1174
1175    #[test]
1176    fn test_initial_font_family() {
1177        let value = get_initial_value(PropertyId::FontFamily);
1178        assert_eq!(value.as_string(), Some("serif"));
1179    }
1180
1181    #[test]
1182    fn test_initial_font_size() {
1183        let value = get_initial_value(PropertyId::FontSize);
1184        assert_eq!(value.as_length(), Some(Length::from_pt(12.0)));
1185    }
1186
1187    #[test]
1188    fn test_initial_margin_zero() {
1189        let value = get_initial_value(PropertyId::MarginTop);
1190        assert_eq!(value.as_length(), Some(Length::ZERO));
1191
1192        let value = get_initial_value(PropertyId::MarginLeft);
1193        assert_eq!(value.as_length(), Some(Length::ZERO));
1194    }
1195
1196    #[test]
1197    fn test_initial_padding_zero() {
1198        let value = get_initial_value(PropertyId::PaddingTop);
1199        assert_eq!(value.as_length(), Some(Length::ZERO));
1200
1201        let value = get_initial_value(PropertyId::PaddingLeft);
1202        assert_eq!(value.as_length(), Some(Length::ZERO));
1203    }
1204
1205    #[test]
1206    fn test_initial_border_style_none() {
1207        let value = get_initial_value(PropertyId::BorderTopStyle);
1208        assert_eq!(value.as_enum(), Some(EN_NONE));
1209    }
1210
1211    #[test]
1212    fn test_initial_border_width_medium() {
1213        let value = get_initial_value(PropertyId::BorderTopWidth);
1214        assert_eq!(value.as_length(), Some(Length::from_pt(1.0)));
1215    }
1216
1217    #[test]
1218    fn test_initial_border_color() {
1219        let value = get_initial_value(PropertyId::BorderTopColor);
1220        assert_eq!(value.as_color(), Some(Color::BLACK));
1221    }
1222
1223    #[test]
1224    fn test_initial_text_align() {
1225        let value = get_initial_value(PropertyId::TextAlign);
1226        assert_eq!(value.as_enum(), Some(EN_START));
1227    }
1228
1229    #[test]
1230    fn test_initial_text_indent() {
1231        let value = get_initial_value(PropertyId::TextIndent);
1232        assert_eq!(value.as_length(), Some(Length::ZERO));
1233    }
1234
1235    #[test]
1236    fn test_initial_line_height() {
1237        let value = get_initial_value(PropertyId::LineHeight);
1238        assert_eq!(value.as_enum(), Some(EN_NORMAL));
1239    }
1240
1241    #[test]
1242    fn test_initial_width_auto() {
1243        let value = get_initial_value(PropertyId::Width);
1244        assert!(value.is_auto());
1245    }
1246
1247    #[test]
1248    fn test_initial_height_auto() {
1249        let value = get_initial_value(PropertyId::Height);
1250        assert!(value.is_auto());
1251    }
1252
1253    #[test]
1254    fn test_initial_table_layout() {
1255        let value = get_initial_value(PropertyId::TableLayout);
1256        assert_eq!(value.as_enum(), Some(EN_AUTO));
1257    }
1258
1259    #[test]
1260    fn test_initial_border_collapse() {
1261        let value = get_initial_value(PropertyId::BorderCollapse);
1262        assert_eq!(value.as_enum(), Some(EN_SEPARATE));
1263    }
1264
1265    #[test]
1266    fn test_initial_empty_cells() {
1267        let value = get_initial_value(PropertyId::EmptyCells);
1268        assert_eq!(value.as_enum(), Some(EN_SHOW));
1269    }
1270
1271    #[test]
1272    fn test_initial_visibility() {
1273        let value = get_initial_value(PropertyId::Visibility);
1274        assert_eq!(value.as_enum(), Some(EN_VISIBLE));
1275    }
1276
1277    #[test]
1278    fn test_initial_overflow() {
1279        let value = get_initial_value(PropertyId::Overflow);
1280        assert_eq!(value.as_enum(), Some(EN_VISIBLE));
1281    }
1282
1283    #[test]
1284    fn test_initial_background_color() {
1285        let value = get_initial_value(PropertyId::BackgroundColor);
1286        assert_eq!(value.as_color(), Some(Color::TRANSPARENT));
1287    }
1288
1289    #[test]
1290    fn test_initial_orphans() {
1291        let value = get_initial_value(PropertyId::Orphans);
1292        assert_eq!(value.as_integer(), Some(2));
1293    }
1294
1295    #[test]
1296    fn test_initial_widows() {
1297        let value = get_initial_value(PropertyId::Widows);
1298        assert_eq!(value.as_integer(), Some(2));
1299    }
1300
1301    #[test]
1302    fn test_initial_direction() {
1303        let value = get_initial_value(PropertyId::Direction);
1304        assert_eq!(value.as_enum(), Some(EN_LTR));
1305    }
1306
1307    #[test]
1308    fn test_initial_writing_mode() {
1309        let value = get_initial_value(PropertyId::WritingMode);
1310        assert_eq!(value.as_enum(), Some(EN_LR_TB));
1311    }
1312
1313    #[test]
1314    fn test_initial_hyphenate() {
1315        let value = get_initial_value(PropertyId::Hyphenate);
1316        assert_eq!(value.as_enum(), Some(EN_FALSE));
1317    }
1318
1319    #[test]
1320    fn test_initial_hyphenation_character() {
1321        let value = get_initial_value(PropertyId::HyphenationCharacter);
1322        assert_eq!(value.as_string(), Some("-"));
1323    }
1324
1325    #[test]
1326    fn test_initial_opacity() {
1327        let value = get_initial_value(PropertyId::Opacity);
1328        assert_eq!(value.as_number(), Some(1.0));
1329    }
1330
1331    #[test]
1332    fn test_initial_column_count() {
1333        let value = get_initial_value(PropertyId::ColumnCount);
1334        assert_eq!(value.as_integer(), Some(1));
1335    }
1336
1337    #[test]
1338    fn test_initial_z_index() {
1339        let value = get_initial_value(PropertyId::ZIndex);
1340        assert!(value.is_auto());
1341    }
1342
1343    #[test]
1344    fn test_all_properties_have_initial_values() {
1345        // Test that we can get initial values for all property IDs
1346        // This ensures we haven't missed any properties
1347        let property_ids = [
1348            PropertyId::AbsolutePosition,
1349            PropertyId::ActiveState,
1350            PropertyId::AlignmentAdjust,
1351            PropertyId::AlignmentBaseline,
1352            PropertyId::AutoRestore,
1353            PropertyId::Azimuth,
1354            PropertyId::Background,
1355            PropertyId::BackgroundAttachment,
1356            PropertyId::BackgroundColor,
1357            PropertyId::BackgroundImage,
1358            // Add more property IDs to test comprehensive coverage
1359            PropertyId::Color,
1360            PropertyId::FontFamily,
1361            PropertyId::FontSize,
1362            PropertyId::MarginTop,
1363            PropertyId::PaddingLeft,
1364            PropertyId::BorderTopStyle,
1365            PropertyId::Width,
1366            PropertyId::Height,
1367            PropertyId::TextAlign,
1368            PropertyId::Visibility,
1369            PropertyId::Opacity,
1370        ];
1371
1372        for prop_id in &property_ids {
1373            let value = get_initial_value(*prop_id);
1374            // Just ensure we get a value (no panic)
1375            assert!(
1376                !matches!(value, PropertyValue::Inherit),
1377                "Initial value should not be Inherit for {:?}",
1378                prop_id
1379            );
1380        }
1381    }
1382
1383    #[test]
1384    fn test_all_295_properties_have_initial_values() {
1385        // Test all 295 property IDs (1-295)
1386        // This ensures we haven't missed any properties
1387        for id_num in 1..=295 {
1388            let property_id: PropertyId = unsafe { std::mem::transmute(id_num as u16) };
1389            let initial_value = get_initial_value(property_id);
1390
1391            // Verify we get a value and it's not Inherit
1392            // (initial values should never be Inherit)
1393            assert!(
1394                !matches!(initial_value, PropertyValue::Inherit),
1395                "Property {:?} (ID {}) has Inherit as initial value, which is invalid",
1396                property_id,
1397                id_num
1398            );
1399
1400            // Just ensure we get some value without panicking
1401            let _ = format!("{:?}", initial_value);
1402        }
1403    }
1404
1405    #[test]
1406    fn test_comprehensive_initial_values() {
1407        // Test a representative sample from each category
1408
1409        // Margins (all 0pt)
1410        assert_eq!(
1411            get_initial_value(PropertyId::MarginRight).as_length(),
1412            Some(Length::ZERO)
1413        );
1414        assert_eq!(
1415            get_initial_value(PropertyId::MarginBottom).as_length(),
1416            Some(Length::ZERO)
1417        );
1418
1419        // Padding (all 0pt)
1420        assert_eq!(
1421            get_initial_value(PropertyId::PaddingRight).as_length(),
1422            Some(Length::ZERO)
1423        );
1424        assert_eq!(
1425            get_initial_value(PropertyId::PaddingBottom).as_length(),
1426            Some(Length::ZERO)
1427        );
1428        assert_eq!(
1429            get_initial_value(PropertyId::PaddingBefore).as_length(),
1430            Some(Length::ZERO)
1431        );
1432        assert_eq!(
1433            get_initial_value(PropertyId::PaddingAfter).as_length(),
1434            Some(Length::ZERO)
1435        );
1436
1437        // Border widths (all medium = 1pt)
1438        assert_eq!(
1439            get_initial_value(PropertyId::BorderRightWidth).as_length(),
1440            Some(Length::from_pt(1.0))
1441        );
1442        assert_eq!(
1443            get_initial_value(PropertyId::BorderBeforeWidth).as_length(),
1444            Some(Length::from_pt(1.0))
1445        );
1446
1447        // Border styles (all none)
1448        assert_eq!(
1449            get_initial_value(PropertyId::BorderRightStyle).as_enum(),
1450            Some(EN_NONE)
1451        );
1452        assert_eq!(
1453            get_initial_value(PropertyId::BorderBottomStyle).as_enum(),
1454            Some(EN_NONE)
1455        );
1456
1457        // Border colors (all black)
1458        assert_eq!(
1459            get_initial_value(PropertyId::BorderRightColor).as_color(),
1460            Some(Color::BLACK)
1461        );
1462        assert_eq!(
1463            get_initial_value(PropertyId::BorderLeftColor).as_color(),
1464            Some(Color::BLACK)
1465        );
1466
1467        // Dimensions
1468        assert!(get_initial_value(PropertyId::MinWidth)
1469            .as_length()
1470            .is_some());
1471        assert!(get_initial_value(PropertyId::MinHeight)
1472            .as_length()
1473            .is_some());
1474        assert!(get_initial_value(PropertyId::MaxWidth).is_none());
1475        assert!(get_initial_value(PropertyId::MaxHeight).is_none());
1476
1477        // Keep/break properties
1478        assert!(get_initial_value(PropertyId::KeepWithNext)
1479            .as_enum()
1480            .is_some());
1481        assert!(get_initial_value(PropertyId::KeepWithPrevious)
1482            .as_enum()
1483            .is_some());
1484        assert!(get_initial_value(PropertyId::BreakAfter)
1485            .as_enum()
1486            .is_some());
1487
1488        // Table properties
1489        assert_eq!(
1490            get_initial_value(PropertyId::NumberColumnsSpanned).as_integer(),
1491            Some(1)
1492        );
1493        assert_eq!(
1494            get_initial_value(PropertyId::NumberRowsSpanned).as_integer(),
1495            Some(1)
1496        );
1497
1498        // Text properties
1499        assert_eq!(
1500            get_initial_value(PropertyId::LetterSpacing).as_enum(),
1501            Some(EN_NORMAL)
1502        );
1503        assert_eq!(
1504            get_initial_value(PropertyId::WordSpacing).as_enum(),
1505            Some(EN_NORMAL)
1506        );
1507
1508        // Hyphenation
1509        assert_eq!(
1510            get_initial_value(PropertyId::HyphenationPushCharacterCount).as_integer(),
1511            Some(2)
1512        );
1513        assert_eq!(
1514            get_initial_value(PropertyId::HyphenationRemainCharacterCount).as_integer(),
1515            Some(2)
1516        );
1517    }
1518}
1519
1520// ===== ADDITIONAL TESTS =====
1521#[cfg(test)]
1522mod additional_tests {
1523    use super::*;
1524
1525    #[test]
1526    fn test_initial_font_weight_is_normal() {
1527        let v = get_initial_value(PropertyId::FontWeight);
1528        // font-weight initial is "normal" (EN_NORMAL = 87)
1529        assert_eq!(v.as_enum(), Some(EN_NORMAL));
1530    }
1531
1532    #[test]
1533    fn test_initial_font_style_is_normal() {
1534        let v = get_initial_value(PropertyId::FontStyle);
1535        assert_eq!(v.as_enum(), Some(EN_NORMAL));
1536    }
1537
1538    #[test]
1539    fn test_initial_letter_spacing_is_normal() {
1540        let v = get_initial_value(PropertyId::LetterSpacing);
1541        assert_eq!(v.as_enum(), Some(EN_NORMAL));
1542    }
1543
1544    #[test]
1545    fn test_initial_word_spacing_is_normal() {
1546        let v = get_initial_value(PropertyId::WordSpacing);
1547        assert_eq!(v.as_enum(), Some(EN_NORMAL));
1548    }
1549
1550    #[test]
1551    fn test_initial_direction_is_ltr() {
1552        let v = get_initial_value(PropertyId::Direction);
1553        assert_eq!(v.as_enum(), Some(EN_LTR));
1554    }
1555
1556    #[test]
1557    fn test_initial_writing_mode_is_lr_tb() {
1558        let v = get_initial_value(PropertyId::WritingMode);
1559        assert_eq!(v.as_enum(), Some(EN_LR_TB));
1560    }
1561
1562    #[test]
1563    fn test_initial_background_color_is_transparent() {
1564        let v = get_initial_value(PropertyId::BackgroundColor);
1565        // background-color initial is transparent (Color::TRANSPARENT or None)
1566        // Just verify it's some kind of value
1567        assert!(v.as_color().is_some() || v.is_none() || v.is_auto());
1568    }
1569
1570    #[test]
1571    fn test_initial_border_top_style_is_none() {
1572        let v = get_initial_value(PropertyId::BorderTopStyle);
1573        assert_eq!(v.as_enum(), Some(EN_NONE));
1574    }
1575
1576    #[test]
1577    fn test_initial_border_bottom_style_is_none() {
1578        let v = get_initial_value(PropertyId::BorderBottomStyle);
1579        assert_eq!(v.as_enum(), Some(EN_NONE));
1580    }
1581
1582    #[test]
1583    fn test_initial_border_left_style_is_none() {
1584        let v = get_initial_value(PropertyId::BorderLeftStyle);
1585        assert_eq!(v.as_enum(), Some(EN_NONE));
1586    }
1587
1588    #[test]
1589    fn test_initial_border_right_style_is_none() {
1590        let v = get_initial_value(PropertyId::BorderRightStyle);
1591        assert_eq!(v.as_enum(), Some(EN_NONE));
1592    }
1593
1594    #[test]
1595    fn test_initial_padding_top_is_zero() {
1596        let v = get_initial_value(PropertyId::PaddingTop);
1597        assert_eq!(v.as_length(), Some(Length::ZERO));
1598    }
1599
1600    #[test]
1601    fn test_initial_padding_bottom_is_zero() {
1602        let v = get_initial_value(PropertyId::PaddingBottom);
1603        assert_eq!(v.as_length(), Some(Length::ZERO));
1604    }
1605
1606    #[test]
1607    fn test_initial_padding_left_is_zero() {
1608        let v = get_initial_value(PropertyId::PaddingLeft);
1609        assert_eq!(v.as_length(), Some(Length::ZERO));
1610    }
1611
1612    #[test]
1613    fn test_initial_padding_right_is_zero() {
1614        let v = get_initial_value(PropertyId::PaddingRight);
1615        assert_eq!(v.as_length(), Some(Length::ZERO));
1616    }
1617
1618    #[test]
1619    fn test_initial_margin_top_is_zero() {
1620        let v = get_initial_value(PropertyId::MarginTop);
1621        assert_eq!(v.as_length(), Some(Length::ZERO));
1622    }
1623
1624    #[test]
1625    fn test_initial_margin_bottom_is_zero() {
1626        let v = get_initial_value(PropertyId::MarginBottom);
1627        assert_eq!(v.as_length(), Some(Length::ZERO));
1628    }
1629
1630    #[test]
1631    fn test_initial_margin_left_is_zero() {
1632        let v = get_initial_value(PropertyId::MarginLeft);
1633        assert_eq!(v.as_length(), Some(Length::ZERO));
1634    }
1635
1636    #[test]
1637    fn test_initial_margin_right_is_zero() {
1638        let v = get_initial_value(PropertyId::MarginRight);
1639        assert_eq!(v.as_length(), Some(Length::ZERO));
1640    }
1641
1642    #[test]
1643    fn test_initial_visibility_is_visible() {
1644        let v = get_initial_value(PropertyId::Visibility);
1645        assert_eq!(v.as_enum(), Some(EN_VISIBLE));
1646    }
1647
1648    #[test]
1649    fn test_initial_overflow_is_visible() {
1650        let v = get_initial_value(PropertyId::Overflow);
1651        assert_eq!(v.as_enum(), Some(EN_VISIBLE));
1652    }
1653
1654    #[test]
1655    fn test_initial_column_count_is_one() {
1656        let v = get_initial_value(PropertyId::ColumnCount);
1657        assert_eq!(v.as_integer(), Some(1));
1658    }
1659
1660    #[test]
1661    fn test_initial_orphans_is_two() {
1662        let v = get_initial_value(PropertyId::Orphans);
1663        assert_eq!(v.as_integer(), Some(2));
1664    }
1665
1666    #[test]
1667    fn test_initial_widows_is_two() {
1668        let v = get_initial_value(PropertyId::Widows);
1669        assert_eq!(v.as_integer(), Some(2));
1670    }
1671
1672    #[test]
1673    fn test_initial_opacity_is_one() {
1674        let v = get_initial_value(PropertyId::Opacity);
1675        assert_eq!(v.as_number(), Some(1.0));
1676    }
1677
1678    #[test]
1679    fn test_initial_z_index_is_auto() {
1680        let v = get_initial_value(PropertyId::ZIndex);
1681        // z-index initial value is "auto"
1682        assert!(v.is_auto() || v.as_integer().is_some());
1683    }
1684
1685    #[test]
1686    fn test_initial_text_indent_is_zero() {
1687        let v = get_initial_value(PropertyId::TextIndent);
1688        assert_eq!(v.as_length(), Some(Length::ZERO));
1689    }
1690
1691    #[test]
1692    fn test_initial_line_height_is_normal() {
1693        let v = get_initial_value(PropertyId::LineHeight);
1694        assert_eq!(v.as_enum(), Some(EN_NORMAL));
1695    }
1696
1697    #[test]
1698    fn test_initial_width_is_auto() {
1699        let v = get_initial_value(PropertyId::Width);
1700        assert!(v.is_auto());
1701    }
1702
1703    #[test]
1704    fn test_initial_height_is_auto() {
1705        let v = get_initial_value(PropertyId::Height);
1706        assert!(v.is_auto());
1707    }
1708
1709    #[test]
1710    fn test_initial_text_align_is_start() {
1711        let v = get_initial_value(PropertyId::TextAlign);
1712        assert_eq!(v.as_enum(), Some(EN_START));
1713    }
1714
1715    #[test]
1716    fn test_initial_border_collapse_is_separate() {
1717        let v = get_initial_value(PropertyId::BorderCollapse);
1718        assert_eq!(v.as_enum(), Some(EN_SEPARATE));
1719    }
1720
1721    #[test]
1722    fn test_get_initial_value_does_not_panic_for_all_ids() {
1723        // Verify get_initial_value doesn't panic for any known property
1724        let ids = [
1725            PropertyId::AbsolutePosition,
1726            PropertyId::BackgroundColor,
1727            PropertyId::BorderTopStyle,
1728            PropertyId::Color,
1729            PropertyId::Direction,
1730            PropertyId::FontFamily,
1731            PropertyId::FontSize,
1732            PropertyId::FontStyle,
1733            PropertyId::FontWeight,
1734            PropertyId::Height,
1735            PropertyId::LineHeight,
1736            PropertyId::MarginTop,
1737            PropertyId::Opacity,
1738            PropertyId::Overflow,
1739            PropertyId::PaddingTop,
1740            PropertyId::TextAlign,
1741            PropertyId::TextIndent,
1742            PropertyId::Visibility,
1743            PropertyId::WhiteSpace,
1744            PropertyId::Width,
1745            PropertyId::WritingMode,
1746            PropertyId::ZIndex,
1747        ];
1748        for id in &ids {
1749            let _ = get_initial_value(*id); // Should not panic
1750        }
1751    }
1752}