LINUX.ORG.RU

Прозрачность битмапов

 ,


0

2

В Моно есть давний баг, что части изображения прозрачные под Windows в линуксовом Моно становятся чёрными. Вроде бы, причина была в ограничениях архитектуры GTK2, но с GTK3 всё хорошо, и баг вот-вот исправят. Уже несколько лет. https://github.com/mono/xwt/issues/456

Существует ли воркэраунд? (Помимо самостоятельно исправлять Моно или запускать под Вайном.)

Для определённости — вот в этом пакете: https://github.com/kevL/OpenXCOM.Tools/ Прозрачные спрайты генерируются здесь: https://github.com/kevL/OpenXCOM.Tools/tree/master/PckView , а отрисовываются где-то здесь: https://github.com/kevL/OpenXCOM.Tools/tree/master/MapView/Forms/MainWindow/M... или здесь: https://github.com/kevL/OpenXCOM.Tools/blob/master/XCom/Palette.cs#L259

Дополнение: отрисовка здесь: https://github.com/kevL/OpenXCOM.Tools/blob/master/MapView/Forms/MainWindow/M...

private void DrawSprite(Image sprite, Rectangle rect)
{
	if (_spriteShadeEnabled)
		_graphics.DrawImage( sprite, rect, 0, 0, 
				XCImage.SpriteWidth, XCImage.SpriteHeight,
				GraphicsUnit.Pixel, _spriteAttributes);
	else
		_graphics.DrawImage(sprite, rect);
}
То есть используется Graphics.DrawImage из System.Drawing.

Дополнение 2: Переделал: https://github.com/tkzv/OpenXCOM.Tools/commit/28fb294da7e723e0f860d1dd3f56b19... Но скорость крайне низкая. Нужно искать новый GTK#.

★★★★★

Возможность это исправить есть точно: у Tilix на GTK3, например, прозрачность есть.

Проблема в том, что разработчики как-то подзабили на гуй у моно и не желают переходить на GTK3 бэкенд. Даже неофициальная рабочая реализация GTK# 3.22 есть, но почему-то никто не спешит ее адаптировать под кроссплатформу в Моно (имею ввиду натив на шин и GTK на линуксе)

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

Tilix на GTK3, например, прозрачность есть.

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

неофициальная рабочая реализация GTK# 3.22 есть,

Можно подробнее?

И что нужно сделать с имеющимися исходниками, чтобы програма начала отрисовывать средствами новой GTK#?

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

что нужно сделать с имеющимися исходниками, чтобы програма начала отрисовывать средствами новой GTK#?

Ну это очевидно. Если библиотека Gtk# это .dll-ка, то у неё есть версия (strongname), которая передаётся компилятору mono. Параметрами для компилятора управляет файл сборки для местного аналого make - msbuild. Т.е. надо его (.csproj) открыть и отредактировать там строки Reference.

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

чтобы програма начала отрисовывать средствами новой GTK#?

https://stackoverflow.com/questions/22335173/monodevelop-gtk-sharp-3-0

Currently is possible to use gtk-sharp3 in MonoDevelop
gtk-sharp3 package
http://addins.monodevelop.com/Project/Index/97
MonoDevelop GTK#3 Project Template
After creating GTK#3.0 project using template is (for my) necessarily add reference to gio-sharp v3.0 and regenerate MainWindow.ui with the use glade!

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

Ну это очевидно.

Мне — нет. Я с Моно впервые работал вчера :)

Если библиотека Gtk# это .dll-ка,

Где её взять? В Ubuntu 16.04 есть пакет gtk-sharp3/xenial 2.99.3-2 — слишком старый? Где искать 3.22? Гугл различает GTK+ и GTK#, и первого гораздо больше.

то у неё есть версия (strongname), которая передаётся компилятору mono. Параметрами для компилятора управляет файл сборки для местного аналого make - msbuild. Т.е. надо его (.csproj) открыть и отредактировать там строки Reference.

Что на что менять в *.csproj? Сейчас там никакой явной привязки к GTK2. «<Reference Include=„System.Drawing“> <Name>System.Drawing</Name> </Reference>» ? Что ещё?

Чувствую, сразу не заведётся, поэтому придётся добавлять его в MonoDevelop. Сейчас там есть темплейт GTK# 2.0, но нет 3.х. Как его добавить? Или как превратить 2.0 в 3.* ? Или всё само применится? Как это проконтролировать?

