Ejemplo n.º 1
0
        public static SCRIPT_TABDEF GetDefault()
        {
            var ret = new SCRIPT_TABDEF();

            ret.cTabStops  = 0;
            ret.iScale     = 0;
            ret.pTabStops  = IntPtr.Zero;
            ret.iTabOrigin = 4;
            return(ret);
        }
Ejemplo n.º 2
0
 public static extern int ScriptStringAnalyse
     (IntPtr hdc,
     IntPtr pString,
     int cString,
     int cGlyphs,
     int iCharset,
     ScripStringAnalyseOptions dwFlags,
     int iReqWidth,
     IntPtr psControl, //SCRIPT_CONTROL*
     IntPtr psState,   //SCRIPT_STATE*
     IntPtr piDx,      // const int*
     ref SCRIPT_TABDEF pTabdef,
     IntPtr pbInClass, //const BYTE*
     ref IntPtr pssa   //SCRIPT_STRING_ANALYSIS*
     );
Ejemplo n.º 3
0
        public static IntPtr ScriptStringAnalyseCall
            (IntPtr hdc,
            IntPtr char_buffer,
            int max_char_len,
            int max_width,
            SCRIPT_TABDEF tab_def)
        {
            var ret        = IntPtr.Zero;
            var actual_buf = char_buffer;
            var opts       =
                ScripStringAnalyseOptions.BREAK |
                ScripStringAnalyseOptions.CLIP |
                //ScripStringAnalyseOptions.FALLBACK | -> это вызывает утечку, не освобождаются объекты gdi font
                ScripStringAnalyseOptions.GLYPHS |
                //ScripStringAnalyseOptions.LINK |
                ScripStringAnalyseOptions.TAB;
            var res0 = ScriptStringAnalyse
                           (hdc,
                           actual_buf,
                           max_char_len,
                           (int)((max_char_len * 1.5) + 16),
                           -1,
                           opts,
                           max_width,
                           IntPtr.Zero,
                           IntPtr.Zero,
                           IntPtr.Zero,
                           ref tab_def,
                           IntPtr.Zero,
                           ref ret);

            if (res0 != S_OK)
            {
                Marshal.ThrowExceptionForHR(res0);
            }
            return(ret);
        }
Ejemplo n.º 4
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);
        }