In some interesting designs of Office documents, colors and brushes are inheritable, and this inheritance includes inheritance of attributes.Gradient colors used in shape filling are properties that can be put into a theme. The brush inside the theme is mainly found, replacing the content defined by the shape itself, which is the brush of the shape.
I get an interesting courseware from which I can see that ShapeProperties inside a Shape element define the GradientFill attribute
// OpenXmlElementList element var gradientFill = element.First<GradientFill>();
The GradientStopList value for this gradientFill is empty
if (gradientFill.GradientStopList != null) { }
adopt Office Open XML - DrawingML - Shapes - Gradient Fill As you know, this GradientStopList is used to define the color of a gradient, that is, the value is empty then the gradient will lose color, that is, the shape filling will lose the gradient color
From the document, there is no value for gsLst in the shape attribute definition
<p:spPr> <a:xfrm> <a:off x="611560" y="1059582"/> <a:ext cx="2120518" cy="645160"/> </a:xfrm> <a:prstGeom prst="rect"> <a:avLst/> </a:prstGeom> <a:gradFill flip="none" rotWithShape="1"> <a:lin ang="10800000" scaled="1"/> <a:tileRect/> </a:gradFill> </p:spPr>
That is, a:gradFill does not contain a:gsLst value, that is, no a:gs defined color
The problem is that there is no GradientStopList value in the OpenXML a:gradFill without a:gsLst gradient
The ShapeStyle value is normally visible in this shape, and one of the attributes within this value is the FillReference representation style fill
<p:style> <a:fillRef idx="2"> <a:schemeClr val="accent3"/> </a:fillRef> </p:style>
The attribute required for this style is the idx attribute, indicating which style belongs to the theme
Then how to get themes in the OpenXML SDK, if an element on the Slide page can get themes from the code below
// Slide slide var slidePart = slide.SlidePart; FormatScheme formatScheme = slidePart?.ThemeOverridePart?.ThemeOverride?.FormatScheme;
Currently, if Slide cannot be taken from SlideLayoutPart, then SlideMasterPart
Then you get the specified element from the FillStyleList of FormatScheme via the idx of the FillReference, noting that idx here uses the subscript from 1.But the array of FillStyleList is C#and the subscript starts with 0
// FillReference reference, FormatScheme formatScheme if (reference.Index != null && formatScheme != null) { var index = (int) reference.Index.Value; var openXmlElementList = formatScheme.FillStyleList?.ChildElements; if (openXmlElementList != null) { return GetThemeElement(index, openXmlElementList); } }
The GetThemeElement method is implemented as follows
private static OpenXmlElement GetThemeElement(int index, OpenXmlElementList elements) { if (index > 0 && elements != null && elements.Count >= index) { //GetItem is an array of 0 base, so you need to subtract 1 var xmlElement = elements.GetItem(index - 1); return xmlElement; } return null; }
Now you have the OpenXmlElement return value, which is a fill color.There is no base class for fill colors in the OpenXML SDK, which is not well designed
The PPT document corresponds to ppt\theme\Themex.xmlThe value of a:fillStyleLst inside the file
<a:fmtScheme name="Office"> <a:fillStyleLst> <a:solidFill> <a:schemeClr val="phClr"/> </a:solidFill> <a:gradFill rotWithShape="1"> <a:gsLst> <a:gs pos="0"> <a:schemeClr val="phClr"> <a:tint val="50000"/> <a:satMod val="300000"/> </a:schemeClr> </a:gs> <a:gs pos="35000"> <a:schemeClr val="phClr"> <a:tint val="37000"/> <a:satMod val="300000"/> </a:schemeClr> </a:gs> <a:gs pos="100000"> <a:schemeClr val="phClr"> <a:tint val="15000"/> <a:satMod val="350000"/> </a:schemeClr> </a:gs> </a:gsLst> <a:lin ang="16200000" scaled="1"/> </a:gradFill> <!-- Ignore Code -->
The document above uses idx as the second corresponding to a:fillStyleLst, which is the value of a:gradFill gradient
The a:gsLst of a:gradFill for the theme at this time will be used for shape filling, if the fill color of the shape is also a gradient color, if the gradient color does not set a:gsLst value, then the value of a:gsLst within the theme will be used.Use shape-defined if the shape itself is defined
See the picture below to see how to get it
Most of the inheritance and relationships that exist are written out in the OpenXML SDK, and only those functions that compare corners need to be implemented by themselves
For the behavior of each property of a gradient, see Office Open XML - DrawingML - Shapes - Gradient Fill
See the official documents GradientFill Class (DocumentFormat.OpenXml.Drawing)