def make_padlock(dst, colour, size=qubesimgconverter.ICON_MAXSIZE, disp=False): cs = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size) cr = cairo.Context(cs) cr.set_source_rgb(*qubesimgconverter.hex_to_float(colour)) cr.set_line_width(.125 * size) cr.rectangle(.125 * size, .5 * size, .75 * size, .4375 * size) cr.fill() cr.move_to(.25 * size, .5 * size) cr.line_to(.25 * size, .375 * size) cr.arc(.5 * size, .375 * size, .25 * size, math.pi, 2 * math.pi) cr.move_to(.75 * size, .375 * size) # this is unneccessary, but helps readability cr.line_to(.75 * size, .5 * size) cr.stroke() if disp: # Careful with those. I have run into severe # floating point errors when adjusting. arrows = 2 gap = 45 * math.pi / 180 offset = 0 radius = .1875 * size width = 0.05 * size cx = .5 * size # cy = .6875 * size cy = .625 * size arrow = 2 * math.pi / arrows for i in range(arrows): cr.move_to(cx, cy) cr.rel_move_to(*polar(radius - width, offset + i * arrow)) cr.arc(cx, cy, radius - width, offset + i * arrow, offset + (i + 1) * arrow - gap) cr.rel_line_to(*polar(width, offset + (i + 1) * arrow - gap + math.pi)) cr.rel_line_to(*polar(width * math.sqrt(8), offset + (i + 1) * arrow - gap + math.pi / 4)) cr.rel_line_to(*polar(width * math.sqrt(8), offset + (i + 1) * arrow - gap - math.pi / 4)) cr.rel_line_to(*polar(width, offset + (i + 1) * arrow - gap + math.pi)) cr.arc_negative(cx, cy, radius + width, offset + (i + 1) * arrow - gap, offset + i * arrow) cr.close_path() cr.set_source_rgb( *qubesimgconverter.hex_to_float('0xcc0000')) # tango's red cr.set_line_width(.0500 * size) cr.set_line_join(cairo.LINE_JOIN_ROUND) cr.stroke_preserve() cr.set_source_rgb(1.0, 1.0, 1.0) cr.fill() cs.write_to_png(dst)
def assertIconColor(self, path, expected_color): image_color_float = self.get_image_color(path, expected_color) expected_color_float = qubesimgconverter.hex_to_float(expected_color) if not all(map(lambda a, b: abs(a - b) <= 0.15, image_color_float, expected_color_float)): self.fail( "Icon {} is not colored as {}".format(path, expected_color))
def get_image_color(self, path, expected_color): """Return mean color of the image as (r, g, b) in float""" image = qubesimgconverter.Image.load_from_file(path) _, l, _ = colorsys.rgb_to_hls( *qubesimgconverter.hex_to_float(expected_color)) def get_hls(pixels, l): for i in range(0, len(pixels), 4): r, g, b, a = tuple(ord(c) / 255. for c in pixels[i:i + 4]) if a == 0.0: continue h, _, s = colorsys.rgb_to_hls(r, g, b) yield h, l, s mean_hls = reduce( lambda x, y: (x[0] + y[0], x[1] + y[1], x[2] + y[2]), get_hls(image.data, l), (0, 0, 0) ) mean_hls = map(lambda x: x / (mean_hls[1] / l), mean_hls) image_color = colorsys.hls_to_rgb(*mean_hls) return image_color
def test_12_hex_to_float_depth_3_not_implemented(self): with self.assertRaises(NotImplementedError): qubesimgconverter.hex_to_float('123456', depth=3)
def test_11_hex_to_float_result_ff(self): self.assertEqual(qubesimgconverter.hex_to_float('0xffffff'), (1.0, 1.0, 1.0))
def test_10_hex_to_float_result_00(self): self.assertEqual(qubesimgconverter.hex_to_float('#000000'), (0.0, 0.0, 0.0))