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:
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
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;
my @rows = ();
if( $text_width <= $rect_width ) {
push @rows, $string;
}else{
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;
};
$current_text->text($test);
if( $current_text->w > $max_width ) {
if( $current_fragment eq '' ) {
push @rows, $test;
}else{
push @rows, $current_fragment;
$current_fragment = $single_chunk;
}
}else{
$current_fragment = $test;
}
printf("width: %s\n", $current_text->w);
}
if( $current_fragment ne '' ) {
push @rows, $current_fragment;
$current_fragment = '';
}
print Dumper \@rows;
}
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;
$rect = SDLx::Rect->new($rect->left, $rect->top, $rect->width, $box_height);
$app->draw_rect($rect, 0x87cefaFF);
my ($x,undef) = $rect->center();
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