LINUX.ORG.RU

svgcleaner 0.7.0

 ,


1

4

Вышла новая версия программы для очистки SVG-файлов от лишней информации.

svgcleaner позиционируется как оптимизатор без потерь, строго следующий спецификации SVG 1.1 Full.

Основные изменения:

  • ядро (консольная версия) переписано с C++ на Rust;
  • реализованы собственные библиотеки для разбора SVG и представления SVG в виде DOM;
  • программа стала работать приблизительно в 3 раза быстрее;
  • все функции очистки теперь работают в режиме lossless;
  • степень очистки упала примерно на 5% ради стабильности и корректности;
  • добавлена документация для каждой опции очистки;
  • графический интерфейс переписан с нуля и вынесен в отдельный репозиторий.

Программа распространяется под лицензией GNU GPL v2. Сопутствующие библиотеки — под MPL v2.

Готовые сборки

>>> Подробности

★★★★★

Проверено: Shaman007 ()

Ответ на: комментарий от q0tw4

И вообще оно сможет кастануть из void*?

Сможет. Мономорфность - для дженериков. То есть, если написано что-то типа fn foo<T: MyTrait>(val: &T), но можно использовать и «виртуальность» (трейт-объекты): fn foo(val: &MyTrait).

Собственно, в расте указатель на таблицу виртуальных функций хранится не в объекте, а в таком вот "особом указателе". Его и надо кастовать в void*.

Хм, а разная версия компилятора не помешает?

А вот это (потенциально) помешает, у раста (пока) нет никаких гарантий касательно ABI.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

В любом случае это опять unsafe с бубном. Особенно если этот указатель надо будет хранить в виде указателя на базовый класс, передать его обратно плагину, который должен откастить его обратно в более конкретный тип (dynamic_cast). Вопщем раст он как sml с haskellом, обычно требует рекомпил софтины для расширения ее функционала, поэтому и удивительно видеть его активное применение в сферах, традиционно использующих динамические плагин системы, таких как геймдев.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

В любом случае это опять unsafe с бубном.

Ну да. Хотя плагины нередко имеют сишный интерфейс и там всё равно ансейф в том или ином виде будет присутствовать.

таких как геймдев.

В геймдеве как раз традиционно всякую логику вообще в скрипты выносят и с языков реализации движка/ядра приложения проблем нет.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Хотя плагины нередко имеют сишный интерфейс

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

В геймдеве как раз традиционно всякую логику вообще в скрипты выносят

Интересно, а такие классы как ThirdPersonCamera или LevelsOfDetailsNode тоже скриптом или же только «как хп упадет до 50%, кастуй зеленые лужи под себя».

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Потому что создать плагин с safe растовым интерфейсом невозможно

Мы сейчас о конкретном или об общем случае? Если второе, то сишный интерфейс позволяет писать плагины на разных языках. Скажем, на расте желающих писать меньше чем на С или С++ будет.

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

сигнатуры функций вытащить

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

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

В расте часто узают дженерики, которые по сути шаблоны.

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

А вообще вытаскивать сигнатуры незачем. Достаточно вытаскивать символы с известными сигнатурами

В смысле? Если речь о том, чтобы возвращать Option на запрос «дай символ с такой-то сигнатурой», то я не вижу принципиальной разницы. Или речь о чём-то другом?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Если речь о том, чтобы возвращать Option на запрос «дай символ с такой-то сигнатурой»

Ну смотри. Ты пишешь хост для плагина. Делаешь как-то так let lib = dlopen(«lib»).unwrap(); let pluginInit: () -> Plugin = unsafe { mem::transmute(lib.get_symbol(«init»)); }.unwrap(); let plugin = pluginInit(); plugin->do_something(self); Где тут сигнатуры выковыривать спрашивается? Очень редкий случай такой необходимости, если например скриптовый язык пишешь и автобиндер к нему.

PS. Простите за мой корявый раст, я пока сишник еще.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Я не понимаю о чём вы, но к расту пишутся биндинги в обе стороны без проблем. Обычно шаблоны и прочую магию выносят в отдельные методы, ака разворачивают шаблоны.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от q0tw4

Где тут сигнатуры выковыривать спрашивается?

Опять же, может я не понял идею, но в той либе, на которую давал ссылку, примерно так и сделано. Вот только если в плагине и основной программе рассинхронизируется сигнатура функции init, то будет фейерверк. Если же сигнатуру (можно было бы) проверять, то такие кривые/устаревшие плагины можно игнорировать на загрузке.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от RazrFalcon