И главный вопрос: нужно ли что-то менять в исходниках?

P.S. Пока писал, получил часть ответов. Спасибо!

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

Что на что менять в *.csproj?

Есть три вида зависимостей:
1) Reference
(пример)
2) ProjectReference
(пример)
3) PackageReference
(пример)

Ищи, какой из них используется у тебя в проекте. Тебе нужно искать именно слово gtk, потому что System.Drawing.dll - это другая dll.

нужно ли что-то менять в исходниках?

Да, может понадобиться (а может и не понадобиться), выше я тебе уже нашел ссылку.

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

Сейчас там есть темплейт GTK# 2.0, но нет 3.х. Как его добавить? Или как превратить 2.0 в 3.* ? Или всё само применится? Как это проконтролировать?

Само не применится, превратить невозможно, нужно взять темплейт v3 и установить в MonoDevelop рядом с темплейтом v2.
Но это всё только для новых проектов нужно, или в качестве примера

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

Гугл различает GTK+ и GTK#, и первого гораздо больше.

Первое - это библиотека на языке C
Второе - это биндинги к первому на языке C#

Всё правильно делает, что различает.

Где её взять?

Хороший вопрос.
если смотреть на пакет из Debian, то получается что тут:
https://salsa.debian.org/dotnet-team/gtk-sharp3

Einstok_Fair ★★ ()

У меня в Wine те приложения, которые используют композитинг для прозрачности, тоже рисуют чёрное. Решается, собственно, включением композитинга. Пример такого приложения - клиент Battle.net

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

Гугл различает GTK+ и GTK#

Всё правильно делает, что различает.

Опечатка. НЕ различает.

https://salsa.debian.org/dotnet-team/gtk-sharp3

Последнее изменение в 2014 году. Это точно оно? Или нужные мне изменения целиком в GTK+, а байндинги годятся старые? (Если второе, то 2.99 в Убунту есть.)

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

Это точно оно?

ArkaDOSik - колись

2.99 в Убунту есть

Ну, эта gtk-sharp3 из Debian - она тоже отфорчена от 2.99.3

меня больше напрягает, что ветки 2.99.3 нет на https://github.com/mono/gtk-sharp
как будто master - это и есть gtk-sharp3

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

Вот: https://github.com/GtkSharp/GtkSharp

Относительно свежие коммиты есть, скорее всего прозрачность там работает.

В случае ТС это вряд ли поможет, потому что нужно либо проект перерисовать, либо адаптировать обвязку над GTK# под 3 версию.

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

В случае ТС это вряд ли поможет, потому что нужно либо проект перерисовать, либо адаптировать обвязку над GTK# под 3 версию.

Вот этот комментарий я совсем не понял.

То есть, там есть какой-то код для Gtk2, если его запустить с Gtk3, то почему он не будет работать?

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

То есть, там есть какой-то код для Gtk2, если его запустить с Gtk3, то почему он не будет работать?

Там вообще нет прямых упоминаний GTK. Это чисто виндовый код, который последний мэйнтэйнер допилил под требования кроссплатформенности. В результате всё собирается и почти работает — с точностью до багов Моно. Отсюда все мои вопросы. Я правильно понимаю, что System.* — обвязка вокруг GTK, обеспечивающая работу виндового API?

Мне нужно, чтобы чёрная заливка на тайлах (спрайтах) была прозрачной, как в Виндоуз. Для этого надо либо заменить бекэнд GTK2 на 3, если это возможно, либо установить места, где виндовый API делает битмап прозрачным и рисует его поверх большего битмапа, и переписать, чтобы не рисовало прозрачные части.

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

Вот: https://github.com/GtkSharp/GtkSharp
Относительно свежие коммиты есть, скорее всего прозрачность там работает.
В случае ТС это вряд ли поможет, потому что нужно либо проект перерисовать, либо адаптировать обвязку над GTK# под 3 версию.

Спасибо. Да, суть проблемы изложена верно. Я ожидаю, что второе проще, но совершенно не представляю, что нужно делать.

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

как устанавливать аддины к monodevelop:

https://www.monodevelop.com/documentation/installing-add-ins/

Темплейт для gtk3 - это аддин

Спасибо, уже нашёл. Но что-то у них опять с сайтом проблемы, MonoDevelop не подключается.

