/// <summary> /// calc layout and render /// </summary> /// <param name="dev"></param> public void UpdateArea(IDeviceContext dev) //public void UpdateArea(Graphics g) { free_lines(); if (TextRegion != null) { TextRegion.Dispose(); } TextRegion = new Region(); IntPtr hdc = dev.GetHdc(); //IntPtr hdc = g.GetHdc(); IntPtr font_ptr = Font.ToHfont(); //IntPtr font_ptr = font_ptr_cached; IntPtr old_font = NativeGdi.SelectObject(hdc, font_ptr); //Font hdc_font = Font.FromHfont(old_font); uint old_align = NativeGdi.SetTextAlign(hdc, 0); int line_height = (int)Math.Ceiling(Font.GetHeight()); IntPtr char_buffer = IntPtr.Zero; int select_first = 0; int select_last = 0; int select_line_first = 0; int select_line_last = 0; OnFetchSelectionRange(out select_first, out select_last); bool EOF = false; int chars_filled = 0; int current_char_offset = 0; int current_Y = 0; while (current_Y + line_height < Bounds.Height) { select_line_first = 0; select_line_last = 0; OnFetchCharsToScreen (current_char_offset, true, out char_buffer, out chars_filled, out EOF); LineInfoSS new_line = new LineInfoSS(); new_line.ReferensePoint = new Point(Bounds.X, Bounds.Y + current_Y); new_line.CharFirst = current_char_offset; //если буфер не пуст рисуем строку if (chars_filled != 0) { new_line.PrepareLayout (hdc, char_buffer, chars_filled, Bounds.Width); //пересчитываем selection if ((select_first >= current_char_offset) && (select_first <= current_char_offset + new_line.CharLength - 1)) { //начало selection попадает в строку select_line_first = select_first - current_char_offset; select_line_last = new_line.CharLength - 1; } if ((select_last >= current_char_offset) && (select_last <= current_char_offset + new_line.CharLength - 1)) { //конец selection попадает в строку select_line_last = select_last - current_char_offset; } if ((select_first <= current_char_offset) && (select_last >= current_char_offset + new_line.CharLength - 1)) { //весь selection попадает в строку select_line_first = select_first - current_char_offset; select_line_last = new_line.CharLength - 1; } //и рисуем new_line.Render(select_line_first, select_line_last); } //прибавляем счетчики current_char_offset = current_char_offset + new_line.CharLength; current_Y = current_Y + line_height; lines_info.Add(new_line); TextRegion.Union(new Rectangle(new_line.ReferensePoint, new_line.Extent)); //если стоит признак конца файла, выходим if (EOF) { break; } } font_ptr = NativeGdi.SelectObject(hdc, old_font); NativeGdi.DeleteObject(font_ptr); //NativeGdi.DeleteObject(old_font); NativeGdi.SetTextAlign(hdc, old_align); NativeGdi.GdiFlush(); //возможно не обязательно dev.ReleaseHdc(); //g.ReleaseHdc(hdc); }
/// <summary> /// without render, only calc lines layout /// </summary> /// <param name="dev"></param> public void CalcLines(IDeviceContext dev, int max_lines_to_calc) { //освобождаем имеющиеся строки free_lines(); if (TextRegion != null) { TextRegion.Dispose(); } TextRegion = new Region(); 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 current_char_offset = 0; int current_Y = 0; int current_line_index = 0; while (current_line_index < max_lines_to_calc) { OnFetchCharsToScreen (current_char_offset, true, out char_buffer, out chars_filled, out EOF); LineInfoSS new_line = new LineInfoSS(); new_line.ReferensePoint = new Point(Bounds.X, Bounds.Y + current_Y); new_line.CharFirst = current_char_offset; //обсчитываем if (chars_filled != 0) { new_line.PrepareLayout (hdc, char_buffer, chars_filled, Bounds.Width); } //прибавляем счетчики current_char_offset = current_char_offset + new_line.CharLength; current_Y = current_Y + line_height; current_line_index++; lines_info.Add(new_line); TextRegion.Union(new Rectangle(new_line.ReferensePoint, new_line.Extent)); //если стоит признак конца файла, выходим if (EOF) { break; } } font_ptr = NativeGdi.SelectObject(hdc, old_font); NativeGdi.DeleteObject(font_ptr); NativeGdi.SetTextAlign(hdc, old_align); dev.ReleaseHdc(); }