30. ACL -- задачи и решения. Графика.

автор: Виктор Кон, Курчатовский институт, URL: http://kohnvict.ucoz.ru/main.htm

1. Введение.

Графические возможности языка программирования ACL не хуже, чем у Java, но благодаря компактной записи, а также возможности записывать процедуры и суперкоманды, использовать эти возможности намного проще и легче. В данной статье я расскажу о базовых возможностях приготовить слайд как картинку, на которой надо разместить много строк текста, много линий, стрелки, закрашенные области и готовые рисунки.

Сами команды ACL охватывают весь спектр возможностей, и поэтому не всегда являются такими уж простыми для понимания. Намного проще работать, особенно новичкам с суперкомандами, которые уже являются процедурами, и объединяют несколько команд, выполняя однотипную и стандартную работу, и задавая те параметры, значения которых оптимальны и редко изменяются.

Стратегия программирования слайда состоит в следующем. Сначала необходимо зарезервировать некую область для рисования, как говорят, открыть графический режим. Потом можно рисовать разные объекты внутри этой области. В конце графический режим надо закрыть и сохранить получившуюся картинку в файл. Если на слайде есть тексты и линии, то спасать картинку лучше всего в png формат, потому что jpg формат такие картинки искажает, и часто файл даже не получается меньшего размера, ради чего все это делается.

Однако есть одна особенность. Я так сделал, что готовые картинки ставятся на слайд только из памяти компьютера, а не из файла. Программа способна запомнить до 100 рисунков, и запоминать рисунки она должна до того, как открыт графический режим. Поэтому я сначала объясню как запомнить рисунок в памяти. Для этого достаточно использовать команду
#w [op=im; mo=0; file=bookpic7.jpg; sav=1;]
Здесь важно знать, что "bookpic7.jpg" -- это имя файла картинки в той же папке, где находится ACL программа. Те, кто знают ACL, могут указать и на файл в других папках, а новичкам следует временно копировать файлы с картинками в папку программы, и тогда все будет работать. Потом их можно вернуть на место. Номер картинки в памяти указывает параметр "sav". Он равен 1. Но если картинок нужно поставить не одну, а несколько, то команду следует повторить с новым именем файла и с другим номером. Номера разных картинок не должны совпадать.

После того, как все картинки оказались в памяти, можно открывать графический режим. Это делается командой
# W=1024; H=768; #eg [op=open; twi=W; the=H; col=246;]
Здесь W и H -- это ширина и высота слайда в пикселах экрана. Если слайд предполагается показывать через проектор, то не следует увлекаться слишком большими размерами, потому что высокоразрешающие проекторы дорого стоят, а массовые проекторы не имеют высокого разрешения. Здесь также указан белый фон полотна. Цвет задается параметром "col=246". Как работать с цветом описано в самом начале 14-й главы описания ACL, поэтому я не буду тут это повторять. Посмотрите там.

После того, как все объекты нарисованы на слайде, нужно закрыть графический режим и спасти картинку в файл. Вот так
#pri slide\E ##egcl
То есть надо напечатать имя файла, в котором будет спасена картинка, причем имя без расширения, расширение будет png. Например, указанный код спасет картинку в файл "slide.png" в ту же папку, в которой находится программа. Естественно имя можно изменить на любое другое. Я надеюсь, что читатель понял как тут все просто и намерен продолжить обучение. Дальше будет ничуть не сложнее. Но разумно разбить материал на разделы

2. Рисование текста на слайде.

Ни один слайд не может обойтись без текста. Поэтому начнем с него. Текст на слайде -- это не просто буквы. Он регулируется многими параметрами, такими как размер, тип, место установки, тип установки, строки и так далее. Я расскажу здесь об одной процедуре (суперкоманде), которая способна сразу поставить на слайд много строк текста в самых разных местах. Но весь текст будет иметь один фасон. Если нужно поменять фасон, то следует повторно записать эту же суперкоманду, но с другими параметрами.

Удобно сразу же записать пример использования суперкоманды, а потом уже разбираться в том, что означает написанное.
#d 90 r(1) 0*90 3 X 100 600 24 # A=0; S=18; P=1; K=1; C=248;
#pri Tahoma\E # D=s(4); E=s(5); #pri \-
Это первая строка текста\n Это вторая строка текста\n Это третья строка текста\n\-
И так далее\n\E ##texts