Но это всё только для новых проектов нужно, или в качестве примера

Для примера и хотел. Оценить работу с прозрачностью.

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

Есть три вида зависимостей:
<Reference Include=«gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL» />
<ProjectReference Include="..\gtk\gtk.csproj">
<PackageReference Include=«GtkSharp» Version=«3.22.24.10» />

Никакого упоминания GTK в проекте нет, поэтому и возникли вопросы. Вот что там: https://github.com/kevL/OpenXCOM.Tools/blob/master/MapView/MapView.csproj#L89

  <ItemGroup>
    <ProjectReference Include="..\YamlDotNet\YamlDotNet.csproj">
      <Project>{bf32de1b-6276-4341-b212-f8862adbba7a}</Project>
      <Name>YamlDotNet</Name>
    </ProjectReference>
    <Reference Include="System">
      <Name>System</Name>
    </Reference>
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data">
      <Name>System.Data</Name>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Design">
      <Name>System.Design</Name>
    </Reference>
    <Reference Include="System.Drawing">
      <Name>System.Drawing</Name>
    </Reference>
    <Reference Include="System.Web.Services">
      <Name>System.Web.Services</Name>
    </Reference>
    <Reference Include="System.Windows.Forms">
      <Name>System.Windows.Forms</Name>
    </Reference>
    <Reference Include="System.Xml">
      <Name>System.XML</Name>
</Reference>

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

То есть, там есть какой-то код для Gtk2, если его запустить с Gtk3, то почему он не будет работать?

Да, и именно поэтому многие проекты не перешли на 3 версию. Ситуация как с питоном. Бэкенд необходимо менять, но разработчики Моно на это забили.

ArkaDOSik ()
Ответ на: комментарий от question4

Мне нужно, чтобы чёрная заливка на тайлах (спрайтах) была прозрачной, как в Виндоуз. Для этого надо либо заменить бекэнд GTK2 на 3, если это возможно, либо установить места, где виндовый API делает битмап прозрачным и рисует его поверх большего битмапа, и переписать, чтобы не рисовало прозрачные части.

Либо ждать нормального бэкенда под линукс для WPF (или что там в этом проекте), либо переписать всю гуёвую часть самому.

P.S. Сам жду нормальной реализации WinForms/WPF, ведь тогда разработчиам станет гораздо легче портировать свой код под онтопик.

ArkaDOSik ()

GtkSharp 3.22 ставится NuGet-ом:

$ nuget install GtkSharp
Attempting to resolve dependency 'GLibSharp (≥ 3.22.24.37)'.
Attempting to resolve dependency 'GioSharp (≥ 3.22.24.37)'.
Attempting to resolve dependency 'AtkSharp (≥ 3.22.24.37)'.
Attempting to resolve dependency 'GdkSharp (≥ 3.22.24.37)'.
Attempting to resolve dependency 'CairoSharp (≥ 3.22.24.37)'.
Attempting to resolve dependency 'PangoSharp (≥ 3.22.24.37)'.
Installing 'GLibSharp 3.22.24.37'.
Successfully installed 'GLibSharp 3.22.24.37'.
Installing 'GioSharp 3.22.24.37'.
Successfully installed 'GioSharp 3.22.24.37'.
Installing 'AtkSharp 3.22.24.37'.
Successfully installed 'AtkSharp 3.22.24.37'.
Installing 'CairoSharp 3.22.24.37'.
Successfully installed 'CairoSharp 3.22.24.37'.
Installing 'PangoSharp 3.22.24.37'.
Successfully installed 'PangoSharp 3.22.24.37'.
Installing 'GdkSharp 3.22.24.37'.
Successfully installed 'GdkSharp 3.22.24.37'.
question4 ★★★★★ ()
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

GtkSharp 3.22 ставится NuGet-ом

У меня такой вопрос:
Ты уже собрал этот OpenXCom и увидел непрозрачность?
я спрашиваю для того, чтобы понять - под силу ли мне повторить твой подвиг и увидеть проблему своими глазами

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

Ты уже собрал этот OpenXCom и увидел непрозрачность?

Да. Поэтому и начал выяснять. Только не OpenXCom, а «MapView из пакета OpenXCom Tools». OpenXCom — другая программа, на C++/SDL :)

Пример проблемы с прозрачностью.

