1# This file is part of MyPaint. 2# Copyright (C) 2015 by Andrew Chadwick <a.t.chadwick@gmail.com> 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8 9 10"""UIColor conversion routines 11 12These are functions which convert 13our display color classes (see `lib.color.UIColor`) 14to and from GDK's equivalents. 15They can't be part of lib/ because of the GDK dependency. 16 17""" 18 19from __future__ import division, print_function 20 21import struct 22 23from lib.gibindings import Gdk 24 25from lib.color import RGBColor 26from lib.helpers import clamp 27 28 29def from_gdk_color(gdk_color): 30 """Construct a new UIColor from a Gdk.Color. 31 32 >>> from_gdk_color(Gdk.Color(0.0000, 0x8000, 0xffff)) 33 <RGBColor r=0.0000, g=0.5000, b=1.0000> 34 35 """ 36 rgb16 = (gdk_color.red, gdk_color.green, gdk_color.blue) 37 return RGBColor(*[c / 65535 for c in rgb16]) 38 39 40def to_gdk_color(color): 41 """Convert a UIColor to a Gdk.Color. 42 43 >>> gcol = to_gdk_color(RGBColor(1,1,1)) 44 >>> gcol.to_string() 45 '#ffffffffffff' 46 47 """ 48 return Gdk.Color(*[int(c*65535) for c in color.get_rgb()]) 49 50 51def from_gdk_rgba(gdk_rgba): 52 """Construct a new UIColor from a `Gdk.RGBA` (omitting alpha) 53 54 >>> from_gdk_rgba(Gdk.RGBA(0.5, 0.8, 0.2, 1)) 55 <RGBColor r=0.5000, g=0.8000, b=0.2000> 56 57 """ 58 rgbflt = (gdk_rgba.red, gdk_rgba.green, gdk_rgba.blue) 59 return RGBColor(*[clamp(c, 0., 1.) for c in rgbflt]) 60 61 62def to_gdk_rgba(color): 63 """Convert to a `GdkRGBA` (with alpha=1.0). 64 65 >>> col = RGBColor(1,1,1) 66 >>> rgba = to_gdk_rgba(col) 67 >>> rgba.to_string() 68 'rgb(255,255,255)' 69 70 """ 71 rgba = list(color.get_rgb()) 72 rgba.append(1.0) 73 return Gdk.RGBA(*rgba) 74 75 76def from_drag_data(bytes): 77 """Construct from drag+dropped bytes of type application/x-color. 78 79 The data format is 8 bytes, RRGGBBAA, with assumed native endianness. 80 Alpha is ignored. 81 """ 82 r, g, b, a = [h / 0xffff for h in struct.unpack("=HHHH", bytes)] 83 return RGBColor(r, g, b) 84 # TODO: check endianness 85 86 87def to_drag_data(color): 88 """Converts to bytes for dragging as application/x-color.""" 89 rgba = [int(c * 0xffff) for c in color.get_rgb()] 90 rgba.append(0xffff) 91 return struct.pack("=HHHH", *rgba) 92 93 94def _test(): 95 import doctest 96 doctest.testmod() 97 98 99if __name__ == '__main__': 100 _test() 101 102