2008-09-23 6 views
16

Ich benutze GDI + in C++. (Dieses Problem kann auch in C# vorkommen).MeasureString() puffert den Text auf der linken und rechten Seite

Ich stelle fest, dass, wenn ich Graphics :: MeasureString() oder Graphics :: DrawString() aufrufen, die Zeichenfolge mit Leerzeichen links und rechts aufgefüllt wird.

Zum Beispiel, wenn ich eine Courier Schriftart verwende, (nicht kursiv!) Und ich "P" erhalte ich 90, aber "PP" gibt mir 150. Ich würde erwarten, dass eine Monospace-Schriftart genau die doppelte Breite gibt für "PP".

Meine Frage ist: ist das beabsichtigte oder dokumentierte Verhalten, und wie deaktiviere ich das?

RectF Rect(0,0,32767,32767); 
RectF Bounds1, Bounds2; 
graphics->MeasureString(L"PP", 1, font, Rect, &Bounds1); 
graphics->MeasureString(L"PP", 2, font, Rect, &Bounds2); 
margin = Bounds1.Width * 2 - Bounds2.Width; 

Antwort

11

Es ist durch Design, das Verfahren verwendet nicht die tatsächlichen Glyphen die Breite zu messen und fügt so eine wenig Polsterung im Fall von Überhängen.

MSDN schlägt eine andere Methode verwenden, wenn Sie eine höhere Genauigkeit benötigen:

Um Metriken geeignet für benachbarte Strings in dem Layout zu erhalten (zum Beispiel, wenn formatierten Text Implementierung), verwenden Sie die MeasureCharacterRanges Methode oder eine der MeasureString Methoden, die eine StringFormat nehmen und GenericTypographic übergeben. Stellen Sie außerdem sicher, dass die TextRenderingHint für die GraphicsAntiAlias ist.

6

Es stimmt, dass durch Design ist jedoch der Link auf der akzeptierte Antwort eigentlich nicht perfekt ist. Das Problem ist die Verwendung von Gleitkommazahlen in all diesen Methoden, wenn das, was Sie wirklich verwenden möchten, Pixel (Ints) ist.

Die TextRenderer class ist für diesen Zweck gedacht und funktioniert mit den wahren Größen. Sehen Sie diese link from msdn für eine exemplarische Vorgehensweise.

+0

Ich bekomme bessere Ergebnisse mit TextRenderer-Klasse. – Bitterblue

+0

TextRenderer war genau das, was ich in einer ähnlichen Situation brauchte – Rob

+0

TextRenderer arbeitete auch viel besser für mich – Migs

0

TextRenderer war großartig für die Größe der Schriftart. Aber in der Zeichnungsschleife war die Verwendung von TextRenderer.DrawText im Vergleich zu graphics.DrawString() unerträglich langsam.

Da die Breite eines Strings ist das Problem, Ihre viel besser eine Kombination aus TextRenderer.MeasureText und Graphics.DrawString ..

5

Anfügen StringFormat.GenericTypographic Ihr Problem beheben wird mit:

graphics->MeasureString(L"PP", 1, font, width, StringFormat.GenericTypographic); 

Bewerben das gleiche Attribut zu DrawString.

+0

GenericTypographic ist ideal für mich, weil ich sowieso meine eigene Marge in der Steuerung verwende. –

+0

Fast perfekt, aber die kleinen Polsterungen sind notwendig. – Slappy