Сама суперкоманда называется ##texts. И, вообще-то говоря, я уже описал ее в 26-й главе вместе с остальными суперкомандами. Но я здесь попробую написать более доходчиво. Прежде всего важно, что мы определили переменную H как вертикальный размер области слайда. Она здесь используется. Дело в том, что графические программы Java размещают на картинке вертикальную ось сверху вниз, что очень неудобно. Все суперкоманды, а также координаты на самой картинке используют размещение вертикальной оси снизу вверх. По сути они просто делают пересчет координат.

Далее, переменные X и Y определяют координаты первой строки, а Z -- базовый вертикальный сдвиг вниз следующей строки. Предполагается, что текстовый массив состоит из нескольких строк, поэтому Z -- это как бы стандартное вертикальное расстояние между строками. Переменная A задает угол поворота каждой строки в градусах, это редко бывает необходимо, но иногда на графиках текст ставится по вертикали и могут быть разные схемы, в которых текст необходимо вращать. Переменная S задает размер текста в пикселях, переменная C определяет номер цвета текста. Переменная P указывает позицию текста относительно записанных координат. Может быть 9 вариантов: 1 - базовая точка слева, 2 - в середине, 3 - справа, вертикальная позиция внизу, 4, 5, 6 - то же самое, но вертикальная позиция посередине, 7, 8, 9 - вертикальная позиция наверху текста. Переменная K указывает тип текста. Может быть 4 варианта: 0 - простой, 1 - жирный, 2 - наклонный, 3 - жирный-наклонный.

Текст может быть нарисован любым шрифтом (фонтом) из тех, которые есть на компьютере. Имя шрифта надо напечатать командой #pri и затем запомнить параметры строки в переменных D и E -- начало и длина строки с фонтом в текстовом массиве t(). Кроме того, в элементах r(1), r(2), . . . необходимо для каждой строки, начиная с первой, задать дополнительный сдвиг ее положения по горизонтали и вертикали, стандартно нужно задавать нули. Всего таких пар чисел надо задать n, если n - число строк. Задаваемые значения не сохраняются. Сам текст должен быть напечатан перед вызовом команды, причем каждая строка должна заканчиваться признаком конца строки (\n), включая последнюю строку.

Тут важно понимать, что если оборвать строку, то символ \n писать не обязательно, признак конца строки сам попадет в текстовый массив. Но удобно все же в конце строки писать \n\- . При этом следующую строку можно начинать не с начала и все пробелы слева не будут учитываться. В противном случае лишние пробелы писать нельзя. Дополнительные сдвиги строк текста позволяют делать пропуски и писать тексты в произвольном порядке. Казалось бы пустую строку можно было бы записать как \n\n , но это почему-то не работает. В пустой строке надо указать хотя бы один пробел. Правильно писать так \n\u32;\n .

Я напоминаю, что команда #pri способна печатать не только те символы, что есть на клавиатуре, но вообще любые юникоды. У нее очень большие возможности, но об этом надо читать в 4-й главе описания.

3. Рисование линий на слайде.

Рисование линий на слайде -- тоже важный момент. Линиями можно сделать рамку, много рамок, таблицу, схему и много всего еще. Вообще говоря, линию можно рисовать как границу области, но здесь я расскажу про другой способ, который аналогичен движению самописца или пера плоттера, у которого есть движения с рисованием и без рисования. Иногда такой режим позволяет нарисовать сразу очень много линий.

Снова сначала запишем пример и потом обсудим его.
# X=100; Y=100; C=247; N=4; T=3; #d 8 r(1) 100 0 0 100 -100 0 0 -100 4 i(1) 1*4 ##lines
Сразу видно, что суперкоманда называется "lines". Она тоже описана в 26-й главе. Я попробую написать подробнее. Эта суперкоманда рисует линию, состоящую из многих сегментов. Снова в переменной H должен быть задан вертикальный размер графической области, мы это сделали в самом начале. Переменная C -- это номер цвета линии, переменная T -- толщина линии в пикселах, переменная N -- число сегментов на линии, X, Y -- координаты первой точки. Координаты первой точки задаются абсолютно, а вот сама линия задается в массиве r(1) -- r(2*N) x,y координатами всех сегментов (отрезков) парами на каждый сегмент, то есть это разности координат последней и первой точки концов сегмента.

Такая форма записи часто позволяет сократить запись больших чисел, и она более универсальна. При переносе линии в другое место достаточно поменять только координаты X и Y, значения чисел в массиве можно не трогать. Наконец, в массиве i(1) -- i(N) должны быть заданы признаки видности сегмента, если 1, то сегмент рисуется, если 0 -- то не рисуется. То есть линия может состоять из кусков как сложный пунктир. Фактически данная суперкоманда способна рисовать не одну линию, а много линий сразу. В этом и состоит ее преимущество. Но все линии будут иметь одинаковую толщину и цвет. Если нужно это поменять, то необходимо снова задать эту команду с новыми параметрами.

