Вычисление переноса текста в .NET DrawingContext Метод DrawText - PullRequest
6 голосов
/ 20 января 2011

Я работаю над проектом, в котором аппроксимируемый текст отображается как изображение, и редактор DHTML для текста.Изображения отображаются с помощью метода DrawText объекта DrawingContext .NET 4.

Метод DrawText будет принимать текст вместе с информацией о шрифте, а также с размерами и вычислять обертку, необходимую для максимально возможного размещения текста, помещая многоточие в конец, если текст слишком длинный.Итак, если у меня есть следующий код для рисования текста в прямоугольнике, он будет сокращен:

string longText = @"A choice of five engines, although the 2-liter turbo diesel, supposedly good for 48 m.p.g. highway, is not coming to America, at least for now. A 300-horsepower supercharged gasoline engine will likely be the first offered in the United States. All models will use start-stop technology, and fuel consumption will decrease by an average of 19 percent across the A6 lineup. A 245-horsepower A6 hybrid was also unveiled, but no decision has yet been made as to its North America sales prospects. Figure later in 2012, if sufficient demand is detected.";

var drawing = new DrawingGroup();
using (var context = drawing.Open())
{
    var text = new FormattedText(longText,
        CultureInfo.CurrentCulture,
        FlowDirection.LeftToRight,
        new Typeface("Calibri"),
        30,
        Brushes.Green);
    text.MaxTextHeight = myRect.Height;
    text.MaxTextWidth = myRect.Width;

    context.DrawText(text, new Point(0, 0));
}

var db = new DrawingBrush(drawing);
db.Stretch = Stretch.None;
myRect.Fill = db;

Есть ли способ рассчитать, как текст будет переноситься?В этом примере выводимый текст обернут в «2 литра» и «48 миль на галлон» и т. Д., Как показано на рисунке ниже: alt text

Ответы [ 2 ]

3 голосов
/ 20 января 2011

Вы можете использовать функцию Graphics.MeasureString (String, Font, Int32). Вы передаете ему строку, шрифт и максимальную ширину. Он возвращает SizeF с прямоугольником, который он сформирует. Вы можете использовать это, чтобы получить общую высоту и, следовательно, количество строк:

Graphics g = ...;
Font f = new Font("Calibri", 30.0);
SizeF sz = g.MeasureString(longText, f, myRect.Width);
float height = sz.Height;
int lines = (int)Math.round(height / f.Height); // overall height divided by the line height = number of lines

Есть много способов получить графический объект, и любой подойдет, поскольку вы используете его только для измерения, а не для рисования (возможно, вам придется исправить его поля DpiX, DpiY и PageUnit, поскольку эти измерения эффекта.

Способы получения графического объекта:

Graphics g = e.Graphics; // in OnPaint, with PaintEventArgs e
Graphics g = x.CreateGrahics(); // where x is any Form or Control
Graphics g = Graphics.CreateFrom(img); // where img is an Image.
2 голосов
/ 13 февраля 2011

Не уверен, что вам все еще нужно решение или это конкретное решение подходит для вашего приложения, но если вы вставите приведенный ниже фрагмент сразу после блока using, он покажет вам текст в каждой строке (и, следовательно, где текст был разбит для упаковки).

Я пришел к этому решению, используя очень гетто / партизанский подход - просто просматривать свойства во время отладки, искать обернутые текстовые сегменты - я нашел их, и они были в доступных свойствах ... вот и все. Там очень хорошо может быть более правильный / прямой путь.

// Object heirarchy:
// DrawingGroup (whole thing)
//  - DrawingGroup (lines)
//     - GlyphRunDrawing.GlyphRun.Characters (parts of lines)

// Note, if text is clipped, the ellipsis will be placed in its own 
// separate "line" below.  Give it a try and you'll see what I mean.

List<DrawingGroup> lines = drawing.Children.OfType<DrawingGroup>().ToList();

foreach (DrawingGroup line in lines)
{
    List<char> lineparts = line.Children
        .OfType<GlyphRunDrawing>()
        .SelectMany(grd => grd.GlyphRun.Characters)
        .ToList();

    string lineText = new string(lineparts.ToArray());

    Debug.WriteLine(lineText);
}

Кстати, привет, Дэвид. : -)

...