diff --git a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/ItemSpan.h b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/ItemSpan.h index fef461007c6..78c81823e20 100644 --- a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/ItemSpan.h +++ b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/ItemSpan.h @@ -8,7 +8,7 @@ #include "Common.h" namespace MS { namespace Internal { - private ref struct Span sealed + private value struct Span { /// /// Constructor @@ -20,12 +20,12 @@ namespace MS { namespace Internal /// /// Span element /// - Object^ element; + initonly Object^ element; /// /// Span length /// - int length; + initonly int length; }; }}//MS::Internal #endif //_ITEM_SPAN_H \ No newline at end of file diff --git a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.cpp b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.cpp index b7186f36dfd..f84f6931fcf 100644 --- a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.cpp +++ b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.cpp @@ -16,7 +16,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface _textAnalyzer = gcnew NativeIUnknownWrapper(textAnalyzer); } - IList^ TextAnalyzer::Itemize( + IList^ TextAnalyzer::Itemize( __in_ecount(length) const WCHAR* text, UINT32 length, CultureInfo^ culture, @@ -46,7 +46,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface try { hr = pDWriteFactory->CreateTextAnalyzer(&pTextAnalyzer); - ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); + ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); pin_ptr pNumberSubstitutionLocaleNamePinned; @@ -73,7 +73,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface ignoreUserOverride, numberSubstitutionMethod, (void**)&pTextAnalysisSource)); - ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); + ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); pTextAnalysisSink = (IDWriteTextAnalysisSink*)pfnCreateTextAnalysisSink(); @@ -83,14 +83,14 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface 0, length, pTextAnalysisSink); - ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); + ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); // Analyze the number substitution ranges. hr = pTextAnalyzer->AnalyzeNumberSubstitution(pTextAnalysisSource, 0, length, pTextAnalysisSink); - ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); + ConvertHresultToException(hr, "List^ TextAnalyzer::Itemize"); DWriteTextAnalysisNode* dwriteScriptAnalysisNode = (DWriteTextAnalysisNode*)pfnGetScriptAnalysisList((void*)pTextAnalysisSink); DWriteTextAnalysisNode* dwriteNumberSubstitutionNode = (DWriteTextAnalysisNode*)pfnGetNumberSubstitutionList((void*)pTextAnalysisSink); @@ -114,7 +114,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface } - IList^ TextAnalyzer::AnalyzeExtendedAndItemize( + IList^ TextAnalyzer::AnalyzeExtendedAndItemize( TextItemizer^ textItemizer, __in_ecount(length) const WCHAR *text, UINT32 length, diff --git a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.h b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.h index 437ad6ab4ba..1c7871f4f92 100644 --- a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.h +++ b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextAnalyzer.h @@ -120,7 +120,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface } } - static IList^ AnalyzeExtendedAndItemize( + static IList^ AnalyzeExtendedAndItemize( TextItemizer^ textItemizer, __in_ecount(length) const WCHAR *text, UINT32 length, @@ -147,7 +147,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface IDWriteTextAnalyzer* textAnalyzer ); - static IList^ Itemize( + static IList^ Itemize( __in_ecount(length) const WCHAR* text, UINT32 length, CultureInfo^ culture, diff --git a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.cpp b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.cpp index 904cb7ca2f8..51cf8a4a6fc 100644 --- a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.cpp +++ b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.cpp @@ -58,7 +58,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface } - __declspec(noinline) IList^ TextItemizer::Itemize(CultureInfo^ numberCulture, __in_ecount(textLength) CharAttributeType* pCharAttribute, UINT32 textLength) + __declspec(noinline) IList^ TextItemizer::Itemize(CultureInfo^ numberCulture, __in_ecount(textLength) CharAttributeType* pCharAttribute, UINT32 textLength) { DWriteTextAnalysisNode* pScriptAnalysisListPrevious = _pScriptAnalysisListHead; DWriteTextAnalysisNode* pScriptAnalysisListCurrent = _pScriptAnalysisListHead; @@ -79,7 +79,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface &pNumberSubstitutionListCurrent, numberSubstitutionRangeIndex, isDigitIndex, isDigitRangeIndex); - List^ spanVector = gcnew List(); + List^ spanVector = gcnew List(); while ( rangeEnd != textLength && (pScriptAnalysisListCurrent != NULL @@ -193,7 +193,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface isLatin ); - spanVector->Add(gcnew Span(itemProps, (int)(rangeEnd - rangeStart))); + spanVector->Add(Span(itemProps, (int)(rangeEnd - rangeStart))); } return spanVector; diff --git a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.h b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.h index c5ef306309e..12f6070d49f 100644 --- a/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.h +++ b/src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/CPP/DWriteWrapper/TextItemizer.h @@ -66,7 +66,7 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface TextItemizer(DWriteTextAnalysisNode* pScriptAnalysisListHead, DWriteTextAnalysisNode* pNumberSubstitutionListHead); - IList^ Itemize(CultureInfo^ numberCulture, __in_ecount(textLength) CharAttributeType* pCharAttribute, UINT32 textLength); + IList^ Itemize(CultureInfo^ numberCulture, __in_ecount(textLength) CharAttributeType* pCharAttribute, UINT32 textLength); void SetIsDigit( UINT32 textPosition, diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Span.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Span.cs index e91e023af53..848361edb1b 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Span.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Span.cs @@ -51,7 +51,7 @@ public IEnumerator GetEnumerator() /// /// Add a new span to vector /// - private void Add(Span span) + private void Add(in Span span) { _spans.Add(span); } @@ -87,6 +87,13 @@ private void Insert(int index, int count) } #region Public operation + /// + /// Place item into the store at index + /// + public void SetAt(int index, in Span span) + { + _spans.SetAt(index, span); + } /// /// Finds the span that contains the specified character position. @@ -164,7 +171,7 @@ internal bool FindSpan(int cp, SpanPosition latestPosition, out SpanPosition spa // Return true if the span is in range. return spanIndex != spanCount; } - + /// /// Set an element as a value to a character range @@ -226,19 +233,23 @@ private SpanPosition Set(int first, int length, object element, Equals equals, S Add(new Span(_defaultObject, first - fc)); } - if ( Count > 0 - && equals(_spans[Count-1].element, element)) + bool addElement = true; + if (Count > 0) { - // New Element matches end Element, just extend end Element - _spans[Count - 1].length += length; - - // Make sure fs and fc still agree - if (fs == Count) + var span = _spans[Count - 1]; + if (equals(span.element, element)) { - fc += length; + // New Element matches end Element, just extend end Element + _spans[Count - 1] = new(span.element, span.length + length); + addElement = false; + // Make sure fs and fc still agree + if (fs == Count) + { + fc += length; + } } } - else + if (addElement) { Add(new Span(element, length)); } @@ -314,7 +325,8 @@ private SpanPosition Set(int first, int length, object element, Equals equals, S if (!Resize(fs + 2)) throw new OutOfMemoryException(); } - _spans[fs].length = first - fc; + var oldFsSpan = _spans[fs]; + _spans[fs] = new Span(oldFsSpan.element, first - fc); _spans[fs + 1] = new Span(element, length); } else @@ -370,7 +382,8 @@ private SpanPosition Set(int first, int length, object element, Equals equals, S if (fc < first) { - _spans[fs].length = first - fc; + var oldFsSpan = _spans[fs]; + _spans[fs] = new Span(oldFsSpan.element, first - fc); fs++; fc = first; } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextStore.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextStore.cs index 7e818831529..75b4d0d9bd5 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextStore.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextStore.cs @@ -1076,7 +1076,8 @@ internal bool InsertFakeLineBreak(int cpLimit) if (lsrun.Type == Plsrun.Text && cp + lsrun.Length > cpLimit) { lsrun.Truncate(cpLimit - cp); - span.length = lsrun.Length; + span = new(span.element, lsrun.Length); + _plsrunVector.SetAt(i, span); } _lscchUpTo = lscp + lsrun.Length; diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs index 6425cf6f625..d69f062d218 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs @@ -2221,6 +2221,17 @@ public void Insert(int index, T value) throw new ArgumentOutOfRangeException(nameof(index)); } + public void SetAt(int index, T value) + { + if ((_listStore is not null) && ((index < _listStore.Count) && (index >= 0))) + { + _listStore.SetAt(index, value); + return; + } + + throw new ArgumentOutOfRangeException(nameof(index)); + } + public bool Remove(T value) { if ((_listStore is not null) && (_listStore.Count > 0))