Преимуществом этой команды является то, что она может рисовать любые объекты типа подписи, человечков, дома и даже портреты. Достаточно только правильно задать координаты. Объект легко переносить, но не очень легко масштабировать. Впрочем ACL и эту задачу легко решает. Достаточно просто умножить массив координат сегмента на число, что делается одной командой.

4. Размещение растровых картинок на слайде.

Вообще говоря, в языке ACL есть очень много вариантов преобразования картинок. Но картинку преобразовать можно и в любой другой программе, которых тоже очень много. По этой причине я покажу как ставится картинка на слайд без преобразования. Это предельно просто. Вот пример.
#d 3 X 500 500 1 ##img
То есть достаточно в переменных X и Y указать координаты центра картинки, в переменной Z -- ее номер в памяти и все, суперкоманда ##img все сделает. Важно понимать, что все последующие команды рисуют объекты, которые ложатся поверх предыдущих объектов. Так если надо на картинке нарисовать текст, то надо сначала нарисовать картинку, а потом записать текст на ее место. И текст появится поверх картинки.

А если сделать наоборот, то картинка закроет текст. Так же точно можно ставить одну картинку поверх другой картинки. Процедура смешивания картинок делается более сложным образом, и я здесь это не описываю. Напомню, что программа "Image pro" в пакете готовых программ умеет это делать.

5. Рисование стрелок на слайде.

Стрелки -- это достаточно простой объект, но он часто встречается и удобно иметь отдельную суперкоманду на этот объект. Вот пример использования этой суперкоманды
# X=800; Y=200; L=100; C=249; A=0; S=8; T=3; #rep 10 ##arrow # A=A+36; #end
Здесь нарисована не одна стрелка, а сразу десять. Этот пример показывает как программирование позволяет упростить рисование сложных объектов. Как легко догадаться, саму стрелку рисует суперкоманда "##arrow". Она также использует переменную H, которая здесь даже не показана. Переменные X и Y задают координаты начала стрелки, при этом предполагается, что головка стрелки находится на ее конце, L -- полная длина стрелки от ее начала до ее конца, включая головку, A -- угол поворота стрелки вокруг начала из горизонтального положения против часовой стрелки, T-- толщина линии на стрелке, C -- номер цвета, которым рисуется стрелка, S -- ширина головки, длина головки фиксирована как полторы ширины.

В примере показано как можно рисовать 10 стрелок меняя в цикле угол вращения стрелки. Точно также можно менять и другие параметры, если это приводит к разумным результатам. В частности можно сразу нарисовать две стрелки, которые смотрят в разные стороны, у первой угол будет равен 0, а у второй 180. Для того, чтобы задать просвет между ними, можно сдвинуть координату второй стрелки. Такие объекты часто рисуют для указания размеров. Если нужно указать вертикальный размер, то все точно так же, только углы равны -90 и 90, а сдвиг по вертикали.

6. Рисование областей с произвольным контуром на слайде.

Часто бывает необходимо рисовать области, залитые цветом и очерченные другим цветом по замкнутому контуру. Это тоже легко можно сделать, используя суперкоманду "##area". Вот пример применения этой суперкоманды
# X=800; Y=500; N=5; C=249; K=248; T=3; #d 10 r(1) 50 0 50 100 -50 100 -50 0 -50 -100 ##area
Снова используется переменная H как вертикальный размер графической области, хотя она и не показана. Далее T -- это толщина линии контура области, если она равна нулю, то линия не рисуется, K -- это цвет линии-контура, если равен нулю, то линия не рисуется, C -- это цвет самой области, если равен нулю, то область не рисуется, N -- это число сегментов на контуре области, последний сегмент добавляется чтобы замкнуть контур, X и Y -- координаты первой точки контура, отсчет координат идет от левого нижнего угла области графика. Также в r(1) -- r(2*N) должны быть заданы координаты всех сегментов.

Как видим тут все точно так же, как на линиях, только весь контур рисуется, если рисуется, и еще он замыкается, чтобы выделить область, которая закрашивается цветом. Я просто скажу, что в ACL есть возможность закрашивать область не только цветом, но и градиентом цвета, а также текстурой, то есть картинкой с повторением. Но это делается более сложным образом и редко используется. Поэтому кто хочет -- учите ACL, в описании все написано.

7. Рисование областей в форме эллипса.