Как оно выглядит, когда я заменяю DrawImage на серию FillRectangle для каждого непрозрачного пикселя.

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

Сама тема: https://openxcom.org/forum/index.php/topic,1321.345.html

С новой GtkSharp ещё не собирал.

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

На всякий случай — советы по сборке старой версии: CSC: error CS0518: The predefined type `System.Object' is not defined or imported С новой так же. Собрать DSShare я смог только в Debug.

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

http://addins.monodevelop.com/Project/Index/97

Скачал оттуда MonoDevelop.GTKSharp3.GTKSharp3Project-0.1.mpack с пометкой «для 4.0», но при попытке его подключить выскакивали ошибки. Но когда установил GTK# 3.22, возможность создавать проекты GTK# 3 добавилась автоматически.

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

Но шаблон проекта ссылался на библиотеки с названиями через дефис, вида «gdk-sharp», а у меня поставились все без дефиса: «GdkSharp». Пришлось ставить пакет gtk-sharp-3 — там нашлись. В процессе обнаружил, что в nuget нет команды uninstall.

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

Собрал приложение из примера. Оно не видело свежеустановленые библиотеки 3.22, пришлось прописывать их вручную. При запуске — эксепшн:

$ ./gtksharp-tests.exe

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'Gtk.Application' threw an exception. ---> System.TypeInitializationException: The type initializer for 'GLib.GType' threw an exception. ---> System.DllNotFoundException: libgobject-2.0-0.dll
  at (wrapper managed-to-native) GLib.GType:g_type_init ()
  at GLib.GType..cctor () <0x404d3520 + 0x00693> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Gtk.Application..cctor () <0x404d2f40 + 0x00023> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at gtksharptests.MainClass.Main (System.String[] args) <0x404d2d50 + 0x0000b> in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: The type initializer for 'Gtk.Application' threw an exception. ---> System.TypeInitializationException: The type initializer for 'GLib.GType' threw an exception. ---> System.DllNotFoundException: libgobject-2.0-0.dll
  at (wrapper managed-to-native) GLib.GType:g_type_init ()
  at GLib.GType..cctor () <0x404d3520 + 0x00693> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Gtk.Application..cctor () <0x404d2f40 + 0x00023> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at gtksharptests.MainClass.Main (System.String[] args) <0x404d2d50 + 0x0000b> in <filename unknown>:0 

glib-sharp версии 3.22 я в настройках проекта прописал. Но зачем-то при инициализации ищет libgobject-2.0-0.dll.

grep показал, что gdk-sharp.dll, glib-sharp.dll и gtk-sharp.dll ссылаются на libgobject-2.0-0.dll. nuget нашёл glib 2.36.2.11 и GLibSharp 3.22.24.37. Поставил 2.36.2.11. Она по зависимостям вытянула:

zlib.redist 1.2.7.30
zlib 1.2.7.30
libintl.redist 0.18.2.1
libintl 0.18.2.1
libffi.redist 3.0.10.3
libffi 3.0.10.3
glib.redist 2.36.2.11
Но это всё оказались виндовые DLL.

question4 ★★★★★ ()

В принципе, для воспроизведения баги не нужен OpenXCom, там же в багрекере есть пример с кастомным контролом, у которого устанавливается прозрачный цвет (но получается чёрным).
Если этот контрол вставить на типовую форму из примера hello world, windows.forms
то можно собирать и смотреть всё на простом проекте, где всё понятно

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

В принципе, для воспроизведения баги не нужен OpenXCom, там же в багрекере есть пример с кастомным контролом, у которого устанавливается прозрачный цвет (но получается чёрным).
Если этот контрол вставить на типовую форму из примера hello world, windows.forms то можно собирать и смотреть всё на простом проекте, где всё понятно

Вот простой пример с новой версией GTK# я пока собрать и не смог.

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

Отвлёкся

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

Первое нужно для того, чтобы другим людям (и мне) подумать об этом, а узнанное желательно записать, чтобы оно не забылось

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

Никакого бетонного блока не было. Упёрся в то, что в nuget нет линуксовых *.so для GTK3, только *.dll. Значит, надо всё пересобирать, что конкретно — сам не разобрался. А тут праздники, тараканы, ремонт стиральной машины, соседи-алкоголики мешают спать, и куча игр в GOG :)

Я к этому вернусь. Когда закончу со стиральной машиной.

question4 ★★★★★ ()