// Rolltext wie bei
STAR WARS Filmen: // Getestet mit D2010 unter Win7
// Achtung! type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SWRoll(moveY: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const
txt =
'Es war an einem kalten Dezemberabend'#13 +
'als ein kleiner, dicker Programmierer'#13 +
'unbedingt den Rolltext von STAR WARS'#13 +
'programmieren wollte. Damit er nicht'#13 +
'das Fahrrad ein zweites Mal erfinden'#13 +
'musste, suchte er im Netz nach einem'#13 +
'Beispiel. Der Quelltext von Phillip'#13 +
'Crocoll aus dem Jahr 1999 wurde somit'#13 +
'die Vorlage für das, was gerade vor'#13 +
'Ihren Augen abläuft. Allerdings hat der'#13 +
'kleine, dicke Programmierer einiges'#13 +
'dazu getan.';
type
TripleArray = array [0 .. 0] of TRGBTriple;
PTriple = ^TripleArray;
var
sz: TSize;
m: TRGBTriple;
sl: TStringlist;
StarBack: TBitmap;
Hlp, Source: TBitmap;
arroi: array of Integer;
mg1, mg2, sw2, mLft: Single;
p1, r1, r2, srcCoord: TPoint;
DR, DG, DB, sh, Tp, SnZ, StY: Integer;
FontColor: TColor = clYellow;
GroundColor: TColor = clBlack;
procedure TForm1.SWRoll(moveY: Integer);
var
param, startX, stopX: Single;
xc, yc: Integer;
HlpTP, SrcTP: PTriple;
begin
BitBlt(Hlp.Canvas.Handle, 0, 0, StarBack.Width, StarBack.Height,
StarBack.Canvas.Handle, 0, 0, srcCopy);
startX := (Hlp.Width - Tp) / 2;
stopX := Hlp.Width - startX;
for yc := 1 to Hlp.Height - 1 do
begin
startX := startX + mLft;
stopX := stopX - mLft;
r2.y := StY - yc;
param := (p1.y * r2.x - p1.x * r2.y) / (r1.x * r2.y - r1.y * r2.x);
srcCoord.y := Source.Height - Round(Source.Height * param) + moveY;
if (srcCoord.y <= 0) or (srcCoord.y >= Source.Height) then
continue;
SrcTP := Source.ScanLine[srcCoord.y];
HlpTP := Hlp.ScanLine[yc];
for xc := Round(startX) to Round(stopX) do
begin
srcCoord.x := Round((xc - startX) / (stopX - startX) * Source.Width);
if (srcCoord.x > 0) and (srcCoord.x < Source.Width) then
begin
if (SrcTP[srcCoord.x].rgbtBlue <> m.rgbtBlue) or
(SrcTP[srcCoord.x].rgbtGreen <> m.rgbtGreen) or
(SrcTP[srcCoord.x].rgbtRed <> m.rgbtRed) then
begin
HlpTP[xc].rgbtRed := Round(m.rgbtRed + (DR * yc / sh));
HlpTP[xc].rgbtGreen := Round(m.rgbtGreen + (DG * yc / sh));
HlpTP[xc].rgbtBlue := Round(m.rgbtBlue + (DB * yc / sh));
end;
end;
end;
end;
end;
// maximale Schriftbreite
function breadth(Cnv: TCanvas): Integer;
var
i: Integer;
begin
setlength(arroi, sl.Count);
result := 0;
for i := 0 to sl.Count - 1 do
begin
sz := Cnv.TextExtent(sl[i]);
arroi[i] := sz.cx;
if sz.cx > result then
result := sz.cx;
end;
end;
// Lesbarkeit verbessern
procedure SetFontAlias(Font: TFont);
var
LogFont: TLogFont;
begin
try
if GetObject(Font.Handle, SizeOf(TLogFont), @LogFont) = 0 then
exit;
LogFont.lfQuality := NONANTIALIASED_QUALITY;
Font.Handle := CreateFontIndirect(LogFont);
except
end;
end;
// Blocksatz
procedure justifiedPrint(Cnv: TCanvas; Tp, Wdth: Integer);
var
i, z, b, d, lr, x, w: Integer;
p: PChar;
s, g: string;
begin
SetFontAlias(Cnv.Font);
b := Cnv.Textwidth(#32);
for i := 0 to sl.Count - 1 do
begin
z := 0;
p := @sl[i][1];
while p^ <> #0 do
begin
if p^ = #32 then
inc(z);
inc(p);
end;
if ((z < 2) // weniger als 3 Worte pro Zeile
and (arroi[i] < Wdth * 0.9)) or (z = 0) then
Cnv.textout((Wdth - arroi[i]) div 2, i * sz.cy + Tp, sl[i])
else
begin
g := sl[i];
w := 0;
d := Trunc((Wdth - arroi[i] + z * b) / z);
for x := 0 to z - 1 do
begin
lr := pos(#32, g);
s := copy(g, 1, lr - 1);
Cnv.textout(w, i * sz.cy + Tp, s);
inc(w, d + Cnv.Textwidth(s));
delete(g, 1, lr);
end;
Cnv.textout(w, i * sz.cy + Tp, g);
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i, x, y: Integer;
b, RCF, GCF, BCF: byte;
begin
DoubleBuffered := true;
Hlp := TBitmap.Create;
Hlp.LoadFromFile('DELPHI.bmp'); // Logo
// Hlp.Handle := loadbitmap(hinstance, 'DELPHI');
Hlp.TransparentColor := clBlack;
Hlp.Transparent := true;
Source := TBitmap.Create;
Source.PixelFormat := pf24bit;
sl := TStringlist.Create;
sl.Text := txt;
with Source do
begin
Canvas.brush.color := GroundColor;
Canvas.Font.color := FontColor;
Canvas.Font.Name := 'Arial';
Canvas.Font.Size := 17;
Canvas.Font.Style := [fsBold];
Width := breadth(Canvas);
Height := sz.cy * sl.Count + Hlp.Height;
Canvas.Draw((Width - Hlp.Width) div 2, 0, Hlp); // Logo
justifiedPrint(Canvas, Hlp.Height, Width);
end;
sh := Source.Height div 2 + 50; // kann beliebig variieren
inc(sh, ord(odd(sh)));
with Image1 do
begin
AutoSize := true;
with Picture.Bitmap, Canvas do
begin
brush.color := GroundColor;
Width := Source.Width;
Height := sh;
end;
end;
GroundColor := ColorToRGB(GroundColor);
FontColor := ColorToRGB(FontColor);
m.rgbtRed := GetRValue(GroundColor);
m.rgbtGreen := GetGValue(GroundColor);
m.rgbtBlue := GetBValue(GroundColor);
// --- einfacher Sternenhimmel ---
StarBack := TBitmap.Create;
StarBack.Canvas.brush.color := GroundColor;
StarBack.Width := Source.Width;
StarBack.Height := sh;
for i := 0 to Trunc(sqrt(StarBack.Height * sh)) do
begin
b := Random(2) * $FF;
with StarBack.Canvas do
begin
x := Random(StarBack.Width);
y := Random(StarBack.Height);
SetPixel(Handle, x, y, RGB(255, 255, b));
end;
end;
Image1.Canvas.Draw(0, 0, StarBack);
// -------------------------------
Hlp.Transparent := false;
Hlp.Width := Source.Width;
Hlp.Height := sh;
Hlp.PixelFormat := Source.PixelFormat;
sw2 := Source.Width / 2;
mg1 := 1 / (sw2 + Source.Height);
mg2 := 1 / sw2;
SnZ := Round(Hlp.Height / (mg1 - mg2));
StY := Round(mg1 * SnZ);
Tp := Round(Hlp.Width * Source.Width / (sw2 + Source.Height) / 2);
p1.x := Source.Width div 2;
p1.y := 1;
r1.x := Source.Height;
r1.y := 0;
r2.x := SnZ;
mLft := (Tp - Hlp.Width) / 2 / Hlp.Height;
RCF := GetRValue(FontColor);
GCF := GetGValue(FontColor);
BCF := GetBValue(FontColor);
DR := RCF - m.rgbtRed;
DG := GCF - m.rgbtGreen;
DB := BCF - m.rgbtBlue;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
arroi := nil;
StarBack.Free;
Source.Free;
Hlp.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
tense: Cardinal;
begin
Button1.Enabled := false;
for i := -Source.Height to Source.Height do
begin
SWRoll(i);
with Image1.Canvas do
Draw(0, 0, Hlp);
tense := Gettickcount + 55;
repeat
Application.ProcessMessages;
if Application.Terminated then
exit;
until Gettickcount >= tense;
end;
Button1.Enabled := true;
end;
|
Zugriffe seit 6.9.2001 auf Delphi-Ecke





