OberonCore https://forum.oberoncore.ru/ |
|
Поворот текста на 90 градусов (для изобр. графиков) https://forum.oberoncore.ru/viewtopic.php?f=24&t=2391 |
Страница 1 из 2 |
Автор: | Иван Денисов [ Среда, 24 Февраль, 2010 01:18 ] |
Заголовок сообщения: | Поворот текста на 90 градусов (для изобр. графиков) |
Выделено: viewtopic.php?f=35&t=1064 Пишу свой модуль для построения графиков, но как развернуть текст на 90 градусов, чтобы подписать ось Y, ума не приложу. Подскажите, пожалуйста. |
Автор: | Илья Ермаков [ Среда, 24 Февраль, 2010 09:23 ] |
Заголовок сообщения: | Re: Построение графиков |
Стандартным образом трудно... в WinApi нет средств вывода текста под углом. Работать с битмапом в памяти и самим разворачивать на 90 разве что. |
Автор: | Info21 [ Среда, 24 Февраль, 2010 10:53 ] |
Заголовок сообщения: | Re: Построение графиков |
divan писал(а): Пишу свой модуль для построения графиков, но как развернуть текст на 90 градусов, чтобы подписать ось Y, ума не приложу. Подскажите, пожалуйста. Что-то, кажется, было в библиотеке Lib на zinnamturm.eu http://zinnamturm.eu/downloadsIN.htm#Lib |
Автор: | Александр Ильин [ Среда, 24 Февраль, 2010 11:37 ] |
Заголовок сообщения: | Re: Построение графиков |
Илья Ермаков писал(а): Стандартным образом трудно... в WinApi нет средств вывода текста под углом. http://msdn.microsoft.com/en-us/library/dd145037(VS.85).aspx писал(а): typedef struct tagLOGFONT { ... LONG lfEscapement; LONG lfOrientation; ... } LOGFONT, *PLOGFONT; lfEscapement The angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text. When the graphics mode is set to GM_ADVANCED, you can specify the escapement angle of the string independently of the orientation angle of the string's characters. When the graphics mode is set to GM_COMPATIBLE, lfEscapement specifies both the escapement and orientation. You should set lfEscapement and lfOrientation to the same value. lfOrientation The angle, in tenths of degrees, between each character's base line and the x-axis of the device. Пример кода: http://nibuthomas.com/2008/02/14/how-to ... ng-winapi/ |
Автор: | Роман М. [ Среда, 24 Февраль, 2010 11:52 ] |
Заголовок сообщения: | Re: Построение графиков |
divan Может, воспользоваться платформо-независимой библиотекой Cairo для вывода примитивов типа линий и текста (всяко лучше, чем с помощью WinAPI)? В ней есть процедура cairo_rotate для поворота объектов. Можно применить всякие трансформации по мере необходимости. Её преимущество в том, что у неё предусмотрено немалое количество генерируемых поверхностей (Win32-GDI+, X11-Xlib, Mac OS-Quartz, PostScript, PDF, SVG, PNG и ещё много других), но главное - она векторная. |
Автор: | Galkov [ Среда, 24 Февраль, 2010 13:22 ] |
Заголовок сообщения: | Re: Построение графиков |
Илья Ермаков писал(а): в WinApi нет средств вывода текста под углом Неправда ВашаЧерез WinApi типа SetWorldTransform - любые линейные извращения делать можно. Вроде бы |
Автор: | Иван Денисов [ Среда, 24 Февраль, 2010 14:02 ] |
Заголовок сообщения: | Re: Построение графиков |
В Lib не понял как поворачивает (если вообще поворачивает), a Plot от Gérard'a Meunier'a нарисовала мне вот такую картинку: Вложение:
Комментарий к файлу: Plot Gérard Meunier Result Screenshot-BlackBox.png [ 5.69 КБ | Просмотров: 19869 ] Поворачивать не умеет! Большое спасибо за наводку на Cairo, она точно пригодится для экспорта графики, поскольку написать свой драйвер для SVG думаю мне не по силам пока. А в BB нет ничего для векторного экспорта? А как будет выглядеть процедура для поворота используя API? К сожалению, не умею пользоваться WinAPI. |
Автор: | Info21 [ Среда, 24 Февраль, 2010 14:16 ] |
Заголовок сообщения: | Re: Построение графиков |
Если график стандартный для, типа, сбора данных, то, возможно, проще всего повернутую надпись заранее подготовить как битмап, открыть в ББ, спасти как вьюшку в файл, и вставлять эту вьюшку в нужное место. |
Автор: | Иван Денисов [ Среда, 24 Февраль, 2010 17:45 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
А возможно написать строку в View или Frame и не отображая преобразовать в bmp, затем обратитя к bmp как к массиву, повернуть на 90 градусов и поместить в нужную вьюшку? |
Автор: | Илья Ермаков [ Среда, 24 Февраль, 2010 19:05 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Да, нужно обратиться к Rider-у фрейма как к HostPorts.Rider и получить его виндовый DC. |
Автор: | Galkov [ Четверг, 25 Февраль, 2010 10:27 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
divan писал(а): А как будет выглядеть процедура для поворота используя API? К сожалению, не умею пользоваться WinAPI Никто не умеет... Ищешь в MSDN нужное ругательство, и внимательно все про него читаешь. Вот и вся наука В данном случае:
В общем, как-то так... это делается на winApi |
Автор: | Иван Денисов [ Среда, 03 Март, 2010 03:13 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Решил попробовать раздобыть dc Код: PROCEDURE Rotate*(f: Views.Frame); VAR i: INTEGER; m: REAL; b: Ports.Rider; dc: WinApi.HANDLE; BEGIN b := f.rider; dc := b.dc (тут всплывает ошибка, что мол UNDEFINED RECORD FIELD); ... END Rotate; Гляжу HostsPorts, а dc в Rider для чтения даже черточкой и не помечен ( и никакой функции нет, чтобы взять этот dc Код: Rider* = POINTER TO EXTENSIBLE RECORD (Ports.Rider) l-, t-, r-, b-: INTEGER; port-: Port; dx, dy: INTEGER; (* scroll offset *) map: WinApi.HANDLE; (* save bitmap *) dc: WinApi.HANDLE; (* save dc *) sl, st, sr, sb: INTEGER (* save rect *) END; Мечение этого поля самостоятельно ни к чему хорошему не привело (не открывается BB). Подскажите как его взять, пожалуйста. |
Автор: | Иван Денисов [ Среда, 03 Март, 2010 04:38 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
По части WinApi на удивление понятно стало. Код: res := WinApi.SetGraphicsMode(dc,WinApi.GM_ADVANCED); xForm.eM11 := 0.8660; xForm.eM12 := 0.5000; xForm.eM21 := -0.5000; xForm.eM22 := 0.8660; xForm.eDx := 0.0; xForm.eDy := 0.0; res := WinApi.SetWorldTransform(dc,xForm); А вот в ридерах и портах совсем запутался ( Скажем хочу сделать функцию на WinApi Views.Frame - расширение SystemPorts.Frame, в котором сам Rider не определен Код: Rider* = POINTER TO ABSTRACT RECORD END; Frame* = POINTER TO ABSTRACT RECORD unit-, dot-: INTEGER; (** inv: dot = point - point MOD unit **) rider-: Rider; gx-, gy-: INTEGER END; А Rider в HostPorts определен. Но как из SystemPorts попасть в HostPorts? Для этого нужно чтобы Frame.rider'у был присвоен HostPorts.rider ? |
Автор: | Info21 [ Среда, 03 Март, 2010 10:08 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
divan писал(а): Решил попробовать раздобыть dc ... b: Ports.Rider; ... dc := b.dc ... Гляжу HostsPorts, а dc в Rider для чтения даже черточкой и не помечен ... Подскажите как его взять, пожалуйста. dc := b( HostPorts.Rider ).dc |
Автор: | Иван Денисов [ Среда, 03 Март, 2010 15:31 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Код: PROCEDURE Rotate(f: Views.Frame; u: REAL); VAR res: INTEGER; dc: WinApi.HANDLE; xForm: WinApi.XFORM; BEGIN dc := f.rider(HostPorts.Rider).port.dc; u := u*Math.Pi()/180; res := WinApi.SetGraphicsMode(dc,WinApi.GM_ADVANCED); xForm.eM11 := SHORT(Math.Cos(u)); xForm.eM12 := SHORT(Math.Sin(u)); xForm.eM21 := - SHORT(Math.Sin(u)); xForm.eM22 := SHORT(Math.Cos(u)); xForm.eDx := 0.0; xForm.eDy := 0.0; res := WinApi.SetWorldTransform(dc,xForm); END Rotate; PROCEDURE (axes: Rendaxes) Restore (f: Views.Frame; fl, ft, fr, fb: INTEGER); Rotate(f, 30); ... Решил проверить функцию, просто развернув весь фрэйм графика. Вложение:
Комментарий к файлу: результат Снимок-BlackBox-2.png [ 9.43 КБ | Просмотров: 19688 ] Не совсем это похоже на то, что я хотел получить ![]() |
Автор: | Иван Кузьмицкий [ Среда, 03 Март, 2010 18:00 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Может, Вам стоит обратить внимание на OpenGL? Там заморочек с поворотами нет. |
Автор: | Info21 [ Среда, 03 Март, 2010 18:41 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Иван Кузьмицкий писал(а): Может, Вам стоит обратить внимание на OpenGL? Там заморочек с поворотами нет. Похоже, тут не тот случай, чтобы из пушки стрелять.Я бы пока не советовал заморачиваться поворотом буковок. Пёс с ними. Пока. Это бирюльки. Сделайте сначала всё остальное -- что по-настоящему важно. |
Автор: | Иван Денисов [ Четверг, 04 Март, 2010 03:31 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Ура!!! Покопался в WinApi и разобрался, как проще сделать вывод в вьюшку повернутого текста. Проще оказалось создать новый шрифт, как советовал Александр Ильин, лишь с отличием, что для создания использован CreateFontW а не CreateFontIndirect. Привожу функцию и результат работы. Всем огромное спасибо за участие в обсуждении! Код: PROCEDURE DrawStringA(f: Views.Frame; x,y: INTEGER; angle: INTEGER; col: Ports.Color; s: ARRAY OF CHAR; font: Fonts.Font); VAR n, a, res: INTEGER; dc: WinApi.HANDLE; ind: WinApi.BOOL; NewFont: WinApi.HFONT; df: HostFonts.DevFont; pt: HostPorts.Port; fsize : WinApi.SIZE; BEGIN pt := f.rider(HostPorts.Rider).port; dc := pt.dc; res := WinApi.SaveDC(dc); res := WinApi.SetBkMode(dc, WinApi.TRANSPARENT); res := WinApi.SetTextColor(dc, col); (* Вычисляем длину строки *) a := LEN(s) - 1; n := 0; WHILE (n < a) & (s[n] # 0X) DO INC(n) END; IF angle MOD 360 = 0 THEN (* Если угол поворота кратен 360, то использовать обычный шрифт *) df := font(HostFonts.Font).dev; res := WinApi.SelectObject(dc,df.id); res := WinApi.TextOutW(dc, x, y, s, n); res := WinApi.RestoreDC(dc, -1) ELSE (* Иначе, создать новый шрифт *) NewFont := WinApi.CreateFontW(-((font.size + pt.unit DIV 2) DIV pt.unit), 0, angle*10, angle*10, Fonts.normal, 0, 0, 0, 0, 7, 2, 1, 38, font.typeface); (* Вычислить ширину строки (для сдвига по Y) *) ind := WinApi.GetTextExtentPoint32W(dc, s, n, fsize); (* Выбрать шрифт *) res := WinApi.SelectObject(dc, NewFont); (* Вывести текст *) res := WinApi.TextOutW(dc, x, y + fsize.cx DIV 2, s, n); res := WinApi.RestoreDC(dc, -1); (* Удалить шрифт *) ind := WinApi.DeleteObject(NewFont); END END DrawStringA; ... (* пример использования выдернутый из контекста *) DrawStringA(f, I(l/f.dot-30), I((t+(h DIV 2))/f.dot), 90, Ports.black, temp, font); Вложение:
Комментарий к файлу: итог, пример использования функции для вывода повернутого текста
Уы.gif [ 11.45 КБ | Просмотров: 19630 ] |
Автор: | Info21 [ Четверг, 04 Март, 2010 10:36 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
divan писал(а): Ура!!! Поздравляю!
|
Автор: | Роман М. [ Понедельник, 22 Март, 2010 14:43 ] |
Заголовок сообщения: | Re: Поворот текста на 90 градусов (для изобр. графиков) |
Доводы против WinApi: 1) это уже прошлый век. Сам Microsoft уходит от этой технологии. 2) привязка к Windows и отсутствие переносимости и, как следствие, потенциальная возможность вымирания. В отличие от WinApi, используя тот же Cairo, добиваешься:
Кроме того, для инжинерных расчётов и графиков можно использовать аналог MATLAB - Octave. А ещё использовать библиотеку liboctave. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |