Come misurare la larghezza in pixel di una cifra in un carattere determinato / dimensioni (C #)

StackOverflow https://stackoverflow.com/questions/1833062

Domanda

Sto cercando di calcolare la larghezza in pixel delle colonne di Excel, come descritto in questo post , utilizzando la formula ufficiale dalla specifica OpenXML. Tuttavia, al fine di applicare questa formula, ho bisogno di sapere il Digit Larghezza massima del Normal di carattere, che è la larghezza in pixel della più ampia cifra numerica. La specifica OpenXML dà questo esempio come una precisazione:

Uso del font Calibri come esempio, la larghezza massima cifra del carattere 11 punti dimensione è di 7 pixel (a 96 dpi).

Ho verificato che questo è corretto esaminando visivamente un 11-punto Calibri cifra ed è indubbiamente ampia 7 pixel. Quindi, sto cercando di creare un metodo che restituirà la larghezza massima cifra per qualsiasi tipo di carattere / dimensione.

Ho seguito le raccomandazioni formulate nella questa domanda , ma non produce i risultati che mi aspetto.

Ecco il mio codice di prova:

var font = new Font("Calibri", 11.0f, FontStyle.Regular);

for (var i = 0; i < 10; i++)
{
    Debug.WriteLine(TextRenderer.MeasureText(i.ToString(), font));
}

Questo riporta che tutte le cifre hanno una larghezza di 15.

Qualche suggerimento per favore?

Grazie, Tim

È stato utile?

Soluzione

Per prima cosa, lasciatemi dire che il codice che sto per mostrare appare come un hack orribile e non sto presentandolo come una soluzione. Piuttosto, sto sperando che rivela un po 'di più sul comportamento dei MeasureText che potrebbe portare alla vostra soluzione finale.

Ho fatto una piccola modifica al codice. Sto misurando la lunghezza di due caratteri di sottolineatura. Poi, nel corpo del ciclo for sto misurando il carattere desiderato con caratteri di sottolineatura su entrambi i lati e sottraendo la lunghezza dei due caratteri di sottolineatura da solo. Per lo scenario di prova sto ottenendo un risultato di 7. Lo scopo principale di questo è stato quello di determinare se MeasureText è contabilità per imbottitura su base carattere per carattere o imbottitura ad inizio / fine della stringa. Sembra che sia la seconda. Forse questo, combinato con alcuni degli altri input che hai ricevuto, vi porterà a una soluzione più elegante.

var font = new Font("Calibri", 11.0f, FontStyle.Regular);
int underscoreWidth = TextRenderer.MeasureText("__", font).Width; 
for (var i = 0; i < 10; i++)
   {
      int charWidth = TextRenderer.MeasureText(String.Concat("_", i.ToString(), "_"), font).Width - underscoreWidth;
      Debug.WriteLine(charWidth);
   }

Altri suggerimenti

TextRenderer non è sempre preciso il modo in cui ci si aspetterebbe:

Da MSDN: http://msdn.microsoft.com/en- us / library / 8wafk2kt.aspx

  

Ad esempio, il comportamento predefinito del TextRenderer è quello di aggiungere imbottitura al rettangolo di delimitazione del testo elaborato per accogliere sovrastante glifi

Hai un oggetto Graphics o un oggetto di controllo? Se si sta utilizzando questi è possibile ottenere restults precisi il modo in cui ci si aspetterebbe.

Date un'occhiata a http: // MSDN. microsoft.com/en-us/library/6xe5hazb(VS.80).aspx

MeasureText aggiunge imbottitura, la quantità è abbastanza imprevedibile sebbene scale all'incirca linearmente con la dimensione del carattere. Il trucco è quello di sottrarre due misure per eliminare l'imbottitura. Questo codice generato numeri molto felice:

        float size = 5;
        for (int ix = 0; ix < 10; ++ix) {
            var font = new Font("Calibri", size, FontStyle.Regular);
            string txt = new string('0', 100);
            SizeF sz1 = TextRenderer.MeasureText("00", font) - TextRenderer.MeasureText("0", font);
            Console.WriteLine("{0} {1:N3}", size, sz1.Width);
            size += 2;
        }

Output:

5 4.000
7 5.000
9 6.000
11 7.000
13 9.000
15 10.000
17 12.000
19 13.000
21 14.000
23 16.000

Che si ottiene il 7 pixel che stai cercando. Attenzione che si dovrà ospitare TrueType hinting, si può regolare la forma della cifra in modo che il suo principale steli caduta sui limiti dei pixel. Aggiungere almeno un pixel.

di misura larghezze di testo può essere un incubo .. Io non so perché l'hanno fatta così confuso ..

Ecco il modo più preciso Ive ha ottenuto per misurare la lunghezza del testo:

    protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font )
    {
        if ( text == "" )
            return 0;

        StringFormat format = new StringFormat ( StringFormat.GenericDefault );
        RectangleF rect = new RectangleF ( 0, 0, 1000, 1000 );
        CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };
        Region[] regions = new Region[1];

        format.SetMeasurableCharacterRanges ( ranges );
        format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

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

        return (int)( rect.Right );
    }

Non sono sicuro al 100% che è quello che esattamente bisogno.

Ma si consiglia di dare un'occhiata a questa pagina Microsoft:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top