From 45a9665614ac77865ac429cf3eac5829acc2356e Mon Sep 17 00:00:00 2001 From: Audionysos Date: Thu, 29 Feb 2024 04:03:38 +0100 Subject: [PATCH] DebuggerTypeProxy for COperator and printing method that is easier to read. Add some missing implementation method for CSequence and fixed it's Copy() method. --- PdfSharp.sln | 2 +- .../PdfSharp/Pdf.Content.Objects/CObjects.cs | 124 +++++++++++------- 2 files changed, 74 insertions(+), 52 deletions(-) diff --git a/PdfSharp.sln b/PdfSharp.sln index 948a5c35..2282c9ff 100644 --- a/PdfSharp.sln +++ b/PdfSharp.sln @@ -439,7 +439,7 @@ Global {7C753636-7947-46E0-95E0-135EAA7BFEB3} = {5912CE0D-0DCE-479F-944A-0DFA4CE95A88} {E97F1455-620B-4BF2-B839-08F7AE2FD772} = {E1933982-1D12-497F-B465-67D5E5C74CA1} {0EDABDD2-05D5-43D0-A635-645DD8127201} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} - {8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA} = {0EDABDD2-05D5-43D0-A635-645DD8127201} + {8770F3E1-3FEE-4611-89D4-AF80DFB3B3EA} = {FD3FEC8C-C8C8-47F1-AF08-F77EC937ACFE} {FD3FEC8C-C8C8-47F1-AF08-F77EC937ACFE} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} {EF9C1FA7-24B3-438A-BD21-400C1500E164} = {18632E7D-54DF-4933-A8DF-A7ECE8666E9B} {71BD4587-A8B0-4653-A3B2-93578F71ABB7} = {5912CE0D-0DCE-479F-944A-0DFA4CE95A88} diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Content.Objects/CObjects.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Content.Objects/CObjects.cs index 6ba668f4..732c760b 100644 --- a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Content.Objects/CObjects.cs +++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Content.Objects/CObjects.cs @@ -114,11 +114,18 @@ public class CSequence : CObject, IList // , ICollection, IEn /// protected override CObject Copy() { - CObject obj = base.Copy(); - _items = new List(_items); + //Commit note: I may be wrong but this didn't seem right to me. + //If we want to make a copy, the clone should contain cloned items, not the original object i.e. + //public bool doingSomething(CSequence s) { + // var i = s[0]; + // var _ = s.Clone(); + // return ReferenceEquals(s[0], i); //this should return true + //} + var c = (CSequence)base.Copy(); + c._items = new List(_items.Count); for (int idx = 0; idx < _items.Count; idx++) - _items[idx] = _items[idx].Clone(); - return obj; + c._items.Add(_items[idx].Clone()); + return c; } /// @@ -179,22 +186,6 @@ public void Insert(int index, CObject value) _items.Insert(index, value); } - /////// - /////// Gets a value indicating whether the sequence has a fixed size. - /////// - ////public bool IsFixedSize - ////{ - //// get { return items.IsFixedSize; } - ////} - - /////// - /////// Gets a value indicating whether the sequence is read-only. - /////// - ////public bool IsReadOnly - ////{ - //// get { return items.IsReadOnly; } - ////} - /// /// Removes the specified value from the sequence. /// @@ -237,22 +228,6 @@ public void CopyTo(CObject[] array, int index) /// public int Count => _items.Count; - ///// - ///// Gets a value indicating whether access to the sequence is synchronized (thread safe). - ///// - //public bool IsSynchronized - //{ - // get { return items.IsSynchronized; } - //} - - ///// - ///// Gets an object that can be used to synchronize access to the sequence. - ///// - //public object SyncRoot - //{ - // get { return items.SyncRoot; } - //} - #endregion #region IEnumerable Members @@ -318,23 +293,23 @@ internal override void WriteObject(ContentWriter writer) int IList.IndexOf(CObject item) { - throw new NotImplementedException(); + return _items.IndexOf(item); } void IList.Insert(int index, CObject item) { - throw new NotImplementedException(); + _items.Insert(index, item); } void IList.RemoveAt(int index) { - throw new NotImplementedException(); + _items.RemoveAt(index); } CObject IList.this[int index] { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); + get => _items[index]; + set => _items[index] = value; } #endregion @@ -343,31 +318,37 @@ CObject IList.this[int index] void ICollection.Add(CObject item) { - throw new NotImplementedException(); + Add(item); } void ICollection.Clear() { - throw new NotImplementedException(); + Clear(); } bool ICollection.Contains(CObject item) { - throw new NotImplementedException(); + return Contains(item); } void ICollection.CopyTo(CObject[] array, int arrayIndex) { - throw new NotImplementedException(); + array = array ?? throw new ArgumentNullException(nameof(array)); + if (arrayIndex < 0) throw new ArgumentOutOfRangeException(); + if (_items.Count > array.Length - arrayIndex) + throw new ArgumentException("The number of elements in the source System.Collections.Generic.ICollection`1 is greater than the available space from arrayIndex to the end of the destination array."); + + for (int i = arrayIndex; i < _items.Count; i++) + array[i] = _items[i]; } - int ICollection.Count => throw new NotImplementedException(); + int ICollection.Count => _items.Count; - bool ICollection.IsReadOnly => throw new NotImplementedException(); + bool ICollection.IsReadOnly => false; bool ICollection.Remove(CObject item) { - throw new NotImplementedException(); + return _items.Remove(item); } #endregion @@ -376,7 +357,7 @@ bool ICollection.Remove(CObject item) IEnumerator IEnumerable.GetEnumerator() { - throw new NotImplementedException(); + return _items.GetEnumerator(); } #endregion @@ -790,7 +771,8 @@ internal override void WriteObject(ContentWriter writer) /// /// Represents an operator a PDF content stream. /// - [DebuggerDisplay("({Name}, operands={Operands.Count})")] + [DebuggerDisplay($@"{{{nameof(_debuggerDisplay)},nq}}")] + [DebuggerTypeProxy(typeof(COperatorDebuggerDisplay))] public class COperator : CObject { /// @@ -855,7 +837,33 @@ public override string ToString() return Name; } - internal override void WriteObject(ContentWriter writer) + #region Printing/Debugger display + /// Function returning string that will be used to displayed object's value in debugger for this type of objects. + public static Func debuggerDisplay { get; set; } = o => o.ToString(15); + internal string _debuggerDisplay => debuggerDisplay(this); + + /// Prints longer version of string including name, operands list and operator description. + /// Maximal number of characters in operands portion of the string that could be displayed. + /// If printing all operands would require greater number of characters, a sting in form like "15 operands" will be put in the result instead. + public string ToString(int maxOperandsStringLength) { + if (maxOperandsStringLength < 1) return ToString(); + + var ops = ""; var sep = ", "; //operands, separator + foreach (var op in Operands) { + var os = op + sep; //this should be optimized and checking the size of before converting to string, I guess some object may be really long... + ops += os; + if (ops.Length > maxOperandsStringLength + sep.Length) { + ops = Operands.Count + " operands" + sep; + break; + } + } + if (ops.Length > 0) ops = ops.Substring(0, ops.Length - sep.Length); + + return $"{Name, -4}({ops}) {OpCode.Description}"; + } + #endregion + + internal override void WriteObject(ContentWriter writer) { if (_sequence != null) { @@ -869,4 +877,18 @@ internal override void WriteObject(ContentWriter writer) writer.WriteLineRaw(ToString()); } } + + internal class COperatorDebuggerDisplay { + private readonly COperator o; + + public string Name => $"{o.Name} - {o.OpCode.Description}"; + public string _Postscript => o.OpCode.Postscript; + public OpCodeFlags __Flags => o.OpCode.Flags; + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public CObject[] ___Operands => o.Operands.ToArray(); + + public COperatorDebuggerDisplay(COperator o) => this.o = o; + + } }