2016-06-17 11 views
1

Betrachten Sie den folgenden Code ein:iTextSharp GetWidthPoint() enthält nicht den Zeichenabstand

var path = AppDomain.CurrentDomain.BaseDirectory; 
var filePath = Path.Combine(path, "test1.pdf"); 

using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)) 
using (var document = new Document(new Rectangle(PageSize.A4.Width, PageSize.A4.Height))) 
using (var writer = PdfWriter.GetInstance(document, stream)) 
{ 

    try 
    { 

     document.Open(); 

     const string value = "The quick brown fox"; 

     for (int i = 0; i < 4; i++) 
     { 

      var chunk = new Chunk(value); 

      chunk.SetCharacterSpacing(i); 

      var origin = new Phrase(chunk); 
      var paragraph1 = new Paragraph(origin); 

      document.Add(paragraph1); 

      var widthPoint = chunk.GetWidthPoint(); 

      Debug.WriteLine(widthPoint); 

     } 

     writer.CloseStream = false; 

    } 
    finally 
    { 
     document.Close(); 
     stream.Close(); 
    } 

} 

ich versucht bin, einen Absatz/Brocken auf einen einzigen PdfPCell in einem neuen PdfPTable hinzuzufügen. Wir haben keine Kontrolle über den tatsächlichen Text, der in die Zellen hineingeht, und es ist möglich, dass der Text etwas länger ist als der verfügbare Platz. Entweder würde der Text auf mehrere Zeilen aufbrechen oder aus der Zelle herausfließen und versteckt werden.

Die Idee ist, den Buchstabenabstand des Textes automatisch zu reduzieren (bis zu einem Mindestbetrag), um zu versuchen, den beschnittenen Text abzuschwächen. Im Grunde einen kleinen negativen Buchstabenabstand anwenden, bis der Text passt. Das Problem ist, dass der Wert von widthPoint immer gleich ist, unabhängig vom verwendeten Buchstabenabstand. Die erzeugte PDF hat deutlich den Text mit unterschiedlichen Breiten gerendert.

Gibt es eine Möglichkeit, die tatsächliche Breite des Textes mit Buchstabenabstand zu berechnen, oder es ist Container? Der Chunk/Absatz sind (wie ich es beschreiben würde) Box-Model-Typ-Elemente. Das heißt, sie füllen die Zelle und haben immer die gleiche Breite.

Keine Ahnung, wie Sie vorgehen.

Dies ist für iTextSharp Version 5.5.9.0

Antwort

1

sagte einfach: Sie sind richtig. Chunk.GetWidthPoint() berechnet nur die Breite ohne Zeichen oder Wortabstand:

virtual public float GetWidthPoint() { 
    if (GetImage() != null) { 
     return GetImage().ScaledWidth; 
    } 
    return font.GetCalculatedBaseFont(true).GetWidthPoint(Content, font.CalculatedSize) * HorizontalScaling; 
} 

So

Gibt es eine Möglichkeit, die tatsächliche Breite des Textes mit dem Buchstaben-Abstand zu berechnen, oder es ist Container?

Es gibt keine von iTextSharp 5 out of the box zur Verfügung gestellt. Aber man kann leicht den richtigen Wert wie folgt berechnen:

float WidthWithCharSpacing = chunk.GetWidthPoint() + chunk.GetCharacterSpacing() * (chunk.Content.Length - 1); 
+0

Ehrlich, ich hätte schwören können, dass ich das probiert habe! GAH! Vielen Dank. –

1

Sie können für die GetWidthPointKerned Methode suchen, die das Kerning zwischen Zeichen berücksichtigt.

+0

Kerning ist * nicht * Zeichenabstand, um den sich die Frage dreht. – mkl

+0

Ich bin mir nicht sicher, was Sie meinen, laut https://en.wikipedia.org/wiki/Kerning heißt es "In der Typografie ist Kerning der Prozess der Anpassung des Abstands zwischen Zeichen in einer proportionalen Schriftart", wenn Sie das bekommen möchten String-Breite einschließlich Abstand zwischen den Buchstaben 'GetWidthPointKerned'; funktioniert, oder hat zumindest für mich. @Mkl könnten Sie erarbeiten? –

+0

Wenn Sie den Artikel weiter lesen, werden Sie feststellen, dass * in der digitalen Typografie Kerning normalerweise auf Buchstabenpaare angewendet wird *, was Ihre vorgeschlagene 'GetWidthPointKerned' Methode tatsächlich berücksichtigt: Kleine Änderungen im Abstand zwischen Buchstaben basierend auf dem einzelnen Buchstabenpaar . Wie Sie jedoch im OP-Code sehen können, verwendet er 'chunk.SetCharacterSpacing (i)', das den Abstand zwischen jedem Buchstabenpaar um einen konstanten Wert ändert, unabhängig von den fraglichen Buchstaben, und Ihre vorgeschlagene 'GetWidthPointKerned'-Methode ignoriert dieser Zeichenabstand. – mkl