![]() // 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