.net - texto - tamaño de letra html
¿Calcular la altura del texto según el ancho y la fuente disponibles? (8)
Estamos creando documentos PDF sobre la marcha a partir de la base de datos utilizando PDFsharp .
Necesito saber cuál es la mejor manera de calcular la altura del área de texto según la fuente utilizada y el ancho disponible.
Necesito saber la altura para poder procesar los saltos de página cuando sea necesario.
En .NET puede llamar Graphics.MeasureString para averiguar qué tan grande será el texto dibujado.
Correcto, pero cuando usas PDFsharp llamas XGraphics.MeasureString.
El OP preguntó cómo calcular la altura del texto según el ancho y la fuente disponibles . Windows .NET proporciona una llamada a la API para esto que toma un argumento de ancho; la versión de PDFsharp que estoy usando (0.9.653, .NET 1.1) no lo hace.
Mi solución: use la llamada a la API .NET con un objeto de Gráficos asignado a un objeto de Mapa de bits creado a la medida para obtener la respuesta.
Lo que funcionó para mí fue usar un mapa de bits que tenía una resolución de 100 ppp (crítica) y resultó ser del tamaño de una página de retrato (probablemente menos crítica).
Entonces solo pregunté a .NET cuál sería el tamaño de píxel para pintar en ese mapa de bits.
Es probable que luego quieras convertir las unidades de 1/100 de pulgada a Puntos (para PDFsharp).
'''''' Adapted Code - this not tested or even compiled - Caveat Emptor! '''''' Target: Visual Basic, .NET 1.1 (VS2003) [adapt as necessary] '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' GraphicsAlt.MeasureString() does substantially what System.Drawing MeasureString(...,Integer) does. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Public Module GraphicsAlt '' '' Static data used Only to compute MeasureString() below. '' '' Cache a single copy of these two objects, to address an otherwise unexplained intermittent exception. '' Private Shared myImage As Bitmap = Nothing Private Shared myGraphics As Graphics = Nothing Public Shared Function GetMeasureGraphics() As Graphics If myImage Is Nothing Then myImage = New Bitmap(1700, 2200) '''' ... Specify 8.5x11 myImage.SetResolution(100, 100) '''' ... and 100 DPI (if you want different units, you might change this) myGraphics = Graphics.FromImage(myImage) End If Return myGraphics End Function ''Given 1/100TH inch max width, return Rect to hold with units 1/100TH inch '' Public Function MeasureString(ByVal text As String, ByVal aFont As System.Drawing.Font, ByVal width As Integer) As System.Drawing.SizeF Return (GraphicsAlt.GetMeasureGraphics()).MeasureString(text, aFont, width) End Function End Module
El objeto PdfSharp.Drawing.XGraphics tiene un método MeasureString que devuelve lo que necesita.
var pdfDoc = new PdfSharp.Pdf.PdfDocument();
var pdfPage = pdfDoc.AddPage();
var pdfGfx = PdfSharp.Drawing.XGraphics.FromPdfPage(pdfPage);
var pdfFont = new PdfSharp.Drawing.XFont("Helvetica", 20);
while (pdfGfx.MeasureString("Hello World!").Width > pdfPage.Width)
--pdfFont.Size;
pdfGfx.DrawString("Hello World!", pdfFont
, PdfSharp.Drawing.XBrushes.Black
, new PdfSharp.Drawing.XPoint(100, 100));
Esto debería ayudarte. Por favor, tenga en cuenta que no probé este código ya que lo escribí sobre la marcha para ayudar. Puede contener algunos errores en tiempo de compilación, pero puede tener la idea.
En .NET puede llamar Graphics.MeasureString para averiguar qué tan grande será el texto dibujado.
En caso de que alguien todavía quiera encontrar una respuesta, he implementado un método razonablemente fácil de entender para averiguar la altura del texto resultante.
Public Function PrintString(text As String, ft As XFont, rect As XRect, graph As XGraphics, b As SolidBrush, Optional tf As XTextFormatter = Nothing) As Integer
If Not IsNothing(tf) Then
tf.DrawString(text, ft, b, rect)
Else
Dim drawLeft As New XStringFormat
drawLeft.Alignment = XStringAlignment.Near
graph.DrawString(text, ft, b, rect, drawLeft)
End If
Dim width As Double = graph.MeasureString(text, ft).Width
Dim multiplier As Integer = 0
While width > 0
multiplier += 1
width -= rect.Width
End While
Dim height As Double = (graph.MeasureString(text, ft).Height) * multiplier
Return height
End Function
Explicando el código:
Primero, imprima el texto. Incluí un XTextFormatter opcional llamado tf porque uso XGraphics o XTextFormatters indistintamente en mi aplicación.
Luego, calcula la longitud del texto con MeasureString (). Ancho.
Luego, calcula cuántas líneas de texto había. Esto se hace dividiendo la longitud total del texto encontrado anteriormente por el ancho del rectángulo provisto (casilla) donde se imprime el impuesto. Lo hice con un bucle de tiempo aquí.
Multiplica la altura del texto (usando graph.MeasureString (). Height) por el número de líneas que haya. Esta es la altura final de tu texto.
Devuelve el valor de altura. Ahora, al llamar a la función PrintString () se imprimirá el texto proporcionado y luego se devolverá la altura del texto impreso.
Escribí un pequeño método de extensión para el objeto XGraphic para hacer precisamente eso: calibre la altura (y el ancho) del texto exacto especificando maxWidth. Consulte el siguiente código para el código: https://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a
PDFsharp incluye una clase XTextFormatter que se puede usar para dibujar texto con saltos de línea.
Sin embargo, no puede determinar la altura necesaria para el texto. Inspirado por un comentario de @ Wakka02, mejoré esta clase, generando la clase XTextFormatterEx.
En mi opinión, también responde a la pregunta original, por lo tanto, publico una respuesta.
Sé que esta es una pregunta antigua y que la respuesta puede no ayudar al OP, pero es una pregunta frecuente y la respuesta puede ayudar a otros.
La nueva clase tiene 500 líneas de código, y creo que esto sería demasiado para esta publicación.
El código fuente se puede encontrar en el foro PDFsharp:
http://forum.pdfsharp.net/viewtopic.php?p=9213#p9213
También se puede encontrar en mi humilde blog:
http://developer.th-soft.com/developer/pdfsharp-improving-the-xtextformatter-class-measuring-the-height-of-the-text/
Al usar la nueva clase, primero puede llamar a PrepareDrawString
para averiguar qué parte del texto cabe y qué altura tiene el texto apropiado. Luego su decodificador puede dibujar el texto preparado o preparar otro texto o preparar el mismo texto con un rectángulo diferente.
Mi nueva clase en el trabajo: XTextFormatterEx tf = new XTextFormatterEx (gfx); int lastCharIndex; doble altura necesaria;
// Draw the text in a box with the optimal height
// (magic: we know that one page is enough).
XRect rect = new XRect(40, 100, 250, double.MaxValue);
//tf.Alignment = ParagraphAlignment.Left;
tf.PrepareDrawString(text, font, rect,
out lastCharIndex, out neededHeight);
rect = new XRect(40, 100, 250, neededHeight);
gfx.DrawRectangle(XBrushes.SeaShell, rect);
// Both variants should look the same.
// Optimized version: draw the prepared string.
tf.DrawString(XBrushes.Black, XStringFormats.TopLeft);
La preparación del texto invoca a MeasureString muchas veces. Posteriormente, se puede dibujar el texto preparado sin invocar de nuevo a MeasureString.
A partir de hoy (17 de julio de 2015), la clase XTextFormatterEx (como el XTextFormatter original) utiliza campos internos de la clase XFont. Esto requiere un tratamiento especial al compilar la clase. Decidí copiar mi clase XTextFormatterEx en la carpeta PDFsharp después de descargar el paquete fuente completo para PDFsharp 1.32.
Cualquiera que intente modificar la clase XTextFormatter o XTextFormatterEx se enfrentará al mismo problema.
Espero que este problema se resuelva con futuras versiones de PDFsharp, permitiendo que las versiones modificadas de estas clases se incluyan en el proyecto de la aplicación.
Tuve un problema similar, así que implementé este método de extensión:
public static double MeasureHeight(this PdfSharp.Drawing.XGraphics gfx, string text, PdfSharp.Drawing.XFont font, int width)
{
var lines = text.Split(''/n'');
double totalHeight = 0;
foreach (string line in lines)
{
var size = gfx.MeasureString(line, font);
double height = size.Height + (size.Height * Math.Floor(size.Width / width));
totalHeight += height;
}
return totalHeight;
}