// Mit dem folgenden Code kann man Text auf einer Zeichenfläche (TCanvas)
// ausgeben, welcher mit einem Schatten hinterlegt ist.

// Getestet mit D4 unter XP

//
Variante 1:

// Die Ausgabe kann nur auf einfarbigen Flächen geschehen, da der Einfachheit
// halber nicht nur der Schatten unscharf dargestellt wird, sondern auch der
// Hintergrund, welcher von Schrift und Schatten belegt ist. Aus diesem Grund
// dürfen sich die Schattenschriften auch nicht überlagern. Die Schrift kann
// einfarbig gestaltet sein, oder für jeden
(bzw. für mehrere) Buchstaben
// unterschiedliche Farben haben.

 

 

type 
  unschaerfe = 0..20; 
 
function SchattenSchrift 
  (cnv: TCanvas; txt, fontname: string; fontsize: integer; 
  fontstyle: TFontstyles; x, y, xversatz, yversatz: integer; 
  fontfarbe: array of TColor; schattenfarbe: TColor; 
  unscharf: unschaerfe; var rct: TRect): boolean; 
var 
  sz: TSize; 
  bm: TBitmap; 
  p: array[0..2] of PBytearray; 
  xv, yv, i, j, k, w, z, li, lg, ob, vd2, txtl, txto: integer; 
begin 
  result := false; 
  lg := length(fontfarbe); 
  if (lg = 0) or (txt = '') then exit; 
  vd2 := unscharf shr 1; 
  xv := abs(xversatz); 
  yv := abs(yversatz); 
  li := ord(xversatz > 0) * xversatz + vd2 + 1; 
  ob := ord(yversatz > 0) * yversatz; 
  txtl := 1 + vd2 + ord(xversatz < 0) * xv; 
  txto := vd2 + ord(yversatz < 0) * yv; 
  dec(x, txtl); 
  dec(y, txto); 
  bm := TBitmap.create; 
  bm.pixelformat := pf24bit; 
  with bm.canvas do begin 
    font.name := fontname; 
    font.color := schattenfarbe; 
    font.size := fontsize; 
    font.style := fontstyle; 
    sz := Textextent(txt); 
    bm.width := 1 + unscharf + sz.cx + xv; 
    bm.height := 1 + unscharf + sz.cy + yv; 
    brush.style := bsclear; 
    rct := rect(x, y, x + bm.width, y + bm.height); 
    bm.canvas.copyrect(rect(0, 0, bm.width, bm.height), cnv, rct); 
    textout(li, ob + vd2, txt); 
    for k := 1 to unscharf do 
      for j := ob + 1 to ob + sz.cy + vd2 do begin 
        for w := 0 to 2 do 
          p[w] := bm.scanline[j - 1 + w]; 
        for i := li to li + sz.cx - 1 do begin 
          z := i * 3; 
          for w := 0 to 2 do 
            p[1][z + w] := round((p[0][z + w] + p[2][z + w] + 
              p[1][(i - 1) * 3 + w] + p[1][(i + 1) * 3 + w]) / 4); 
        end; 
      end; 
    font.color := fontfarbe[0]; 
    textout(txtl, txto, txt[1]); 
    for i := 1 to length(txt) - 1 do begin 
      if lg > i then font.color := fontfarbe[i]; 
      textout(penpos.x, txto, txt[i + 1]); 
    end; 
  end; 
  cnv.draw(x, y, bm); 
  bm.free; 
  result := true; 
end; 
 

// Beispiel 1 (siehe obige Abbildung) 
 
procedure TForm1.Button6Click(Sender: TObject); 
const 
  bunt: array[0..12] of Tcolor = 
  ($80FF80, $80FF80, $80FF80, clnone, $6699FF, $6699FF, $6699FF, clnone, 
    claqua, claqua, claqua, clnone, clyellow); 
  bunt2: array[0..15] of Tcolor = 
  ($BC, clpurple, $66, clnone, $BC, clpurple, $66, clnone, 
    $BC, clpurple, $66, clnone, $BC, clpurple, $66, $BC); 
  bunt3: array[0..8] of Tcolor = 
  (clyellow, clyellow, clyellow, clnone, clyellow, clyellow, clyellow, clnone, 
    cllime); 
var 
  dummy: TRect; 
begin 
  refresh; 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 20, 3, 3, bunt, clblack, 3, dummy); 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 52, 0, 0, [$E83322], clblue, 7, dummy); 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 80, 7, 7, [clred], $666666, 4, dummy); 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 117, -2, -3, bunt2, $8000FF, 15, dummy); 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 147, -1, -1, bunt3, $334455, 0, dummy); 
  schattenschrift(canvas, 'Das ist ein Test', 'Arial', 14, [fsBold], 
    30, 172, 1, 1, [$FDFDFD], clblack, 0, dummy); 
end; 
 
 

// Beispiel 2 
 
var 
  rct: TRect; 
  links, oben: integer; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  doublebuffered := true; 
  canvas.brush.color := color; 
  Edit1.text := ''; 
  rct := rect(0, 0, 0, 0); 
  links := 10; 
  oben := 20; 
end; 
 
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; 
  Shift: TShiftState); 
begin 
  canvas.fillrect(rct); 
  schattenschrift(canvas, Edit1.text, 'Times New Roman', 12, [fsItalic], 
    links, oben, 2, 2, [clblack], clblue, 2, rct); 
end;


// ---------------------------------------------------------------------


// Variante 2

