// Decorates the composition with IME specified underlining. private void SetCompositionAdorner(int[] clauseInfo, byte[] attributes) { if ((clauseInfo != null) && (attributes != null)) { for (int i = 0; i < clauseInfo.Length - 1; i++) { ITextPointer startClause = _startComposition.CreatePointer(clauseInfo[i], LogicalDirection.Backward); ITextPointer endClause = _startComposition.CreatePointer(clauseInfo[i + 1], LogicalDirection.Forward); if (_compositionAdorner == null) { _compositionAdorner = new CompositionAdorner(_editor.TextView); _compositionAdorner.Initialize(_editor.TextView); } // // UnsafeNativeMethods.TF_DISPLAYATTRIBUTE displayAttribute = new UnsafeNativeMethods.TF_DISPLAYATTRIBUTE(); displayAttribute.crLine.type = UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_COLORREF; displayAttribute.crLine.indexOrColorRef = 0; displayAttribute.lsStyle = UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_NONE; displayAttribute.fBoldLine = false; switch (attributes[clauseInfo[i]]) { case NativeMethods.ATTR_INPUT: displayAttribute.lsStyle = UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_DOT; break; case NativeMethods.ATTR_TARGET_CONVERTED: displayAttribute.lsStyle = UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_SOLID; displayAttribute.fBoldLine = true; break; case NativeMethods.ATTR_CONVERTED: displayAttribute.lsStyle = UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_SOLID; break; case NativeMethods.ATTR_TARGET_NOTCONVERTED: displayAttribute.lsStyle = UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_SOLID; break; case NativeMethods.ATTR_INPUT_ERROR: break; case NativeMethods.ATTR_FIXEDCONVERTED: break; } #if UNUSED_IME_HIGHLIGHT_LAYER // Demand create the highlight layer. if (_highlightLayer == null) { _highlightLayer = new DisplayAttributeHighlightLayer(); } // ToDo: Need to pass the foreground and background color of the composition _highlightLayer.Add(startClause, endClause, /*TextDecorationCollection:*/null); #endif TextServicesDisplayAttribute textServiceDisplayAttribute = new TextServicesDisplayAttribute(displayAttribute); // Add the attribute range into CompositionAdorner. _compositionAdorner.AddAttributeRange(startClause, endClause, textServiceDisplayAttribute); } #if UNUSED_IME_HIGHLIGHT_LAYER if (_highlightLayer != null) { _editor.TextContainer.Highlights.AddLayer(_highlightLayer); } #endif if (_compositionAdorner != null) { // Update the layout to get the acurated rectangle from calling GetRectangleFromTextPosition _editor.TextView.RenderScope.UpdateLayout(); // Invalidate the composition adorner to apply the composition attribute ranges. _compositionAdorner.InvalidateAdorner(); } } }
internal override void OnEndEdit(UnsafeNativeMethods.ITfContext context, int ecReadOnly, UnsafeNativeMethods.ITfEditRecord editRecord) { Guid displayAttributeGuid; UnsafeNativeMethods.ITfProperty displayAttributeProperty; UnsafeNativeMethods.IEnumTfRanges attributeRangeEnumerator; UnsafeNativeMethods.ITfRange[] attributeRanges; int fetched; int guidAtom; TextServicesDisplayAttribute displayAttribute; ITextPointer start; ITextPointer end; // // Remove any existing display attribute highlights. // #if UNUSED_IME_HIGHLIGHT_LAYER if (_highlightLayer != null) { this.TextStore.TextContainer.Highlights.RemoveLayer(_highlightLayer); _highlightLayer = null; } #endif // // Remove any existing composition adorner for display attribute. // if (_compositionAdorner != null) { _compositionAdorner.Uninitialize(); _compositionAdorner = null; } // // Look for new ones. // // Get the DisplayAttributeProperty. displayAttributeGuid = Guid; context.GetProperty(ref displayAttributeGuid, out displayAttributeProperty); // Get a range enumerator for the property. if (displayAttributeProperty.EnumRanges(ecReadOnly, out attributeRangeEnumerator, null) == NativeMethods.S_OK) { attributeRanges = new UnsafeNativeMethods.ITfRange[1]; // Walk each range. while (attributeRangeEnumerator.Next(1, attributeRanges, out fetched) == NativeMethods.S_OK) { // Get a DisplayAttribute for this range. guidAtom = GetInt32Value(ecReadOnly, displayAttributeProperty, attributeRanges[0]); displayAttribute = GetDisplayAttribute(guidAtom); if (displayAttribute != null && !displayAttribute.IsEmptyAttribute()) { // Set a matching highlight for the attribute range. ConvertToTextPosition(attributeRanges[0], out start, out end); if (start != null) { #if UNUSED_IME_HIGHLIGHT_LAYER // Demand create the highlight layer. if (_highlightLayer == null) { _highlightLayer = new DisplayAttributeHighlightLayer(); } #endif if (_compositionAdorner == null) { _compositionAdorner = new CompositionAdorner(this.TextStore.TextView); _compositionAdorner.Initialize(this.TextStore.TextView); } #if UNUSED_IME_HIGHLIGHT_LAYER // ToDo: Need to pass the foreground and background color of the composition _highlightLayer.Add(start, end, /*TextDecorationCollection:*/null); #endif // Add the attribute range into CompositionAdorner. _compositionAdorner.AddAttributeRange(start, end, displayAttribute); } } Marshal.ReleaseComObject(attributeRanges[0]); } #if UNUSED_IME_HIGHLIGHT_LAYER if (_highlightLayer != null) { this.TextStore.TextContainer.Highlights.AddLayer(_highlightLayer); } #endif if (_compositionAdorner != null) { // Update the layout to get the acurated rectangle from calling GetRectangleFromTextPosition this.TextStore.RenderScope.UpdateLayout(); // Invalidate the composition adorner to render the composition attribute ranges. _compositionAdorner.InvalidateAdorner(); } Marshal.ReleaseComObject(attributeRangeEnumerator); } Marshal.ReleaseComObject(displayAttributeProperty); }
/// <summary> /// Calback function for TextEditSink /// we track the property change here. /// </summary> internal override void OnEndEdit(UnsafeNativeMethods.ITfContext context, int ecReadOnly, UnsafeNativeMethods.ITfEditRecord editRecord) { Guid displayAttributeGuid; UnsafeNativeMethods.ITfProperty displayAttributeProperty; UnsafeNativeMethods.IEnumTfRanges attributeRangeEnumerator; UnsafeNativeMethods.ITfRange[] attributeRanges; int fetched; int guidAtom; TextServicesDisplayAttribute displayAttribute; ITextPointer start; ITextPointer end; // // Remove any existing display attribute highlights. // #if UNUSED_IME_HIGHLIGHT_LAYER if (_highlightLayer != null) { this.TextStore.TextContainer.Highlights.RemoveLayer(_highlightLayer); _highlightLayer = null; } #endif // // Remove any existing composition adorner for display attribute. // if (_compositionAdorner != null) { _compositionAdorner.Uninitialize(); _compositionAdorner = null; } // // Look for new ones. // // Get the DisplayAttributeProperty. displayAttributeGuid = Guid; context.GetProperty(ref displayAttributeGuid, out displayAttributeProperty); // Get a range enumerator for the property. if (displayAttributeProperty.EnumRanges(ecReadOnly, out attributeRangeEnumerator, null) == NativeMethods.S_OK) { attributeRanges = new UnsafeNativeMethods.ITfRange[1]; // Walk each range. while (attributeRangeEnumerator.Next(1, attributeRanges, out fetched) == NativeMethods.S_OK) { // Get a DisplayAttribute for this range. guidAtom = GetInt32Value(ecReadOnly, displayAttributeProperty, attributeRanges[0]); displayAttribute = GetDisplayAttribute(guidAtom); if (displayAttribute != null && !displayAttribute.IsEmptyAttribute()) { // Set a matching highlight for the attribute range. ConvertToTextPosition(attributeRanges[0], out start, out end); if (start != null) { #if UNUSED_IME_HIGHLIGHT_LAYER // Demand create the highlight layer. if (_highlightLayer == null) { _highlightLayer = new DisplayAttributeHighlightLayer(); } #endif if (_compositionAdorner == null) { _compositionAdorner = new CompositionAdorner(this.TextStore.TextView); _compositionAdorner.Initialize(this.TextStore.TextView); } #if UNUSED_IME_HIGHLIGHT_LAYER // Need to pass the foreground and background color of the composition _highlightLayer.Add(start, end, /*TextDecorationCollection:*/ null); #endif // Add the attribute range into CompositionAdorner. _compositionAdorner.AddAttributeRange(start, end, displayAttribute); } } Marshal.ReleaseComObject(attributeRanges[0]); } #if UNUSED_IME_HIGHLIGHT_LAYER if (_highlightLayer != null) { this.TextStore.TextContainer.Highlights.AddLayer(_highlightLayer); } #endif if (_compositionAdorner != null) { // Update the layout to get the acurated rectangle from calling GetRectangleFromTextPosition this.TextStore.RenderScope.UpdateLayout(); // Invalidate the composition adorner to render the composition attribute ranges. _compositionAdorner.InvalidateAdorner(); } Marshal.ReleaseComObject(attributeRangeEnumerator); } Marshal.ReleaseComObject(displayAttributeProperty); }