Current section
Files
Jump to
Current section
Files
lib/desktop/pixmap.ex
defmodule Desktop.Pixmap do
@moduledoc false
alias Desktop.Wx
def from_wx_icon(icon, opts \\ []) do
env = Keyword.get(opts, :env, nil)
if env != nil do
:wx.set_env(env)
end
width = :wxIcon.getWidth(icon)
height = :wxIcon.getHeight(icon)
bitmap = :wxBitmap.new(width, height)
if not :wxBitmap.copyFromIcon(bitmap, icon) do
raise "Failed to copy bitmap from icon #{inspect({width, height})}"
end
ret = pixmap_from_wx_bitmap(bitmap, opts)
:wxBitmap.destroy(bitmap)
ret
end
defp pixmap_from_wx_bitmap(bitmap, opts) do
width = :wxBitmap.getWidth(bitmap)
height = :wxBitmap.getHeight(bitmap)
image = :wxBitmap.convertToImage(bitmap)
# Rescaling happens in place, meaning it changes the memory data
# inside the wxImage ref
resize_width = Keyword.get(opts, :width, width)
resize_height = Keyword.get(opts, :height, height)
rescale? = Keyword.get(opts, :rescale, false)
{width, height, image} =
if rescale? and (width != resize_width or height != resize_height) do
rescale_image(image, resize_width, resize_height)
else
{width, height, image}
end
argb = argb_from_wx_image(image)
:wxImage.destroy(image)
{width, height, argb}
end
defp rescale_image(image, width, height) do
image = :wxImage.rescale(image, width, height, quality: Wx.wxIMAGE_QUALITY_HIGH())
{width, height, image}
end
defp argb_from_wx_image(image) do
rgb = :wxImage.getData(image)
alpha = :wxImage.getAlpha(image)
to_argb(alpha, rgb)
end
defp to_argb(<<>>, <<>>) do
<<>>
end
defp to_argb(
<<a, alpha::binary>>,
<<r, g, b, rgb::binary>>
) do
<<a, r, g, b>> <> to_argb(alpha, rgb)
end
end