// Dieser Code ist nicht für fortlaufendes Eintippen
(Beispiel 2 in Variante 1)
// gedacht, sondern nur zur einmaligen Ausgabe. Bunte Schrift muss einzeln
// zusammengesetzt werden. Dafür kann die Schrift aber über Muster und Bilder
// gelegt werden. Durch die Kombination mit dem Hintergrund wird der Schatten
// jedoch etwas blasser. Deshalb darf seine maximale Unschärfe
(im Gegensatz zu
// Variante 1) auch nur den Wert "10" haben. Um die Schrift bei Neuzeichnen
// des Fensters nicht zu verlieren, sollten Sie das Ganze vielleicht in ein
// TImage zeichnen lassen.

 
type 
  unschaerfe = 0..10; 
 
var 
  fontfarbe, schattenfarbe: TColor; 
  schatten, schablone: TBitmap; 
  fontstyle: TFontstyles; 
  fontname, txt: string; 
  fontsize: Integer; 
  sz: TSize; 
 
procedure Einstellungen(cnv: TCanvas; var r, g, b: byte); 
begin 
  with schablone.canvas do begin 
    font.name := fontname; 
    font.size := fontsize; 
    font.style := fontstyle; 
    sz := TextExtent(txt); 
  end; 
  with cnv do begin 
    font.name := fontname; 
    font.color := fontfarbe; 
    font.size := fontsize; 
    font.style := fontstyle; 
    brush.style := bsclear; 
  end; 
  schattenfarbe := colortorgb(schattenfarbe); 
  r := getrvalue(schattenfarbe); 
  g := getgvalue(schattenfarbe); 
  b := getbvalue(schattenfarbe); 
end; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  schatten := TBitmap.create; 
  schatten.pixelformat := pf24bit; 
  schablone := TBitmap.create; 
  schablone.pixelformat := pf24bit; 
  schablone.canvas.font.color := 0; 
  schablone.canvas.brush.color := $FFFFFF; 
  txt := ''; 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  schatten.free; 
  schablone.free; 
end; 
 
procedure schattenschrift 
  (cnv: TCanvas; x, y, xversatz, yversatz: integer; unscharf: unschaerfe); 
var 
  i, j, k, w, z, li, ob, b3: integer; 
  p: array[0..2] of PBytearray; 
  r, g, b: byte; 
begin 
  if txt = '' then exit; 
  Einstellungen(cnv, r, g, b); 
  schablone.width := sz.cx + unscharf shl 1; 
  schablone.height := sz.cy + unscharf shl 1; 
  b3 := schablone.width * 3; 
  with schablone.canvas do begin 
    fillrect(cliprect); 
    textout(unscharf, unscharf, txt); 
  end; 
  for k := 1 to unscharf do 
    for j := 1 to schablone.height - 2 do begin 
      for w := 0 to 2 do 
        p[w] := schablone.scanline[j - 1 + w]; 
      for i := 1 to schablone.width - 2 do begin 
        z := i * 3; 
        for w := 0 to 2 do 
          p[1][z + w] := (p[0][z + w] + p[2][z + w] + 
            p[1][(i - 1) * 3 + w] + p[1][(i + 1) * 3 + w]) shr 2; 
      end; 
    end; 
  schatten.width := schablone.width; 
  schatten.height := schablone.height; 
  li := x + xversatz - unscharf; 
  ob := y + yversatz - unscharf; 
  schatten.canvas.copyrect(rect(0, 0, schatten.width, schatten.height), 
    cnv, rect(li, ob, li + schatten.width, ob + schatten.height)); 
  for j := 0 to schatten.height - 1 do begin 
    p[0] := schatten.scanline[j]; 
    p[1] := schablone.scanline[j]; 
    i := 0; 
    while i < b3 do begin 
      if p[1][i] <> 255 then begin 
        z := round((256 - p[1][i]) * 1.5); 
        w := z + 256; 
        p[0][i] := (p[0][i] shl 8 + z * b) div w; 
        p[0][i + 1] := (p[0][i + 1] shl 8 + z * g) div w; 
        p[0][i + 2] := (p[0][i + 2] shl 8 + z * r) div w; 
      end; 
      inc(i, 3); 
    end; 
  end; 
  cnv.draw(li, ob, schatten); 
  cnv.textout(x, y, txt); 
end; 
 
 
// Beispiel (Bild bei Variante 2) 
 
procedure TForm1.Button4Click(Sender: TObject); 
begin 
  refresh; 
  fontname := 'Arial'; 
  fontsize := 14; 
  fontstyle := [fsBold]; 
  txt := 'Das ist ein Test'; 
  schattenfarbe := clblack; 
  fontfarbe := clred; 
  schattenschrift(canvas, 10, 45, 9, 9, 3); 
  fontfarbe := clblack; 
  schattenfarbe := clyellow; 
  schattenschrift(canvas, 10, 80, 0, 0, 7); 
  schattenfarbe := $FF2211; 
  fontfarbe := $FDFDFD; 
  schattenschrift(canvas, 10, 111, 0, -1, 1); 
  schattenfarbe := clblack; 
  fontfarbe := $80FF80; 
  txt := 'Das '; 
  schattenschrift(canvas, 10, 20, 2, 2, 1); 
  fontfarbe := $6699FF; 
  txt := 'ist '; 
  schattenschrift(canvas, canvas.penpos.x, 20, 2, 2, 1); 
  fontfarbe := claqua; 
  txt := 'ein '; 
  schattenschrift(canvas, canvas.penpos.x, 20, 2, 2, 1); 
  fontfarbe := clyellow; 
  txt := 'Test'; 
  schattenschrift(canvas, canvas.penpos.x, 20, 2, 2, 1); 
end;




 

Zugriffe seit 6.9.2001 auf Delphi-Ecke