public void Purge() { _doc.PageNumber = 1; foreach (int id in _containers) { IndirectObject io = _doc.ObjectSoup[id]; while (io != null) { Atom rez = io.Resolve(Atom.GetItem(io.Atom, "Resources")); DictAtom fonts = io.Resolve(Atom.GetItem(rez, "Font")) as DictAtom; if ((fonts != null) && (fonts.Count > 0)) { List <string> fontsToRemove = new List <string>(); foreach (KeyValuePair <string, Atom> pair in fonts) { IndirectObject font = io.ResolveObj(pair.Value); if (font == null) { continue; // shouldn't ever happen } if (!_fonts.Contains(font.ID)) { fontsToRemove.Add(pair.Key); } } foreach (string key in fontsToRemove) { fonts.Remove(key); } } io = io.ResolveObj(Atom.GetItem(io.Atom, "Parent")); } } }
public void Purge() { // First establish the count of images; per page (or xobject), per image. Dictionary <int, Dictionary <int, int> > imageCountPerParent = new Dictionary <int, Dictionary <int, int> >(); foreach (ImageProperties image in _images) { foreach (ImageRendition rendition in image.Renditions) { int parent = rendition.StreamObject is FormXObject ? rendition.StreamID : rendition.PageID; Dictionary <int, int> imageCount = null; imageCountPerParent.TryGetValue(parent, out imageCount); if (imageCount == null) { imageCount = new Dictionary <int, int>(); imageCountPerParent[parent] = imageCount; } int count = 0; if (!imageCount.TryGetValue(image.PixMap.ID, out count)) { imageCount[image.PixMap.ID] = 0; count = 0; } if (!_redactionSet.Contains(rendition)) { imageCount[image.PixMap.ID] = count + 1; } } } // Then remove the ones that have been redacted foreach (KeyValuePair <int, Dictionary <int, int> > pair1 in imageCountPerParent) { HashSet <int> imagesToRemove = new HashSet <int>(); foreach (KeyValuePair <int, int> pair2 in pair1.Value) { if (pair2.Value == 0) // no references left { imagesToRemove.Add(pair2.Key); } } if (imagesToRemove.Count > 0) { IndirectObject io = _doc.ObjectSoup[pair1.Key]; while (io != null) { Atom rez = io.Resolve(Atom.GetItem(io.Atom, "Resources")); DictAtom xobjs = io.Resolve(Atom.GetItem(rez, "XObject")) as DictAtom; if ((xobjs != null) && (xobjs.Count > 0)) { List <string> namesToRemove = new List <string>(); foreach (KeyValuePair <string, Atom> pair in xobjs) { IndirectObject xobj = io.ResolveObj(pair.Value); if (xobj == null) { continue; // shouldn't ever happen } if (imagesToRemove.Contains(xobj.ID)) { namesToRemove.Add(pair.Key); } } foreach (string key in namesToRemove) { xobjs.Remove(key); } } io = _imagesCoverWholeDoc ? io.ResolveObj(Atom.GetItem(io.Atom, "Parent")) : null; } } } }
public void PurgeForm() { Catalog cat = _doc.ObjectSoup.Catalog; Atom form = cat.Resolve(Atom.GetItem(cat.Atom, "AcroForm")); if (form == null) { return; } // look at default appearance for documents and widgets HashSet <string> fontsToKeep = new HashSet <string>(); Atom docDA = cat.Resolve(Atom.GetItem(form, "DA")); bool needsDocDA = false; for (int i = 0; i < _doc.PageNumber; i++) { _doc.PageNumber = i + 1; Page page = (Page)_doc.ObjectSoup[_doc.Page]; foreach (Annotation annot in page.GetAnnotations()) { bool needsDA = false; if ((annot.FieldType == FieldType.Text) || (annot.FieldType == FieldType.Signature) || (annot.FieldType == FieldType.List) || (annot.FieldType == FieldType.Combo)) { needsDA = true; } else { string subtype = Atom.GetName(cat.Resolve(Atom.GetItem(annot.Atom, "Subtype"))); if ((subtype == "FreeText") || ((subtype == "Redact") && (Atom.GetItem(annot.Atom, "OverlayText") != null))) { needsDA = true; } } if (!needsDA) { continue; // we can ignore this annotation } Atom da = cat.Resolve(Atom.GetItem(annot.Atom, "DA")); if (da == null) { needsDocDA = true; continue; // we add in the doc DA at the end } KeepFonts(fontsToKeep, da); } } Debug.Assert((needsDocDA == false) || (docDA != null), "Both Widgets and Document fail to define required DA entry."); if (!needsDocDA) { Atom.RemoveItem(form, "DA"); docDA = null; } if (docDA != null) { KeepFonts(fontsToKeep, docDA); } HashSet <string> fontsToRemove = new HashSet <string>(); Atom rez = cat.Resolve(Atom.GetItem(form, "DR")); DictAtom fonts = cat.Resolve(Atom.GetItem(rez, "Font")) as DictAtom; if (fonts != null) { foreach (KeyValuePair <string, Atom> pair in fonts) { if (!fontsToKeep.Contains(pair.Key)) { fontsToRemove.Add(pair.Key); } } foreach (string key in fontsToRemove) { fonts.Remove(key); } } }