Да мы обсуждаем применимость раста в «большом мире», где плагины - норма жизни. Вот например применимо к сабжу, можно ли сделать так, чтоб я мог дописать свой алгоритм очистки svg на расте, использовать его из под Вашей проги без перекомпиляции, и при этом получить те же гарантии корректности, которые дает раст для простых одноэкзешных проектов. Желательно чтоб unsafe прослойка, без которой тут никак, получилась тонкой и понятной. Или была успешно вынесена в crate.

q0tw4 ★★★★ ()
Ответ на: комментарий от DarkEld3r

рассинхронизируется сигнатура функции init

Уважаемый сорцы плагинов не читал. Обычно там что-то вроде init1_0(). Надо сменить сигнатуру - добавят init2_0(). Как его, обратная совместимость оно называется, наверное. Только версия раста может забакопорить дело, потому что там узается трейт, сгенеренный кодом, скомпиленным потенциально другой версией.

q0tw4 ★★★★ ()
Последнее исправление: q0tw4 (всего исправлений: 1)
Ответ на: комментарий от q0tw4

Без понятия. Плагины мне не интересуют ни на каком языке програмирования. Это одна боль и 0 профита.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от q0tw4

скомпиленным потенциально другой версией.

В плюсах те же проблемы. Нужна одна и та же версия компилятора.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

В плюсах те же проблемы. Нужна одна и та же версия компилятора.

в теории. В жизни он настолько стабилен, что хватает единства марки компилера. И даже так есть хак thiscall позволяющий из mingw вызвать msvc.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

В жизни он настолько стабилен, что хватает единства марки компилера.

Смешно. Настолько стабилен, что ABI cc, gcc и clang почти не совместимы.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

Ну я и сказал, достаточно одну фирму использовать.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Уважаемый сорцы плагинов не читал.

Вот это вот у тебя спокойно уживается рядом с заявлениями об гарантиях?..

Понятное дело, что можно разные костыли подставлять, но от «случайной» возможности выстрелить в ногу оно полной защиты не даёт. Но если такая ситуация устраивает, то не понимаю какие претензии к расту? Ну кроме очевидных отсутствия каких-либо гарантий в плане АБИ.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от q0tw4

В жизни он настолько стабилен, что хватает единства марки компилера

Была же, как минимум, поломка АБИ из-за «недавнего» запрета CoW для строк?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

но от «случайной» возможности выстрелить в ногу оно полной защиты не даёт

Защиту от случайной описки, которая случайно еще и скомпилилась даёт только agda и coq. В реальной жизни простые конвенции типа «изменяя сигнатуру переименовуй» работают не хуже, чем растовый ownership check. Просто последний, кроме того, способен работать в нетривиальных задачах, в которых одного взгляда на код уже недостаточно для подтверждения его корректности.

q0tw4 ★★★★ ()
Ответ на: комментарий от DarkEld3r

запрета CoW для строк

А теперь для тех кто в танке, кто запретил? И кто разрешил ему запрещать?

хотя это опять же stl и к компилятору прямого отношения не имеет.

q0tw4 ★★★★ ()
Последнее исправление: q0tw4 (всего исправлений: 1)
Ответ на: комментарий от q0tw4

А теперь для тех кто в танке, кто запретил?

Запретил стандарт С++11. В нём говорится, что итераторы не могут стать невалидными после не константного вызова operator[], что конфликтует с работой CoW.

хотя это опять же stl и к компилятору прямого отношения не имеет.

Зато это имеет прямое отношение к ABI С++ и тому, что оно не ломается в рамках «марки компилятора».

DarkEld3r ★★★★★ ()
Ответ на: комментарий от q0tw4

Защиту от случайной описки, которая случайно еще и скомпилилась даёт только agda и coq.

Давай ещё раз: в либе используется unsafe для каста сигнатуры. Тебя это, судя по всему, устраивает. Тогда о чём мы вообще спорим?

Мой аргумент в том, что теоретически сигнатуры проверять можно, а значит и обойтись без этого unsafe. И если я прав и эта информация в растовых либах уже имеется, то жертвовать ничем не придётся. Зато надёжности будет чуть больше.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от uin

Ну это просто например сказано было, твоей программы это конечно не касается. В общем #ABCABC до #abc сокращать можно точно так же как #000.

Укурок. #AABBCC до #abc сокращается.

Deleted ()
Ответ на: комментарий от DarkEld3r

ABI С++

stl это не C++. C++ бывает без stl. Например Qt. Так что не надо спихивать проблемы укурков, написавших stl (и еще больших укурков, написавших boost) на язык. Без stl С++ еще довольно терпимый язык.

