Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 06.05.2018
Сообщений: 162

Отрисовка RTF на канве

20.02.2020, 15:02. Показов 2918. Ответов 30

Студворк — интернет-сервис помощи студентам
Добрый день.
Хочу отричовать RTF текст на канве, в идеале мечтаю сотворить что-то вроде:
Delphi
1
function DrawRTF(ARTFText: String; ARect: TRect; ACanvas: TCanvas): boolean;
Много гуглил, вся информация которую нашел упирается в TRichEdit, способов отрисовки без него не нашел (надо еще уметь правильно гугл спростить).
За неимением варианта без TRichEdit пробую рисовать текст с ним - рисует, но есть проблема. Текст рисуется вместе с фоном TRichEdit (белая заливка) и убрать его не могу, делаю так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
with FormatRange do
    begin
       hdc:= ACanvas.Handle;
       hdcTarget:= hdc;
       rc:=  Rect(0, 0,
                  ARight    * 1440 div Screen.PixelsPerInch,
                  ABottom * 1440 div Screen.PixelsPerInch
                 );
       rcPage:= rc;
       chrg.cpMin := 0;
       chrg.cpMax := RichEdit.GetTextLen;
    end;
    SetBkMode(ACanvas.Handle, TRANSPARENT); // <- Вроде должно делать прозрачным и так не работает etBkMode(GetDC(RichEdit.Handle), TRANSPARENT);
    RichEdit.Perform(EM_FORMATRANGE, 1, Integer(@FormatRange));
    RichEdit.Perform(EM_FORMATRANGE, 0, 0);
Подскажите как избавиться от белого фона?
Или как ричовать RTF вообще без RichEdit?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.02.2020, 15:02
Ответы с готовыми решениями:

Некорректная отрисовка графика на канве
Где ошибка? Почему так плохо рисует график? //--------------------------------------------------------------------------- #include...

Рисование на канве
В программе предусмотреть возможность изменения цвета и стиля линий для каждой из фигур. На плоскости заданы n точек своими координатами...

Рисование на канве
Солнце с 10 лучами вращается против часовой стрелки с дискретом 100/сек. Длина цикла 30 сек. Запуск движения – команда контекстного меню.

30
Заблокирован
02.03.2020, 13:00
Студворк — интернет-сервис помощи студентам
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.FormPaint(Sender: TObject);
begin
 Form1.Canvas.Pen.Color:= clRed;
 Form1.Canvas.Brush.Color:= clRed;
 Form1.Canvas.Rectangle(0,0,200,200);
 Form1.Canvas.Brush.Color:= clGreen; // <= Цвет фона (кисти) зелёный
 
 Form1.Canvas.Font.Color:= clGreen;  // <= Цвет текста зелёный
 Form1.Canvas.Font.Height:= 24;
 Form1.Canvas.TextOut(10,10, 'Test 1');  // <=  текст сливается с фоном
 Form1.Canvas.Brush.Style:= bsClear;     // Очищаем фон (кисть)
 Form1.Canvas.TextOut(50,50, 'Test 2');
end;
Добавлено через 8 минут
NB
Важные моменты о которых спотыкаются не только новички

Рисовать надо исключительно в обработчике Paint.
Для любителей компонента Image, поясню. Там всё тоже самое но сделано за пользователя.
Для рисования на всём остальном, надо делать ручками.
Рисовать на отдельных битмапах а потом отрисовывать их на объекте вывода.
Или рисовать прямо в обработчике Paint
В DirectX делается так же. Там нет промежуточных битмапов, но есть буферы.

Ещё один момент. Очень важный.
Любые свойства нужно задавать непосредственно перед отрисовкой той или иной группы объектов, если что-то меняется.

Добавлено через 25 минут
Судя по задумке, автор поста хочет сделать нечто очень для него сложное.
И тут не один вопрос а сразу несколько.
1 Формат RTF
Но RTF это формат исключительно для хранения текста. Манипулировать им крайне сложно и долго.
Даже в Word любой другой формат преобразовывается в свой внутренний, а только потом выводится.
Проще всего использовать XML или его подмножество HML. Это если нужен вывод с сложным форматированием
Но тут нужно писать как минимум парсер.

