Calculating Text Metrics for TextBox in Word Document
Home › Forums › Open-Xml-Sdk › Calculating Text Metrics for TextBox in Word Document
Tagged: w:extent wps:txbx
This topic contains 2 replies, has 2 voices, and was last updated by tdemay 8 years, 3 months ago.
-
AuthorPosts
-
July 29, 2016 at 12:09 am #3586
What’s the best way to calculate dimensions for a TextBox given the text and font.
In other words, how do I calculate cx and cy for wp:extent for a wps:txbx ?
I’m trying to add a watermark to a word document using OpenXML SDK in C# and .Net 4.0
Inputs are
Font, FontSize, Bold, Italics, Text, Rotation, Position (horizontal and vertical on page), Text Alignment, ColorI’ve got everything working… I just need to calculate the size of the text box.
July 29, 2016 at 2:34 pm #3591This is a non-trivial (but doable) task.
After many experiments, I found that the text metrics methods in System.Windows.Forms.TextRenderer gave me the best results. This is the text metric functionality that WmlToHtmlConverter uses. You can look at the code in WmlToHtmlConverter as one example of the use of TextRenderer.
Dealing with rotation means that you will need to remember your basic trigonometry from high school. 🙂
July 29, 2016 at 6:24 pm #3596Thanks for your immediate response. I built the extension method below from your example in WmlToHtmlConverter.cs. Posting it here for anyone that might need it.
Let me know if you have any thoughts on this. I doubled the font size because for some reason I don’t understand the FontSize that is used in the <w:sz> elements for the TextBox is doubled in the XML than what the user sees in the FontSize drop down in the UI.
public static D.Size GetTextSize(this CWatermarkItemBase watermark, string runText) { D.FontStyle fs = D.FontStyle.Regular; if (watermark.FontBold) fs |= D.FontStyle.Bold; if (watermark.FontItalic) fs |= D.FontStyle.Italic; var sz = watermark.FontSize * 2; var proposedSize = new D.Size(int.MaxValue, int.MaxValue); D.Size sf; using (var ff = new D.FontFamily(watermark.FontFamily)) { try { using (var f = new D.Font(ff, (float)sz, fs)) { const TextFormatFlags tff = TextFormatFlags.NoPadding; sf = TextRenderer.MeasureText(runText, f, proposedSize, tff); } } catch (ArgumentException) { try { const D.FontStyle fs2 = D.FontStyle.Regular; using (D.Font f = new D.Font(ff, (float)sz, fs2)) { const TextFormatFlags tff = TextFormatFlags.NoPadding; sf = TextRenderer.MeasureText(runText, f, proposedSize, tff); } } catch (ArgumentException) { const D.FontStyle fs2 = D.FontStyle.Bold; try { using (var f = new D.Font(ff, (float)sz, fs2)) { const TextFormatFlags tff = TextFormatFlags.NoPadding; sf = TextRenderer.MeasureText(runText, f, proposedSize, tff); } } catch (ArgumentException) { // if both regular and bold fail, then get metrics for Times New Roman // use the original FontStyle (in fs) using (var ff2 = new D.FontFamily("Times New Roman")) using (var f = new D.Font(ff2, (float)sz, fs)) { const TextFormatFlags tff = TextFormatFlags.NoPadding; sf = TextRenderer.MeasureText(runText, f, proposedSize, tff); } } } } } const int multiplier = 5000; return new D.Size(sf.Width * multiplier, sf.Height * multiplier); }
-
AuthorPosts
You must be logged in to reply to this topic.