Области могут быть любыми. Наиболее простая область -- это прямоугольник, но часто бывают еще и округлые области, самой простой из которых является круг, как частный случай эллипса. Контур эллипса рисовать ломаной линией не очень удобно, поэтому удобно иметь отдельную суперкоманду на такую область. Вот пример ее использования
# X=400; Y=150; U=300; V=200; C=249; K=248; T=3; ##elli
Здесь все почти также как в области, только координаты X и Y определяют центр эллипса, а параметры U и V задают ширину и высоту прямоугольника, в который эллипс вписан. Соответственно, если хотим нарисовать линию как границу эллипса, то ставим C=0, и получаем чистую линию.

8. Заключение.

Описанные выше объекты являются достаточно мощными примитивами, с помощью которых можно нарисовать практически все, что необходимо. Однако, некоторые программы рисунков будут иметь много текста. Так как в ACL есть возможность создавать процедуры и потом многократно их использовать, то простор для творчества тут большой. Более того, любой объект, однажды нарисованный, можно потом использовать всю оставшуюся жизнь.

На самом деле, у меня уже создано много других объектов для рисования на слайдах, например, графики функций, разные схемы. Но вместо того, чтобы все это многократно рисовать, есть и другой путь, а именно, спасти в картинку любой фрагмент любого документа и потом поставить картинку на слайд. Есть даже специальная программа vkSM, которая только и делает, что спасает любые фрагменты экрана компьютера в файлы, а потом выставляет их на слайде.

К таким фрагментам относятся, например, формулы. Тексты все же не часто различаются своими параметрами, и их выгодно писать на слайде сразу. А вот писать формулы на слайдах -- отдельная проблема. В принципе, варьируя параметры текста, указанные программы позволяют писать формулы, но проще воспользоваться готовыми редакторами формул. Не стоит забывать и о том, что на языке постскрипт тоже можно нарисовать все, что угодно, даже формулы. При этом даже никакой программы не нужно (и все бесплатно).

С другой стороны, используя данные команды в цикле, можно без труда нарисовать и градиент цвета, и не только линейный, а и круговой. И даже текстуру. Можно писать не только плоские буквы, но и объемные (со сдвигом и с переменой цвета). И это заведомо превышает возможности многих типографских систем, таких, например, как Латех.

Последнее замечание. Рисовать слайды можно не только в программе vkACL.jar, но и в готовой ACL программе "Player". Только в этом случае все имена используемых файлов надо указывать относительно главной папки.

9. Пример слайда -- заголовок фото-шоу

В этом разделе показан пример программы слайда без использования описанных выше суперкоманд, которые используют пакет расширенной графики, но с использованием команд простой графики, у которой меньше возможностей, но иногда их достаточно, а программа выглядит проще. Я сначала покажу весь текст программы, а потом объясню что в ней делается.

#g [op=open; twi=800; the=600; col=247;]
#g [op=imag; nx=50; ny=60; n=0; file=myport.jpg;]
#p [op=text; nx=110; sty=1; col=246; tfo=3; tki=1; tsi=18;]
#g [ny=15;] http://kohnvict.ucoz.ru/main.htm\E
#g [ny=50;] http://kohnvict.ya.ru\E
#g [ny=85;] автор: Виктор Кон\E
#g [nx=400; ny=350; tsi=44; sty=2;] КРАСОТА, вып. 2\E
#g [ny=300; tsi=24;] показаны художественные фотографии красивых\E
#g [ny=265;] женщин, собранные в интернете и обработанные\E
#g [ny=230;] специально для слайд-шоу\E
#g [op=clos; sav=1;] 0\E #f [op=topng; n=1; form=beauty-2;]
#w [op=im; mo=0; save=0; file=beauty-2.png;]

Для фото-шоу я использовал размер слайдов 800*600. В первой строке открывается графический режим на слайд такого размера. Во второй строке на слайд ставится картинка. В этом режиме ее можно ставить прямо из файла, если n = 0. Все координаты в этом режиме являются целыми и указывают пикселы экрана. То есть параметры nx,ny задают координаты центра картинки. Картинка ставится как есть, то есть без преобразований, а ее файл должен находится в той же папке, где и программа. В третьей строке задаются параметры текста, сама команда ничего не делает. Строки 4-6 ставят тексты на слайд с указанными параметрами, меняется только вертикальная позиция текста, она отсчитывается снизу вверх. В 7 строке меняются горизонтальная позиция текста, его размер и стиль установки. Сторки 8-10 ставят еще три линии текста. При этом в 8 строке снова меняется размер и во всех строках меняется только вертикальная позиция. В 11 строке завершается рисование и картинка спасается в память, Затем из памяти она спасается в файл в png формате. Наконец, в 12 строке указана команда, которая показывает готовую картинку из файла в отдельном окне.