Beispiel #1
0
        public int FindPreviousLineStart(IDeviceContext dev)
        {
            //для обсчета строки будет нужен контекст
            IntPtr hdc          = dev.GetHdc();
            IntPtr font_ptr     = Font.ToHfont();
            IntPtr old_font     = NativeGdi.SelectObject(hdc, font_ptr);
            uint   old_align    = NativeGdi.SetTextAlign(hdc, 0);
            int    line_height  = (int)Math.Ceiling(Font.GetHeight());
            IntPtr char_buffer  = IntPtr.Zero;
            bool   EOF          = false;
            int    chars_filled = 0;
            int    ret          = 0;

            //получаем буфер символов начиная от -max_chars_in_line
            OnFetchCharsToScreen
                (-max_chars_in_line,
                false,
                out char_buffer,
                out chars_filled,
                out EOF);

            if (chars_filled <= 0)
            {
                //то есть и так находимся в начале
                ret = 0;
            }
            else
            {
                //получаем ssa_sctruct
                IntPtr ssa_scruct = NativeScript.ScriptStringAnalyseCall
                                        (hdc,
                                        char_buffer,
                                        chars_filled,
                                        SCRIPT_TABDEF.GetDefault());

                //берем logical wodths
                int[] widths = NativeScript.GetLogicalWidths(ssa_scruct);
                //освобождаем ssa_scruct
                NativeScript.ScriptStringFree(ref ssa_scruct);

                //суммируем полученные ширины символов с конца, пока не превысим
                //максимальную ширину или не встретим второй hard break
                char current_char  = '\0';
                int  current_width = 0;
                int  finding_ind   = -1;
                for (int i = chars_filled - 1; i >= 0; i--)
                {
                    current_char  = get_char_from_buffer(char_buffer, i);
                    current_width = current_width + widths[i];
                    //проверяем ширину
                    if (current_width > Bounds.Width)
                    {
                        finding_ind = i;
                        break;
                    }

                    //проверяем hard break (\n   \r     \r\n) начиная со второго шага
                    if (i != chars_filled - 1)
                    {
                        if (current_char == '\n')
                        {
                            if (((i - 1) >= 0) && (get_char_from_buffer(char_buffer, i - 1) == '\r'))
                            {
                                finding_ind = i;
                                break;
                            }
                            finding_ind = i;
                            break;
                        }
                        else if ((current_char == '\r') && (i < chars_filled - 2))
                        {
                            finding_ind = i;
                            break;
                        }
                    }
                }

                //finding_ind теперь соответствует концу предыщей строки
                ret = -(chars_filled - finding_ind - 1);
            }

            font_ptr = NativeGdi.SelectObject(hdc, old_font);
            NativeGdi.DeleteObject(font_ptr);
            NativeGdi.SetTextAlign(hdc, old_align);
            dev.ReleaseHdc();

            return(ret);
        }