2012-07-29 21 views
5

Prima di tutto, domanda How to measure width of character precisely? a cui viene data risposta, non è di grande aiuto per questo caso, quindi non si tratta di un duplicato di quello.come misurare con precisione la larghezza di una stringa?

Ho una stringa. Disegno utilizzando graphics.DrawString, tuttavia quando ho bisogno di metterne un altro dopo, ho bisogno di conoscere la larghezza precisa della stringa precedente.

Per questo uso graphics.MeasureString con:

StringFormat format = new StringFormat(StringFormat.GenericTypographic); 
format.Alignment = StringAlignment.Center; 
format.Trimming = StringTrimming.None; 
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

Ho provato molte altre funzioni, come TextRendered.MeasureText tuttavia tutti loro sicuro, con tutte le possibili combinazioni di parametri.

la combinazione menzionata di MeasureString è la più vicina a ciò di cui ho bisogno (funziona nella maggior parte dei casi, ad eccezione di caratteri speciali), tuttavia l'utilizzo di caratteri come # lo interrompe. La larghezza è più breve o più lunga.

C'è un modo per ottenere una dimensione precisa del testo prodotta dalla funzione DrawString? In che modo DrawString calcola la dimensione dell'area di disegno? Deve essere chiaramente un'altra funzione perché le dimensioni differiscono sempre.

Il codice sorgente di tutta l'applicazione è qui https://gitorious.org/pidgeon/pidgeon-main/ (File dove lavoro con questo, è https://gitorious.org/pidgeon/pidgeon-main/blobs/master/scrollback/SBABox.cs)

+0

possibile duplicato ([Come misurare la larghezza in pixel della stringa drawed su Drawing.Bitmap in .NET?] http://stackoverflow.com/questions/2555739/how-to-measure-the-pixel-width-of-the-string-drawed-over-drawing-bitmap-in-net) –

+0

se la domanda chiaramente non ha detto MeasureString non funziona, sarebbe duplicato – Petr

+0

Senza una descrizione migliore di come e quando "non funziona" e il codice che include MeasureString e DrawString insieme, questa non è una vera domanda. Vieni con una piccola testina. –

risposta

7

Hai solo bisogno di eliminare la larghezza supplementare. È possibile farlo utilizzando string format:

GdipStringFormatGetGenericTypographic() 

Si potrebbe anche usare:

float doubleWidth = g.MeasureString(text+text,...).Width; 
float singleWidth = g.MeasureString(text).Width; 
float textWidth = doubleWidth-singleWidth; 

Questo vi permetterà di lavorare con altre lingue come il giapponese.

On codeproject, la soluzione di Pierre Anaud era quello di utilizzare MeasureCharacterRanges, che restituisce una regione corrispondente esattamente la casella di delimitazione della stringa specificata:

static public int MeasureDisplayStringWidth(Graphics graphics, string text, Font font) 
{ 
    System.Drawing.StringFormat format = new System.Drawing.StringFormat(); 
    System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000); 
    var ranges = new System.Drawing.CharacterRange(0, text.Length); 
    System.Drawing.Region[] regions = new System.Drawing.Region[1]; 

    format.SetMeasurableCharacterRanges (ranges); 

    regions = graphics.MeasureCharacterRanges (text, font, rect, format); 
    rect = regions[0].GetBounds (graphics); 

    return (int)(rect.Right + 1.0f); 
} 
+0

sembrava funzionare fino a quando ho trovato alcuni problemi con il formato, quando l'ho risolto, l'intera funzione ha appena iniziato a restituire lo stesso valore errato di MeasureString ... – Petr

+1

funziona bene ... l'unica correzione è quella linea: ** formato. SetMeasurableCharacterRanges (new CharacterRange [] {ranges}); ** – ymz

1

tenta di utilizzare questa modalità:

GDI+ (graphics.MeasureString and graphics.DrawString) >> System.Drawing.Graphics 
GDI (TextRenderer.MeasureText and TextRenderer.DrawText) 

Può anche aiutare:

Scrivete un metodo misura personalizzato:

  • Split stringa di entrata in caratteri speciali
  • Usa sopra i metodi .net
  • Calcolare la larghezza di caratteri speciali e somma ...

Read Ian Boyd answer

2

Sono un po 'in ritardo per la festa qui, ma stavo cercando di fare qualcosa di simile e sono incappato in questa domanda.Probabilmente avete già visto la seguente osservazione da the documentation for the Graphics.MeasureString method on MSDN:

Il metodo MeasureString è progettato per l'uso con singole stringhe e include una piccola quantità di spazio in più, prima e dopo la stringa per consentire a strapiombo glifi. Inoltre, il metodo DrawString regola i punti del glifo per ottimizzare la qualità della visualizzazione e potrebbe visualizzare una stringa più stretta di quella riportata da MeasureString. Per ottenere le metriche adatte alle stringhe adiacenti nel layout (ad esempio, quando si implementa il testo formattato), utilizzare il metodo MeasureCharacterRanges o uno dei metodi MeasureString che prende uno StringFormat e passare GenericTypographic. Inoltre, assicurati che lo TextRenderingHint per lo Graphics sia AntiAlias.

Sembra che si stava tentando di seguire questo consiglio perché si sta utilizzando StringFormat.GenericTypographic come punto di partenza per il vostro oggetto personalizzato StringFormat. Tuttavia, la linea

format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

nega in modo efficace il fatto che si è iniziato con StringFormat.GenericTypographic perché cancella eventuali bandiere precedentemente impostati. Quello che probabilmente si intende fare è impostare il flag StringFormatFlags.MeasureTrailingSpaces preservando le altre bandiere, in questo modo:

format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; 
Problemi correlati