PPTShape.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using DocumentFormat.OpenXml.Drawing;
  5. using DocumentFormat.OpenXml.Packaging;
  6. using DocumentFormat.OpenXml.Presentation;
  7. using ClearSlideLibrary.Dom.PPTTexts;
  8. using Shape = DocumentFormat.OpenXml.Presentation.Shape;
  9. using TextBody = DocumentFormat.OpenXml.Presentation.TextBody;
  10. using DocumentFormat.OpenXml;
  11. using System.Drawing;
  12. using System.Drawing.Drawing2D;
  13. using System.Drawing.Imaging;
  14. using System.IO;
  15. namespace ClearSlideLibrary.Dom
  16. {
  17. public class PPTShape : PPTShapeBase
  18. {
  19. // contains values of type: slideIndex_shapeId
  20. public static LinkedList<string> effectShapes = new LinkedList<string>();
  21. private const double RotationIndex = 60000;
  22. private const string PictureBulletDirName = "PictureBullet";
  23. public Boolean IsText { get; set; }
  24. public PPTSlide slide { get; set; }
  25. private PlaceholderShape placeholder;
  26. // Create a new linked list of strings.
  27. public LinkedList<PPTParagraph> Texts = new LinkedList<PPTParagraph>();
  28. public PPTShape(SlidePart slidePart, Shape shape, PPTSlide slide): base()
  29. {
  30. this.slide = slide;
  31. SetShapeVisualProperties(slidePart, shape);
  32. SetShapeNonVisualProperties(slidePart, shape);
  33. SetSpecificProperties(slidePart, shape);
  34. }
  35. private void SetShapeNonVisualProperties(SlidePart slidePart, Shape shape)
  36. {
  37. if (shape.NonVisualShapeProperties.NonVisualDrawingProperties.HyperlinkOnClick != null)
  38. foreach (HyperlinkRelationship link in slidePart.HyperlinkRelationships)
  39. {
  40. if (link.Id.Equals(shape.NonVisualShapeProperties.NonVisualDrawingProperties.HyperlinkOnClick.Id))
  41. {
  42. ClickLinkUrl = link.Uri.IsAbsoluteUri ? link.Uri.AbsoluteUri : link.Uri.OriginalString;
  43. }
  44. }
  45. if (shape.NonVisualShapeProperties.NonVisualDrawingProperties.HyperlinkOnHover != null)
  46. foreach (HyperlinkRelationship link in slidePart.HyperlinkRelationships)
  47. {
  48. if (link.Id.Equals(shape.NonVisualShapeProperties.NonVisualDrawingProperties.HyperlinkOnHover.Id))
  49. {
  50. HoverLinkUrl = link.Uri.IsAbsoluteUri ? link.Uri.AbsoluteUri : link.Uri.OriginalString;
  51. }
  52. }
  53. var nonVisualShapeProp = new PPTNonVisualShapeProp
  54. {
  55. Id = "s1s" + //HARD CODED: we split it into separate HTML files!
  56. shape.NonVisualShapeProperties.NonVisualDrawingProperties.Id,
  57. Name = shape.LocalName,
  58. Type = "PPTShape"
  59. };
  60. base.NonVisualShapeProp = nonVisualShapeProp;
  61. }
  62. private void SetShapeVisualProperties(SlidePart slidePart, Shape shape)
  63. {
  64. if (shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape != null)
  65. {
  66. placeholder = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.
  67. PlaceholderShape;
  68. if (placeholder.Type == null)
  69. placeholder.Type = PlaceholderValues.Body;
  70. }
  71. base.VisualShapeProp = new PPTVisualPPTShapeProp();
  72. base.SetSlideLayoutVisualShapeProperties(slidePart, shape);
  73. if (shape.ShapeProperties.Transform2D != null)
  74. {
  75. Int32Value rot = shape.ShapeProperties.Transform2D.Rotation;
  76. if (rot != null)
  77. {
  78. double degrees = Math.Round(rot / RotationIndex);
  79. if (degrees < 0)
  80. {
  81. degrees = 360 + degrees;
  82. }
  83. base.VisualShapeProp.Rotate = degrees;
  84. }
  85. base.VisualShapeProp.Extents = shape.ShapeProperties.Transform2D.Extents;
  86. base.VisualShapeProp.Offset = shape.ShapeProperties.Transform2D.Offset;
  87. }
  88. }
  89. private void SetSpecificProperties(SlidePart slidePart, Shape shape)
  90. {
  91. IsText = true;
  92. //Check if this is text
  93. if (shape.TextBody == null)
  94. {
  95. IsText = false;
  96. return;
  97. }
  98. if (shape.TextBody.BodyProperties != null)
  99. {
  100. if (shape.TextBody.BodyProperties.Anchor != null)
  101. VerticalAlign = shape.TextBody.BodyProperties.Anchor;
  102. if (shape.TextBody.BodyProperties.GetFirstChild<NormalAutoFit>() != null &&
  103. shape.TextBody.BodyProperties.GetFirstChild<NormalAutoFit>().FontScale != null)
  104. fontScale = shape.TextBody.BodyProperties.GetFirstChild<NormalAutoFit>().FontScale.Value;
  105. }
  106. int index = 0;
  107. foreach (var paragraph in shape.TextBody.Descendants<Paragraph>())
  108. {
  109. var par = new PPTParagraph(slide, placeholder)
  110. {
  111. Paragraph = index++
  112. };
  113. if (paragraph.ParagraphProperties != null)
  114. {
  115. int level = paragraph.ParagraphProperties.Level == null ?
  116. -1 : paragraph.ParagraphProperties.Level.Value;
  117. par.Level = level;
  118. }
  119. par.SetParagraphProperties(paragraph, slidePart,
  120. shapeListStyleMaster, shapeListStyleLayout);
  121. bool hasText = false;
  122. foreach (var obj in paragraph.ChildElements)
  123. {
  124. hasText = GetParagraphChildElements(shape, par, hasText, obj);
  125. }
  126. //This is because when we set paragraph properties we add the bullet to the text runs.
  127. //If we don't have text it still outputs the bullet character.
  128. if (par.bullet != null && hasText)
  129. {
  130. par.RunPropList.Insert(0, par.bullet);
  131. }
  132. Texts.AddLast(par);
  133. }
  134. }
  135. private bool GetParagraphChildElements(Shape shape, PPTParagraph par, bool hasText, OpenXmlElement obj)
  136. {
  137. if (obj is Run)
  138. {
  139. Run run = (Run)obj;
  140. hasText = true;
  141. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  142. runProp.Text = run.Text.Text;
  143. runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
  144. runProp.FontSize = Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  145. par.RunPropList.Add(runProp);
  146. }
  147. else if (obj is Field)
  148. {
  149. Field run = (Field)obj;
  150. hasText = true;
  151. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  152. runProp.Text = run.Text.Text;
  153. runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
  154. runProp.FontSize = Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  155. par.RunPropList.Add(runProp);
  156. }
  157. else if (obj is Break)
  158. {
  159. Break aBreak = (Break)obj;
  160. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  161. runProp.SetRunProperties(aBreak.RunProperties, shape, ref effectShapes);
  162. runProp.FontSize = Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  163. runProp.isBreak = true;
  164. par.RunPropList.Add(runProp);
  165. }
  166. return hasText;
  167. }
  168. }
  169. }