1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
#!perl use strict; use warnings; use SDL; use SDLx::App; use SDLx::Text; use SDLx::Rect; use SDL::Event; use SDL::Events; use Data::Dumper qw/Dumper/; =comment Breche einen Text in einem Rect so um, dass er passt. Wenn der Text länger als die erlaubte Breite ist, dann soll er überstehen. =cut my $app = SDLx::App->new( title => 'text wrap', exit_on_quit => 1, ); my $string = 'blabla blablabla blabla-blablablabla iica blablablablablablablabla'; my $rect = SDLx::Rect->new(10, 10, 200, 60); my $text = SDLx::Text->new( text => $string, color => 0xFFFFFFFF, h_align => 'center', ); $app->draw_rect($rect, 0xC0C0C0FF); my $text_width = $text->w; my $rect_width = $rect->w; print "text-width: $text_width\n"; print "rect-width: $rect_width\n"; my $max_width = $rect->w; # maximale Breite des Textes my @rows = (); # für die einzelnen Zeilen, die in die Box geschrieben werden if( $text_width <= $rect_width ) { # Der Text passt wunderbar in die Box. Es ist nichts weiter zu tun. push @rows, $string; }else{ # Der Text passt nicht genau rein, also muss er umgebrochen werden. my @chunks = split(m/\s+/, $string); my $current_fragment = ''; my $current_text = SDLx::Text->new(); foreach my $single_chunk ( @chunks ) { my $test = $current_fragment; if($current_fragment eq '' ) { $test = $single_chunk; }else{ $test = $current_fragment . ' ' . $single_chunk; }; # mach einen SDLx::Text daraus $current_text->text($test); if( $current_text->w > $max_width ) { if( $current_fragment eq '' ) { # Es handelt sich um einen Text, der breiter ist, als die Box. # Der wird trotzde, gezeichnet, es kommt aber sonst nichts mehr # in die Zeile. push @rows, $test; }else{ # Der Text ist zuzüglich des neuen Stückchens zu breit. # Das vorherige wird eine Zeile und das neue Stück wird in die # nächste Zeile geschoben. push @rows, $current_fragment; $current_fragment = $single_chunk; } }else{ # Die Zeile ist noch nicht voll. Auf zur nächsten Iteration! $current_fragment = $test; } printf("width: %s\n", $current_text->w); } # wenn jetzt noch etwas in $current_fragment steht, dann ist dieser Text # kürzer als die maximale Textbreite und kommt einfach in eine neue Zeile. if( $current_fragment ne '' ) { push @rows, $current_fragment; $current_fragment = ''; } print Dumper \@rows; } # -- Die Box muss jetzt entsprechend der Zeilen in der Höhe angepasst werden. my $line_spacing = 2; my $row_height = $text->h; print "row-height: $row_height\n"; my $box_height = scalar(@rows) * ($row_height + $line_spacing) + $line_spacing; # neue Box zeichnen $rect = SDLx::Rect->new($rect->left, $rect->top, $rect->width, $box_height); $app->draw_rect($rect, 0x87cefaFF); my ($x,undef) = $rect->center(); # Jede Zeile schreiben foreach (my $i = 0; $i <= $#rows; $i++ ) { my $single_row = $rows[$i]; my $y = ($row_height * ($i+1)) + ($line_spacing * $i); printf("<%s, %s>\n", $x, $y); $text->write_xy($app, $x, int($y - $row_height / 2), $single_row); } $app->update(); $app->run(); exit(0);
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!perl use strict; use warnings; use SDL; use SDLx::App; use SDLx::Text; my $text = SDLx::Text->new(); for( qw/a w c Z/ ) { printf("Breite: %s\n", $text->text($_)->w); } exit(0);
QuoteBreite: 11
Breite: 17
Breite: 11
Breite: 13