2 Само рисование. Главный вопрос Где и Зачем.
Вопрос очень важный. Но главнее, какие именно элеменеты форматирования нужны.
Основной момент. Текст в Делфи по умолчанию выводится без Антиалисинга. То есть без сглаживания.
Можно конечно обратится к API и включить антиалисинг. А можно взять GDI+ однако это тормоз ещё тот...

Но выход есть. Это учится учится и учится не боясь трудностей.
Дело в том, что кода выводящего текст с форматированием крайне мало. Все пишут его для себя а выдать - жаба давит, ибо это действительно высший пилотаж программирования. Когда были такие модули для вывода теста с тегами, но ссылки все сдохли, а до авторов не достучишься.
Есть готовые компоненты для рисования в собственном браузере. Можно воспользоваться им.

А если делать всё самому - готовьтесь к трудностям и сложностям.
Я знаю что это такое. Я сам написал для себя подобную функцию.
Но писал я её в КОL. КОL крайне непривычная библиотека для многих. Но в ней есть многие вещи, которые в VCL приходится делать ручками.
Например для каждого компонента есть перетаскивание. Есть Антиалистинг для текста. Есть Юникод без дополнительных библиотек.
Но много чего нет. Но это всё ненужный мусор.
Впрочем вам решать. Я могу вас научить как всё это сделать и без KOL
Но повторяю, это очень сложно для новичка.
0
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
02.03.2020, 14:01
RADStudio
Может попытаться сделать так:
1) рисуешь то, что нужно в битмап
2) ставишь этот битмап как фоновый рисунок для RichEdit
0
Заблокирован
02.03.2020, 17:02
Теперь немного о текстовой геометрии.

Сам шрифт можно настроить средствами Delphi как обычно
Но. Забываем про SIZE пользуемся HEIGHT то есть высотой шрифта в пикселях.
Шрифты не моноширные, и поэтому ширина каждого символа разная.
Она даётся автоматически в зависимости от высоты и получит её можно функцией ..Canvas.TextWidth(S)

Когда текст выводится цепочкой, это очень важный параметр.
Но. Текст для с форматированием выводится по символам. И этот параметр становится наиглавнейшим.

Второй важный параметр это позиция текста.
Вообще текст можно позиционировать по 9 точкам.
Задаётся двумя флагами. По горизонтали и по вертикали
Лево центр право
Верх .... Низ
По умолчанию это верхний левый угол.
Левая сторона будет всё время.
Но по вертикали нужно нам то, что пока ....
Попробуйте вывести текст разной высоты
TOP - первый в примере
BOTTOM второй
Сами видите что выходит

Нужен нам то что было точками - BASLINE Базовая линия текста.
По этой линии выравнивается весь текст.
Это нижняя часть всех символов, без всяких хвостиков.
Эти хвостики и закорючки , как в букве Щ у запятой, находятся под базовой линией.
В общем посмотрите пример и увидите что только с базовой линией текст не скачет.
И вращать текст нужно задав базовую линию.

Но после отрисовки текста не забывайте вернуть всё на место.
И вообще за параметрами надо строго следить.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
procedure TForm1.FormPaint(Sender: TObject);
var
  i   : Integer;
  Pos_: Integer;
  S   : WideString;
begin
 
 Form1.Canvas.Font.Name:= 'Arial';
 Form1.Canvas.Pen.Color:= clYellow;
 Form1.Canvas.Brush.Color:= clYellow;
 Form1.Canvas.Rectangle(0,0,200,200);
 
 
 Form1.Canvas.Font.Color:= clRed;  // <= Цвет текста зелёный
 Form1.Canvas.Brush.Style:= bsClear;     // Очищаем фон (кисть)
 
   Form1.Canvas.Pen.Color:= clBlack;
 
  Form1.Canvas.MoveTo(0, 10);
  Form1.Canvas.LineTo(600, 10);
  S:= 'TOP';
  Pos_:= 20;
  for I:= 0 to 3 do
  begin
    Form1.Canvas.Font.Height:= I * 5 + 20;
    Form1.Canvas.TextOut(Pos_, 10, S);
    Pos_:= Pos_ + Form1.Canvas.TextWidth(S) + 20;
  end;
 
  Form1.Canvas.MoveTo(0, 80);
  Form1.Canvas.LineTo(600, 80);
 
  SetTextAlign(Form1.Canvas.Handle, TA_BOTTOM);
  S:= 'BOTTOM';
  Pos_:= 20;
  for I:= 0 to 3 do
  begin
    Form1.Canvas.Font.Height:= I * 5 + 10;
    Form1.Canvas.TextOut(Pos_, 80, S);
    Pos_:= Pos_ + Form1.Canvas.TextWidth(S) + 20;
  end;
 
  Form1.Canvas.MoveTo(0, 130);
  Form1.Canvas.LineTo(600, 130);
  S:= 'BASELINE';
  SetTextAlign(Form1.Canvas.Handle, TA_BASELINE);
  Pos_:= 20;
  for I:= 0 to 3 do
  begin
    Form1.Canvas.Font.Height:= I * 5 + 10;
    Form1.Canvas.TextOut(Pos_, 130, S);
    Pos_:= Pos_ + Form1.Canvas.TextWidth(S) + 20;
 
 
  end;
  SetTextAlign(Form1.Canvas.Handle, TA_TOP); // Вернём на место верх
 