q0tw4 ★★★★ ()
Ответ на: комментарий от DarkEld3r

в либе используется unsafe для каста сигнатуры. Тебя это, судя по всему, устраивает.

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

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Например Qt.

Шта? Они от stl напрямую зависят.

Без stl С++ еще довольно терпимый язык.

stl убожество, не спорю. Но это непосредственная часть языка и компилятора. Как никак, сейчас 3-и основных компилятора (vs, gcc, clang) имею свои реализации.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

Они от stl напрямую зависят.

Какая разница зависит или не зависит. Если не узаешь в своем коде, то его ABI не ломается. Зависимость там только для совместимости нужна.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

При чём тут ABI? Если я использую Qt классы, которые используют stl, то я использую stl. Путь и не на прямую. И если в stl что-то сломается, сломается и в Qt. Именно поэтому в сорцах Qt куча ifdef под разные платформы.

Зависимость там только для совместимости нужна

Совместимости с чем? Qt построен поверх stl.

RazrFalcon ★★★★★ ()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от q0tw4

Достаточно подгрузить сигнатуру по имени из общего хедера.

Хедер (в рамках раста) лишняя сущность и вполне может рассинхронизироваться.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Хедер (в рамках раста) лишняя сущность

ну я то имел ввиду те хедеры, которые сорцы. Ну use crate tratata; let f: tatata::Signature. О каких хедерах говорите Вы, я не понимаю.

q0tw4 ★★★★ ()
Ответ на: комментарий от RazrFalcon

Qt построен поверх stl

Сходу нарыл qarraydata.h

struct Q_CORE_EXPORT QArrayData
{
    QtPrivate::RefCount ref;
    int size;
    uint alloc : 31;
    uint capacityReserved : 1;

    qptrdiff offset; // in bytes from beginning of header

    void *data()
    {
        Q_ASSERT(size == 0
                || offset < 0 || size_t(offset) >= sizeof(QArrayData));
        return reinterpret_cast<char *>(this) + offset;
    }

    ....

template <class T, size_t N>
struct QStaticArrayData
{
    QArrayData header;
    T data[N];
};

stl-ем там не пахнет. Он фигурирует только в fromStdVector и toStdVector. Собственно Qt писался вроде как когда stlя еще толком и не было и пытался им стать.

q0tw4 ★★★★ ()
Последнее исправление: q0tw4 (всего исправлений: 2)
Ответ на: комментарий от DarkEld3r

это часть стандарта

Да мне както плевать на какието бумажки. Главное то, что его можно отключить и юзать что нравится.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Всё с вами понятно. На здравый смысл вам, похоже, тоже плевать.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от q0tw4

Да мне както плевать на какието бумажки.

Да пожалуйста. Вот только реализации по этим бумажкам делают.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от RazrFalcon

grep std:: до прозрения.

Ну std::algorithm никак не сломает ABI. Я имел ввиду что в форматах данных stlя нет

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

Почему не сломает? Если реализация алгоритма будет другая - результат тоже изменится. И именно это описано в стандарте, на который вам плевать.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Вот только реализации по этим бумажкам делают.

Ага, а потом эти бумажки правят потому что половина реализаций не осилили фичу. Я к тому, что если в стандарте написано, что std::vector такой, это не означает что хранить данные я обязан в нем. Вот к чему я.

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

это не означает что хранить данные я обязан в нем

Именно это и означает. Стандарт плюсов под 1500 страниц не просто так.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

результат тоже изменится

Результаты выполнения функций не являются предметом рассмотрения программной безопасности. Важно только не словить segfault или undefined behavior.

q0tw4 ★★★★ ()
Ответ на: комментарий от RazrFalcon

Именно это и означает. Стандарт плюсов под 1500 страниц не просто так.

Ага а наличие в мире корана означает что я должен убивать неверных?

q0tw4 ★★★★ ()
Ответ на: комментарий от q0tw4

ну я то имел ввиду те хедеры, которые сорцы.

Ну ок, но как по мне, это не особо лучше ручного каста. В общем, повторю мысль про то, что если информация в либе есть, то её воспользоваться было бы полезно.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от q0tw4

Ага, а потом эти бумажки правят потому что половина реализаций не осилили фичу.

Ну справедливости ради, такое присходило не часто.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

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

q0tw4 ★★★★ ()
Ответ на: комментарий от RazrFalcon

Процент людей, разрабатывающих компилятор С++ среди всех кодеров исчезающе мал. Так давайте не будем о том, зачем стандарт им, а будем про простых нас, которых большинство.

q0tw4 ★★★★ ()
Последнее исправление: q0tw4 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.