public static void RedactCharacters(Doc doc, IList <TextFragment> fragments) { if (fragments.Count == 0) { return; } ResourceTracker tracker = new ResourceTracker(doc); Dictionary <int, List <TextFragment> > streams = new Dictionary <int, List <TextFragment> >(); foreach (TextFragment fragment in fragments) { List <TextFragment> redactions = null; int id = tracker.CopyOnWrite(fragment.StreamID, fragment.PageID); streams.TryGetValue(id, out redactions); if (redactions == null) { redactions = new List <TextFragment>(); streams[id] = redactions; } redactions.Add(fragment); } foreach (KeyValuePair <int, List <TextFragment> > pair in streams) { // get data StreamObject stream = doc.ObjectSoup[pair.Key] as StreamObject; Debug.Assert(stream != null); // should never happen stream.Decompress(); // shouldn't really be necessary Debug.Assert(stream.Compressed == false); // should never happen byte[] data = stream.GetData(); // construct new stream List <TextFragment> redactions = pair.Value; redactions.Sort((x, y) => x.StreamOffset.CompareTo(y.StreamOffset)); MemoryStream mem = new MemoryStream(data.Length); int p = 0; for (int i = 0; i < redactions.Count; i++) { TextFragment redaction = redactions[i]; RedactionGroup group = new RedactionGroup(data); for (int j = i; j < redactions.Count; j++) { if (!group.Add(redactions[j])) { i = j - 1; break; } } if (p < redaction.StreamOffset) { mem.Write(data, p, redaction.StreamOffset - p); byte[] tjBytes = group.GetTextOperator().GetData(); mem.Write(tjBytes, 1, tjBytes.Length - 2); } p = redaction.StreamOffset + redaction.StreamLength; } mem.Write(data, p, data.Length - p); stream.SetData(mem.ToArray()); } }
public static void RedactTextOps(Doc doc, IList <TextFragment> fragments) { if (fragments.Count == 0) { return; } ResourceTracker tracker = new ResourceTracker(doc); Dictionary <int, List <TextFragment> > streams = new Dictionary <int, List <TextFragment> >(); foreach (TextFragment fragment in fragments) { List <TextFragment> redactions = null; int id = tracker.CopyOnWrite(fragment.StreamID, fragment.PageID); streams.TryGetValue(id, out redactions); if (redactions == null) { redactions = new List <TextFragment>(); streams[id] = redactions; } redactions.Add(fragment); } foreach (KeyValuePair <int, List <TextFragment> > pair in streams) { // get data StreamObject stream = doc.ObjectSoup[pair.Key] as StreamObject; Debug.Assert(stream != null); // should never happen stream.Decompress(); // shouldn't really be necessary Debug.Assert(stream.Compressed == false); // should never happen byte[] data = stream.GetData(); // construct new stream List <TextFragment> redactions = pair.Value; redactions.Sort((x, y) => x.StreamOffset.CompareTo(y.StreamOffset)); MemoryStream mem = new MemoryStream(data.Length); int p = 0; foreach (TextFragment redaction in redactions) { if (p < redaction.StreamOffset) { mem.Write(data, p, redaction.StreamOffset - p); IDictionary <char, int> widths = redaction.Font.Widths; int defaultWidth = doc.GetInfoInt(redaction.Font.ID, "/DescendantFonts[0]*/DW*"); if (defaultWidth == 0) { defaultWidth = 1000; } int width1000ths = 0; foreach (char c in redaction.Text) { int width = 0; if (!widths.TryGetValue(c, out width)) { width = defaultWidth; } width1000ths += defaultWidth; } string tj = string.Format("[{0}] TJ\r\n", width1000ths); byte[] tjBytes = ASCIIEncoding.ASCII.GetBytes(tj); mem.Write(tjBytes, 0, tjBytes.Length); } p = redaction.StreamOffset + redaction.StreamLength; } mem.Write(data, p, data.Length - p); stream.SetData(mem.ToArray()); } }