1use crate::objects::{Dictionary, Object};
7
8#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum PageLayout {
11 SinglePage,
13 OneColumn,
15 TwoColumnLeft,
17 TwoColumnRight,
19 TwoPageLeft,
21 TwoPageRight,
23}
24
25impl PageLayout {
26 pub fn to_pdf_name(&self) -> &'static str {
28 match self {
29 PageLayout::SinglePage => "SinglePage",
30 PageLayout::OneColumn => "OneColumn",
31 PageLayout::TwoColumnLeft => "TwoColumnLeft",
32 PageLayout::TwoColumnRight => "TwoColumnRight",
33 PageLayout::TwoPageLeft => "TwoPageLeft",
34 PageLayout::TwoPageRight => "TwoPageRight",
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
41pub enum PageMode {
42 UseNone,
44 UseOutlines,
46 UseThumbs,
48 FullScreen,
50 UseOC,
52 UseAttachments,
54}
55
56impl PageMode {
57 pub fn to_pdf_name(&self) -> &'static str {
59 match self {
60 PageMode::UseNone => "UseNone",
61 PageMode::UseOutlines => "UseOutlines",
62 PageMode::UseThumbs => "UseThumbs",
63 PageMode::FullScreen => "FullScreen",
64 PageMode::UseOC => "UseOC",
65 PageMode::UseAttachments => "UseAttachments",
66 }
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq)]
72pub enum NonFullScreenPageMode {
73 UseNone,
75 UseOutlines,
77 UseThumbs,
79 UseOC,
81}
82
83impl NonFullScreenPageMode {
84 pub fn to_pdf_name(&self) -> &'static str {
86 match self {
87 NonFullScreenPageMode::UseNone => "UseNone",
88 NonFullScreenPageMode::UseOutlines => "UseOutlines",
89 NonFullScreenPageMode::UseThumbs => "UseThumbs",
90 NonFullScreenPageMode::UseOC => "UseOC",
91 }
92 }
93}
94
95#[derive(Debug, Clone, Copy, PartialEq)]
97pub enum Direction {
98 L2R,
100 R2L,
102}
103
104impl Direction {
105 pub fn to_pdf_name(&self) -> &'static str {
107 match self {
108 Direction::L2R => "L2R",
109 Direction::R2L => "R2L",
110 }
111 }
112}
113
114#[derive(Debug, Clone, Copy, PartialEq)]
116pub enum PrintScaling {
117 None,
119 AppDefault,
121}
122
123impl PrintScaling {
124 pub fn to_pdf_name(&self) -> &'static str {
126 match self {
127 PrintScaling::None => "None",
128 PrintScaling::AppDefault => "AppDefault",
129 }
130 }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq)]
135pub enum Duplex {
136 Simplex,
138 DuplexFlipShortEdge,
140 DuplexFlipLongEdge,
142}
143
144impl Duplex {
145 pub fn to_pdf_name(&self) -> &'static str {
147 match self {
148 Duplex::Simplex => "Simplex",
149 Duplex::DuplexFlipShortEdge => "DuplexFlipShortEdge",
150 Duplex::DuplexFlipLongEdge => "DuplexFlipLongEdge",
151 }
152 }
153}
154
155#[derive(Debug, Clone, Default)]
157pub struct ViewerPreferences {
158 pub hide_toolbar: Option<bool>,
160 pub hide_menubar: Option<bool>,
162 pub hide_window_ui: Option<bool>,
164 pub fit_window: Option<bool>,
166 pub center_window: Option<bool>,
168 pub display_doc_title: Option<bool>,
170 pub page_layout: Option<PageLayout>,
172 pub page_mode: Option<PageMode>,
174 pub non_full_screen_page_mode: Option<NonFullScreenPageMode>,
176 pub direction: Option<Direction>,
178 pub view_area: Option<String>,
180 pub view_clip: Option<String>,
182 pub print_area: Option<String>,
184 pub print_clip: Option<String>,
186 pub print_scaling: Option<PrintScaling>,
188 pub duplex: Option<Duplex>,
190 pub print_page_range: Option<Vec<(u32, u32)>>,
192 pub num_copies: Option<u32>,
194 pub pick_tray_by_pdf_size: Option<bool>,
196}
197
198impl ViewerPreferences {
199 pub fn new() -> Self {
201 ViewerPreferences::default()
202 }
203
204 pub fn hide_toolbar(mut self, hide: bool) -> Self {
206 self.hide_toolbar = Some(hide);
207 self
208 }
209
210 pub fn hide_menubar(mut self, hide: bool) -> Self {
212 self.hide_menubar = Some(hide);
213 self
214 }
215
216 pub fn hide_window_ui(mut self, hide: bool) -> Self {
218 self.hide_window_ui = Some(hide);
219 self
220 }
221
222 pub fn fit_window(mut self, fit: bool) -> Self {
224 self.fit_window = Some(fit);
225 self
226 }
227
228 pub fn center_window(mut self, center: bool) -> Self {
230 self.center_window = Some(center);
231 self
232 }
233
234 pub fn display_doc_title(mut self, display: bool) -> Self {
236 self.display_doc_title = Some(display);
237 self
238 }
239
240 pub fn page_layout(mut self, layout: PageLayout) -> Self {
242 self.page_layout = Some(layout);
243 self
244 }
245
246 pub fn page_mode(mut self, mode: PageMode) -> Self {
248 self.page_mode = Some(mode);
249 self
250 }
251
252 pub fn non_full_screen_page_mode(mut self, mode: NonFullScreenPageMode) -> Self {
254 self.non_full_screen_page_mode = Some(mode);
255 self
256 }
257
258 pub fn direction(mut self, direction: Direction) -> Self {
260 self.direction = Some(direction);
261 self
262 }
263
264 pub fn print_scaling(mut self, scaling: PrintScaling) -> Self {
266 self.print_scaling = Some(scaling);
267 self
268 }
269
270 pub fn duplex(mut self, duplex: Duplex) -> Self {
272 self.duplex = Some(duplex);
273 self
274 }
275
276 pub fn num_copies(mut self, copies: u32) -> Self {
278 self.num_copies = Some(copies.max(1));
279 self
280 }
281
282 pub fn pick_tray_by_pdf_size(mut self, pick: bool) -> Self {
284 self.pick_tray_by_pdf_size = Some(pick);
285 self
286 }
287
288 pub fn add_print_page_range(mut self, start: u32, end: u32) -> Self {
290 if self.print_page_range.is_none() {
291 self.print_page_range = Some(Vec::new());
292 }
293 if let Some(ref mut ranges) = self.print_page_range {
294 ranges.push((start.min(end), start.max(end)));
295 }
296 self
297 }
298
299 pub fn to_dict(&self) -> Dictionary {
301 let mut dict = Dictionary::new();
302
303 if let Some(hide) = self.hide_toolbar {
304 dict.set("HideToolbar", Object::Boolean(hide));
305 }
306
307 if let Some(hide) = self.hide_menubar {
308 dict.set("HideMenubar", Object::Boolean(hide));
309 }
310
311 if let Some(hide) = self.hide_window_ui {
312 dict.set("HideWindowUI", Object::Boolean(hide));
313 }
314
315 if let Some(fit) = self.fit_window {
316 dict.set("FitWindow", Object::Boolean(fit));
317 }
318
319 if let Some(center) = self.center_window {
320 dict.set("CenterWindow", Object::Boolean(center));
321 }
322
323 if let Some(display) = self.display_doc_title {
324 dict.set("DisplayDocTitle", Object::Boolean(display));
325 }
326
327 if let Some(layout) = self.page_layout {
328 dict.set("PageLayout", Object::Name(layout.to_pdf_name().to_string()));
329 }
330
331 if let Some(mode) = self.page_mode {
332 dict.set("PageMode", Object::Name(mode.to_pdf_name().to_string()));
333 }
334
335 if let Some(mode) = self.non_full_screen_page_mode {
336 dict.set(
337 "NonFullScreenPageMode",
338 Object::Name(mode.to_pdf_name().to_string()),
339 );
340 }
341
342 if let Some(direction) = self.direction {
343 dict.set(
344 "Direction",
345 Object::Name(direction.to_pdf_name().to_string()),
346 );
347 }
348
349 if let Some(ref area) = self.view_area {
350 dict.set("ViewArea", Object::Name(area.clone()));
351 }
352
353 if let Some(ref clip) = self.view_clip {
354 dict.set("ViewClip", Object::Name(clip.clone()));
355 }
356
357 if let Some(ref area) = self.print_area {
358 dict.set("PrintArea", Object::Name(area.clone()));
359 }
360
361 if let Some(ref clip) = self.print_clip {
362 dict.set("PrintClip", Object::Name(clip.clone()));
363 }
364
365 if let Some(scaling) = self.print_scaling {
366 dict.set(
367 "PrintScaling",
368 Object::Name(scaling.to_pdf_name().to_string()),
369 );
370 }
371
372 if let Some(duplex) = self.duplex {
373 dict.set("Duplex", Object::Name(duplex.to_pdf_name().to_string()));
374 }
375
376 if let Some(ref ranges) = self.print_page_range {
377 let range_array: Vec<Object> = ranges
378 .iter()
379 .flat_map(|(start, end)| {
380 vec![Object::Integer(*start as i64), Object::Integer(*end as i64)]
381 })
382 .collect();
383 dict.set("PrintPageRange", Object::Array(range_array));
384 }
385
386 if let Some(copies) = self.num_copies {
387 dict.set("NumCopies", Object::Integer(copies as i64));
388 }
389
390 if let Some(pick) = self.pick_tray_by_pdf_size {
391 dict.set("PickTrayByPDFSize", Object::Boolean(pick));
392 }
393
394 dict
395 }
396
397 pub fn presentation() -> Self {
401 ViewerPreferences::new()
402 .page_mode(PageMode::FullScreen)
403 .hide_toolbar(true)
404 .hide_menubar(true)
405 .hide_window_ui(true)
406 .fit_window(true)
407 .center_window(true)
408 }
409
410 pub fn reading() -> Self {
412 ViewerPreferences::new()
413 .page_layout(PageLayout::TwoColumnRight)
414 .page_mode(PageMode::UseOutlines)
415 .fit_window(true)
416 .display_doc_title(true)
417 }
418
419 pub fn printing() -> Self {
421 ViewerPreferences::new()
422 .print_scaling(PrintScaling::None)
423 .duplex(Duplex::DuplexFlipLongEdge)
424 .pick_tray_by_pdf_size(true)
425 }
426
427 pub fn minimal_ui() -> Self {
429 ViewerPreferences::new()
430 .hide_toolbar(true)
431 .hide_menubar(true)
432 .center_window(true)
433 .fit_window(true)
434 }
435}
436
437#[cfg(test)]
438mod tests {
439 use super::*;
440
441 #[test]
442 fn test_page_layout_names() {
443 assert_eq!(PageLayout::SinglePage.to_pdf_name(), "SinglePage");
444 assert_eq!(PageLayout::OneColumn.to_pdf_name(), "OneColumn");
445 assert_eq!(PageLayout::TwoColumnLeft.to_pdf_name(), "TwoColumnLeft");
446 assert_eq!(PageLayout::TwoColumnRight.to_pdf_name(), "TwoColumnRight");
447 assert_eq!(PageLayout::TwoPageLeft.to_pdf_name(), "TwoPageLeft");
448 assert_eq!(PageLayout::TwoPageRight.to_pdf_name(), "TwoPageRight");
449 }
450
451 #[test]
452 fn test_page_mode_names() {
453 assert_eq!(PageMode::UseNone.to_pdf_name(), "UseNone");
454 assert_eq!(PageMode::UseOutlines.to_pdf_name(), "UseOutlines");
455 assert_eq!(PageMode::UseThumbs.to_pdf_name(), "UseThumbs");
456 assert_eq!(PageMode::FullScreen.to_pdf_name(), "FullScreen");
457 assert_eq!(PageMode::UseOC.to_pdf_name(), "UseOC");
458 assert_eq!(PageMode::UseAttachments.to_pdf_name(), "UseAttachments");
459 }
460
461 #[test]
462 fn test_basic_preferences() {
463 let prefs = ViewerPreferences::new()
464 .hide_toolbar(true)
465 .hide_menubar(true)
466 .fit_window(true);
467
468 let dict = prefs.to_dict();
469 assert_eq!(dict.get("HideToolbar"), Some(&Object::Boolean(true)));
470 assert_eq!(dict.get("HideMenubar"), Some(&Object::Boolean(true)));
471 assert_eq!(dict.get("FitWindow"), Some(&Object::Boolean(true)));
472 }
473
474 #[test]
475 fn test_page_layout_preference() {
476 let prefs = ViewerPreferences::new().page_layout(PageLayout::TwoColumnLeft);
477
478 let dict = prefs.to_dict();
479 assert_eq!(
480 dict.get("PageLayout"),
481 Some(&Object::Name("TwoColumnLeft".to_string()))
482 );
483 }
484
485 #[test]
486 fn test_print_preferences() {
487 let prefs = ViewerPreferences::new()
488 .print_scaling(PrintScaling::None)
489 .duplex(Duplex::DuplexFlipLongEdge)
490 .num_copies(3);
491
492 let dict = prefs.to_dict();
493 assert_eq!(
494 dict.get("PrintScaling"),
495 Some(&Object::Name("None".to_string()))
496 );
497 assert_eq!(
498 dict.get("Duplex"),
499 Some(&Object::Name("DuplexFlipLongEdge".to_string()))
500 );
501 assert_eq!(dict.get("NumCopies"), Some(&Object::Integer(3)));
502 }
503
504 #[test]
505 fn test_print_page_ranges() {
506 let prefs = ViewerPreferences::new()
507 .add_print_page_range(1, 5)
508 .add_print_page_range(10, 15);
509
510 let dict = prefs.to_dict();
511 if let Some(Object::Array(ranges)) = dict.get("PrintPageRange") {
512 assert_eq!(ranges.len(), 4); assert_eq!(ranges[0], Object::Integer(1));
514 assert_eq!(ranges[1], Object::Integer(5));
515 assert_eq!(ranges[2], Object::Integer(10));
516 assert_eq!(ranges[3], Object::Integer(15));
517 } else {
518 panic!("Expected PrintPageRange array");
519 }
520 }
521
522 #[test]
523 fn test_convenience_constructors() {
524 let presentation = ViewerPreferences::presentation();
525 assert_eq!(presentation.page_mode, Some(PageMode::FullScreen));
526 assert_eq!(presentation.hide_toolbar, Some(true));
527
528 let reading = ViewerPreferences::reading();
529 assert_eq!(reading.page_layout, Some(PageLayout::TwoColumnRight));
530 assert_eq!(reading.page_mode, Some(PageMode::UseOutlines));
531
532 let printing = ViewerPreferences::printing();
533 assert_eq!(printing.print_scaling, Some(PrintScaling::None));
534 assert_eq!(printing.duplex, Some(Duplex::DuplexFlipLongEdge));
535
536 let minimal = ViewerPreferences::minimal_ui();
537 assert_eq!(minimal.hide_toolbar, Some(true));
538 assert_eq!(minimal.hide_menubar, Some(true));
539 }
540
541 #[test]
542 fn test_num_copies_bounds() {
543 let prefs = ViewerPreferences::new().num_copies(0);
544 assert_eq!(prefs.num_copies, Some(1)); }
546
547 #[test]
548 fn test_direction() {
549 assert_eq!(Direction::L2R.to_pdf_name(), "L2R");
550 assert_eq!(Direction::R2L.to_pdf_name(), "R2L");
551 }
552
553 #[test]
554 fn test_print_scaling() {
555 assert_eq!(PrintScaling::None.to_pdf_name(), "None");
556 assert_eq!(PrintScaling::AppDefault.to_pdf_name(), "AppDefault");
557 }
558
559 #[test]
560 fn test_duplex_modes() {
561 assert_eq!(Duplex::Simplex.to_pdf_name(), "Simplex");
562 assert_eq!(
563 Duplex::DuplexFlipShortEdge.to_pdf_name(),
564 "DuplexFlipShortEdge"
565 );
566 assert_eq!(
567 Duplex::DuplexFlipLongEdge.to_pdf_name(),
568 "DuplexFlipLongEdge"
569 );
570 }
571
572 #[test]
573 fn test_empty_preferences() {
574 let prefs = ViewerPreferences::new();
575 let dict = prefs.to_dict();
576 assert!(dict.is_empty()); }
578
579 #[test]
580 fn test_non_full_screen_page_mode_names() {
581 assert_eq!(NonFullScreenPageMode::UseNone.to_pdf_name(), "UseNone");
582 assert_eq!(
583 NonFullScreenPageMode::UseOutlines.to_pdf_name(),
584 "UseOutlines"
585 );
586 assert_eq!(NonFullScreenPageMode::UseThumbs.to_pdf_name(), "UseThumbs");
587 assert_eq!(NonFullScreenPageMode::UseOC.to_pdf_name(), "UseOC");
588 }
589
590 #[test]
591 fn test_non_full_screen_page_mode_to_dict() {
592 let prefs =
593 ViewerPreferences::new().non_full_screen_page_mode(NonFullScreenPageMode::UseOutlines);
594 let dict = prefs.to_dict();
595 assert_eq!(
596 dict.get("NonFullScreenPageMode"),
597 Some(&Object::Name("UseOutlines".to_string()))
598 );
599 }
600
601 #[test]
602 fn test_direction_to_dict() {
603 let prefs_l2r = ViewerPreferences::new().direction(Direction::L2R);
604 let dict_l2r = prefs_l2r.to_dict();
605 assert_eq!(
606 dict_l2r.get("Direction"),
607 Some(&Object::Name("L2R".to_string()))
608 );
609
610 let prefs_r2l = ViewerPreferences::new().direction(Direction::R2L);
611 let dict_r2l = prefs_r2l.to_dict();
612 assert_eq!(
613 dict_r2l.get("Direction"),
614 Some(&Object::Name("R2L".to_string()))
615 );
616 }
617
618 #[test]
619 fn test_view_area_and_clip() {
620 let mut prefs = ViewerPreferences::new();
621 prefs.view_area = Some("MediaBox".to_string());
622 prefs.view_clip = Some("CropBox".to_string());
623
624 let dict = prefs.to_dict();
625 assert_eq!(
626 dict.get("ViewArea"),
627 Some(&Object::Name("MediaBox".to_string()))
628 );
629 assert_eq!(
630 dict.get("ViewClip"),
631 Some(&Object::Name("CropBox".to_string()))
632 );
633 }
634
635 #[test]
636 fn test_print_area_and_clip() {
637 let mut prefs = ViewerPreferences::new();
638 prefs.print_area = Some("BleedBox".to_string());
639 prefs.print_clip = Some("TrimBox".to_string());
640
641 let dict = prefs.to_dict();
642 assert_eq!(
643 dict.get("PrintArea"),
644 Some(&Object::Name("BleedBox".to_string()))
645 );
646 assert_eq!(
647 dict.get("PrintClip"),
648 Some(&Object::Name("TrimBox".to_string()))
649 );
650 }
651
652 #[test]
653 fn test_pick_tray_by_pdf_size_to_dict() {
654 let prefs = ViewerPreferences::new().pick_tray_by_pdf_size(true);
655 let dict = prefs.to_dict();
656 assert_eq!(dict.get("PickTrayByPDFSize"), Some(&Object::Boolean(true)));
657
658 let prefs_false = ViewerPreferences::new().pick_tray_by_pdf_size(false);
659 let dict_false = prefs_false.to_dict();
660 assert_eq!(
661 dict_false.get("PickTrayByPDFSize"),
662 Some(&Object::Boolean(false))
663 );
664 }
665
666 #[test]
667 fn test_hide_window_ui_to_dict() {
668 let prefs = ViewerPreferences::new().hide_window_ui(true);
669 let dict = prefs.to_dict();
670 assert_eq!(dict.get("HideWindowUI"), Some(&Object::Boolean(true)));
671 }
672
673 #[test]
674 fn test_center_window_to_dict() {
675 let prefs = ViewerPreferences::new().center_window(true);
676 let dict = prefs.to_dict();
677 assert_eq!(dict.get("CenterWindow"), Some(&Object::Boolean(true)));
678 }
679
680 #[test]
681 fn test_display_doc_title_to_dict() {
682 let prefs = ViewerPreferences::new().display_doc_title(true);
683 let dict = prefs.to_dict();
684 assert_eq!(dict.get("DisplayDocTitle"), Some(&Object::Boolean(true)));
685 }
686
687 #[test]
688 fn test_page_mode_to_dict() {
689 let prefs = ViewerPreferences::new().page_mode(PageMode::UseAttachments);
690 let dict = prefs.to_dict();
691 assert_eq!(
692 dict.get("PageMode"),
693 Some(&Object::Name("UseAttachments".to_string()))
694 );
695 }
696
697 #[test]
698 fn test_print_page_range_reversed() {
699 let prefs = ViewerPreferences::new().add_print_page_range(10, 5);
701 let dict = prefs.to_dict();
702 if let Some(Object::Array(ranges)) = dict.get("PrintPageRange") {
703 assert_eq!(ranges[0], Object::Integer(5)); assert_eq!(ranges[1], Object::Integer(10)); } else {
706 panic!("Expected PrintPageRange array");
707 }
708 }
709
710 #[test]
711 fn test_all_page_layouts_to_dict() {
712 let layouts = [
713 (PageLayout::SinglePage, "SinglePage"),
714 (PageLayout::OneColumn, "OneColumn"),
715 (PageLayout::TwoColumnLeft, "TwoColumnLeft"),
716 (PageLayout::TwoColumnRight, "TwoColumnRight"),
717 (PageLayout::TwoPageLeft, "TwoPageLeft"),
718 (PageLayout::TwoPageRight, "TwoPageRight"),
719 ];
720
721 for (layout, expected_name) in layouts {
722 let prefs = ViewerPreferences::new().page_layout(layout);
723 let dict = prefs.to_dict();
724 assert_eq!(
725 dict.get("PageLayout"),
726 Some(&Object::Name(expected_name.to_string()))
727 );
728 }
729 }
730
731 #[test]
732 fn test_print_scaling_app_default_to_dict() {
733 let prefs = ViewerPreferences::new().print_scaling(PrintScaling::AppDefault);
734 let dict = prefs.to_dict();
735 assert_eq!(
736 dict.get("PrintScaling"),
737 Some(&Object::Name("AppDefault".to_string()))
738 );
739 }
740
741 #[test]
742 fn test_duplex_simplex_to_dict() {
743 let prefs = ViewerPreferences::new().duplex(Duplex::Simplex);
744 let dict = prefs.to_dict();
745 assert_eq!(
746 dict.get("Duplex"),
747 Some(&Object::Name("Simplex".to_string()))
748 );
749 }
750
751 #[test]
752 fn test_duplex_flip_short_edge_to_dict() {
753 let prefs = ViewerPreferences::new().duplex(Duplex::DuplexFlipShortEdge);
754 let dict = prefs.to_dict();
755 assert_eq!(
756 dict.get("Duplex"),
757 Some(&Object::Name("DuplexFlipShortEdge".to_string()))
758 );
759 }
760
761 #[test]
762 fn test_full_preferences_to_dict() {
763 let mut prefs = ViewerPreferences::new()
764 .hide_toolbar(true)
765 .hide_menubar(true)
766 .hide_window_ui(true)
767 .fit_window(true)
768 .center_window(true)
769 .display_doc_title(true)
770 .page_layout(PageLayout::TwoColumnRight)
771 .page_mode(PageMode::UseOutlines)
772 .non_full_screen_page_mode(NonFullScreenPageMode::UseThumbs)
773 .direction(Direction::R2L)
774 .print_scaling(PrintScaling::None)
775 .duplex(Duplex::DuplexFlipLongEdge)
776 .num_copies(2)
777 .pick_tray_by_pdf_size(true)
778 .add_print_page_range(1, 10);
779
780 prefs.view_area = Some("MediaBox".to_string());
781 prefs.view_clip = Some("CropBox".to_string());
782 prefs.print_area = Some("BleedBox".to_string());
783 prefs.print_clip = Some("TrimBox".to_string());
784
785 let dict = prefs.to_dict();
786
787 assert!(dict.contains_key("HideToolbar"));
789 assert!(dict.contains_key("HideMenubar"));
790 assert!(dict.contains_key("HideWindowUI"));
791 assert!(dict.contains_key("FitWindow"));
792 assert!(dict.contains_key("CenterWindow"));
793 assert!(dict.contains_key("DisplayDocTitle"));
794 assert!(dict.contains_key("PageLayout"));
795 assert!(dict.contains_key("PageMode"));
796 assert!(dict.contains_key("NonFullScreenPageMode"));
797 assert!(dict.contains_key("Direction"));
798 assert!(dict.contains_key("ViewArea"));
799 assert!(dict.contains_key("ViewClip"));
800 assert!(dict.contains_key("PrintArea"));
801 assert!(dict.contains_key("PrintClip"));
802 assert!(dict.contains_key("PrintScaling"));
803 assert!(dict.contains_key("Duplex"));
804 assert!(dict.contains_key("PrintPageRange"));
805 assert!(dict.contains_key("NumCopies"));
806 assert!(dict.contains_key("PickTrayByPDFSize"));
807 }
808}