commit -m "better"
Недавно рассказывал, что соорудил рендеринг #svg иконок в png, через #inkscape. Все же, мне этот процесс кажется не очень технологичным: * Inkscape - overkill по зависимостям * И, хотя я и сделал, что от пакета с иконками зависит только финальный #realm…
Мужик сказал - мужик сделал!
Запилил я gdk pixbuf #svg loader поверх #lunasvg!
В процессе, конечно, узнал много чего интересного, чем и спешу поделиться.
Короткая предыстория:
* Сперва у меня вообще не было рендера svg, потому что #rsvg перешел на Rust, а его у меня (пока?) нет.
* Потом я научился использовать довольно старую версию librsvg, которая была написана на C, и глючила, что пиздец - 1/4 иконок была отренжерена с какими-то артефактами. Это, конечно, то еще достижение, учитывая простоту формата svg.
* Потом я научился готовить для всех scalable иконок png заранее, с помощью inkscape. Примерно для 1/4 оставшихся использовался старый rsvg render, с баглом и артефактами.
* Потом я нашел замечательную #lunasvg, и перешел на нее для рендеринга png, а то, что мой процесс не находил, или были нужны какие-то особенные разрешения, использовался старый rsvg.
* (мы находимся тут) -> png рендерятся с помощью lunasvg, остатки - тоже.
https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp - вот код клея между lunasvg и gdk-pixbuf.
БОльшую часть кода я написал за полчаса, а потом еще часа 3 трахался за последние 5 строк кода, без которых на экране был мусор:
* Примерно полтора часа - это "нормальная" отладка - разбирательство с тем, в каком формате поверхность отдает lunasvg, в каком ожидает GdkPixbuf, и как их "поженить", разбирательство с моделью владения памятью в glib(чтобы не текло и не ездило по use-after-free), и с обработкой ошибок в ней же.
* А вторые полтора часа - это какая-то совершенно безумная ебала, когда, на первый взгляд, я делаю все правильно, при этом, знаю, что command line часть lunasvg родила корректный png, но, если отрендерить его в динамике моим кодом, то на экране - мусор.
В какой-то момент времени я остановился, и подумал: "А какое бы безумное действие я мог бы совершить на месте авторов gtk, чтобы у меня ничего не работало"?
Единственное, что мне пришло в голову - что они, зачем-то, портят xml с svg, перед тем, как его передать мне. Ну потому что как еще объяснить факт, что pixmap data получается разная?
Sooka! Sooka! Аааа!
https://github.com/GNOME/gtk/blob/main/gtk/gdkpixbufutils.c#L249
Короче, они манглят svg во вложенный svg в виде base64 блоба. КМК, это сделано затем, чтобы указать уникальный размер для рендеринга. Да, да, в scalable vector graphics есть width, и height, чтобы им пусто было.
Я, конечно, решил, что раз эти негодяи формируют xml через printf, то парсить я его буду регулярками. https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp#L93 (да, да, это точно надо занести в upstream)
После этого почти(в следующей серии!) все заработало, иконки выглядят очень хорошо, всяко лучше, чем в бажной и глючной старой librsvg.
Запилил я gdk pixbuf #svg loader поверх #lunasvg!
В процессе, конечно, узнал много чего интересного, чем и спешу поделиться.
Короткая предыстория:
* Сперва у меня вообще не было рендера svg, потому что #rsvg перешел на Rust, а его у меня (пока?) нет.
* Потом я научился использовать довольно старую версию librsvg, которая была написана на C, и глючила, что пиздец - 1/4 иконок была отренжерена с какими-то артефактами. Это, конечно, то еще достижение, учитывая простоту формата svg.
* Потом я научился готовить для всех scalable иконок png заранее, с помощью inkscape. Примерно для 1/4 оставшихся использовался старый rsvg render, с баглом и артефактами.
* Потом я нашел замечательную #lunasvg, и перешел на нее для рендеринга png, а то, что мой процесс не находил, или были нужны какие-то особенные разрешения, использовался старый rsvg.
* (мы находимся тут) -> png рендерятся с помощью lunasvg, остатки - тоже.
https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp - вот код клея между lunasvg и gdk-pixbuf.
БОльшую часть кода я написал за полчаса, а потом еще часа 3 трахался за последние 5 строк кода, без которых на экране был мусор:
* Примерно полтора часа - это "нормальная" отладка - разбирательство с тем, в каком формате поверхность отдает lunasvg, в каком ожидает GdkPixbuf, и как их "поженить", разбирательство с моделью владения памятью в glib(чтобы не текло и не ездило по use-after-free), и с обработкой ошибок в ней же.
* А вторые полтора часа - это какая-то совершенно безумная ебала, когда, на первый взгляд, я делаю все правильно, при этом, знаю, что command line часть lunasvg родила корректный png, но, если отрендерить его в динамике моим кодом, то на экране - мусор.
В какой-то момент времени я остановился, и подумал: "А какое бы безумное действие я мог бы совершить на месте авторов gtk, чтобы у меня ничего не работало"?
Единственное, что мне пришло в голову - что они, зачем-то, портят xml с svg, перед тем, как его передать мне. Ну потому что как еще объяснить факт, что pixmap data получается разная?
Sooka! Sooka! Аааа!
https://github.com/GNOME/gtk/blob/main/gtk/gdkpixbufutils.c#L249
Короче, они манглят svg во вложенный svg в виде base64 блоба. КМК, это сделано затем, чтобы указать уникальный размер для рендеринга. Да, да, в scalable vector graphics есть width, и height, чтобы им пусто было.
Я, конечно, решил, что раз эти негодяи формируют xml через printf, то парсить я его буду регулярками. https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp#L93 (да, да, это точно надо занести в upstream)
После этого почти(в следующей серии!) все заработало, иконки выглядят очень хорошо, всяко лучше, чем в бажной и глючной старой librsvg.
GitHub
ix/pkgs/lib/lunasvg/gdk/io.cpp at main · pg83/ix
ix package manager. Contribute to pg83/ix development by creating an account on GitHub.
👍10🔥6👌3😁2👏1
commit -m "better"
Мужик сказал - мужик сделал! Запилил я gdk pixbuf #svg loader поверх #lunasvg! В процессе, конечно, узнал много чего интересного, чем и спешу поделиться. Короткая предыстория: * Сперва у меня вообще не было рендера svg, потому что #rsvg перешел на Rust…
Продолжение истории про #lunasvg. #svg
Я закончил на том, что у меня часть иконок была отренжерена через lunasvg в процессе построения пакета с иконками, а часть(которая вне этого пакета) - в процессе работы приложения.
Проблема была в том, что иконки, отренжеренные в динамике, были не черные, а слегка желтоватые. С таким уклоном в сепию, как будто-то кто сблендил чутка желтого цвета на поверхность.
Причем я совершенно точно уверен, что цвета я отдал правильные, я вывел их на консоль, и сравнил с тем, что шло в сгенеренных png. Уклона в сепию в этих цветах не было.
Я бы тут хотел ткнуть вас куском кода из rsvg/cairo/gdk, который страдает такой херней, но я не сумел, там все слишком запутано.
Чего только стоят несовпадения ARGB/RGBA, где-то используется premultiplied alpha, где-то - нет, premultiplied alpha по разным формулам, все эти поверхности постоянно туда-сюда преобразуются.
Я решил просто потвикать r, g, b, a каналы в разные стороны, и посмотреть, что получится.
В процессе я выяснил:
* g, b каналы никак не использовались, ну, то есть, я мог туда записать все, что угодно.
* r канал давал изменение от цвета фона к ярко-желтому цвету. 0 - фон, 255 - ярко-желтый(нет, это не cmyk, и не прочие модели, по крайней мере, не те, что я знаю).
* alpha канал работал, как надо.
Мое лучшее предположение - что рендеринг symbolic иконки - это, собственно, отбрасывание r, g, b, и использование только alpha компоненты для блендинга между фоном и цветом для рисования.
Желтый? Хер его знает, может, для дебага, может, я вообще неверно все понял.
В итоге, решение вида "оставить только alpha канал для svg, которые загружаются как symbolic иконки", вполне себе сработало, я с лупой не нашел отличий. https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp#L100
Так-то это достаточно логично - а как еще наиболее дешево "оконтурить" произвольную svg?
Где это происходит в связке rsvg/gdk/cairo, я не нашел, они большие мастера прятать такое говнецо.
Я закончил на том, что у меня часть иконок была отренжерена через lunasvg в процессе построения пакета с иконками, а часть(которая вне этого пакета) - в процессе работы приложения.
Проблема была в том, что иконки, отренжеренные в динамике, были не черные, а слегка желтоватые. С таким уклоном в сепию, как будто-то кто сблендил чутка желтого цвета на поверхность.
Причем я совершенно точно уверен, что цвета я отдал правильные, я вывел их на консоль, и сравнил с тем, что шло в сгенеренных png. Уклона в сепию в этих цветах не было.
Я бы тут хотел ткнуть вас куском кода из rsvg/cairo/gdk, который страдает такой херней, но я не сумел, там все слишком запутано.
Чего только стоят несовпадения ARGB/RGBA, где-то используется premultiplied alpha, где-то - нет, premultiplied alpha по разным формулам, все эти поверхности постоянно туда-сюда преобразуются.
Я решил просто потвикать r, g, b, a каналы в разные стороны, и посмотреть, что получится.
В процессе я выяснил:
* g, b каналы никак не использовались, ну, то есть, я мог туда записать все, что угодно.
* r канал давал изменение от цвета фона к ярко-желтому цвету. 0 - фон, 255 - ярко-желтый(нет, это не cmyk, и не прочие модели, по крайней мере, не те, что я знаю).
* alpha канал работал, как надо.
Мое лучшее предположение - что рендеринг symbolic иконки - это, собственно, отбрасывание r, g, b, и использование только alpha компоненты для блендинга между фоном и цветом для рисования.
Желтый? Хер его знает, может, для дебага, может, я вообще неверно все понял.
В итоге, решение вида "оставить только alpha канал для svg, которые загружаются как symbolic иконки", вполне себе сработало, я с лупой не нашел отличий. https://github.com/pg83/ix/blob/main/pkgs/lib/lunasvg/gdk/io.cpp#L100
Так-то это достаточно логично - а как еще наиболее дешево "оконтурить" произвольную svg?
Где это происходит в связке rsvg/gdk/cairo, я не нашел, они большие мастера прятать такое говнецо.
GitHub
ix/pkgs/lib/lunasvg/gdk/io.cpp at main · pg83/ix
ix package manager. Contribute to pg83/ix development by creating an account on GitHub.
👍4🐳3❤2🔥2🌭1🍌1
commit -m "better"
Недавно рассказывал, что соорудил рендеринг #svg иконок в png, через #inkscape. Все же, мне этот процесс кажется не очень технологичным: * Inkscape - overkill по зависимостям * И, хотя я и сделал, что от пакета с иконками зависит только финальный #realm…
Я тут, на досуге, продолжил возню с #svg.
Не то чтобы меня не устраивало, как работает #lunasvg, но вот этот вот svgren, о котором шла речь в предыдущем посте, он использует AGG https://en.wikipedia.org/wiki/Anti-Grain_Geometry в качестве канвы для отрисовки, а я, знаете ли, испытываю к ней нежные чувства (не спрашивайте). Ну и мне показалось прикольным, если за рендерингом svg у меня будет стоять это произведение искусства!
Вот список зависимостей, которые пришлось подтащить для сборки этой самой svgren - https://github.com/pg83/ix/tree/main/pkgs/lib/svgren Это все - адовые велосипеды от того же автора, что и сам svgren.
Знаете, я долго сдерживал смех, пока клал эти библиотеки, одну за одной, но вот когда мне пришлось написать нечто вот такое в своем коде - https://github.com/cppfw/svgren/blob/master/tests/render/main.cpp#L120-L121, я уже не смог сдерживаться, и пока отложил порт.
Не то чтобы меня не устраивало, как работает #lunasvg, но вот этот вот svgren, о котором шла речь в предыдущем посте, он использует AGG https://en.wikipedia.org/wiki/Anti-Grain_Geometry в качестве канвы для отрисовки, а я, знаете ли, испытываю к ней нежные чувства (не спрашивайте). Ну и мне показалось прикольным, если за рендерингом svg у меня будет стоять это произведение искусства!
Вот список зависимостей, которые пришлось подтащить для сборки этой самой svgren - https://github.com/pg83/ix/tree/main/pkgs/lib/svgren Это все - адовые велосипеды от того же автора, что и сам svgren.
Знаете, я долго сдерживал смех, пока клал эти библиотеки, одну за одной, но вот когда мне пришлось написать нечто вот такое в своем коде - https://github.com/cppfw/svgren/blob/master/tests/render/main.cpp#L120-L121, я уже не смог сдерживаться, и пока отложил порт.
Wikipedia
Anti-Grain Geometry
graphics library
😁8👍3❤2🤔1🤡1🐳1
https://github.com/llvm/llvm-project/releases/tag/llvmorg-16.0.0-rc1
На днях вышел rc к clang 16.
А сегодня у меня сошелся CI контур с ним.
Неожиданно было тяжело!
* Появилось много предупреждений по делу, которые нельзя просто так выключать, потому что это указатель на реальную ошибку. Для примера:
Некоторые проекты отключил от сборки подальше, потому что непонятно, как они вообще могли работать.
* Сломалось много configure проверок, например, проверка размеров типов:
Может, баг в новом clang, может, более верная трактовка стандарта.
(если полезете искать - вам нужен стандарт на C, а не на С++)
* Сломался рендер svg-шек, который #svgren, а не #lunasvg
Буквально на одной svg, я пока не понял, кто там не прав.
Сломался парсинг unsigned int в контексте ".12345" - то есть, на вход парсеру интов передали float. Может, компилятор накосячил (miscompile), может, раньше ошибочно float парсился и округлялся к ближайшему целому.
На днях вышел rc к clang 16.
А сегодня у меня сошелся CI контур с ним.
Неожиданно было тяжело!
* Появилось много предупреждений по делу, которые нельзя просто так выключать, потому что это указатель на реальную ошибку. Для примера:
gstv4l2object.c:544:23:Вот таких вот багов нашел штук 5.
error: incompatible function
pointer types assigning to
'gint (*)(gint, ioctl_req_t, ...)'
(aka 'int (*)(int, unsigned long, ...)')
from 'int (int, int, ...)'
v4l2object->ioctl = ioctl;
Некоторые проекты отключил от сборки подальше, потому что непонятно, как они вообще могли работать.
* Сломалось много configure проверок, например, проверка размеров типов:
configure:23637: clang -cМне вот совершенно неинтересно, можно ли брать в скобки имя типа в этом выражении, или нельзя.
conftest.c:185:20: error: expected expression:
if (sizeof ((pid_t)))
Может, баг в новом clang, может, более верная трактовка стандарта.
(если полезете искать - вам нужен стандарт на C, а не на С++)
* Сломался рендер svg-шек, который #svgren, а не #lunasvg
Буквально на одной svg, я пока не понял, кто там не прав.
Сломался парсинг unsigned int в контексте ".12345" - то есть, на вход парсеру интов передали float. Может, компилятор накосячил (miscompile), может, раньше ошибочно float парсился и округлялся к ближайшему целому.
GitHub
Release LLVM 16.0.0-rc1 · llvm/llvm-project
LLVM 16.0.0-rc1 Release
👍7🔥5🤔4
commit -m "better"
Продолжение истории про #lunasvg. #svg Я закончил на том, что у меня часть иконок была отренжерена через lunasvg в процессе построения пакета с иконками, а часть(которая вне этого пакета) - в процессе работы приложения. Проблема была в том, что иконки, отренжеренные…
Я как-то давно рассказывал, что у меня в репе нет librsvg, и что #svg иконки я отрисовываю без нее.
Вот, раз уж добавил в репозиторий skia (https://t.iss.one/itpgchannel/2035), то было грех не запилить +1 рендер иконок, уже с ее помощью:
https://github.com/pg83/ix/blob/main/pkgs/bin/skia/svg/ss.cpp - это сама тулза, которая рендерит svg через #skia.
https://github.com/pg83/ix/tree/main/pkgs/bld/iconker - заодно похвастаюсь, сколько у меня вообще сейчас способов отрисовать svg иконку - через inkscape, через #lunasvg, через resvg (библиотека на Rust, лучше, чем librsvg, https://github.com/RazrFalcon/resvg), теперь вот через skia, ну и через #svgren.
Рендер через skia (он же рендер из google chrome) весьма неплох, даже по меркам авторов resvg - https://github.com/RazrFalcon/resvg?tab=readme-ov-file#svg-support
librsvg? Принципиально не буду ее добавлять, потому что нехер создавать людям столько трудностей в попытке иметь базовую систему без Rust!
Вот, раз уж добавил в репозиторий skia (https://t.iss.one/itpgchannel/2035), то было грех не запилить +1 рендер иконок, уже с ее помощью:
https://github.com/pg83/ix/blob/main/pkgs/bin/skia/svg/ss.cpp - это сама тулза, которая рендерит svg через #skia.
https://github.com/pg83/ix/tree/main/pkgs/bld/iconker - заодно похвастаюсь, сколько у меня вообще сейчас способов отрисовать svg иконку - через inkscape, через #lunasvg, через resvg (библиотека на Rust, лучше, чем librsvg, https://github.com/RazrFalcon/resvg), теперь вот через skia, ну и через #svgren.
Рендер через skia (он же рендер из google chrome) весьма неплох, даже по меркам авторов resvg - https://github.com/RazrFalcon/resvg?tab=readme-ov-file#svg-support
librsvg? Принципиально не буду ее добавлять, потому что нехер создавать людям столько трудностей в попытке иметь базовую систему без Rust!
GitHub
ix/pkgs/bin/skia/svg/ss.cpp at main · pg83/ix
ix package manager. Contribute to pg83/ix development by creating an account on GitHub.
🤡7🐳6👍3❤1
https://www.phoronix.com/news/Rust-Debian-2025
"around 8% of the source packages in Debian Sid are building against at least one librust-* package. That 8% figure for Debian source packages building against at least one Rust library package is around double of what it is for Debian 12 "Bookworm". Quite a significant uptake over the past few years and it's only continuing to grow with more open-source projects introducing varying levels of Rust integration"
Понятное дело, что это librsvg, или какие-нить кодеки, которые не являются обязательными, но против них нужно собраться, чтобы получить "полный" пакет, но, тем не менее, цифра довольно внушительная.
У меня против Rust собирается ровно 0 от базовой системы, потому что librsvg для загрузки иконок в gtk я переписал на кастомный #svg loader over #lunasvg/#skia/#svgren (по выбору), и убрал все эти опциональные зависимости.
Ну просто потому, что Rust не является #bootstrap абельным (я не могу собрать его из исходников, не имея под рукой готовый компилятор Rust, подробности в моей эпопее с #mrustc), а это зашквар.
"around 8% of the source packages in Debian Sid are building against at least one librust-* package. That 8% figure for Debian source packages building against at least one Rust library package is around double of what it is for Debian 12 "Bookworm". Quite a significant uptake over the past few years and it's only continuing to grow with more open-source projects introducing varying levels of Rust integration"
Понятное дело, что это librsvg, или какие-нить кодеки, которые не являются обязательными, но против них нужно собраться, чтобы получить "полный" пакет, но, тем не менее, цифра довольно внушительная.
У меня против Rust собирается ровно 0 от базовой системы, потому что librsvg для загрузки иконок в gtk я переписал на кастомный #svg loader over #lunasvg/#skia/#svgren (по выбору), и убрал все эти опциональные зависимости.
Ну просто потому, что Rust не является #bootstrap абельным (я не могу собрать его из исходников, не имея под рукой готовый компилятор Rust, подробности в моей эпопее с #mrustc), а это зашквар.
Phoronix
Around 8% Of Debian Source Packages Are Building Against Rust Libraries
At last week's DebConf25 Debian developer conference in France, Rust packaging within Debian Linux was talked about by Fabian Grünbichler
🤡8🔥5❤4👍3😁2💯1