void UpdateCaret(bool forceUpdate = false)
        {
            TextField.CharPosition cp;
            if (_editing)
            {
                cp = GetCharPosition(_caretPosition + Input.compositionString.Length);
            }
            else
            {
                cp = GetCharPosition(_caretPosition);
            }

            Vector2 pos = GetCharLocation(cp);

            TextField.LineInfo line   = textField.lines[cp.lineIndex];
            Vector2            offset = pos + textField.xy;

            if (offset.x < textField.textFormat.size)
            {
                offset.x += Mathf.Min(50, _contentRect.width * 0.5f);
            }
            else if (offset.x > _contentRect.width - GUTTER_X - textField.textFormat.size)
            {
                offset.x -= Mathf.Min(50, _contentRect.width * 0.5f);
            }

            if (offset.x < GUTTER_X)
            {
                offset.x = GUTTER_X;
            }
            else if (offset.x > _contentRect.width - GUTTER_X)
            {
                offset.x = Mathf.Max(GUTTER_X, _contentRect.width - GUTTER_X);
            }

            if (offset.y < GUTTER_Y)
            {
                offset.y = GUTTER_Y;
            }
            else if (offset.y + line.height >= _contentRect.height - GUTTER_Y)
            {
                offset.y = Mathf.Max(GUTTER_Y, _contentRect.height - line.height - GUTTER_Y);
            }

            MoveContent(offset - pos, forceUpdate);

            if (_editing)
            {
                _caret.position = textField.xy + pos;
                _caret.height   = line.height > 0 ? line.height : textField.textFormat.size;

                if (_editable)
                {
                    Vector2 cursorPos = _caret.LocalToWorld(new Vector2(0, _caret.height));
                    cursorPos = StageCamera.main.WorldToScreenPoint(cursorPos);
#if !UNITY_2019_OR_NEWER
                    if (Stage.devicePixelRatio == 1)
                    {
#endif
                    cursorPos.y = Screen.height - cursorPos.y;
                    cursorPos   = cursorPos / Stage.devicePixelRatio;
                    Input.compositionCursorPos = cursorPos + new Vector2(0, 20);
#if !UNITY_2019_OR_NEWER
                }
                else
                {
                    Input.compositionCursorPos = cursorPos - new Vector2(0, 20);
                }
#endif
                }

                _nextBlink = Time.time + 0.5f;
                _caret.graphics.enabled = true;

                UpdateSelection(cp);
            }
        }