STDAPI touchmind::control::DWriteEditControlTextEditSink::OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
{
    std::shared_ptr<control::DWriteEditControl> pEditControl = m_pEditControl.lock();
    DisplayAttributeProperties dispAttrProps;
    HRESULT hr = m_displayAttribute.GetDisplayAttributeProperties(dispAttrProps);
    if (SUCCEEDED(hr)) {
        IEnumTfRanges *pEnum;
        hr = pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT,
                dispAttrProps.GetPropTablePointer(),
                static_cast<ULONG>(dispAttrProps.Count()),
                &pEnum);
        if (SUCCEEDED(hr) && pEnum) {
            ITfRange *pRange;
            if (pEnum->Next(1, &pRange, nullptr) == S_OK) {
                pRange->Release();

                pEditControl->ClearCompositionRenderInfo();

                ITfRange *pRangeEntire = nullptr;
                ITfRange *pRangeEnd = nullptr;
                if (SUCCEEDED(pic->GetStart(ecReadOnly, &pRangeEntire)) &&
                        SUCCEEDED(pic->GetEnd(ecReadOnly, &pRangeEnd)) &&
                        SUCCEEDED(pRangeEntire->ShiftEndToRange(ecReadOnly, pRangeEnd, TF_ANCHOR_END))) {
                    IEnumTfRanges *pEnumRanges;
                    ITfReadOnlyProperty *pProp = nullptr;

                    m_displayAttribute.GetDisplayAttributeTrackPropertyRange(pic, dispAttrProps, &pProp);

                    if (SUCCEEDED(pProp->EnumRanges(ecReadOnly, &pEnumRanges, pRangeEntire))) {
                        while (pEnumRanges->Next(1, &pRange, nullptr) == S_OK) {
                            TF_DISPLAYATTRIBUTE da;
                            ZeroMemory(&da, sizeof(da));
                            TfGuidAtom guid;
                            if (m_displayAttribute.GetDisplayAttributeData(ecReadOnly, pProp, pRange, &da, &guid) == S_OK) {
                                ITfRangeACP *pRangeACP;
                                if (pRange->QueryInterface(IID_ITfRangeACP, (void **)&pRangeACP) == S_OK) {
                                    LONG nStart;
                                    LONG nEnd;
                                    pRangeACP->GetExtent(&nStart, &nEnd);
                                    pEditControl->AddCompositionRenderInfo(nStart, nStart + nEnd, &da);
                                    pRangeACP->Release();
                                }
                            }
                        }
                    }
                }

                if (pRangeEntire) {
                    pRangeEntire->Release();
                }
                if (pRangeEnd) {
                    pRangeEnd->Release();
                }

            }
            pEnum->Release();
        }
    }
    return S_OK;
}
BOOL CTextService::_GetVertical(TfEditCookie ec, ITfContext *pContext)
{
	BOOL ret = FALSE;

	if(pContext != NULL)
	{
		ITfRange *pRange;
		if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
		{
			ITfReadOnlyProperty *pReadOnlyProperty;
			if(pContext->GetAppProperty(TSATTRID_Text_VerticalWriting, &pReadOnlyProperty) == S_OK)
			{
				VARIANT var;
				if(pReadOnlyProperty->GetValue(ec, pRange, &var) == S_OK)
				{
					if(var.vt == VT_BOOL)
					{
						ret = var.boolVal;
					}
				}
				SafeRelease(&pReadOnlyProperty);
			}
			SafeRelease(&pRange);
		}
	}

	return ret;
}
STDAPI CTextEditSink::OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
{
    CDispAttrProps *pDispAttrProps = GetDispAttrProps();
    if (pDispAttrProps)
    {
        IEnumTfRanges *pEnum;
        if (SUCCEEDED(pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT,
                                                             pDispAttrProps->GetPropTablePointer(),
                                                             pDispAttrProps->Count(),
                                                             &pEnum)) && pEnum)
        {
            ITfRange *pRange;
            if (pEnum->Next(1, &pRange, NULL) == S_OK)
            {
                // We check if there is a range to be changed.
                pRange->Release();

                _pEditor->ClearCompositionRenderInfo();

                // We read the display attribute for entire range.
                // It could be optimized by filtering the only delta with ITfEditRecord interface. 
                ITfRange *pRangeEntire = NULL;
                ITfRange *pRangeEnd = NULL;
                if (SUCCEEDED(pic->GetStart(ecReadOnly, &pRangeEntire)) &&
                    SUCCEEDED(pic->GetEnd(ecReadOnly, &pRangeEnd)) &&
                    SUCCEEDED(pRangeEntire->ShiftEndToRange(ecReadOnly, pRangeEnd, TF_ANCHOR_END)))
                {
                    IEnumTfRanges *pEnumRanges;
                    ITfReadOnlyProperty *pProp = NULL;

                    GetDisplayAttributeTrackPropertyRange(ecReadOnly, pic, pRangeEntire, &pProp, pDispAttrProps);

                    if (SUCCEEDED(pProp->EnumRanges(ecReadOnly, &pEnumRanges, pRangeEntire)))
                    {
                        while (pEnumRanges->Next(1, &pRange, NULL) == S_OK)
                        {
                            TF_DISPLAYATTRIBUTE da;
                            TfGuidAtom guid;
                            if (GetDisplayAttributeData(ecReadOnly, pProp, pRange, &da, &guid) == S_OK)
                            {
                                ITfRangeACP *pRangeACP;
                                if (pRange->QueryInterface(IID_ITfRangeACP, (void **)&pRangeACP) == S_OK)
                                {
                                    LONG nStart;
                                    LONG nEnd;
                                    pRangeACP->GetExtent(&nStart, &nEnd);
                                    _pEditor->AddCompositionRenderInfo(nStart, nStart + nEnd, &da);
                                    pRangeACP->Release();
                                }
                            }
                        }
                    }
                }

                if (pRangeEntire)
                    pRangeEntire->Release();
                if (pRangeEnd)
                    pRangeEnd->Release();
 
            }
            pEnum->Release();
        }

        delete pDispAttrProps;
    }

    return S_OK;
}