Thread [SDL] Textumbruch bei gegebener Breite
(2 answers)
Opened by pktm at 2012-01-16 17:26
Hallo!
Ich möchte gerne in SDL eine Box (SDLx::Rect) mit fester Breite und variabler Höhe erzeugen und da Text hinein schreiben. Der Text soll automatisch umbrechen, wenn er zu Breit für die Box wird. Da ich keine Möglichkeit gefunden habe, wie mir SDL das abnehmen könnte, habe ich mir selbst etwas geschrieben und hätte dazu gerne Meinungen. Eventuell kann man ja etwas richtig schön besser machen. Hier der Code: Code (perl): (dl
)
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); Eventuell hat jemand was im Peto, das die Aufteilung der Zeichenkette besser macht? Im Moment wird bei Leerzeichen aufgeteilt, wobei die Anzahl der Leerzeichen und die Leerzeichen selbst verloren gehen. Schön wäre, wenn auch bei Bindestrichen geteilt würde, so dass der Bildestrich am ersten Wortteil dran bleibt. Aus 'Baum-Haus' soll also 'Baum-' und 'Haus' werden. Mal sehen was so kommt. Oder gibt es das eventuell scon irgendwo fertig? Grüße, pktm http://www.intergastro-service.de (mein erstes CMS :) )
|