Beispiel #1
0
 /// <summary>
 /// dispose obligatory!!
 /// </summary>
 public void Dispose()
 {
     if (ssa_struct_ptr != IntPtr.Zero)
     {
         int res = NativeScript.ScriptStringFree(ref ssa_struct_ptr);
         if (res != 0)
         {
             Marshal.ThrowExceptionForHR(res);
         }
     }
 }
Beispiel #2
0
            public void PrepareLayout(IntPtr hdc, IntPtr char_buffer, int max_char_len, int max_width)
            {
                ssa_struct_ptr = NativeScript.ScriptStringAnalyseCall
                                     (hdc,
                                     char_buffer,
                                     max_char_len,
                                     max_width,
                                     tab_def);

                //сколько поместилось
                int chars_clipped = NativeScript.GetPcOutChars(ssa_struct_ptr);

                //просматриваем с конца для поиска разрыва линии
                IntPtr attr_buffer    = NativeScript.ScriptString_pLogAttr(ssa_struct_ptr);
                int    line_break_ind = -1;

                //если вся строка уместилась в линию
                if (chars_clipped == max_char_len)
                {
                    line_break_ind = chars_clipped - 1;
                }

                //если вся строка не уместилась, ищем крайний с конца SoftBreak
                if (line_break_ind == -1)
                {
                    LogicalCharacterAttribute attr = LogicalCharacterAttribute.None;
                    for (int i = chars_clipped - 1; i > 0; i--)
                    {
                        attr = NativeScript.GetCharacterAttribute(attr_buffer, i);
                        if ((attr & LogicalCharacterAttribute.SoftBreak) == LogicalCharacterAttribute.SoftBreak)
                        {
                            line_break_ind = i - 1;
                            break;
                        }
                    }
                }

                //если и softBreak не найден, рвем по умещению
                if (line_break_ind == -1)
                {
                    line_break_ind = chars_clipped - 1;
                }

                //если разрываем, вторично вызываем обссчет с новой длиной строки
                if (line_break_ind + 1 != max_char_len)
                {
                    //освобождаем предыдущий ssa_sctuct_ptr
                    int res3 = NativeScript.ScriptStringFree(ref ssa_struct_ptr);
                    if (res3 != 0)
                    {
                        Marshal.ThrowExceptionForHR(res3);
                    }

                    //и обновляем
                    ssa_struct_ptr = NativeScript.ScriptStringAnalyseCall
                                         (hdc,
                                         char_buffer,
                                         line_break_ind + 1,
                                         tab_def);
                }

                //debug
                //string actual_string = Marshal.PtrToStringAuto(char_buffer, line_break_ind + 1);
                //char[] actual_chars = actual_string.ToCharArray();

                //заполняем свойства
                Extent     = NativeScript.GetScriptStringExtent(ssa_struct_ptr);
                CharLength = line_break_ind + 1;

                //debug
                //if (Extent.Width == 0)
                //{
                //    int debug = 0;
                //}
            }
Beispiel #3
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);
        }