Beispiel #1
0
        public static CharacterPositionInfo FromCharIndex(IntPtr ssa_struct, int char_index, CharacterPositionType pos_type)
        {
            if ((pos_type == CharacterPositionType.AfterEnd) ||
                (pos_type == CharacterPositionType.BeforeBeginning) ||
                (pos_type == CharacterPositionType.ClusterPart))
            {
                throw new ArgumentException("Illegal parameter.", "pos_type");
            }

            var trailing = (pos_type == CharacterPositionType.TrailingEdge);
            var x_offset = 0;
            var res      = NativeScript.ScriptStringCPtoX
                               (ssa_struct,
                               char_index,
                               trailing,
                               ref x_offset);

            if (res != NativeScript.S_OK)
            {
                Marshal.ThrowExceptionForHR(res);
            }

            var ret = new CharacterPositionInfo();

            ret.CharIndex    = char_index;
            ret.PositionType = pos_type;
            ret.Xoffset      = x_offset;

            return(ret);
        }
Beispiel #2
0
        public static CharacterPositionInfo FromXoffset(IntPtr ssa_struct, int x_offset)
        {
            var char_pos      = 0;
            var char_trailing = 0;

            if (ssa_struct == IntPtr.Zero)
            {
                x_offset = 0;
                return(new CharacterPositionInfo());
            }
            var res = NativeScript.ScriptStringXtoCP
                          (ssa_struct,
                          x_offset,
                          ref char_pos,
                          ref char_trailing);

            if (res != NativeScript.S_OK)
            {
                Marshal.ThrowExceptionForHR(res);
            }
            var chars_count = NativeScript.GetPcOutChars(ssa_struct);
            var ret         = new CharacterPositionInfo();

            ret.CharIndex = char_pos;
            ret.Xoffset   = x_offset;
            if (char_trailing == 0)
            {
                if (char_pos == chars_count)
                {
                    ret.PositionType = CharacterPositionType.AfterEnd;
                }
                else
                {
                    ret.PositionType = CharacterPositionType.LeadingEdge;
                }
            }
            else if (char_trailing == 1)
            {
                if (char_pos == -1)
                {
                    ret.PositionType = CharacterPositionType.BeforeBeginning;
                }
                else
                {
                    ret.PositionType = CharacterPositionType.TrailingEdge;
                }
            }
            else
            {
                ret.PositionType = CharacterPositionType.ClusterPart;
                ret.OffsetToNextCaretPosition = char_trailing;
            }
            return(ret);
        }
Beispiel #3
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 #4
0
            public void Render(int select_first, int select_last)
            {
                int res0 = NativeScript.ScriptStringOut
                               (ssa_struct_ptr,
                               ReferensePoint.X,
                               ReferensePoint.Y,
                               GDI_ExtTextOutOption.None,
                               IntPtr.Zero,
                               select_first,
                               select_last,
                               false);

                if (res0 != NativeScript.S_OK)
                {
                    Marshal.ThrowExceptionForHR(res0);
                }
            }
Beispiel #5
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 #6
0
            public LogicalCharacterAttribute GetLogicalAttribute(int char_index)
            {
                IntPtr log_attr_buffer = NativeScript.ScriptString_pLogAttr(ssa_struct_ptr);

                return(NativeScript.GetCharacterAttribute(log_attr_buffer, char_index));
            }
Beispiel #7
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);
        }