2011-01-19 36 views
5

我正在研究一個項目,該項目使我近似渲染爲文本的圖像和DHTML編輯器的文本。圖像使用.NET 4 DrawingContext對象的DrawText方法呈現。在.NET DrawingContext中計算文本環繞DrawText方法

DrawText方法會將文本和字體信息以及尺寸一起取出並計算必要的包裝以使文本儘可能合適,如果文本太長,則在末尾放置省略號。所以,如果我有以下的代碼來繪製一個矩形文本會abbrevaiate它:

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 m.p.g」等,如下圖所示: alt text

回答

2

不知道,如果你仍然需要一個解決方案,或者如果這個特定的解決方案適合你的應用程序,但是如果你插入下面的片段t就在你的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); 
} 

順便說一句,嗨大衛。 :-)

3

您可以使用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. 
+0

Graphics.MeasureString *不是*替代TextRenderer.MeasureText()。 – 2011-01-20 01:22:59

+0

+1 Hans。實際上,這個問題的根源在於,使用上述技術的代碼幾乎是定期不準確的。 – t3rse 2011-01-20 13:50:04