2010-04-08 12 views
6

Ho un'applicazione C# che esegue il rendering del testo, qualcosa alla pari con un semplice editor di testo wysiwyg.TextRenderer.DrawText rende Arial in modo diverso su XP vs Vista

Sto utilizzando TextRenderer.DrawText per eseguire il rendering del testo sullo schermo e GetTextExtentPoint32 per misurare il testo in modo da poter posizionare stili di carattere/dimensioni diversi sulla stessa riga.

In Vista tutto funziona correttamente. In XP, tuttavia, Arial esegue il rendering in modo diverso, alcuni caratteri come "o" e "b" occupano più spazio rispetto a Vista. GetTextExtentPoint32 sembra misurare la stringa come se fosse in Vista, con le larghezze più piccole. Il risultato finale è che ogni tanto una sequenza di testo si sovrappone al testo che lo precede perché il testo precedente viene misurato più piccolo di quanto non sia effettivamente sullo schermo.

Inoltre, il mio codice di rendering del testo simula il rendering del testo esatto (per la semplice formattazione e solo la lingua inglese) e cioè il rendering del testo sembra essere coerente tra vista e xp - è così che ho notato il cambiamento di dimensioni dei diversi caratteri.

Qualcuno ha qualche idea su cosa sta succedendo?

In breve, TextRenderer.DrawText e GetTextExtentPoint32 non corrispondono in xp per Arial. DrawText sembra disegnare alcuni caratteri più grandi e/o più piccoli rispetto a Vista, ma GetTextExtentPoint32 sembra misurare il testo come sarebbe in Vista (che sembra corrispondere al rendering del testo in cioè su entrambi xp e vista). Spero che abbia un senso.

Nota: sfortunatamente TextRenderer.MeasureString non è veloce o preciso per soddisfare i miei requisiti. Ho provato a usarlo e ho dovuto strapparlo.

+0

+1 Perché so a cosa ti stai occupando! E ho solo dovuto occuparmi di caratteri a larghezza fissa. – leppie

+0

Sei sicuro che non sia un tipo di problema DPI o Cleartype? –

risposta

0

Non sono un ragazzo di C#, ma credo che il rendering .NET sia basato su GDI +. Sono anche abbastanza sicuro che GDI + esegua il rendering dei font che utilizza il ridimensionamento non verificato.

GetTextExtentPoint32, d'altra parte, fa parte di GDI. GDI utilizza suggerimenti di dimensionamento, che possono influire sulla larghezza dei caratteri in base alla dimensione del carattere. In generale il testo GDI a piccole dimensioni sembrerà un po 'getter, ma non scalerà linearmente.

È necessario utilizzare in modo coerente un modello o l'altro per ottenere risultati perfetti per i pixel.

Ci possono essere altri fattori in gioco che possono rendere questo più ovvio su XP che su Vista, ma il problema fondamentale esiste in entrambi. Questi altri fattori potrebbero includere le impostazioni DPI, il ridimensionamento DPI, le impostazioni ClearType o antialiasing, il collegamento font (se si mescolano script di altri alfabeti), la sostituzione dei caratteri (soprattutto in stampa) e, eventualmente, anche diverse versioni di Arial. Non sono nemmeno sicuro che GDI + utilizzi la stessa modalità di mapping predefinita di GDI.

Vedere anche my answer on print preview.

2

Grazie per aver trovato il tempo di rispondere Adrian.

La mia comprensione è che TextRenderer.DrawText racchiude effettivamente una chiamata a GDI, ignorando completamente il rendering del testo GDI +. Ecco perché ero confuso dal fatto che GetTextExtentPoint32 non si stesse muovendo con l'output.

Penso di aver trovato il problema. Risulta che se si imposta Graphics.TextRenderingHint su System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, o eventualmente su altri valori, alcuni caratteri di alcuni tipi di carattere aumentano o diminuiscono di dimensioni. Questo sembra essere vero più in XP che in Vista. Non l'ho visto accadere affatto in Vista.In ogni caso, sembra che GetTextExtentPoint32 non sia in grado di riconoscere la differenza o non sto impostando alcun tipo di flag quando effettuo la chiamata.

La mia soluzione è utilizzare solo le impostazioni di textrenderinghint predefinite di sistema.

+0

Sembra giusto. Ho trovato alcune buone informazioni qui (ma fa anche alcune affermazioni discutibili, quindi state attenti). http://blogs.msdn.com/cjacks/archive/2006/05/11/595525.aspx –

0

In realtà sia TextTenderer DrawText che MeasureString basati su DrawTextEx (e questa è User32, non la funzione Gdi). Quindi è possibile considerare l'utilizzo di chiamate marshalled native a questa funzione anziché MeauseString, perché esegue alcuni calcoli aggiuntivi (specialmente se si sta utilizzando la funzione di sovrascrittura senza HDC).

Forse anche questo post sarà utile anche per te.

Problemi correlati