end;
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
02.03.2020, 23:26
Wolwirk, тут вы немножко не в тему, речь как бы совершенно вообще не об рисовании обычными GDI/Canvas...
0
Заблокирован
03.03.2020, 00:33
Цитата Сообщение от GoodWeather Посмотреть сообщение
Wolwirk, тут вы немножко не в тему, речь как бы совершенно вообще не об рисовании обычными GDI/Canvas..
Вы глубоко ошибаетесь. Человек хочет выводить форматированный текст на канву. А это и есть графика и GDI
Пожалуйста ещё раз внимательно прочитайте самый первый пост.

Добавлено через 4 минуты
Цитата Сообщение от Wolwirk Посмотреть сообщение
S : WideString;
Кстати в 5 строке нужно просто String
Я писал для юникода, но потом решил что не стоит пока запутывать.
А тип изменить забыл

Впрочем и Form1. можно убрать.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
03.03.2020, 00:53
Форматированный. RTF.

Добавлено через 2 минуты
У человека строка с RTF-текстом. Например:
Цитата Сообщение от GoodWeather Посмотреть сообщение
Delphi
1
2
3
Var RTF: AnsiString;
Begin
RTF := '{\rtf1{{\colortbl ;\red255\green0\blue0;}foo \cf1\b bar \cf0\b0 baz!}';
или
Цитата Сообщение от RADStudio Посмотреть сообщение
Пример RTF строки
Delphi
1
2
3
4
5
6
7
8
9
RTF: string = '{\rtf1\fbidis\ansi\ansicpg1251\deff0\deflang1049{\fonttbl{\f0\fswiss\fprq2\fcharset204 Calibri;}{\f1\fnil Tahoma;}}' +
    '{\colortbl ;\red0\green176\blue80;\red255\green0\blue0;}' +
    '\viewkind4\uc1\pard\ltrpar\sa200\sl276\slmult1\lang1033\f0\fs22 Dgfgdfggj' +
    '\par Dfghgh\fs32 jghjgd \fs22 fg d \b dfgfgdf\b0 gdffg' +
    '\par \cf1 Fgh g h\cf0  dfgdf d \cf2 fgd fg h\cf0  fghffgfghedrfg' +
    '\par Fghj' +
    '\par \strike ghjhjggh' +
    '\par \pard\ltrpar\lang1049\strike0\f1\fs16' +
    '\par }';
Добавлено через 56 секунд
Ему это вручную сначала разгребать, а потом и рисовать тоже вручную..?

