public BaseImageOperationsExtensionTest() { this.options = new GraphicsOptions { AntialiasSubpixelDepth = 99, Antialias = false, BlendPercentage = 0.9f, AlphaCompositionMode = PixelAlphaCompositionMode.DestOut, ColorBlendingMode = PixelColorBlendingMode.Multiply }; this.textOptions = new TextOptions { TabWidth = 99 }; this.shapeOptions = new ShapeOptions { IntersectionRule = IntersectionRule.Nonzero }; this.source = new Image <Rgba32>(91 + 324, 123 + 56); this.rect = new Rectangle(91, 123, 324, 56); // make this random? this.internalOperations = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(this.source.GetConfiguration(), this.source, false); this.internalOperations.SetShapeOptions(this.shapeOptions); this.internalOperations.SetTextOptions(this.textOptions); this.internalOperations.SetGraphicsOptions(this.options); this.operations = this.internalOperations; }
public void Initialize() { IMapTiles.GameTileScale = GameTileScale; IMapTiles.BufferSize = bufferSize; foreach (var b in TagParser.cachedBitmaps) { cachedBitmaps.Add(b.Key, Image.Load(b.Value)); } foreach (var g in TagParser.allStyleGroups) { foreach (var s in g.Value) { foreach (var p in s.Value.PaintOperations) { cachedPaints.Add(p.Id, SetPaintForTPP(p)); cachedGameTilePens.Add(p.Id, SetPenForGameTile(p)); } } } dOpts = new DrawingOptions(); ShapeOptions so = new ShapeOptions(); so.IntersectionRule = IntersectionRule.OddEven; //already the default; GraphicsOptions go = new GraphicsOptions(); go.Antialias = true; go.AntialiasSubpixelDepth = 16; //defaults to 16, would 4 improve speed? would 25 or 64 improve quality? (not visible so from early testing.) dOpts.GraphicsOptions = go; dOpts.ShapeOptions = so; }
public void GetDefaultOptionsFromProcessingContext_AlwaysReturnsInstance() { var config = new Configuration(); var context = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(config, null, true); ShapeOptions ctxOptions = context.GetShapeOptions(); Assert.NotNull(ctxOptions); }
public void GetDefaultOptionsFromConfiguration_AlwaysReturnsSameValue() { var config = new Configuration(); ShapeOptions options = config.GetShapeOptions(); ShapeOptions options2 = config.GetShapeOptions(); Assert.Equal(options, options2); }
public void GetDefaultOptionsFromConfiguration_AlwaysReturnsInstance() { var config = new Configuration(); Assert.DoesNotContain(typeof(ShapeOptions), config.Properties.Keys); ShapeOptions options = config.GetShapeOptions(); Assert.NotNull(options); }
public void SetDefaultOptionsOnConfiguration() { var option = new ShapeOptions(); var config = new Configuration(); config.SetShapeOptions(option); Assert.Equal(option, config.Properties[typeof(ShapeOptions)]); }
public void GetDefaultOptionsFromConfiguration_IgnoreIncorectlyTypesDictionEntry() { var config = new Configuration(); config.Properties[typeof(ShapeOptions)] = "wronge type"; ShapeOptions options = config.GetShapeOptions(); Assert.NotNull(options); Assert.IsType <ShapeOptions>(options); }
public void GetDefaultOptionsFromProcessingContext_IgnoreIncorectlyTypesDictionEntry() { var config = new Configuration(); var context = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(config, null, true); context.Properties[typeof(ShapeOptions)] = "wronge type"; ShapeOptions options = context.GetShapeOptions(); Assert.NotNull(options); Assert.IsType <ShapeOptions>(options); }
//Instantiate the effect and set some of it's variables public void ShowEffect(GameObject Target ,ShapeOptions input_ShapeOptions ) { if (input_ShapeOptions == ShapeOptions.SphereShape) { Vector3 dir = Target.transform.position - transform.position; Quaternion Rotation = Quaternion.LookRotation(dir); GameObject ThisEffect = Instantiate(GenericEffect_Sphere,gameObject.transform.position,Rotation) as GameObject; ThisEffect.transform.localScale = gameObject.transform.lossyScale * 1.01f; ThisEffect.transform.parent = gameObject.transform; AnimateEffectScript AES = ThisEffect.transform.FindChild("Effect").gameObject.GetComponent<AnimateEffectScript>(); AES.StartColor = StartColor; AES.EndColor = EndColor; AES.AnimatedTexture = AnimatedTexture; AES._fps = (int)FramesPerSecond; AES._uvTieX = XFrames; AES._uvTieY = YFrames; AES.DestroyOnComplete = DestroyOnComplete; if (AnimatedTexture.name.IndexOf("Particle") == 0) { ThisEffect.transform.rotation = Quaternion.Euler(ThisEffect.transform.rotation.eulerAngles.x,ThisEffect.transform.rotation.eulerAngles.y,Random.Range(0f,360f)); } } else { GameObject ThisEffect = Instantiate(GenericEffect_Plane,Target.transform.position,gameObject.transform.rotation) as GameObject; ThisEffect.transform.localScale = gameObject.transform.lossyScale * 1.01f; ThisEffect.transform.parent = gameObject.transform; AnimateEffectScript AES = ThisEffect.transform.FindChild("Effect").gameObject.GetComponent<AnimateEffectScript>(); AES.StartColor = StartColor; AES.EndColor = EndColor; AES.AnimatedTexture = AnimatedTexture; AES._fps = (int)FramesPerSecond; AES._uvTieX = XFrames; AES._uvTieY = YFrames; AES.DestroyOnComplete = DestroyOnComplete; if (AES.AnimatedTexture.name.IndexOf("Particle") == 0) { ThisEffect.transform.localRotation = Quaternion.Euler(0f,Random.Range(0f,180f),0f); } } }
public void GetDefaultOptionsFromProcessingContext_FallbackToConfigsInstance() { var option = new ShapeOptions(); var config = new Configuration(); config.SetShapeOptions(option); var context = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(config, null, true); ShapeOptions ctxOptions = context.GetShapeOptions(); Assert.Equal(option, ctxOptions); }
public void SetDefaultOptionsOnProcessingContext() { var option = new ShapeOptions(); var config = new Configuration(); var context = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(config, null, true); context.SetShapeOptions(option); // sets the prop on the processing context not on the configuration Assert.Equal(option, context.Properties[typeof(ShapeOptions)]); Assert.DoesNotContain(typeof(ShapeOptions), config.Properties.Keys); }
public void ShowEffect(GameObject Target, ShapeOptions input_ShapeOptions) { if (input_ShapeOptions == ShapeOptions.SphereShape) { //Vector3 dir = Target.transform.position - transform.position; //Quaternion rotation = Quaternion.LookRotation(dir); //GameObject ThisEffect = Instantiate(GenericEffect_Sphere, gameObject.transform.position, rotation) as GameObject; } else { } }
private void RenderShapeToCanvas(SvgGraphicsElement svgGraphicsElement, IPath path) { var matrix = CalulateUpdatedMatrix(svgGraphicsElement); var brush = svgGraphicsElement.CreateFillPaintServer()?.Accept(BrushGenerator <TPixel> .Instance); IBrush strokFill = null; IPath outline = null; if (svgGraphicsElement.StrokeWidth > 0) { strokFill = svgGraphicsElement.CreateStrokePaintServer()?.Accept(BrushGenerator <TPixel> .Instance); if (strokFill != null) { var pattern = svgGraphicsElement.Style.StrokeDashArray.Value?.Select(X => X.Value).ToArray(); var joint = svgGraphicsElement.Style.StrokeLineJoin.AsJointStyle(); var end = svgGraphicsElement.Style.StrokeLineCap.AsEndCapStyle(); if (pattern == null || pattern.Length == 0) { outline = path.GenerateOutline(svgGraphicsElement.StrokeWidth, joint, end); } else { outline = path.GenerateOutline(svgGraphicsElement.StrokeWidth, pattern, false, joint, end); } } } var shapeOptions = new ShapeOptions { IntersectionRule = IntersectionRule.Nonzero }; var shapeGraphicsOptions = new DrawingOptions() { ShapeOptions = shapeOptions }; if (brush != null) { image.Fill(shapeGraphicsOptions, brush, path.Transform(matrix)); } if (outline != null && strokFill != null) { image.Fill(shapeGraphicsOptions, strokFill, outline.Transform(matrix)); } }
public void BrushDefaultOptions() { this.operations.Clear(this.brush); FillProcessor processor = this.Verify <FillProcessor>(); ShapeOptions expectedOptions = this.shapeOptions; Assert.Equal(expectedOptions, processor.Options.ShapeOptions); Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage); Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode); Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode); Assert.Equal(this.brush, processor.Brush); }
public void GetDefaultOptionsFromConfiguration_SettingNullThenReturnsNewInstance() { var config = new Configuration(); ShapeOptions options = config.GetShapeOptions(); Assert.NotNull(options); config.SetShapeOptions((ShapeOptions)null); ShapeOptions options2 = config.GetShapeOptions(); Assert.NotNull(options2); // we set it to null should now be a new instance Assert.NotEqual(options, options2); }
public void ColorSet() { this.operations.Clear(this.nonDefaultOptions, Color.Red); FillProcessor processor = this.Verify <FillProcessor>(); ShapeOptions expectedOptions = this.shapeOptions; Assert.NotEqual(expectedOptions, processor.Options.ShapeOptions); Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage); Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode); Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode); Assert.NotEqual(this.brush, processor.Brush); SolidBrush brush = Assert.IsType <SolidBrush>(processor.Brush); Assert.Equal(Color.Red, brush.Color); }
public BaseImageOperationsExtensionTest() { this.options = new GraphicsOptions { Antialias = false }; this.textOptions = new TextOptions { TabWidth = 99 }; this.shapeOptions = new ShapeOptions { IntersectionRule = IntersectionRule.Nonzero }; this.source = new Image <Rgba32>(91 + 324, 123 + 56); this.rect = new Rectangle(91, 123, 324, 56); // make this random? this.internalOperations = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(this.source.GetConfiguration(), this.source, false); this.internalOperations.SetShapeOptions(this.shapeOptions); this.internalOperations.SetTextOptions(this.textOptions); this.internalOperations.SetGraphicsOptions(this.options); this.operations = this.internalOperations; }
public void UpdateDefaultOptionsOnConfiguration_AlwaysNewInstance() { var option = new ShapeOptions() { IntersectionRule = IntersectionRule.Nonzero }; var config = new Configuration(); config.SetShapeOptions(option); config.SetShapeOptions(o => { Assert.Equal(IntersectionRule.Nonzero, o.IntersectionRule); // has origional values o.IntersectionRule = IntersectionRule.OddEven; }); ShapeOptions returnedOption = config.GetShapeOptions(); Assert.Equal(IntersectionRule.OddEven, returnedOption.IntersectionRule); Assert.Equal(IntersectionRule.Nonzero, option.IntersectionRule); // hasn't been mutated }
public void UpdateDefaultOptionsOnProcessingContext_AlwaysNewInstance() { var option = new ShapeOptions() { IntersectionRule = IntersectionRule.Nonzero }; var config = new Configuration(); var context = new FakeImageOperationsProvider.FakeImageOperations <Rgba32>(config, null, true); context.SetShapeOptions(option); context.SetShapeOptions(o => { Assert.Equal(IntersectionRule.Nonzero, o.IntersectionRule); // has origional values o.IntersectionRule = IntersectionRule.OddEven; }); ShapeOptions returnedOption = context.GetShapeOptions(); Assert.Equal(IntersectionRule.OddEven, returnedOption.IntersectionRule); Assert.Equal(IntersectionRule.Nonzero, option.IntersectionRule); // hasn't been mutated }
//public void Apply(BlipStoreEntry bse, Shape shape, ShapeOptions options, Rectangle bounds, ConversionContext ctx, string spid, ref Point size) public void Apply(List <ArrayList> VMLEntriesList, ConversionContext ctx) { _ctx = ctx; BlipStoreEntry bse; _writer.WriteStartDocument(); _writer.WriteStartElement("xml"); _writer.WriteStartElement("o", "shapelayout", OpenXmlNamespaces.Office); _writer.WriteAttributeString("v", "ext", OpenXmlNamespaces.VectorML, "edit"); _writer.WriteStartElement("o", "idmap", OpenXmlNamespaces.Office); _writer.WriteAttributeString("v", "ext", OpenXmlNamespaces.VectorML, "edit"); _writer.WriteAttributeString("data", "1079"); _writer.WriteEndElement(); //idmap _writer.WriteEndElement(); //shapelayout //v:shapetype PictureFrameType type = new PictureFrameType(); type.Convert(new VMLShapeTypeMapping(_ctx, _writer)); foreach (ArrayList VMLEntry in VMLEntriesList) { bse = (BlipStoreEntry)VMLEntry[0]; ShapeOptions options = (ShapeOptions)VMLEntry[2]; Rectangle bounds = (Rectangle)VMLEntry[3]; string spid = (string)VMLEntry[4]; Point size = (Point)VMLEntry[5]; ImagePart imgPart = copyPicture(bse, ref size); if (imgPart != null) { //v:shape _writer.WriteStartElement("v", "shape", OpenXmlNamespaces.VectorML); _writer.WriteAttributeString("id", spid); _writer.WriteAttributeString("type", "#" + VMLShapeTypeMapping.GenerateTypeId(type)); StringBuilder style = new StringBuilder(); style.Append("position:absolute;"); style.Append("left:" + (new EmuValue(Utils.MasterCoordToEMU(bounds.Left)).ToPoints()).ToString() + "pt;"); style.Append("top:" + (new EmuValue(Utils.MasterCoordToEMU(bounds.Top)).ToPoints()).ToString() + "pt;"); style.Append("width:").Append(new EmuValue(Utils.MasterCoordToEMU(bounds.Width)).ToPoints()).Append("pt;"); style.Append("height:").Append(new EmuValue(Utils.MasterCoordToEMU(bounds.Height)).ToPoints()).Append("pt;"); _writer.WriteAttributeString("style", style.ToString()); foreach (ShapeOptions.OptionEntry entry in options.OptionsByID.Values) { switch (entry.pid) { //BORDERS case ShapeOptions.PropertyId.borderBottomColor: RGBColor bottomColor = new RGBColor((int)entry.op, RGBColor.ByteOrder.RedFirst); _writer.WriteAttributeString("o", "borderbottomcolor", OpenXmlNamespaces.Office, "#" + bottomColor.SixDigitHexCode); break; case ShapeOptions.PropertyId.borderLeftColor: RGBColor leftColor = new RGBColor((int)entry.op, RGBColor.ByteOrder.RedFirst); _writer.WriteAttributeString("o", "borderleftcolor", OpenXmlNamespaces.Office, "#" + leftColor.SixDigitHexCode); break; case ShapeOptions.PropertyId.borderRightColor: RGBColor rightColor = new RGBColor((int)entry.op, RGBColor.ByteOrder.RedFirst); _writer.WriteAttributeString("o", "borderrightcolor", OpenXmlNamespaces.Office, "#" + rightColor.SixDigitHexCode); break; case ShapeOptions.PropertyId.borderTopColor: RGBColor topColor = new RGBColor((int)entry.op, RGBColor.ByteOrder.RedFirst); _writer.WriteAttributeString("o", "bordertopcolor", OpenXmlNamespaces.Office, "#" + topColor.SixDigitHexCode); break; } } //v:imageData _writer.WriteStartElement("v", "imagedata", OpenXmlNamespaces.VectorML); _writer.WriteAttributeString("o", "relid", OpenXmlNamespaces.Office, imgPart.RelIdToString); _writer.WriteAttributeString("o", "title", OpenXmlNamespaces.Office, ""); _writer.WriteEndElement(); //imagedata //close v:shape _writer.WriteEndElement(); } } _writer.WriteEndElement(); //xml _writer.WriteEndDocument(); _writer.Flush(); }
public void Apply(ShapeOptions so) { RegularContainer slide = so.FirstAncestorWithType <Slide>(); if (slide == null) { slide = so.FirstAncestorWithType <Note>(); } if (slide == null) { slide = so.FirstAncestorWithType <Handout>(); } string colorval = ""; string colorval2 = ""; uint fillType = 0; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillType)) { fillType = so.OptionsByID[ShapeOptions.PropertyId.fillType].op; } switch (fillType) { case 0x0: //solid string SchemeType = ""; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, (RegularContainer)slide, so, ref SchemeType); } else { colorval = "FFFFFF"; //TODO: find out which color to use in this case } _writer.WriteStartElement("a", "solidFill", OpenXmlNamespaces.DrawingML); if (SchemeType.Length == 0) { _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", colorval); } else { _writer.WriteStartElement("a", "schemeClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", SchemeType); } if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } _writer.WriteEndElement(); _writer.WriteEndElement(); break; case 0x1: //pattern uint blipIndex1 = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; DrawingGroup gr1 = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType <PPDrawingGroup>().Children[0]; BlipStoreEntry bse1 = (BlipStoreEntry)gr1.FirstChildWithType <BlipStoreContainer>().Children[(int)blipIndex1 - 1]; BitmapBlip b1 = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse1.foDelay]; _writer.WriteStartElement("a", "pattFill", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("prst", Utils.getPrstForPatternCode(b1.m_bTag)); //Utils.getPrstForPattern(blipNamePattern)); _writer.WriteStartElement("a", "fgClr", OpenXmlNamespaces.DrawingML); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so)); _writer.WriteEndElement(); _writer.WriteEndElement(); _writer.WriteStartElement("a", "bgClr", OpenXmlNamespaces.DrawingML); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); } else { colorval = "ffffff"; //TODO: find out which color to use in this case } _writer.WriteAttributeString("val", colorval); _writer.WriteEndElement(); _writer.WriteEndElement(); _writer.WriteEndElement(); break; case 0x2: //texture case 0x3: //picture uint blipIndex = 0; string strUrl = ""; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBlip)) { blipIndex = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; } else if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.Pib)) { blipIndex = so.OptionsByID[ShapeOptions.PropertyId.Pib].op; } else if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBlipFlags) && so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBlipName)) { uint flags = so.OptionsByID[ShapeOptions.PropertyId.fillBlipFlags].op; bool comment = !Tools.Utils.BitmaskToBool(flags, 0x1); bool file = Tools.Utils.BitmaskToBool(flags, 0x1); bool url = Tools.Utils.BitmaskToBool(flags, 0x1 << 1); bool DoNotSave = Tools.Utils.BitmaskToBool(flags, 0x1 << 2); bool LinkToFile = Tools.Utils.BitmaskToBool(flags, 0x1 << 3); if (url) { strUrl = ASCIIEncoding.ASCII.GetString(so.OptionsByID[ShapeOptions.PropertyId.fillBlipName].opComplex); strUrl = strUrl.Replace("\0", ""); } } else { break; } //string blipName = Encoding.UTF8.GetString(so.OptionsByID[ShapeOptions.PropertyId.fillBlipName].opComplex); string rId = ""; DrawingGroup gr = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType <PPDrawingGroup>().Children[0]; ImagePart imgPart = null; if (strUrl.Length > 0) { ExternalRelationship er = _parentSlideMapping.targetPart.AddExternalRelationship(OpenXmlRelationshipTypes.Image, strUrl); rId = er.Id; _writer.WriteStartElement("a", "blipFill", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("dpi", "0"); _writer.WriteAttributeString("rotWithShape", "1"); _writer.WriteStartElement("a", "blip", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("r", "link", OpenXmlNamespaces.Relationships, rId); _writer.WriteEndElement(); _writer.WriteElementString("a", "srcRect", OpenXmlNamespaces.DrawingML, ""); if (fillType == 0x3) { _writer.WriteStartElement("a", "stretch", OpenXmlNamespaces.DrawingML); _writer.WriteElementString("a", "fillRect", OpenXmlNamespaces.DrawingML, ""); _writer.WriteEndElement(); } else { _writer.WriteStartElement("a", "tile", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("tx", "0"); _writer.WriteAttributeString("ty", "0"); _writer.WriteAttributeString("sx", "100000"); _writer.WriteAttributeString("sy", "100000"); _writer.WriteAttributeString("flip", "none"); _writer.WriteAttributeString("algn", "tl"); _writer.WriteEndElement(); } _writer.WriteEndElement(); } else if (blipIndex <= gr.FirstChildWithType <BlipStoreContainer>().Children.Count) { BlipStoreEntry bse = (BlipStoreEntry)gr.FirstChildWithType <BlipStoreContainer>().Children[(int)blipIndex - 1]; if (_ctx.Ppt.PicturesContainer._pictures.ContainsKey(bse.foDelay)) { Record rec = _ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; if (rec is BitmapBlip) { BitmapBlip b = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); imgPart.TargetDirectory = "..\\media"; System.IO.Stream outStream = imgPart.GetStream(); outStream.Write(b.m_pvBits, 0, b.m_pvBits.Length); } else { MetafilePictBlip b = (MetafilePictBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); imgPart.TargetDirectory = "..\\media"; System.IO.Stream outStream = imgPart.GetStream(); byte[] decompressed = b.Decrompress(); outStream.Write(decompressed, 0, decompressed.Length); } rId = imgPart.RelIdToString; _writer.WriteStartElement("a", "blipFill", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("dpi", "0"); _writer.WriteAttributeString("rotWithShape", "1"); _writer.WriteStartElement("a", "blip", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("r", "embed", OpenXmlNamespaces.Relationships, rId); _writer.WriteEndElement(); _writer.WriteElementString("a", "srcRect", OpenXmlNamespaces.DrawingML, ""); if (fillType == 0x3) { _writer.WriteStartElement("a", "stretch", OpenXmlNamespaces.DrawingML); _writer.WriteElementString("a", "fillRect", OpenXmlNamespaces.DrawingML, ""); _writer.WriteEndElement(); } else { _writer.WriteStartElement("a", "tile", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("tx", "0"); _writer.WriteAttributeString("ty", "0"); _writer.WriteAttributeString("sx", "100000"); _writer.WriteAttributeString("sy", "100000"); _writer.WriteAttributeString("flip", "none"); _writer.WriteAttributeString("algn", "tl"); _writer.WriteEndElement(); } _writer.WriteEndElement(); } } break; case 0x4: //shade case 0x5: //shadecenter case 0x6: //shadeshape _writer.WriteStartElement("a", "gradFill", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("rotWithShape", "1"); _writer.WriteStartElement("a", "gsLst", OpenXmlNamespaces.DrawingML); bool useFillAndBack = true; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillShadeColors)) { byte[] colors = so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].opComplex; if (colors != null && colors.Length > 0) { useFillAndBack = false; ShapeOptions.OptionEntry type = so.OptionsByID[ShapeOptions.PropertyId.fillShadeType]; UInt16 nElems = System.BitConverter.ToUInt16(colors, 0); UInt16 nElemsAlloc = System.BitConverter.ToUInt16(colors, 2); UInt16 cbElem = System.BitConverter.ToUInt16(colors, 4); List <string> positions = new List <string>(); switch (nElems) { case 1: case 2: case 3: case 4: case 5: positions.Add("0"); positions.Add("30000"); positions.Add("65000"); positions.Add("90000"); positions.Add("100000"); break; case 6: case 7: case 8: case 9: case 10: default: positions.Add("0"); positions.Add("8000"); positions.Add("13000"); positions.Add("21000"); positions.Add("52000"); positions.Add("56000"); positions.Add("58000"); positions.Add("71000"); positions.Add("94000"); positions.Add("100000"); break; } string[] alphas = new string[nElems]; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity)) { decimal end = Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)); decimal start = Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)); alphas[0] = start.ToString(); for (int i = 1; i < nElems - 1; i++) { alphas[i] = Math.Round(start + (end - start) / 3 * i).ToString(); } //alphas[1] = Math.Round(start + (end - start) / 3).ToString(); //alphas[2] = Math.Round(start + (end - start) / 3 * 2).ToString(); //alphas[3] = Math.Round(start + (end - start) / 3 * 3).ToString(); alphas[nElems - 1] = end.ToString(); } for (int i = 0; i < nElems * cbElem; i += cbElem) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(System.BitConverter.ToUInt32(colors, 6 + i), slide, so); _writer.WriteStartElement("a", "gs", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("pos", positions[i / cbElem]); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", colorval); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", alphas[i / cbElem]); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } _writer.WriteEndElement(); _writer.WriteEndElement(); } } } if (useFillAndBack) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so); _writer.WriteStartElement("a", "gs", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("pos", "0"); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", colorval); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } _writer.WriteEndElement(); _writer.WriteEndElement(); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); } else { if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.shadowColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.shadowColor].op, slide, so); } else { //use filColor } } _writer.WriteStartElement("a", "gs", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("pos", "100000"); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", colorval); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } _writer.WriteEndElement(); _writer.WriteEndElement(); } _writer.WriteEndElement(); //gsLst switch (fillType) { case 0x5: case 0x6: _writer.WriteStartElement("a", "path", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("path", "shape"); _writer.WriteStartElement("a", "fillToRect", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("l", "50000"); _writer.WriteAttributeString("t", "50000"); _writer.WriteAttributeString("r", "50000"); _writer.WriteAttributeString("b", "50000"); _writer.WriteEndElement(); _writer.WriteEndElement(); //path break; default: _writer.WriteStartElement("a", "path", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("path", "rect"); _writer.WriteStartElement("a", "fillToRect", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("r", "100000"); _writer.WriteAttributeString("b", "100000"); _writer.WriteEndElement(); _writer.WriteEndElement(); //path break; } _writer.WriteEndElement(); //gradFill break; case 0x7: //shadescale _writer.WriteStartElement("a", "gradFill", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("rotWithShape", "1"); _writer.WriteStartElement("a", "gsLst", OpenXmlNamespaces.DrawingML); decimal angle = 90; bool switchColors = false; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillAngle)) { if (so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op != 0) { byte[] bytes = BitConverter.GetBytes(so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op); int integral = BitConverter.ToInt16(bytes, 0); uint fractional = BitConverter.ToUInt16(bytes, 2); Decimal result = integral + ((decimal)fractional / (decimal)65536); angle = 65536 - fractional; //I have no idea why this works!! angle = angle - 90; if (angle < 0) { angle += 360; switchColors = true; } } } Dictionary <int, string> shadeColorsDic = new Dictionary <int, string>(); List <string> shadeColors = new List <string>(); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillShadeColors) && so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].opComplex != null && so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].opComplex.Length > 0) { uint length = so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].op; //An IMsoArray record that specifies colors and their relative positions. //Each element of the array contains an OfficeArtCOLORREF record color and a FixedPoint, as specified in [MS-OSHARED] //section 2.2.1.6, that specifies its relative position along the gradient vector. byte[] data = so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].opComplex; int pos = 0; string colval; FixedPointNumber fixedpoint; UInt16 nElems = BitConverter.ToUInt16(data, pos); pos += 2; UInt16 nElemsAlloc = BitConverter.ToUInt16(data, pos); pos += 2; UInt16 cbElem = BitConverter.ToUInt16(data, pos); pos += 2; if (cbElem == 0xFFF0) { //If this value is 0xFFF0 then this record is an array of truncated 8 byte elements. Only the 4 low-order bytes are recorded. Each element's 4 high-order bytes equal 0x00000000 and each element's 4 low-order bytes are contained in data. } else { while (pos < length) { colval = Utils.getRGBColorFromOfficeArtCOLORREF(BitConverter.ToUInt32(data, pos), slide, so); pos += 4; fixedpoint = new FixedPointNumber(BitConverter.ToUInt16(data, pos), BitConverter.ToUInt16(data, pos + 2)); shadeColors.Insert(0, colval); pos += 4; } } } else { bool switchcolors = false; if (switchColors & so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); } else { if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so); } else { colorval = "FFFFFF"; //TODO: find out which color to use in this case switchcolors = true; } } if (switchColors | !so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) { colorval2 = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so); } else { colorval2 = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); } if (switchcolors) { //this is a workaround for a bug. Further analysis necessarry string dummy = colorval; colorval = colorval2; colorval2 = dummy; } shadeColors.Add(colorval); shadeColors.Add(colorval2); } int gspos; string col; for (int i = 0; i < shadeColors.Count; i++) { col = shadeColors[i]; if (i == 0) { gspos = 0; } else if (i == shadeColors.Count - 1) { gspos = 100000; } else { gspos = i * 100000 / shadeColors.Count; } _writer.WriteStartElement("a", "gs", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("pos", gspos.ToString()); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", col); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillShadeType)) { uint flags = so.OptionsByID[ShapeOptions.PropertyId.fillShadeType].op; bool none = Tools.Utils.BitmaskToBool(flags, 0x1); bool gamma = Tools.Utils.BitmaskToBool(flags, 0x1 << 1); bool sigma = Tools.Utils.BitmaskToBool(flags, 0x1 << 2); bool band = Tools.Utils.BitmaskToBool(flags, 0x1 << 3); bool onecolor = Tools.Utils.BitmaskToBool(flags, 0x1 << 4); if (gamma) { _writer.WriteElementString("a", "gamma", OpenXmlNamespaces.DrawingML, ""); } if (band) { _writer.WriteStartElement("a", "shade", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", "37255"); _writer.WriteEndElement(); } if (gamma) { _writer.WriteElementString("a", "invGamma", OpenXmlNamespaces.DrawingML, ""); } } _writer.WriteEndElement(); _writer.WriteEndElement(); } ////new colorval //_writer.WriteStartElement("a", "gs", OpenXmlNamespaces.DrawingML); //_writer.WriteAttributeString("pos", "100000"); //_writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); //_writer.WriteAttributeString("val", colorval2); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackOpacity)) //{ // _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); // _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteEndElement(); //} //_writer.WriteEndElement(); //_writer.WriteEndElement(); _writer.WriteEndElement(); //gsLst _writer.WriteStartElement("a", "lin", OpenXmlNamespaces.DrawingML); angle *= 60000; //if (angle > 5400000) angle = 5400000; _writer.WriteAttributeString("ang", angle.ToString()); _writer.WriteAttributeString("scaled", "1"); _writer.WriteEndElement(); _writer.WriteEndElement(); break; case 0x8: //shadetitle case 0x9: //background break; } }
public void ShowEffect(Vector3 Target, ShapeOptions input_ShapeOptions) { }
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source) { Configuration configuration = this.Configuration; ShapeOptions shapeOptions = this.definition.Options.ShapeOptions; GraphicsOptions graphicsOptions = this.definition.Options.GraphicsOptions; IBrush brush = this.definition.Brush; Region region = this.definition.Region; Rectangle rect = region.Bounds; bool isSolidBrushWithoutBlending = IsSolidBrushWithoutBlending(graphicsOptions, this.definition.Brush, out SolidBrush solidBrush); TPixel solidBrushColor = isSolidBrushWithoutBlending ? solidBrush.Color.ToPixel <TPixel>() : default; // Align start/end positions. int minX = Math.Max(0, rect.Left); int maxX = Math.Min(source.Width, rect.Right); int minY = Math.Max(0, rect.Top); int maxY = Math.Min(source.Height, rect.Bottom); if (minX >= maxX) { return; // no effect inside image; } if (minY >= maxY) { return; // no effect inside image; } int maxIntersections = region.MaxIntersections; float subpixelCount = 4; // we need to offset the pixel grid to account for when we outline a path. // basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5] // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the# // region to align with the pixel grid. if (graphicsOptions.Antialias) { subpixelCount = graphicsOptions.AntialiasSubpixelDepth; if (subpixelCount < 4) { subpixelCount = 4; } } using (BrushApplicator <TPixel> applicator = brush.CreateApplicator(configuration, graphicsOptions, source, rect)) { int scanlineWidth = maxX - minX; MemoryAllocator allocator = this.Configuration.MemoryAllocator; using (IMemoryOwner <float> bBuffer = allocator.Allocate <float>(maxIntersections)) using (IMemoryOwner <float> bScanline = allocator.Allocate <float>(scanlineWidth)) { bool scanlineDirty = true; float subpixelFraction = 1f / subpixelCount; float subpixelFractionPoint = subpixelFraction / subpixelCount; Span <float> buffer = bBuffer.Memory.Span; Span <float> scanline = bScanline.Memory.Span; for (int y = minY; y < maxY; y++) { if (scanlineDirty) { scanline.Clear(); scanlineDirty = false; } float yPlusOne = y + 1; for (float subPixel = y; subPixel < yPlusOne; subPixel += subpixelFraction) { int pointsFound = region.Scan(subPixel, buffer, configuration, shapeOptions.IntersectionRule); if (pointsFound == 0) { // nothing on this line, skip continue; } for (int point = 0; point < pointsFound && point < buffer.Length - 1; point += 2) { // points will be paired up float scanStart = buffer[point] - minX; float scanEnd = buffer[point + 1] - minX; int startX = (int)MathF.Floor(scanStart); int endX = (int)MathF.Floor(scanEnd); if (startX >= 0 && startX < scanline.Length) { for (float x = scanStart; x < startX + 1; x += subpixelFraction) { scanline[startX] += subpixelFractionPoint; scanlineDirty = true; } } if (endX >= 0 && endX < scanline.Length) { for (float x = endX; x < scanEnd; x += subpixelFraction) { scanline[endX] += subpixelFractionPoint; scanlineDirty = true; } } int nextX = startX + 1; endX = Math.Min(endX, scanline.Length); // reduce to end to the right edge nextX = Math.Max(nextX, 0); for (int x = nextX; x < endX; x++) { scanline[x] += subpixelFraction; scanlineDirty = true; } } } if (scanlineDirty) { if (!graphicsOptions.Antialias) { bool hasOnes = false; bool hasZeros = false; for (int x = 0; x < scanlineWidth; x++) { if (scanline[x] >= 0.5) { scanline[x] = 1; hasOnes = true; } else { scanline[x] = 0; hasZeros = true; } } if (isSolidBrushWithoutBlending && hasOnes != hasZeros) { if (hasOnes) { source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrushColor); } continue; } } applicator.Apply(scanline, minX, y); } } } } }
override public void Apply(RegularContainer slide) { this.Slide = (Slide)slide; TraceLogger.DebugInternal("SlideMapping.Apply"); // Associate slide with slide layout SlideAtom slideAtom = slide.FirstChildWithType <SlideAtom>(); UInt32 mainMasterId = GetMainMasterId(slideAtom); MasterLayoutManager layoutManager = _ctx.GetOrCreateLayoutManagerByMasterId(mainMasterId); SlideLayoutPart layoutPart = null; RoundTripContentMasterId12 masterInfo = slide.FirstChildWithType <RoundTripContentMasterId12>(); // PPT2007 OOXML-Layout if (masterInfo != null) { layoutPart = layoutManager.GetLayoutPartByInstanceId(masterInfo.ContentMasterInstanceId); } // Pre-PPT2007 Title master layout else if (mainMasterId != slideAtom.MasterId) { layoutPart = layoutManager.GetOrCreateLayoutPartForTitleMasterId(slideAtom.MasterId); } // Pre-PPT2007 SSlideLayoutAtom primitive SlideLayoutType layout else { MainMaster m = (MainMaster)_ctx.Ppt.FindMasterRecordById(slideAtom.MasterId); if (m.Layouts.Count == 1 && slideAtom.Layout.Geom == SlideLayoutType.Blank) { foreach (string layout in m.Layouts.Values) { string output = Tools.Utils.replaceOutdatedNamespaces(layout); layoutPart = layoutManager.GetOrCreateLayoutPartByCode(output); } } else { layoutPart = layoutManager.GetOrCreateLayoutPartByLayoutType(slideAtom.Layout.Geom, slideAtom.Layout.PlaceholderTypes); } } this.targetPart.ReferencePart(layoutPart); // Start the document _writer.WriteStartDocument(); _writer.WriteStartElement("p", "sld", OpenXmlNamespaces.PresentationML); // Force declaration of these namespaces at document start _writer.WriteAttributeString("xmlns", "a", null, OpenXmlNamespaces.DrawingML); // Force declaration of these namespaces at document start _writer.WriteAttributeString("xmlns", "r", null, OpenXmlNamespaces.Relationships); if (Tools.Utils.BitmaskToBool(slideAtom.Flags, 0x1 << 0) == false) { _writer.WriteAttributeString("showMasterSp", "0"); } // TODO: Write slide data of master slide _writer.WriteStartElement("p", "cSld", OpenXmlNamespaces.PresentationML); ShapeContainer sc = slide.FirstChildWithType <PPDrawing>().FirstChildWithType <DrawingContainer>().FirstChildWithType <ShapeContainer>(); if (sc != null) { Shape sh = sc.FirstChildWithType <Shape>(); ShapeOptions so = sc.FirstChildWithType <ShapeOptions>(); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.FillStyleBooleanProperties)) { bool ignore = false; if (sc.AllChildrenWithType <ShapeOptions>().Count > 1) { ShapeOptions so2 = sc.AllChildrenWithType <ShapeOptions>()[1]; if (so2.OptionsByID.ContainsKey(ShapeOptions.PropertyId.FillStyleBooleanProperties)) { FillStyleBooleanProperties p2 = new FillStyleBooleanProperties(so2.OptionsByID[ShapeOptions.PropertyId.FillStyleBooleanProperties].op); if (!p2.fUsefFilled || !p2.fFilled) { ignore = true; } } } SlideAtom sa = slide.FirstChildWithType <SlideAtom>(); if (Tools.Utils.BitmaskToBool(sa.Flags, 0x1 << 2)) { ignore = true; //this means the slide gets its background from the master } if (!ignore) { _writer.WriteStartElement("p", "bg", OpenXmlNamespaces.PresentationML); _writer.WriteStartElement("p", "bgPr", OpenXmlNamespaces.PresentationML); FillStyleBooleanProperties p = new FillStyleBooleanProperties(so.OptionsByID[ShapeOptions.PropertyId.FillStyleBooleanProperties].op); if (p.fUsefFilled & p.fFilled) // so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillType)) { new FillMapping(_ctx, _writer, this).Apply(so); } _writer.WriteElementString("a", "effectLst", OpenXmlNamespaces.DrawingML, ""); _writer.WriteEndElement(); //p:bgPr _writer.WriteEndElement(); //p:bg } } } _writer.WriteStartElement("p", "spTree", OpenXmlNamespaces.PresentationML); shapeTreeMapping = new ShapeTreeMapping(_ctx, _writer); shapeTreeMapping.parentSlideMapping = this; shapeTreeMapping.Apply(slide.FirstChildWithType <PPDrawing>()); checkHeaderFooter(shapeTreeMapping); _writer.WriteEndElement(); //spTree _writer.WriteEndElement(); //cSld // TODO: Write clrMapOvr if (slide.FirstChildWithType <SlideShowSlideInfoAtom>() != null) { new SlideTransitionMapping(_ctx, _writer).Apply(slide.FirstChildWithType <SlideShowSlideInfoAtom>()); } if (slide.FirstChildWithType <ProgTags>() != null) { if (slide.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>() != null) { if (slide.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>().FirstChildWithType <ProgBinaryTagDataBlob>() != null) { new AnimationMapping(_ctx, _writer).Apply(slide.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>().FirstChildWithType <ProgBinaryTagDataBlob>(), this, shapeTreeMapping.animinfos, shapeTreeMapping); } } } // End the document _writer.WriteEndElement(); //sld _writer.WriteEndDocument(); _writer.Flush(); }
public void Write() { // Start the document _writer.WriteStartDocument(); _writer.WriteStartElement("p", "sldMaster", OpenXmlNamespaces.PresentationML); // Force declaration of these namespaces at document start _writer.WriteAttributeString("xmlns", "a", null, OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("xmlns", "r", null, OpenXmlNamespaces.Relationships); _writer.WriteStartElement("p", "cSld", OpenXmlNamespaces.PresentationML); ShapeContainer sc = this.Master.FirstChildWithType <PPDrawing>().FirstChildWithType <DrawingContainer>().FirstChildWithType <ShapeContainer>(); if (sc != null) { Shape sh = sc.FirstChildWithType <Shape>(); ShapeOptions so = sc.FirstChildWithType <ShapeOptions>(); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillType)) { _writer.WriteStartElement("p", "bg", OpenXmlNamespaces.PresentationML); _writer.WriteStartElement("p", "bgPr", OpenXmlNamespaces.PresentationML); new FillMapping(_ctx, _writer, this).Apply(so); _writer.WriteElementString("a", "effectLst", OpenXmlNamespaces.DrawingML, ""); _writer.WriteEndElement(); //p:bgPr _writer.WriteEndElement(); //p:bg } else if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillColor)) { string colorval; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillColor)) { colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, this.Master, so); } else { colorval = "000000"; //TODO: find out which color to use in this case } _writer.WriteStartElement("p", "bg", OpenXmlNamespaces.PresentationML); _writer.WriteStartElement("p", "bgPr", OpenXmlNamespaces.PresentationML); _writer.WriteStartElement("a", "solidFill", OpenXmlNamespaces.DrawingML); _writer.WriteStartElement("a", "srgbClr", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", colorval); if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity) && so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op != 65536) { _writer.WriteStartElement("a", "alpha", OpenXmlNamespaces.DrawingML); _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) _writer.WriteEndElement(); } _writer.WriteEndElement(); _writer.WriteEndElement(); _writer.WriteElementString("a", "effectLst", OpenXmlNamespaces.DrawingML, ""); _writer.WriteEndElement(); //p:bgPr _writer.WriteEndElement(); //p:bg } } _writer.WriteStartElement("p", "spTree", OpenXmlNamespaces.PresentationML); ShapeTreeMapping stm = new ShapeTreeMapping(_ctx, _writer); stm.parentSlideMapping = this; stm.Apply(this.Master.FirstChildWithType <PPDrawing>()); _writer.WriteEndElement(); _writer.WriteEndElement(); // Write clrMap ColorMappingAtom clrMap = this.Master.FirstChildWithType <ColorMappingAtom>(); if (clrMap != null) { // clrMap from ColorMappingAtom wrongly uses namespace DrawingML _writer.WriteStartElement("p", "clrMap", OpenXmlNamespaces.PresentationML); foreach (XmlAttribute attr in clrMap.XmlDocumentElement.Attributes) { if (attr.Prefix != "xmlns") { _writer.WriteAttributeString(attr.LocalName, attr.Value); } } _writer.WriteEndElement(); } else { // In absence of ColorMappingAtom write default clrMap Utils.GetDefaultDocument("clrMap").WriteTo(_writer); } // Write slide layout part id list _writer.WriteStartElement("p", "sldLayoutIdLst", OpenXmlNamespaces.PresentationML); List <SlideLayoutPart> layoutParts = this.LayoutManager.GetAllLayoutParts(); // Master must have at least one SlideLayout or RepairDialog will appear if (layoutParts.Count == 0) { SlideLayoutPart layoutPart = this.LayoutManager.GetOrCreateLayoutPartByLayoutType(0, null); layoutParts.Add(layoutPart); } foreach (SlideLayoutPart slideLayoutPart in layoutParts) { _writer.WriteStartElement("p", "sldLayoutId", OpenXmlNamespaces.PresentationML); _writer.WriteAttributeString("r", "id", OpenXmlNamespaces.Relationships, slideLayoutPart.RelIdToString); _writer.WriteEndElement(); } _writer.WriteEndElement(); if (this.Master.FirstChildWithType <SlideShowSlideInfoAtom>() != null) { new SlideTransitionMapping(_ctx, _writer).Apply(this.Master.FirstChildWithType <SlideShowSlideInfoAtom>()); } if (this.Master.FirstChildWithType <ProgTags>() != null) { if (this.Master.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>() != null) { if (this.Master.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>().FirstChildWithType <ProgBinaryTagDataBlob>() != null) { new AnimationMapping(_ctx, _writer).Apply(this.Master.FirstChildWithType <ProgTags>().FirstChildWithType <ProgBinaryTag>().FirstChildWithType <ProgBinaryTagDataBlob>(), this, stm.animinfos, stm); } } } // Write txStyles RoundTripOArtTextStyles12 roundTripTxStyles = this.Master.FirstChildWithType <RoundTripOArtTextStyles12>(); if (false & roundTripTxStyles != null) { roundTripTxStyles.XmlDocumentElement.WriteTo(_writer); } else { //throw new NotImplementedException("Write txStyles in case of PPT without roundTripTxStyles"); // TODO (pre PP2007) //XmlDocument slideLayoutDoc = Utils.GetDefaultDocument("txStyles"); //slideLayoutDoc.WriteTo(_writer); new TextMasterStyleMapping(_ctx, _writer, this).Apply(this.Master); } // Write theme // // Note: We need to create a new theme part for each master, // even if it they have the same content. // // Otherwise PPT will complain about the structure of the file. ThemePart themePart = _ctx.Pptx.PresentationPart.AddThemePart(); XmlNode xmlDoc; Theme theme = this.Master.FirstChildWithType <Theme>(); if (theme != null) { xmlDoc = theme.XmlDocumentElement; //Tools.Utils.recursiveReplaceOutdatedNamespaces(ref xmlDoc); xmlDoc.WriteTo(themePart.XmlWriter); } else { List <ColorSchemeAtom> schemes = this.Master.AllChildrenWithType <ColorSchemeAtom>(); if (schemes.Count > 0) { new ColorSchemeMapping(_ctx, themePart.XmlWriter).Apply(schemes); } else { // In absence of Theme record use default theme xmlDoc = Utils.GetDefaultDocument("theme"); xmlDoc.WriteTo(themePart.XmlWriter); } } themePart.XmlWriter.Flush(); this.MasterPart.ReferencePart(themePart); // End the document _writer.WriteEndElement(); _writer.WriteEndDocument(); _writer.Flush(); }
private void insertDrawingFillProperties(AreaFormat areaFormat, ShapeOptions so) { var rgbFore = areaFormat.rgbFore; var rgbBack = areaFormat.rgbBack; uint fillType = 0; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillType)) { fillType = so.OptionsByID[ShapeOptions.PropertyId.fillType].op; } switch (fillType) { case 0x0: //solid // a:solidFill (CT_SolidColorFillProperties) this._writer.WriteStartElement(Dml.Prefix, Dml.ShapeEffects.ElSolidFill, Dml.Ns); { // a:srgbColor this._writer.WriteStartElement(Dml.Prefix, Dml.BaseTypes.ElSrgbClr, Dml.Ns); this._writer.WriteAttributeString(Dml.BaseTypes.AttrVal, rgbFore.SixDigitHexCode.ToUpper()); this._writer.WriteEndElement(); // a:srgbColor } this._writer.WriteEndElement(); // a:solidFill break; case 0x1: //pattern //uint blipIndex1 = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; //DrawingGroup gr1 = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType<PPDrawingGroup>().Children[0]; //BlipStoreEntry bse1 = (BlipStoreEntry)gr1.FirstChildWithType<BlipStoreContainer>().Children[(int)blipIndex1 - 1]; //BitmapBlip b1 = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse1.foDelay]; //_writer.WriteStartElement(Dml.Prefix, "pattFill", Dml.Ns); //_writer.WriteAttributeString("prst", Utils.getPrstForPatternCode(b1.m_bTag)); //Utils.getPrstForPattern(blipNamePattern)); //_writer.WriteStartElement(Dml.Prefix, "fgClr", Dml.Ns); //_writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); //_writer.WriteAttributeString("val", Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so)); //_writer.WriteEndElement(); //_writer.WriteEndElement(); //_writer.WriteStartElement(Dml.Prefix, "bgClr", Dml.Ns); //_writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) //{ // colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); //} //else //{ // colorval = "ffffff"; //TODO: find out which color to use in this case //} //_writer.WriteAttributeString("val", colorval); //_writer.WriteEndElement(); //_writer.WriteEndElement(); //_writer.WriteEndElement(); break; case 0x2: //texture case 0x3: //picture //uint blipIndex = 0; //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBlip)) //{ // blipIndex = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; //} //else //{ // blipIndex = so.OptionsByID[ShapeOptions.PropertyId.Pib].op; //} ////string blipName = Encoding.UTF8.GetString(so.OptionsByID[ShapeOptions.PropertyId.fillBlipName].opComplex); //string rId = ""; //DrawingGroup gr = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType<PPDrawingGroup>().Children[0]; //if (blipIndex <= gr.FirstChildWithType<BlipStoreContainer>().Children.Count) //{ // BlipStoreEntry bse = (BlipStoreEntry)gr.FirstChildWithType<BlipStoreContainer>().Children[(int)blipIndex - 1]; // if (_ctx.Ppt.PicturesContainer._pictures.ContainsKey(bse.foDelay)) // { // Record rec = _ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // ImagePart imgPart = null; // if (rec is BitmapBlip) // { // BitmapBlip b = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); // imgPart.TargetDirectory = "..\\media"; // System.IO.Stream outStream = imgPart.GetStream(); // outStream.Write(b.m_pvBits, 0, b.m_pvBits.Length); // } // else // { // MetafilePictBlip b = (MetafilePictBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); // imgPart.TargetDirectory = "..\\media"; // System.IO.Stream outStream = imgPart.GetStream(); // byte[] decompressed = b.Decrompress(); // outStream.Write(decompressed, 0, decompressed.Length); // } // rId = imgPart.RelIdToString; // _writer.WriteStartElement(Dml.Prefix, "blipFill", Dml.Ns); // _writer.WriteAttributeString("dpi", "0"); // _writer.WriteAttributeString("rotWithShape", "1"); // _writer.WriteStartElement(Dml.Prefix, "blip", Dml.Ns); // _writer.WriteAttributeString("r", "embed", OpenXmlNamespaces.Relationships, rId); // _writer.WriteEndElement(); // _writer.WriteElementString(Dml.Prefix, "srcRect", Dml.Ns, ""); // if (fillType == 0x3) // { // _writer.WriteStartElement(Dml.Prefix, "stretch", Dml.Ns); // _writer.WriteElementString(Dml.Prefix, "fillRect", Dml.Ns, ""); // _writer.WriteEndElement(); // } // else // { // _writer.WriteStartElement(Dml.Prefix, "tile", Dml.Ns); // _writer.WriteAttributeString("tx", "0"); // _writer.WriteAttributeString("ty", "0"); // _writer.WriteAttributeString("sx", "100000"); // _writer.WriteAttributeString("sy", "100000"); // _writer.WriteAttributeString("flip", "none"); // _writer.WriteAttributeString("algn", "tl"); // _writer.WriteEndElement(); // } // _writer.WriteEndElement(); // } //} break; case 0x4: //shade case 0x5: //shadecenter case 0x6: //shadeshape case 0x7: //shadescale this._writer.WriteStartElement(Dml.Prefix, "gradFill", Dml.Ns); this._writer.WriteAttributeString("rotWithShape", "1"); { this._writer.WriteStartElement(Dml.Prefix, "gsLst", Dml.Ns); { this._writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); this._writer.WriteAttributeString("pos", "0"); this._writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); this._writer.WriteAttributeString("val", rgbFore.SixDigitHexCode.ToUpper()); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity)) //{ // _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); // _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteEndElement(); //} this._writer.WriteEndElement(); this._writer.WriteEndElement(); this._writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); this._writer.WriteAttributeString("pos", "100000"); this._writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); this._writer.WriteAttributeString("val", rgbBack.SixDigitHexCode.ToUpper()); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackOpacity)) //{ // _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); // _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteEndElement(); //} this._writer.WriteEndElement(); this._writer.WriteEndElement(); } this._writer.WriteEndElement(); //gsLst switch (fillType) { case 0x5: case 0x6: this._writer.WriteStartElement(Dml.Prefix, "path", Dml.Ns); this._writer.WriteAttributeString("path", "shape"); this._writer.WriteStartElement(Dml.Prefix, "fillToRect", Dml.Ns); this._writer.WriteAttributeString("l", "50000"); this._writer.WriteAttributeString("t", "50000"); this._writer.WriteAttributeString("r", "50000"); this._writer.WriteAttributeString("b", "50000"); this._writer.WriteEndElement(); this._writer.WriteEndElement(); //path break; case 0x7: decimal angle = 90; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillAngle)) { if (so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op != 0) { var bytes = BitConverter.GetBytes(so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op); int integral = BitConverter.ToInt16(bytes, 0); uint fractional = BitConverter.ToUInt16(bytes, 2); decimal result = integral + ((decimal)fractional / (decimal)65536); angle = 65536 - fractional; //I have no idea why this works!! angle = angle - 90; if (angle < 0) { angle += 360; } } } this._writer.WriteStartElement(Dml.Prefix, "lin", Dml.Ns); angle *= 60000; if (angle > 5400000) { angle = 5400000; } this._writer.WriteAttributeString("ang", angle.ToString()); this._writer.WriteAttributeString("scaled", "1"); this._writer.WriteEndElement(); break; default: this._writer.WriteStartElement(Dml.Prefix, "path", Dml.Ns); this._writer.WriteAttributeString("path", "rect"); this._writer.WriteStartElement(Dml.Prefix, "fillToRect", Dml.Ns); this._writer.WriteAttributeString("r", "100000"); this._writer.WriteAttributeString("b", "100000"); this._writer.WriteEndElement(); this._writer.WriteEndElement(); //path break; } } this._writer.WriteEndElement(); //gradFill break; case 0x8: //shadetitle case 0x9: //background break; } }
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source) { Configuration configuration = this.Configuration; ShapeOptions shapeOptions = this.definition.Options.ShapeOptions; GraphicsOptions graphicsOptions = this.definition.Options.GraphicsOptions; IBrush brush = this.definition.Brush; bool isSolidBrushWithoutBlending = IsSolidBrushWithoutBlending(graphicsOptions, brush, out SolidBrush solidBrush); TPixel solidBrushColor = isSolidBrushWithoutBlending ? solidBrush.Color.ToPixel <TPixel>() : default; // Align start/end positions. var interest = Rectangle.Intersect(this.bounds, source.Bounds()); if (interest.Equals(Rectangle.Empty)) { return; // No effect inside image; } int minX = interest.Left; int subpixelCount = FillPathProcessor.MinimumSubpixelCount; // We need to offset the pixel grid to account for when we outline a path. // basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5] // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the# // region to align with the pixel grid. if (graphicsOptions.Antialias) { subpixelCount = Math.Max(subpixelCount, graphicsOptions.AntialiasSubpixelDepth); } using BrushApplicator <TPixel> applicator = brush.CreateApplicator(configuration, graphicsOptions, source, interest); int scanlineWidth = interest.Width; MemoryAllocator allocator = this.Configuration.MemoryAllocator; bool scanlineDirty = true; var scanner = PolygonScanner.Create( this.path, interest.Top, interest.Bottom, subpixelCount, shapeOptions.IntersectionRule, configuration.MemoryAllocator); try { using IMemoryOwner <float> bScanline = allocator.Allocate <float>(scanlineWidth); Span <float> scanline = bScanline.Memory.Span; while (scanner.MoveToNextPixelLine()) { if (scanlineDirty) { scanline.Clear(); } scanlineDirty = scanner.ScanCurrentPixelLineInto(minX, 0F, scanline); if (scanlineDirty) { int y = scanner.PixelLineY; if (!graphicsOptions.Antialias) { bool hasOnes = false; bool hasZeros = false; for (int x = 0; x < scanline.Length; x++) { if (scanline[x] >= 0.5F) { scanline[x] = 1F; hasOnes = true; } else { scanline[x] = 0F; hasZeros = true; } } if (isSolidBrushWithoutBlending && hasOnes != hasZeros) { if (hasOnes) { source.PixelBuffer.DangerousGetRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrushColor); } continue; } } applicator.Apply(scanline, minX, y); } } } finally { scanner.Dispose(); } }
/// <inheritdoc/> protected override void OnFrameApply(ImageFrame <TPixel> source) { Configuration configuration = this.Configuration; ShapeOptions shapeOptions = this.definition.Options.ShapeOptions; GraphicsOptions graphicsOptions = this.definition.Options.GraphicsOptions; IBrush brush = this.definition.Brush; Region region = this.definition.Region; Rectangle rect = region.Bounds; bool isSolidBrushWithoutBlending = IsSolidBrushWithoutBlending(graphicsOptions, this.definition.Brush, out SolidBrush solidBrush); TPixel solidBrushColor = isSolidBrushWithoutBlending ? solidBrush.Color.ToPixel <TPixel>() : default; // Align start/end positions. int minX = Math.Max(0, rect.Left); int maxX = Math.Min(source.Width, rect.Right); int minY = Math.Max(0, rect.Top); int maxY = Math.Min(source.Height, rect.Bottom); if (minX >= maxX) { return; // no effect inside image; } if (minY >= maxY) { return; // no effect inside image; } int subpixelCount = FillRegionProcessor.MinimumSubpixelCount; // we need to offset the pixel grid to account for when we outline a path. // basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5] // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the# // region to align with the pixel grid. if (graphicsOptions.Antialias) { subpixelCount = Math.Max(subpixelCount, graphicsOptions.AntialiasSubpixelDepth); } using BrushApplicator <TPixel> applicator = brush.CreateApplicator(configuration, graphicsOptions, source, rect); int scanlineWidth = maxX - minX; MemoryAllocator allocator = this.Configuration.MemoryAllocator; bool scanlineDirty = true; var scanner = PolygonScanner.Create( region.Shape, minY, maxY, subpixelCount, shapeOptions.IntersectionRule, configuration.MemoryAllocator); try { using IMemoryOwner <float> bScanline = allocator.Allocate <float>(scanlineWidth); Span <float> scanline = bScanline.Memory.Span; while (scanner.MoveToNextPixelLine()) { if (scanlineDirty) { scanline.Clear(); } scanlineDirty = scanner.ScanCurrentPixelLineInto(minX, 0, scanline); if (scanlineDirty) { int y = scanner.PixelLineY; if (!graphicsOptions.Antialias) { bool hasOnes = false; bool hasZeros = false; for (int x = 0; x < scanline.Length; x++) { if (scanline[x] >= 0.5) { scanline[x] = 1; hasOnes = true; } else { scanline[x] = 0; hasZeros = true; } } if (isSolidBrushWithoutBlending && hasOnes != hasZeros) { if (hasOnes) { source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrushColor); } continue; } } applicator.Apply(scanline, minX, y); } } } finally { // ref structs can't implement interfaces so technically PolygonScanner is not IDisposable scanner.Dispose(); } }
private void insertDrawingFillProperties(AreaFormat areaFormat, ShapeOptions so) { RGBColor rgbFore = areaFormat.rgbFore; RGBColor rgbBack = areaFormat.rgbBack; uint fillType = 0; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillType)) { fillType = so.OptionsByID[ShapeOptions.PropertyId.fillType].op; } switch (fillType) { case 0x0: //solid // a:solidFill (CT_SolidColorFillProperties) _writer.WriteStartElement(Dml.Prefix, Dml.ShapeEffects.ElSolidFill, Dml.Ns); { // a:srgbColor _writer.WriteStartElement(Dml.Prefix, Dml.BaseTypes.ElSrgbClr, Dml.Ns); _writer.WriteAttributeString(Dml.BaseTypes.AttrVal, rgbFore.SixDigitHexCode.ToUpper()); _writer.WriteEndElement(); // a:srgbColor } _writer.WriteEndElement(); // a:solidFill break; case 0x1: //pattern //uint blipIndex1 = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; //DrawingGroup gr1 = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType<PPDrawingGroup>().Children[0]; //BlipStoreEntry bse1 = (BlipStoreEntry)gr1.FirstChildWithType<BlipStoreContainer>().Children[(int)blipIndex1 - 1]; //BitmapBlip b1 = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse1.foDelay]; //_writer.WriteStartElement(Dml.Prefix, "pattFill", Dml.Ns); //_writer.WriteAttributeString("prst", Utils.getPrstForPatternCode(b1.m_bTag)); //Utils.getPrstForPattern(blipNamePattern)); //_writer.WriteStartElement(Dml.Prefix, "fgClr", Dml.Ns); //_writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); //_writer.WriteAttributeString("val", Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so)); //_writer.WriteEndElement(); //_writer.WriteEndElement(); //_writer.WriteStartElement(Dml.Prefix, "bgClr", Dml.Ns); //_writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) //{ // colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); //} //else //{ // colorval = "ffffff"; //TODO: find out which color to use in this case //} //_writer.WriteAttributeString("val", colorval); //_writer.WriteEndElement(); //_writer.WriteEndElement(); //_writer.WriteEndElement(); break; case 0x2: //texture case 0x3: //picture //uint blipIndex = 0; //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBlip)) //{ // blipIndex = so.OptionsByID[ShapeOptions.PropertyId.fillBlip].op; //} //else //{ // blipIndex = so.OptionsByID[ShapeOptions.PropertyId.Pib].op; //} ////string blipName = Encoding.UTF8.GetString(so.OptionsByID[ShapeOptions.PropertyId.fillBlipName].opComplex); //string rId = ""; //DrawingGroup gr = (DrawingGroup)this._ctx.Ppt.DocumentRecord.FirstChildWithType<PPDrawingGroup>().Children[0]; //if (blipIndex <= gr.FirstChildWithType<BlipStoreContainer>().Children.Count) //{ // BlipStoreEntry bse = (BlipStoreEntry)gr.FirstChildWithType<BlipStoreContainer>().Children[(int)blipIndex - 1]; // if (_ctx.Ppt.PicturesContainer._pictures.ContainsKey(bse.foDelay)) // { // Record rec = _ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // ImagePart imgPart = null; // if (rec is BitmapBlip) // { // BitmapBlip b = (BitmapBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); // imgPart.TargetDirectory = "..\\media"; // System.IO.Stream outStream = imgPart.GetStream(); // outStream.Write(b.m_pvBits, 0, b.m_pvBits.Length); // } // else // { // MetafilePictBlip b = (MetafilePictBlip)_ctx.Ppt.PicturesContainer._pictures[bse.foDelay]; // imgPart = _parentSlideMapping.targetPart.AddImagePart(ShapeTreeMapping.getImageType(b.TypeCode)); // imgPart.TargetDirectory = "..\\media"; // System.IO.Stream outStream = imgPart.GetStream(); // byte[] decompressed = b.Decrompress(); // outStream.Write(decompressed, 0, decompressed.Length); // } // rId = imgPart.RelIdToString; // _writer.WriteStartElement(Dml.Prefix, "blipFill", Dml.Ns); // _writer.WriteAttributeString("dpi", "0"); // _writer.WriteAttributeString("rotWithShape", "1"); // _writer.WriteStartElement(Dml.Prefix, "blip", Dml.Ns); // _writer.WriteAttributeString("r", "embed", OpenXmlNamespaces.Relationships, rId); // _writer.WriteEndElement(); // _writer.WriteElementString(Dml.Prefix, "srcRect", Dml.Ns, ""); // if (fillType == 0x3) // { // _writer.WriteStartElement(Dml.Prefix, "stretch", Dml.Ns); // _writer.WriteElementString(Dml.Prefix, "fillRect", Dml.Ns, ""); // _writer.WriteEndElement(); // } // else // { // _writer.WriteStartElement(Dml.Prefix, "tile", Dml.Ns); // _writer.WriteAttributeString("tx", "0"); // _writer.WriteAttributeString("ty", "0"); // _writer.WriteAttributeString("sx", "100000"); // _writer.WriteAttributeString("sy", "100000"); // _writer.WriteAttributeString("flip", "none"); // _writer.WriteAttributeString("algn", "tl"); // _writer.WriteEndElement(); // } // _writer.WriteEndElement(); // } //} break; case 0x4: //shade case 0x5: //shadecenter case 0x6: //shadeshape case 0x7: //shadescale _writer.WriteStartElement(Dml.Prefix, "gradFill", Dml.Ns); _writer.WriteAttributeString("rotWithShape", "1"); { _writer.WriteStartElement(Dml.Prefix, "gsLst", Dml.Ns); { _writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); _writer.WriteAttributeString("pos", "0"); _writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); _writer.WriteAttributeString("val", rgbFore.SixDigitHexCode.ToUpper()); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity)) //{ // _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); // _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteEndElement(); //} _writer.WriteEndElement(); _writer.WriteEndElement(); _writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); _writer.WriteAttributeString("pos", "100000"); _writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); _writer.WriteAttributeString("val", rgbBack.SixDigitHexCode.ToUpper()); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackOpacity)) //{ // _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); // _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteEndElement(); //} _writer.WriteEndElement(); _writer.WriteEndElement(); } _writer.WriteEndElement(); //gsLst switch (fillType) { case 0x5: case 0x6: _writer.WriteStartElement(Dml.Prefix, "path", Dml.Ns); _writer.WriteAttributeString("path", "shape"); _writer.WriteStartElement(Dml.Prefix, "fillToRect", Dml.Ns); _writer.WriteAttributeString("l", "50000"); _writer.WriteAttributeString("t", "50000"); _writer.WriteAttributeString("r", "50000"); _writer.WriteAttributeString("b", "50000"); _writer.WriteEndElement(); _writer.WriteEndElement(); //path break; case 0x7: decimal angle = 90; if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillAngle)) { if (so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op != 0) { byte[] bytes = BitConverter.GetBytes(so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op); int integral = BitConverter.ToInt16(bytes, 0); uint fractional = BitConverter.ToUInt16(bytes, 2); decimal result = integral + ((decimal)fractional / (decimal)65536); angle = 65536 - fractional; //I have no idea why this works!! angle = angle - 90; if (angle < 0) { angle += 360; } } } _writer.WriteStartElement(Dml.Prefix, "lin", Dml.Ns); angle *= 60000; if (angle > 5400000) { angle = 5400000; } _writer.WriteAttributeString("ang", angle.ToString()); _writer.WriteAttributeString("scaled", "1"); _writer.WriteEndElement(); break; default: _writer.WriteStartElement(Dml.Prefix, "path", Dml.Ns); _writer.WriteAttributeString("path", "rect"); _writer.WriteStartElement(Dml.Prefix, "fillToRect", Dml.Ns); _writer.WriteAttributeString("r", "100000"); _writer.WriteAttributeString("b", "100000"); _writer.WriteEndElement(); _writer.WriteEndElement(); //path break; } } _writer.WriteEndElement(); //gradFill break; //case 0x7: //shadescale //_writer.WriteStartElement(Dml.Prefix, "gradFill", Dml.Ns); //_writer.WriteAttributeString("rotWithShape", "1"); //_writer.WriteStartElement(Dml.Prefix, "gsLst", Dml.Ns); //bool switchColors = false; //decimal angle = 90; //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillAngle)) //{ // if (so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op != 0) // { // byte[] bytes = BitConverter.GetBytes(so.OptionsByID[ShapeOptions.PropertyId.fillAngle].op); // int integral = BitConverter.ToInt16(bytes, 0); // uint fractional = BitConverter.ToUInt16(bytes, 2); // decimal result = integral + ((decimal)fractional / (decimal)65536); // angle = 65536 - fractional; //I have no idea why this works!! // angle = angle - 90; // if (angle < 0) // { // angle += 360; // switchColors = true; // } // } //} //Dictionary<int, string> shadeColorsDic = new Dictionary<int, string>(); //List<string> shadeColors = new List<string>(); //if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillShadeColors)) //{ // uint length = so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].op; // //An IMsoArray record that specifies colors and their relative positions. // //Each element of the array contains an OfficeArtCOLORREF record color and a FixedPoint, as specified in [MS-OSHARED] // //section 2.2.1.6, that specifies its relative position along the gradient vector. // byte[] data = so.OptionsByID[ShapeOptions.PropertyId.fillShadeColors].opComplex; // int pos = 0; // string colval; // FixedPointNumber fixedpoint; // UInt16 nElems = BitConverter.ToUInt16(data, pos); // pos += 2; // UInt16 nElemsAlloc = BitConverter.ToUInt16(data, pos); // pos += 2; // UInt16 cbElem = BitConverter.ToUInt16(data, pos); // pos += 2; // if (cbElem == 0xFFF0) // { // //If this value is 0xFFF0 then this record is an array of truncated 8 byte elements. Only the 4 low-order bytes are recorded. Each element's 4 high-order bytes equal 0x00000000 and each element's 4 low-order bytes are contained in data. // } // else // { // while (pos < length) // { // colval = Utils.getRGBColorFromOfficeArtCOLORREF(BitConverter.ToUInt32(data, pos), slide, so); // pos += 4; // fixedpoint = new FixedPointNumber(BitConverter.ToUInt16(data, pos), BitConverter.ToUInt16(data, pos + 2)); // shadeColors.Insert(0, colval); // pos += 4; // } // } //} //else //{ // bool switchcolors = false; // if (switchColors & so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) // { // colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); // } // else // { // if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillColor)) // { // colorval = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so); // } // else // { // colorval = "FFFFFF"; //TODO: find out which color to use in this case // switchcolors = true; // } // } // if (switchColors | !so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackColor)) // { // colorval2 = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillColor].op, slide, so); // } // else // { // colorval2 = Utils.getRGBColorFromOfficeArtCOLORREF(so.OptionsByID[ShapeOptions.PropertyId.fillBackColor].op, slide, so); // } // if (switchcolors) // { // //this is a workaround for a bug. Further analysis necessarry // string dummy = colorval; // colorval = colorval2; // colorval2 = dummy; // } // shadeColors.Add(colorval); // shadeColors.Add(colorval2); //} //int gspos; //string col; //for (int i = 0; i < shadeColors.Count; i++) //{ // col = shadeColors[i]; // if (i == 0) // { // gspos = 0; // } // else if (i == shadeColors.Count - 1) // { // gspos = 100000; // } // else // { // gspos = i * 100000 / shadeColors.Count; // } // _writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); // _writer.WriteAttributeString("pos", gspos.ToString()); // _writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); // _writer.WriteAttributeString("val", col); // if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillOpacity)) // { // _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); // decimal alpha = Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillOpacity].op / 65536 * 100000)); //we need the percentage of the opacity (65536 means 100%) // _writer.WriteAttributeString("val", alpha.ToString(CultureInfo.InvariantCulture)); // _writer.WriteEndElement(); // } // if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillShadeType)) // { // uint flags = so.OptionsByID[ShapeOptions.PropertyId.fillShadeType].op; // bool none = Tools.Utils.BitmaskToBool(flags, 0x1); // bool gamma = Tools.Utils.BitmaskToBool(flags, 0x1 << 1); // bool sigma = Tools.Utils.BitmaskToBool(flags, 0x1 << 2); // bool band = Tools.Utils.BitmaskToBool(flags, 0x1 << 3); // bool onecolor = Tools.Utils.BitmaskToBool(flags, 0x1 << 4); // if (gamma) _writer.WriteElementString(Dml.Prefix, "gamma", Dml.Ns, ""); // if (band) // { // _writer.WriteStartElement(Dml.Prefix, "shade", Dml.Ns); // _writer.WriteAttributeString("val", "37255"); // _writer.WriteEndElement(); // } // if (gamma) _writer.WriteElementString(Dml.Prefix, "invGamma", Dml.Ns, ""); // } // _writer.WriteEndElement(); // _writer.WriteEndElement(); //} //////new colorval ////_writer.WriteStartElement(Dml.Prefix, "gs", Dml.Ns); ////_writer.WriteAttributeString("pos", "100000"); ////_writer.WriteStartElement(Dml.Prefix, "srgbClr", Dml.Ns); ////_writer.WriteAttributeString("val", colorval2); ////if (so.OptionsByID.ContainsKey(ShapeOptions.PropertyId.fillBackOpacity)) ////{ //// _writer.WriteStartElement(Dml.Prefix, "alpha", Dml.Ns); //// _writer.WriteAttributeString("val", Math.Round(((decimal)so.OptionsByID[ShapeOptions.PropertyId.fillBackOpacity].op / 65536 * 100000)).ToString()); //we need the percentage of the opacity (65536 means 100%) //// _writer.WriteEndElement(); ////} ////_writer.WriteEndElement(); ////_writer.WriteEndElement(); //_writer.WriteEndElement(); //gsLst //_writer.WriteStartElement(Dml.Prefix, "lin", Dml.Ns); //angle *= 60000; //if (angle > 5400000) angle = 5400000; //_writer.WriteAttributeString("ang", angle.ToString()); //_writer.WriteAttributeString("scaled", "1"); //_writer.WriteEndElement(); //_writer.WriteEndElement(); break; case 0x8: //shadetitle case 0x9: //background break; } }