Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - TextWidth gibt mir falsche Werte


EPS - Mi 28.06.06 10:28
Titel: TextWidth gibt mir falsche Werte
Hi zusammen. Ich hab ein kleines Problem mit meiner DLL. Diese soll einen String entgegennehmen, diesen in der angegebenen Schriftart in ein Bild schreiben und dieses Speichern. Zur Auswahl steht dabei ebenfalls ob der String AntiAliasing hat oder nicht.

Das erzeugte Bild soll dabei exakt so groß sein wie es nötig ist und da kommt das Problem. Sobald der Text Kursiv dargestellt wird rechnet TextWidth falsch, bzw. gibt mir die Werte nicht für Kursiven Text sondern für "normalen" zurück - jedenfalls scheint es so. Dadurch ergibt sich aber das, z.B. beim Buchstaben "W", der obere rechte Teil des Buchstabens aus dem Bildrand entschwindet.

Hier erst einmal mein bisheriger Code:


Delphi-Quelltext
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:
function AA_String( Text, FontName:String; Height, FontAttrib:Integer; AntiAliasing:Bool ): integer; stdcall;
var
      LogFont     :     TLogFont;
      Image1      :     TBitmap;
      FontStyle   :     TFontStyles;
begin
      Text := LeftStr( Text, Pos( CHR(0), Text ) - 1 );
      Image1 := TBitmap.Create;

      with Image1.Canvas do begin

              Font.Name := FontName;
              Font.Height := Height;

              FontStyle := [];
              if (FontAttrib and 1) = 1 then FontStyle := FontStyle + [fsBold];
              if (FontAttrib and 2) = 2 then FontStyle := FontStyle + [fsItalic];
              if (FontAttrib and 4) = 4 then FontStyle := FontStyle + [fsUnderline];
              if (FontAttrib and 8) = 8 then FontStyle := FontStyle + [fsStrikeout];

              Font.Style := FontStyle;
              Image1.Width := 2048;
              Image1.Height := Height;

              if AntiAliasing then
              begin
                 GetObject(Font.Handle, SizeOf(LogFont), @LogFont);
                 LogFont.lfQuality := ANTIALIASED_QUALITY;
                 Font.Handle := CreateFontIndirect(LogFont);
              end;

              Image1.Width := TextWidth( Text );
              TextOut( 00, Text );
              Image1.SaveToFile( 'test.bmp' );

      end;
      Result := 1;
end;


Zur Funktionsweise: Ich erzeuge ein etwas größeres Bild, schreibe den Text rein und möchte das Bild danach auf die nötigen Maße zurechtschneiden um es zu speichern. Wundert euch bitte nicht über Sachen wie die Auswertung des FontAttrib, das hat was mit dem Programm zu tun welches die DLL später mal nutzen soll.

Hat jemand ne Idee wie man das Problem sonst noch lösen könnte, abgesehen von ner Scanline Routine?

Vielen Dank schon einmal.

Moderiert von user profile iconjasocul: Code-Tags durch Delphi-Tags ersetzt


smiegel - Mi 28.06.06 10:42

Hallo,

schau Dir einmal die API-Funktionen GetFontData und GetCharABCWidths an. Vielleicht helfen die Dir weiter.


Kroko - Mi 28.06.06 11:27

Ich nehme diese Proc, die funktionert mit fett und kursiv

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
{--------------------------------}
{ berechnet Textbreite und -höhe }
{--------------------------------}
function CalcTextExtent (const DC: HDC; const Text: String): TSize;
var 
  R: TRect;
begin
  SetRectEmpty(R);
  DrawText(DC, PChar(Text), Length(Text), R, dt_CalcRect);
  Result.cx := R.Right-R.Left;
  Result.cy := R.Bottom-R.Top;
end;


EPS - Mi 28.06.06 11:35

Vielen Dank euch beiden, Der Tipp von smiegel hat mir schon weiter geholfen, aber ich werd das andere auch mal antesten.

Auf jeden Fall ist das Problem gelöst :)