11use super :: test_support:: { make_simple_document, make_test_png} ;
22use super :: * ;
33use crate :: ir:: * ;
4+ use std:: collections:: BTreeMap ;
45
56#[ test]
67fn test_render_document_empty_document ( ) {
@@ -259,6 +260,140 @@ fn test_render_document_image_mixed_with_text() {
259260 assert ! ( pdf. starts_with( b"%PDF" ) ) ;
260261}
261262
263+ #[ test]
264+ fn test_render_document_fixed_textbox_ordered_list_keeps_all_numbers ( ) {
265+ let doc = Document {
266+ metadata : Metadata :: default ( ) ,
267+ pages : vec ! [ Page :: Fixed ( FixedPage {
268+ size: PageSize {
269+ width: 780.0 ,
270+ height: 540.0 ,
271+ } ,
272+ elements: vec![ FixedElement {
273+ x: 300.0 ,
274+ y: 200.0 ,
275+ width: 260.0 ,
276+ height: 160.0 ,
277+ kind: FixedElementKind :: TextBox ( TextBoxData {
278+ content: vec![ Block :: List ( List {
279+ kind: ListKind :: Ordered ,
280+ items: vec![
281+ ListItem {
282+ content: vec![ Paragraph {
283+ style: ParagraphStyle {
284+ indent_left: Some ( 36.0 ) ,
285+ indent_first_line: Some ( -36.0 ) ,
286+ ..ParagraphStyle :: default ( )
287+ } ,
288+ runs: vec![ Run {
289+ text: "Alpha" . to_string( ) ,
290+ style: TextStyle {
291+ font_size: Some ( 20.0 ) ,
292+ ..TextStyle :: default ( )
293+ } ,
294+ href: None ,
295+ footnote: None ,
296+ } ] ,
297+ } ] ,
298+ level: 0 ,
299+ start_at: Some ( 1 ) ,
300+ } ,
301+ ListItem {
302+ content: vec![ Paragraph {
303+ style: ParagraphStyle {
304+ indent_left: Some ( 36.0 ) ,
305+ indent_first_line: Some ( -36.0 ) ,
306+ ..ParagraphStyle :: default ( )
307+ } ,
308+ runs: vec![ Run {
309+ text: "Beta" . to_string( ) ,
310+ style: TextStyle {
311+ font_size: Some ( 20.0 ) ,
312+ ..TextStyle :: default ( )
313+ } ,
314+ href: None ,
315+ footnote: None ,
316+ } ] ,
317+ } ] ,
318+ level: 0 ,
319+ start_at: None ,
320+ } ,
321+ ListItem {
322+ content: vec![ Paragraph {
323+ style: ParagraphStyle {
324+ indent_left: Some ( 36.0 ) ,
325+ indent_first_line: Some ( -36.0 ) ,
326+ ..ParagraphStyle :: default ( )
327+ } ,
328+ runs: vec![ Run {
329+ text: "Gamma" . to_string( ) ,
330+ style: TextStyle {
331+ font_size: Some ( 20.0 ) ,
332+ ..TextStyle :: default ( )
333+ } ,
334+ href: None ,
335+ footnote: None ,
336+ } ] ,
337+ } ] ,
338+ level: 0 ,
339+ start_at: None ,
340+ } ,
341+ ] ,
342+ level_styles: BTreeMap :: from( [ (
343+ 0 ,
344+ ListLevelStyle {
345+ kind: ListKind :: Ordered ,
346+ numbering_pattern: Some ( "1." . to_string( ) ) ,
347+ full_numbering: false ,
348+ marker_text: None ,
349+ marker_style: None ,
350+ } ,
351+ ) ] ) ,
352+ } ) ] ,
353+ padding: Insets :: default ( ) ,
354+ vertical_align: TextBoxVerticalAlign :: Top ,
355+ fill: None ,
356+ opacity: None ,
357+ stroke: None ,
358+ shape_kind: None ,
359+ no_wrap: false ,
360+ auto_fit: false ,
361+ } ) ,
362+ } ] ,
363+ background_color: None ,
364+ background_gradient: None ,
365+ } ) ] ,
366+ styles : StyleSheet :: default ( ) ,
367+ } ;
368+
369+ let pdf = render_document ( & doc) . unwrap ( ) ;
370+ let text = pdf_extract:: extract_text_from_mem ( & pdf) . unwrap ( ) ;
371+ assert ! (
372+ text. contains( "1." ) ,
373+ "Expected first marker in PDF text, got:\n {text}" ,
374+ ) ;
375+ assert ! (
376+ text. contains( "2." ) ,
377+ "Expected second marker in PDF text, got:\n {text}" ,
378+ ) ;
379+ assert ! (
380+ text. contains( "3." ) ,
381+ "Expected third marker in PDF text, got:\n {text}" ,
382+ ) ;
383+ assert ! (
384+ text. contains( "Alpha" ) ,
385+ "Expected first item text, got:\n {text}"
386+ ) ;
387+ assert ! (
388+ text. contains( "Beta" ) ,
389+ "Expected second item text, got:\n {text}"
390+ ) ;
391+ assert ! (
392+ text. contains( "Gamma" ) ,
393+ "Expected third item text, got:\n {text}"
394+ ) ;
395+ }
396+
262397#[ test]
263398fn test_render_document_with_system_font_in_ir ( ) {
264399 let doc = Document {
@@ -585,6 +720,7 @@ fn test_render_pptx_style_document_size() {
585720 stroke: None ,
586721 shape_kind: None ,
587722 no_wrap: false ,
723+ auto_fit: false ,
588724 } ) ,
589725 } ] ,
590726 } ) ) ;
@@ -644,6 +780,7 @@ fn test_render_document_with_centered_fixed_text_box() {
644780 stroke: None ,
645781 shape_kind: None ,
646782 no_wrap: false ,
783+ auto_fit: false ,
647784 } ) ,
648785 } ] ,
649786 } ) ] ,
@@ -656,3 +793,69 @@ fn test_render_document_with_centered_fixed_text_box() {
656793 "Centered fixed text box should compile to a valid PDF"
657794 ) ;
658795}
796+
797+ #[ test]
798+ fn test_render_document_with_auto_fit_fixed_text_box ( ) {
799+ let doc = Document {
800+ metadata : Metadata :: default ( ) ,
801+ pages : vec ! [ Page :: Fixed ( FixedPage {
802+ size: PageSize {
803+ width: 300.0 ,
804+ height: 200.0 ,
805+ } ,
806+ background_color: None ,
807+ background_gradient: None ,
808+ elements: vec![ FixedElement {
809+ x: 20.0 ,
810+ y: 20.0 ,
811+ width: 150.0 ,
812+ height: 22.0 ,
813+ kind: FixedElementKind :: TextBox ( TextBoxData {
814+ content: vec![ Block :: Paragraph ( Paragraph {
815+ style: ParagraphStyle {
816+ alignment: Some ( Alignment :: Right ) ,
817+ ..ParagraphStyle :: default ( )
818+ } ,
819+ runs: vec![
820+ Run {
821+ text: "3. 시스템 연동 방안 " . to_string( ) ,
822+ style: TextStyle {
823+ font_size: Some ( 28.0 ) ,
824+ bold: Some ( true ) ,
825+ ..TextStyle :: default ( )
826+ } ,
827+ href: None ,
828+ footnote: None ,
829+ } ,
830+ Run {
831+ text: "클라우드 기반 업무 시스템 연동" . to_string( ) ,
832+ style: TextStyle {
833+ font_size: Some ( 16.0 ) ,
834+ bold: Some ( true ) ,
835+ ..TextStyle :: default ( )
836+ } ,
837+ href: None ,
838+ footnote: None ,
839+ } ,
840+ ] ,
841+ } ) ] ,
842+ padding: Insets :: default ( ) ,
843+ vertical_align: TextBoxVerticalAlign :: Top ,
844+ fill: None ,
845+ opacity: None ,
846+ stroke: None ,
847+ shape_kind: None ,
848+ no_wrap: false ,
849+ auto_fit: true ,
850+ } ) ,
851+ } ] ,
852+ } ) ] ,
853+ styles : StyleSheet :: default ( ) ,
854+ } ;
855+
856+ let pdf = render_document ( & doc) . unwrap ( ) ;
857+ assert ! (
858+ pdf. starts_with( b"%PDF" ) ,
859+ "Auto-fit fixed text box should compile to a valid PDF"
860+ ) ;
861+ }
0 commit comments