/// <summary> /// Updates the <code>TextMeasurer</code> after a single character has /// been deleted /// from the paragraph currently represented by this /// <code>TextMeasurer</code>. After this call, this /// <code>TextMeasurer</code> is equivalent to a new <code>TextMeasurer</code> /// created from the text; however, it will usually be more efficient /// to update an existing <code>TextMeasurer</code> than to create a new one /// from scratch. /// </summary> /// <param name="newParagraph"> the text of the paragraph after performing /// the deletion. Cannot be null. </param> /// <param name="deletePos"> the position in the text where the character was removed. /// Must not be less than /// the start of <code>newParagraph</code>, and must not be greater than the /// end of <code>newParagraph</code>. </param> /// <exception cref="IndexOutOfBoundsException"> if <code>deletePos</code> is /// less than the start of <code>newParagraph</code> or greater /// than the end of <code>newParagraph</code> </exception> /// <exception cref="NullPointerException"> if <code>newParagraph</code> is /// <code>null</code> </exception> public void DeleteChar(AttributedCharacterIterator newParagraph, int deletePos) { FStart = newParagraph.BeginIndex; int end = newParagraph.EndIndex; if (end - FStart != FChars.Length - 1) { InitAll(newParagraph); } char[] newChars = new char[end - FStart]; int changedIndex = deletePos - FStart; System.Array.Copy(FChars, 0, newChars, 0, deletePos - FStart); System.Array.Copy(FChars, changedIndex + 1, newChars, changedIndex, end - deletePos); FChars = newChars; if (FBidi != null) { FBidi = new Bidi(newParagraph); if (FBidi.LeftToRight) { FBidi = null; } } FParagraph = StyledParagraph.DeleteChar(newParagraph, FChars, deletePos, FParagraph); InvalidateComponents(); }
/// <summary> /// Updates the <code>TextMeasurer</code> after a single character has /// been inserted /// into the paragraph currently represented by this /// <code>TextMeasurer</code>. After this call, this /// <code>TextMeasurer</code> is equivalent to a new /// <code>TextMeasurer</code> created from the text; however, it will /// usually be more efficient to update an existing /// <code>TextMeasurer</code> than to create a new one from scratch. /// </summary> /// <param name="newParagraph"> the text of the paragraph after performing /// the insertion. Cannot be null. </param> /// <param name="insertPos"> the position in the text where the character was /// inserted. Must not be less than the start of /// <code>newParagraph</code>, and must be less than the end of /// <code>newParagraph</code>. </param> /// <exception cref="IndexOutOfBoundsException"> if <code>insertPos</code> is less /// than the start of <code>newParagraph</code> or greater than /// or equal to the end of <code>newParagraph</code> </exception> /// <exception cref="NullPointerException"> if <code>newParagraph</code> is /// <code>null</code> </exception> public void InsertChar(AttributedCharacterIterator newParagraph, int insertPos) { if (CollectStats) { PrintStats(); } if (WantStats) { CollectStats = true; } FStart = newParagraph.BeginIndex; int end = newParagraph.EndIndex; if (end - FStart != FChars.Length + 1) { InitAll(newParagraph); } char[] newChars = new char[end - FStart]; int newCharIndex = insertPos - FStart; System.Array.Copy(FChars, 0, newChars, 0, newCharIndex); char newChar = newParagraph.setIndex(insertPos); newChars[newCharIndex] = newChar; System.Array.Copy(FChars, newCharIndex, newChars, newCharIndex + 1, end - insertPos - 1); FChars = newChars; if (FBidi != null || Bidi.RequiresBidi(newChars, newCharIndex, newCharIndex + 1) || newParagraph.GetAttribute(TextAttribute.BIDI_EMBEDDING) != null) { FBidi = new Bidi(newParagraph); if (FBidi.LeftToRight) { FBidi = null; } } FParagraph = StyledParagraph.InsertChar(newParagraph, FChars, insertPos, FParagraph); InvalidateComponents(); }
/// <summary> /// Return a StyledParagraph reflecting the insertion of a single character /// into the text. This method will attempt to reuse the given paragraph, /// but may create a new paragraph. </summary> /// <param name="aci"> an iterator over the text. The text should be the same as the /// text used to create (or most recently update) oldParagraph, with /// the exception of deleting a single character at deletePos. </param> /// <param name="chars"> the characters in aci </param> /// <param name="deletePos"> the index where a character was removed </param> /// <param name="oldParagraph"> a StyledParagraph for the text in aci before the /// insertion </param> public static StyledParagraph DeleteChar(AttributedCharacterIterator aci, char[] chars, int deletePos, StyledParagraph oldParagraph) { // We will reuse oldParagraph unless there was a length-1 run // at deletePos. We could do more work and check the individual // Font and Decoration runs, but we don't right now... deletePos -= aci.BeginIndex; if (oldParagraph.Decorations == null && oldParagraph.Fonts == null) { oldParagraph.Length -= 1; return(oldParagraph); } if (oldParagraph.GetRunLimit(deletePos) == deletePos + 1) { if (deletePos == 0 || oldParagraph.GetRunLimit(deletePos - 1) == deletePos) { return(new StyledParagraph(aci, chars)); } } oldParagraph.Length -= 1; if (oldParagraph.Decorations != null) { DeleteFrom(deletePos, oldParagraph.DecorationStarts, oldParagraph.Decorations.Count); } if (oldParagraph.Fonts != null) { DeleteFrom(deletePos, oldParagraph.FontStarts, oldParagraph.Fonts.Count); } return(oldParagraph); }
/// <summary> /// Initialize state, including fChars array, direction, and /// fBidi. /// </summary> private void InitAll(AttributedCharacterIterator text) { FStart = text.BeginIndex; // extract chars FChars = new char[text.EndIndex - FStart]; int n = 0; for (char c = text.First(); c != java.text.CharacterIterator_Fields.DONE; c = text.Next()) { FChars[n++] = c; } text.First(); FBidi = new Bidi(text); if (FBidi.LeftToRight) { FBidi = null; } text.First(); //JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET: //ORIGINAL LINE: java.util.Map<? extends java.text.AttributedCharacterIterator_Attribute, ?> paragraphAttrs = text.getAttributes(); IDictionary <?, ?> paragraphAttrs = text.Attributes; NumericShaper shaper = AttributeValues.getNumericShaping(paragraphAttrs); if (shaper != null) { shaper.Shape(FChars, 0, FChars.Length); } FParagraph = new StyledParagraph(text, FChars); { // set paragraph attributes // If there's an embedded graphic at the start of the // paragraph, look for the first non-graphic character // and use it and its font to initialize the paragraph. // If not, use the first graphic to initialize. FJustifyRatio = AttributeValues.getJustification(paragraphAttrs); bool haveFont = TextLine.AdvanceToFirstFont(text); if (haveFont) { Font defaultFont = TextLine.GetFontAtCurrentPos(text); int charsStart = text.Index - text.BeginIndex; LineMetrics lm = defaultFont.GetLineMetrics(FChars, charsStart, charsStart + 1, FFrc); FBaseline = (sbyte)lm.BaselineIndex; FBaselineOffsets = lm.BaselineOffsets; } else { // hmmm what to do here? Just try to supply reasonable // values I guess. GraphicAttribute graphic = (GraphicAttribute)paragraphAttrs[TextAttribute.CHAR_REPLACEMENT]; FBaseline = TextLayout.GetBaselineFromGraphic(graphic); //JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET: //ORIGINAL LINE: java.util.Hashtable<java.text.AttributedCharacterIterator_Attribute, ?> fmap = new java.util.Hashtable<>(5, (float)0.9); Dictionary <AttributedCharacterIterator_Attribute, ?> fmap = new Dictionary <AttributedCharacterIterator_Attribute, ?>(5, (float)0.9); Font dummyFont = new Font(fmap); LineMetrics lm = dummyFont.GetLineMetrics(" ", 0, 1, FFrc); FBaselineOffsets = lm.BaselineOffsets; } FBaselineOffsets = TextLine.GetNormalizedOffsets(FBaselineOffsets, FBaseline); } InvalidateComponents(); }
/// <summary> /// Return a StyledParagraph reflecting the insertion of a single character /// into the text. This method will attempt to reuse the given paragraph, /// but may create a new paragraph. </summary> /// <param name="aci"> an iterator over the text. The text should be the same as the /// text used to create (or most recently update) oldParagraph, with /// the exception of inserting a single character at insertPos. </param> /// <param name="chars"> the characters in aci </param> /// <param name="insertPos"> the index of the new character in aci </param> /// <param name="oldParagraph"> a StyledParagraph for the text in aci before the /// insertion </param> public static StyledParagraph InsertChar(AttributedCharacterIterator aci, char[] chars, int insertPos, StyledParagraph oldParagraph) { // If the styles at insertPos match those at insertPos-1, // oldParagraph will be reused. Otherwise we create a new // paragraph. char ch = aci.setIndex(insertPos); int relativePos = System.Math.Max(insertPos - aci.BeginIndex - 1, 0); //JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET: //ORIGINAL LINE: java.util.Map<? extends java.text.AttributedCharacterIterator_Attribute, ?> attributes = addInputMethodAttrs(aci.getAttributes()); IDictionary <?, ?> attributes = AddInputMethodAttrs(aci.Attributes); Decoration d = Decoration.getDecoration(attributes); if (!oldParagraph.GetDecorationAt(relativePos).Equals(d)) { return(new StyledParagraph(aci, chars)); } Object f = GetGraphicOrFont(attributes); if (f == null) { FontResolver resolver = FontResolver.Instance; int fontIndex = resolver.getFontIndex(ch); f = resolver.getFont(fontIndex, attributes); } if (!oldParagraph.GetFontOrGraphicAt(relativePos).Equals(f)) { return(new StyledParagraph(aci, chars)); } // insert into existing paragraph oldParagraph.Length += 1; if (oldParagraph.Decorations != null) { InsertInto(relativePos, oldParagraph.DecorationStarts, oldParagraph.Decorations.Count); } if (oldParagraph.Fonts != null) { InsertInto(relativePos, oldParagraph.FontStarts, oldParagraph.Fonts.Count); } return(oldParagraph); }