формат векторной графики

Applications development, KoOS API questions
  • Разобрался сам.
    Может быть, кому-нибудь поможет:
    Команда M 1,1 переводит перо в точку 1,1
    Команда q 10,10 20,20 построит кривую Безье (в данном случае линию) по опорным точкам (1,1) (10+1,10+1) (20+1,20+1)
    Если за ней последует q 30,30 20,20, то опорные точки будут такими: (20+1, 20+1) (30+20+1, 30+20+1) (20+20+1, 20+20+1)

    Если бы подумал головой, то понял, что так и должно было быть. Но на сложных примерах понять это было непросто.
  • Прошу прощения за столько сообщений подряд.
    Набросал простую программку для отрисовки SVG paths (пока еще слишком сырая для работы), правда, еще не придумал, как удобно это дело масштабировать и заливать.
    Но если отрендерить path для буквы n из Arial, потом залить в графическом редакторе черным и с бикубическим сглаживанием уменьшить, получится вот так:
    canvas.png
    canvas.png (499 Bytes)
    Viewed 5977 times
    По-моему, очень неплохо.
    Буду думать, как аккуратно заливать контуры и адекватно масштабировать символы. Буду рад подсказкам.

    UPD:ан нет, упустил в спецификации T. The control point is assumed to be the reflection of the control point on the previous command relative to the current point - это как?
  • Sorcerer wrote:Набросал простую программку для отрисовки SVG paths (пока еще слишком сырая для работы), правда, еще не придумал, как удобно это дело масштабировать и заливать.
    Если эта программа на asm-е, то думаю из нее можно перенести функции рисующие SVG paths в какую-либо графическую библиотеку. Многим подобные функции окажутся полезными. Рекурсивный алгоритм заливки требует много места в стеке, так что насчет заливки ничего толкового сказать не могу.
  • Пока что не на асме... Но с планами перевестись на асм. Ничего сверхестественного в коде нет.
  • Интересный алгоритм заливки, может быть, даже будет работать быстро. Только не представляю, как его доделать для случаев, когда внутри закрашиваемой области есть "дыры", которые закрашивать не нужно.
    http://expace.narod.ru/imageprocessing/algoritm.html
  • Добил реализацию путей (пока что на javascript, но код действительно простейший). Сейчас буду думать над заливкой. Что касается масштабирования, мне нравится качество работы плагина scaling из zsea.
    Чтобы полноценно выводить символы с помощью SVG paths, достаточно реализации следующих функций:
    (prevx, prevy - переменные для хранения предыдущего положения пера, contx, conty - переменные для хранения предыдущей контрольной точки)

    M (x, y) - перенести перо в точку (x,y). prevx=x; prevy=y; contx =0; conty = 0
    L (x,y) - построить линию из (prevx,prevy) в (x,y). prevx=x; prevy=y; contx =0; conty = 0
    H (x) - построить линию из (prevx,prevy) в (x,prevy). prevx=x; prevy=prevy; contx =0; conty = 0
    h (x) - построить линию из (prevx,prevy) в (x+prevx,prevy). prevx=x+prevx; prevy=prevy; contx =0; conty = 0
    V (y) - построить линию из (prevx,prevy) в (prevx,y). prevx=prevx; prevy=y; contx =0; conty = 0
    v (y) - построить линию из (prevx,prevy) в (prevx,y+prevy). prevx=prevx; prevy=y+prevy; contx =0; conty = 0
    Q (x,y) (x1, y1) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x1,y1) при контрольной точке (x,y). prevx=x1; prevy=y1; contx=x; conty=y
    q (x,y) (x1, y1) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x1+prevx,y1+prevy) при контрольной точке (x+prevx,y+prevy). prevx=x1+prevx; prevy=y1+prevy; contx=x+prevx; conty=y+prevy
    T (x,y) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x,y) при контрольной точке, равной (2*prevx-contx,2*prevy-conty), если contx и conty не равны 0, иначе contx=x; conty=y
    z - залить контур

    Большая часть из этих функций уже есть (или легко может быть добавлена) в библиотеке vectors (нужно лишь научиться ее готовить - это я про себя).

    Остается:
    1. Написать парсер выражений,
    2. Придумать, как заливать и масштабировать такую графику.

    [offtop]Надеюсь, что смогу сделать всё это, и что не загорами тот день, когда в системе наконец появятся современные векторные масштабируемые шрифты. (По поводу их размера можно не переживать - Droid Sans занимает около 15 килобайт) [/offtop]
  • Sorcerer, круто, нет слов :)

    в свою очередь хотел дописать в спецификацию:

    неграфические функции:
    1) объявить шрифт. параметры - метка (внутр. имя - номер) шрифта, формат шрифта (число), сам текст определения шрифта в этом формате, строка параметров для этого шрифта (кегль и т.д, могут отличаться от формата к формату, поэтому не стандартизуем). Есть изначально один предопределенный шрифт, это системный. Шрифт можно этой же функцией копировать-изменить, задав в строке-параметрах новые параметры, но не задавая описание формата (на него сперва нужно переключиться, т.к. такое работает для текущего шрифта), и присвоить новой метке, автоматического переключения не происходит.
    2) переключиться на другой шрифт. параметры - метка шрифта.
    И мы уже давно не пешки,
    Мы пули, мы орлы, и решки!
    Война ютит бинарный код,
    Умри, или иди вперед!
  • причем форматом шрифта может быть... опять таки BFG(VS) =)
    С неграфической функцией "начать определение буквы". Но т.к. это не для общего формата, то функция в нулевую уходит (контекстно-зависимый набор функций, в данном случае контекст - рисование шрифта). То есть подмножество формата. Туда же можно сколько угодно функций, нужных только для шрифтов занести (хотя я вот так сходу не могу таких придумать больше)
    И мы уже давно не пешки,
    Мы пули, мы орлы, и решки!
    Война ютит бинарный код,
    Умри, или иди вперед!
  • Так, пока не забыл.. была мысль использовать для координат только целые значения. Хотя почему была, она есть и будет есть) добавить возможность объявлять несколько координатных сеток разного масштаба - и можно рисовать звездные небеса. При автоматической конвертации создавать самую мелкую необходимую сетку - числа потратят столько же, сколько в формате-источнике (если это не SVG, где числа текстом пишутся), а при создании новых произведений (или полуручной конвертации) подбирать необходимую точность. В ручную, конечно, это никто не будет делать, да и это забота не художника, а сохранялки в формат)
    И мы уже давно не пешки,
    Мы пули, мы орлы, и решки!
    Война ютит бинарный код,
    Умри, или иди вперед!
  • Разве из целочисленных координат не следует невозможность нормального масштабирования в будущем? Допустим, у нас есть квадрат (0,0)-(13,13). Как его уменьшить в 14 раз?
  • И "самая мелкая сетка" - это какая? Даже сетки в 1x1 пиксел может не хватить, если мы хотим изображение 800x600 впихнуть в thumbnail "по-быстрому".
  • Gluk wrote:причем форматом шрифта может быть... опять таки BFG(VS) =)
    С неграфической функцией "начать определение буквы". Но т.к. это не для общего формата, то функция в нулевую уходит (контекстно-зависимый набор функций, в данном случае контекст - рисование шрифта). То есть подмножество формата. Туда же можно сколько угодно функций, нужных только для шрифтов занести (хотя я вот так сходу не могу таких придумать больше)
    Примерно как SVG - шрифты... Там все это задается тегами font и glyph
  • "Примерно как SVG - шрифты... Там все это задается тегами font и glyph" - ну и хорошо, проще будет конвертация =)

    "И "самая мелкая сетка" - это какая? Даже сетки в 1x1 пиксел может не хватить, если мы хотим изображение 800x600 впихнуть в thumbnail "по-быстрому"." - вопрос закономерен, я его ожидал) если в рисунке - источнике в координатах самая точная из них равна 5.75379, то сетки 1000000*1000000 хватит за глаза. А если, каким-то чудом все остальные координаты кратны первой, то можно сетку y*x (где x,y кратны этому числу, и одна клеточка имеет размеры, равные этому числу) делать, этого будет достаточно для точного расположения всех объектов.

    "Разве из целочисленных координат не следует невозможность нормального масштабирования в будущем? Допустим, у нас есть квадрат (0,0)-(13,13). Как его уменьшить в 14 раз?" - неа, не следует. В примере выше показано как можно заменить вещественную координату целочисленной, не потеряв в точности.
    Вот как масштабировать квадрат с вещественными координатами (0.0,0.0)-(1.3*1.3)? Правильно, разделить его координаты на 14. получится квадрат (0.0,0.0)-(0.9285314...*0.9285314...).
    В целочисленных координатах, квадрат останется (0,0)-(13,13), но вот если раньше одна клетка сетки была равна 7 пикселов, то теперь она равна 0.5 пиксела. Как раз эти коэффициенты остаются вещественными)
    И мы уже давно не пешки,
    Мы пули, мы орлы, и решки!
    Война ютит бинарный код,
    Умри, или иди вперед!
  • еще 1 графический объект...
    #) Вычитание. Параметры: метка (вычитание считается графическим объектом, и как к таковому, к нему можно обращаться по метке для копирования и т.д.), сколько объектов вычитать (по умолчанию - 1), из скольки объектов вычитать (по умолчанию - 1), затем, после команды, идут по очереди объекты, которые вычитают, и, сразу следом, из которых вычитают. Такой порядок позволяет строить первые в буферной области, а вторые рисовать, просто учитывая ее (не ставя пиксел) при рисовании второго. Ну можно так и не делать, но в любом случае такой порядок мешать не будет)
    И мы уже давно не пешки,
    Мы пули, мы орлы, и решки!
    Война ютит бинарный код,
    Умри, или иди вперед!
  • Who is online

    Users browsing this forum: No registered users and 4 guests