2013-03-17 1 views
4

PDFsharp поддерживает автоматический перенос текста при рисовании длинных текстовых частей:PDFsharp: Измерение высоты длинного текста со словом обернуть

textFormatter.DrawString(text, font, XBrushes.Black, new XRect(x, y, textAreaWidth, 1000), XStringFormats.TopLeft); 

Это будет обернуть текст, если он больше, чем textAreaWidth.

Как получить высоту текста, который только что был нарисован?

Я пробовал его с gfx.MeasureString(), но нет перегрузки, которая поддерживает максимальную ширину. gfx.MeasureString() возвращает размер текста без переноса текста.

Спасибо за любые подсказки.

+2

Если одна страница не достаточно, и вы, возможно, потребуется больше страниц, то лучше переключатель прямо в MigraDoc. Если вы уверены, что одной страницы будет достаточно на все времена, просто добавьте параметр out в XTextFormatter.DrawString, который вернет высоту текста, который был только что нарисован. –

ответ

4

Класс XTextFormatter (исходный код, включенный в PDFsharp) предназначен для начала работы. Измените его, если он не соответствует вашим потребностям.

Поскольку XTextFormatter сохраняет внутреннее положение Y, это было бы довольно простое изменение, чтобы вернуть высоту текста, который был только что нарисован.

Вместо изменения XTextFormatter, вместо этого используйте вместо этого MigraDoc Foundation (также включенный).

3

Это расширение PDFsharp не совсем сработало для меня. Не знаю, почему, но я продолжал получать большую высоту, чем ожидалось (почти вдвое больше необходимого). Поэтому я решил написать метод расширения объекта XGraphics, где я могу указать maxWidth и внутренне рассчитать разрывы в мягких линиях. Код использует значение по умолчанию XGraphics.MeasureString(string, XFont) для вложенного текста Ширина и Агрегаты со словами из текста для вычисления разрывов строк. Код для расчета мягкие разрывы строки выглядит следующим образом:

/// <summary> 
/// Calculate the number of soft line breaks 
/// </summary> 
private static int GetSplittedLineCount(this XGraphics gfx, string content, XFont font, double maxWidth) 
{ 
    //handy function for creating list of string 
    Func<string, IList<string>> listFor = val => new List<string> { val }; 
    // string.IsNullOrEmpty is too long :p 
    Func <string, bool> nOe = str => string.IsNullOrEmpty(str); 
    // return a space for an empty string (sIe = Space if Empty) 
    Func<string, string> sIe = str => nOe(str) ? " " : str; 
    // check if we can fit a text in the maxWidth 
    Func<string, string, bool> canFitText = (t1, t2) => gfx.MeasureString($"{(nOe(t1) ? "" : $"{t1} ")}{sIe(t2)}", font).Width <= maxWidth; 

    Func<IList<string>, string, IList<string>> appendtoLast = 
      (list, val) => list.Take(list.Count - 1) 
           .Concat(listFor($"{(nOe(list.Last()) ? "" : $"{list.Last()} ")}{sIe(val)}")) 
           .ToList(); 

    var splitted = content.Split(' '); 

    var lines = splitted.Aggregate(listFor(""), 
      (lfeed, next) => canFitText(lfeed.Last(), next) ? appendtoLast(lfeed, next) : lfeed.Concat(listFor(next)).ToList(), 
      list => list.Count()); 

    return lines; 
} 

Смотрите следующий GIST для полного кода: https://gist.github.com/erichillah/d198f4a1c9e8f7df0739b955b245512a

+0

Я хотел бы получить некоторую обратную связь по дате голосования –

+0

Спасибо, это сработало для меня, хотя я не совсем понимаю код. Я немного новичок на C#, может быть, поэтому. – bobwki

 Смежные вопросы

  • Нет связанных вопросов^_^