Добавлено через 38 секунд
В любом случае вопрос уже решён, остались лишь незначительные нюансы.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,497
03.03.2020, 09:48
Цитата Сообщение от Wolwirk Посмотреть сообщение
Человек хочет выводить форматированный текст на канву.
Вот именно. И для этого есть 2 пути.
1) Использовать имеющиеся форматы и наработки. RTF уже есть, его можно легко создать в разных программах.
2) Придумать свой формат и написать свою процедуру вывода форматированного текста. Потом написать свой редактор для своего формата, или конвертер из уже имеющегося формата, например, RTF. А если писать конвертер из RTF, то уже сразу можно написать и свой вывод форматированного текста RTF. Вернулись к началу задачи.
0
Заблокирован
03.03.2020, 11:08
Цитата Сообщение от AzAtom Посмотреть сообщение
Придумать свой формат и написать свою процедуру вывода форматированного текста. Потом написать свой редактор для своего формата, или конвертер из уже имеющегося формата, например, RTF. А если писать конвертер из RTF, то уже сразу можно написать и свой вывод форматированного текста RTF. Вернулись к началу задачи.
Ага. Именно я так и сделал. Написал свою функцию и создал свой язык форматирования, основанный на тегах и написал парсер. Но опять же. Ничего нового я не изобрёл. Строго говоря я взял XML и заменил в нём команды, нужные именно мне.
Если бы я взял RTF, Текст, который и без того полмегабайта вырос бы до неимоверной величины. И его обработка украла бы много драгоценного времени в игре, ровно как и в генераторе титров для DVD.
Кроме того, я сомневаюсь чтобы ваши решения подошли бы человеку, по той простой причине что речь шла не сколько о RTF сколько о тексте на фотографии или картинке. Причём красивого текста.
Кроме того я не знаю что делает ваше решение, но помимо прочего нужно выравнивание текста по ширине, причём с переносом слов по мягким переносам. Да, есть такая возможность в RTF модуле, но она имеет много неудобств.
Писать редактор RTF вообще нет смысла. Это всё можно прекрасно сделать и в ворде.
Дело именно в применении текста в графике. А это ещё помимо прочего и спецэффекты всякого рода.
Один из актуальных вопросов это чёткость текста. А это вопрос далеко не так прост. На картинке просто текст может сливаться с фоном и для устранения этого недостатка нужно его оконтуривание.
Но опять же, это надо делать. И остаётся проблема с сглаживанием. Её то тоже нужно как-то решать.
Вопросов много. И если вы хотя бы на эти ответите - да, это сделано в моём предложении, можете писать мне разгромные посты и обвинять меня в некомпетентности вопроса.
0
Заблокирован
03.03.2020, 11:43
Чтобы не быть голословным, вот демопроект самой первой версии этой функции. Нет ещё юникода, нет пока стилей.
Отрабатывался этот модуль под конкретную задачу и поэтому введён эффект постепенного вывода текста.
Текст для вывода задан в файле 1.txt
Туда можно вставить любой текст.
Собственно готовый текст делается у меня в ворде через макрос.
Кроме того, функция следит за величиной текста и выводит только в поле, которое задано рамками.
Лишний текст обрезается.

Сейчас уже и юникод есть и другие штучки, но не суть.
Я ,собственно, хотел чтобы человек научился писать нечто подобное или лучше. Но если ему не надо, то ладно.
Вот екзешник. Исходника конечно не дам. Сами должны писать. А помочь - помогу если есть у кого желание.
Кстати, обратите внимание на размер файла. Это фишка KOL
Вложения
Тип файла: rar TextTag.rar (25.1 Кб, 8 просмотров)
0
 Аватар для mr-Crocodile
3054 / 1673 / 657
Регистрация: 19.03.2019
Сообщений: 5,380
03.03.2020, 16:07
Цитата Сообщение от Wolwirk Посмотреть сообщение
Чтобы не быть голословным, вот демопроект самой первой версии этой функции.
Можешь сделать такой же проект, но чтобы вывод шёл на картинку (поверх Image)?
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
03.03.2020, 19:06
Мы вам объясняем, у ТС текст в формате RTF.
И предполагается два режима ввода - компонент TRichEdit или RTF-файл.
Требуется вывести содержимое RTF-документа поверх битмапа с его текущим форматированием как есть. Только без белого фона листа.
И ТС уже сам нашёл код, который именно это успешно делает. На WinAPI.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.03.2020, 19:06

Перемещение по канве.
Есть некий объект, который мышью перемещяют по Canvas. Canvas помещен в ScrollViewer. При попытке утянуть объект за пределы Canvas , у него...

Рисование на канве
У меня есть текст, затем рисую прямоугольник на канве и этот текст перекрывается прямоугольником (рис. 1). Как сделать, чтобы Label был...

Время на канве
В общем, я хотел создать прогу, которая РИСУЕТ на форме время компа. Именно через канву, потому что на label некрасиво(с ним то...

Диаграмма на канве
Написал парочку процедур по созданию диаграмм, но неправильно выводит нужные мне прямоугольники Исходные данные: ребра и их...

Графики на канве
Всем привет. Не так давно начал изучать Делфи, но вот с канвой вообще понятия не имею как работать. Поэтому прошу у вас помощи, надеюсь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru