Calculate text size (extents) (TextBody) in OpenXML (PresentationML) PowerPoint (PPTX)

I want to create a presentation with data coming from a database. I will be able to get valid presentations that open in PowerPoint ( Open XML Productivity Tool in SDK 2.5, this is a big help with this). But how to calculate the size of text forms? I see where to put the values, but new Extents() defaults to zero width and height. When I take some a Shape values โ€‹โ€‹from an existing view, I can get the correct height (at least for texts with one line or a fixed number of lines), but the text will overflow to the right or bottom (depending on the dictionary setting).

Inserting NormalAutoFit into BodyProperties TextBody does not help - the necessary values โ€‹โ€‹for FontScale and LineSpaceReduction not calculated in OpenXML.

So what is the best practice for installing Extents a Shape with TextBody ?

Is there a built-in way to calculate Extents given TextBody or Shape ? (a rule of thumb with built-in methods would be better than nothing)

I know that PowerPoint will recalculate NormalAutoFit values โ€‹โ€‹after making any changes (at least for the heap of slides before and after this change), but this does not help when the presentation starts before the change was (or if it was started with using the PowerPoint Viewer).

+6
source share
1 answer

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) { // 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); } } } } } D.Size s2 = pixelsToEmus(sf.Width, sf.Height, 96, 96, 100, 100); return s2; } public static D.Size GetImageSize(this CWatermarkItemImage watermarkItem) { var img = new BitmapImage(new Uri(watermarkItem.FilePath, UriKind.RelativeOrAbsolute)); return pixelsToEmus(img.PixelWidth, img.PixelHeight, img.DpiX, img.DpiY, watermarkItem.ZoomWidth, watermarkItem.ZoomHeight); } 
+3
source

All Articles