OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Среда, 23 Январь, 2019 06:39

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Среда, 24 Февраль, 2010 01:18 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
Выделено: viewtopic.php?f=35&t=1064

Пишу свой модуль для построения графиков, но как развернуть текст на 90 градусов, чтобы подписать ось Y, ума не приложу. Подскажите, пожалуйста.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 09:23 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9072
Откуда: Россия, Орёл
Стандартным образом трудно... в WinApi нет средств вывода текста под углом. Работать с битмапом в памяти и самим разворачивать на 90 разве что.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 10:53 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7947
Откуда: Троицк, Москва
divan писал(а):
Пишу свой модуль для построения графиков, но как развернуть текст на 90 градусов, чтобы подписать ось Y, ума не приложу. Подскажите, пожалуйста.


Что-то, кажется, было в библиотеке Lib на zinnamturm.eu
http://zinnamturm.eu/downloadsIN.htm#Lib


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 11:37 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2289
Откуда: Россия, Санкт-Петербург
Илья Ермаков писал(а):
Стандартным образом трудно... в 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/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 11:52 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
divan
Может, воспользоваться платформо-независимой библиотекой Cairo для вывода примитивов типа линий и текста (всяко лучше, чем с помощью WinAPI)? В ней есть процедура cairo_rotate для поворота объектов. Можно применить всякие трансформации по мере необходимости.

Её преимущество в том, что у неё предусмотрено немалое количество генерируемых поверхностей (Win32-GDI+, X11-Xlib, Mac OS-Quartz, PostScript, PDF, SVG, PNG и ещё много других), но главное - она векторная.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 13:22 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Илья Ермаков писал(а):
в WinApi нет средств вывода текста под углом
Неправда Ваша
Через WinApi типа SetWorldTransform - любые линейные извращения делать можно. Вроде бы


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 14:02 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
В Lib не понял как поворачивает (если вообще поворачивает), a Plot от Gérard'a Meunier'a нарисовала мне вот такую картинку:
Вложение:
Комментарий к файлу: Plot Gérard Meunier Result
Screenshot-BlackBox.png
Screenshot-BlackBox.png [ 5.69 КБ | Просмотров: 13056 ]

Поворачивать не умеет!

Большое спасибо за наводку на Cairo, она точно пригодится для экспорта графики, поскольку написать свой драйвер для SVG думаю мне не по силам пока.
А в BB нет ничего для векторного экспорта?

А как будет выглядеть процедура для поворота используя API? К сожалению, не умею пользоваться WinAPI.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Построение графиков
СообщениеДобавлено: Среда, 24 Февраль, 2010 14:16 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7947
Откуда: Троицк, Москва
Если график стандартный для, типа, сбора данных, то, возможно, проще всего повернутую надпись заранее подготовить как битмап, открыть в ББ, спасти как вьюшку в файл, и вставлять эту вьюшку в нужное место.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Февраль, 2010 17:45 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
А возможно написать строку в View или Frame и не отображая преобразовать в bmp, затем обратитя к bmp как к массиву, повернуть на 90 градусов и поместить в нужную вьюшку?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Февраль, 2010 19:05 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9072
Откуда: Россия, Орёл
Да, нужно обратиться к Rider-у фрейма как к HostPorts.Rider и получить его виндовый DC.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 25 Февраль, 2010 10:27 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
divan писал(а):
А как будет выглядеть процедура для поворота используя API? К сожалению, не умею пользоваться WinAPI

Никто не умеет... Ищешь в MSDN нужное ругательство, и внимательно все про него читаешь. Вот и вся наука
В данном случае:
  1. Добываешь где-то, как-то - нужный тебе hDC
  2. Произносишь магическое слово SetGraphicsMode(hDC,GM_ADVANCED)
  3. Готовишь где-то "матрицу преобразований" XFORM (повороты, перекосы, масштабирование - в одном флаконе)
  4. Применяешь эту "матрицу" к hDC с помощью SetWorldTransform
  5. Рисуешь "нормально" на ентом hDC, чего душа пожелает (хучь текст, хучь загогулины) - и оно все будет появляться, нужным образом искореженное.

В общем, как-то так... это делается на winApi


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Март, 2010 03:13 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
Решил попробовать раздобыть 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 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
По части 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 ?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Март, 2010 10:08 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7947
Откуда: Троицк, Москва
divan писал(а):
Решил попробовать раздобыть dc
...
b: Ports.Rider;
...
dc := b.dc
...
Гляжу HostsPorts, а dc в Rider для чтения даже черточкой и не помечен ...
Подскажите как его взять, пожалуйста.


dc := b( HostPorts.Rider ).dc


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Март, 2010 15:31 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
Код:
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
Снимок-BlackBox-2.png [ 9.43 КБ | Просмотров: 12875 ]


Не совсем это похоже на то, что я хотел получить :) на 45 вместо 30 градусов повернулось и текст упорно остается по горизонтали. Как думаете, в чем может быть причина того, что не поворачивается текст?


Последний раз редактировалось Иван Денисов Четверг, 04 Март, 2010 03:37, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Март, 2010 18:00 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2930
Откуда: г. Ярославль
Может, Вам стоит обратить внимание на OpenGL? Там заморочек с поворотами нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Март, 2010 18:41 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7947
Откуда: Троицк, Москва
Иван Кузьмицкий писал(а):
Может, Вам стоит обратить внимание на OpenGL? Там заморочек с поворотами нет.
Похоже, тут не тот случай, чтобы из пушки стрелять.

Я бы пока не советовал заморачиваться поворотом буковок. Пёс с ними. Пока. Это бирюльки.

Сделайте сначала всё остальное -- что по-настоящему важно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Март, 2010 03:31 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2247
Ура!!! Покопался в 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
Уы.gif [ 11.45 КБ | Просмотров: 12817 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Март, 2010 10:36 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 7947
Откуда: Троицк, Москва
divan писал(а):
Ура!!!
Поздравляю!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Март, 2010 14:43 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Доводы против WinApi: 1) это уже прошлый век. Сам Microsoft уходит от этой технологии. 2)
привязка к Windows и отсутствие переносимости и, как следствие, потенциальная возможность вымирания.

В отличие от WinApi, используя тот же Cairo, добиваешься:
  1. вывода на разные поверхности (экспорт в векторный или растровый формат, на печать или на экран), включая опциональное аппаратное ускорение графики.
  2. гибкости
  3. переносимости между ОС

Кроме того, для инжинерных расчётов и графиков можно использовать аналог MATLAB - Octave. А ещё использовать библиотеку liboctave.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB