From Eric White Forum
This is a non-trivial (but doable) task.
After many experiments, I found that the text metric methods in System.Windows.Forms.TextRenderer gave me the best results. This is the text metric functionality that the WmlToHtmlConverter uses. You can see the code in WmlToHtmlConverter as one example of using TextRenderer.
Here is the code I came up with for my purposes based on Eric White WmlToHtmlConverter, this post and. I use this to calculate TextBox sizes for text watermarks and image watermarks for OpenXml documents for Word.
private static D.Size pixelsToEmus(int widthPx, int heightPx, double resDpiX, double resDpiY, int zoomX, int zoomY) { const int emusPerInch = 914400; const int emusPerCm = 360000; const decimal maxWidthCm = 16.51m; var widthEmus = (int)(widthPx / resDpiX * emusPerInch) * zoomX / 100; var heightEmus = (int)(heightPx / resDpiY * emusPerInch) * zoomY / 100; var maxWidthEmus = (int)(maxWidthCm * emusPerCm); if (widthEmus > maxWidthEmus) { var ratio = ((decimal)heightEmus / (decimal)widthEmus); widthEmus = maxWidthEmus; heightEmus = (int)(widthEmus * ratio); } return new D.Size(widthEmus, heightEmus); } public static D.Size GetTextSize(this CWatermarkItemBase watermark, string runText) { var fs = watermark.GetFontStyle(); var sz = watermark.FontSize; 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) {
source share