Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Philipp Hörist
gajim
Commits
8e44939b
Commit
8e44939b
authored
Apr 18, 2018
by
Philipp Hörist
Browse files
F17
parent
c2cd53c9
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
gajim/common/coloring.py
0 → 100644
View file @
8e44939b
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 Jonas Wielicki <jonas AT wielicki.name>
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# This file is part of Gajim.
#
# Gajim is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
import
math
import
functools
import
unicodedata
import
hashlib
from
gi.repository
import
Gdk
@
functools
.
lru_cache
()
def
normalise_text_for_hash
(
text
):
return
unicodedata
.
normalize
(
"NFKC"
,
text
)
def
hsva_to_rgba
(
h
,
s
,
v
,
a
):
if
s
==
0
:
return
v
,
v
,
v
,
a
h
=
h
%
(
math
.
pi
*
2
)
indexf
=
h
/
(
math
.
pi
*
2
/
6
)
index
=
math
.
floor
(
indexf
)
fractional
=
indexf
-
index
p
=
v
*
(
1.0
-
s
)
q
=
v
*
(
1.0
-
(
s
*
fractional
))
t
=
v
*
(
1.0
-
(
s
*
(
1.0
-
fractional
)))
return
[
(
v
,
t
,
p
),
(
q
,
v
,
p
),
(
p
,
v
,
t
),
(
p
,
q
,
v
),
(
t
,
p
,
v
),
(
v
,
p
,
q
)
][
index
]
+
(
a
,
)
def
rgba_to_hsva
(
r
,
g
,
b
,
a
):
deg_60
=
math
.
pi
/
3
Cmin
=
min
(
r
,
g
,
b
)
Cmax
=
max
(
r
,
g
,
b
)
delta
=
Cmax
-
Cmin
if
r
>=
g
and
r
>=
b
:
h
=
(
g
-
b
)
/
delta
elif
g
>=
r
and
g
>=
b
:
h
=
(
b
-
r
)
/
delta
+
2
else
:
h
=
(
r
-
g
)
/
delta
+
4
h
*=
deg_60
if
Cmax
==
0
:
s
=
0
else
:
s
=
delta
/
Cmax
return
h
,
s
,
Cmax
,
a
def
luminance
(
r
,
g
,
b
):
return
r
*
0.2126
+
g
*
0.7152
+
b
*
0.0722
def
colour_distance_hsv
(
hsv_a
,
hsv_b
):
h_a
,
s_a
,
v_a
=
hsv_a
h_b
,
s_b
,
v_b
=
hsv_b
r_a
,
g_a
,
b_a
,
_
=
hsva_to_rgba
(
h_a
,
s_a
,
v_a
,
0
)
r_b
,
g_b
,
b_b
,
_
=
hsva_to_rgba
(
h_b
,
s_b
,
v_b
,
0
)
if
r_a
>
0.5
:
return
math
.
sqrt
(
3
*
(
r_a
-
r_b
)
**
2
+
4
*
(
g_a
-
g_b
)
**
2
+
2
*
(
b_a
-
b_b
)
**
2
)
else
:
return
math
.
sqrt
(
2
*
(
r_a
-
r_b
)
**
2
+
4
*
(
g_a
-
g_b
)
**
2
+
3
*
(
b_a
-
b_b
)
**
2
)
# lum_a = luminance(r_a, g_a, b_a)
# lum_b = luminance(r_b, g_b, b_b)
# h_dist = min(abs(h_a-h_b), abs(h_b-h_a))
# return h_dist * abs(lum_a-lum_b) + abs(s_a-s_b) * abs(lum_a-lum_b)
# return abs(lum_a-lum_b)
return
math
.
sqrt
(
(
r_a
-
r_b
)
**
2
+
(
g_a
-
g_b
)
**
2
+
(
b_a
-
b_b
)
**
2
)
# K_R = 0.299
# K_G = 0.587
# K_R = 0.0593
# K_G = 0.2627
K_R
=
0.2627
K_B
=
0.0593
K_G
=
1
-
K_R
-
K_B
def
ycbcr_to_rgb
(
y
,
cb
,
cr
):
r
=
2
*
(
1
-
K_R
)
*
cr
+
y
b
=
2
*
(
1
-
K_B
)
*
cb
+
y
g
=
(
y
-
K_R
*
r
-
K_B
*
b
)
/
K_G
return
r
,
g
,
b
def
clip_rgb
(
r
,
g
,
b
):
return
(
min
(
max
(
r
,
0
),
1
),
min
(
max
(
g
,
0
),
1
),
min
(
max
(
b
,
0
),
1
),
)
def
angle_to_cbcr_edge
(
angle
):
cr
=
math
.
sin
(
angle
)
cb
=
math
.
cos
(
angle
)
# if abs(cr) > abs(cb):
# factor = 0.5 / abs(cr)
# else:
# factor = 0.5 / abs(cb)
factor
=
0.5
return
cb
*
factor
,
cr
*
factor
@
functools
.
lru_cache
()
def
text_to_colour
(
text
):
text
=
normalise_text_for_hash
(
text
)
# hash_ = hashlib.sha1()
# hash_.update(text.encode("utf-8"))
# # lets take four bytes of entropy
# data = hash_.digest()
# hue, = struct.unpack("<H", data[:2])
MASK
=
0xffff
# data = binascii.crc32(text.encode("utf-8"))
h
=
hashlib
.
sha1
()
h
.
update
(
text
.
encode
(
"utf-8"
))
hue
=
(
int
.
from_bytes
(
h
.
digest
()[:
2
],
"little"
)
&
MASK
)
/
MASK
# hue = data & 0xffff
# first attempt, simply mix with the inverse of in_contrast_with
# initial_color = Qt.QColor(*struct.unpack("<BBB", data), 255)
# contrast_inverse = Qt.QColor(
# 255 - in_contrast_with[0],
# 255 - in_contrast_with[1],
# 255 - in_contrast_with[2],
# 255,
# )
# FACTOR = 0.4
# INV_FACTOR = 1-FACTOR
# return Qt.QColor(
# INV_FACTOR*initial_color.red() + FACTOR*contrast_inverse.red(),
# INV_FACTOR*initial_color.green() + FACTOR*contrast_inverse.green(),
# INV_FACTOR*initial_color.blue() + FACTOR*contrast_inverse.blue(),
# 255,
# )
# if in_contrast_with is not None:
# *back, _ = rgba_to_hsva(*in_contrast_with, 1.0)
# else:
# back = None
# while len(data) > 3:
# h, s, v = struct.unpack("<BBB", data[:3])
# data = data[1:]
# h = h/255 * math.pi*2
# s = (s//64 + 4) / 7
# v_int = (v//128 + 6)
# if back is None:
# v = v_int/7
# break
# for v_base in [v_int, v_int ^ 1]:
# v = v_base/7
# dist = colour_distance_hsv((h, s, v), back)
# if dist >= 0.4:
# break
# else:
# continue
# break
# else:
# print("out of options for", text)
# r, g, b, _ = hsva_to_rgba(h, s, v, 1)
# return r, g, b
cb
,
cr
=
angle_to_cbcr_edge
(
hue
*
math
.
pi
*
2
)
r
,
g
,
b
=
ycbcr_to_rgb
(
0.5
,
cb
,
cr
)
r
,
g
,
b
=
clip_rgb
(
r
,
g
,
b
)
r
*=
0.8
g
*=
0.8
b
*=
0.8
return
r
,
g
,
b
def
get_color_for_jid
(
jid
):
red
,
green
,
blue
=
text_to_colour
(
jid
)
return
Gdk
.
Color
.
from_floats
(
red
,
green
,
blue
)
if
__name__
==
'__main__'
:
print
(
get_color_for_jid
(
'test@test.at'
))
gajim/conversation_textview_new.py
View file @
8e44939b
...
...
@@ -24,6 +24,7 @@
from
gi.repository
import
Pango
from
gajim.common
import
app
from
gajim.common.coloring
import
get_color_for_jid
from
gajim.common.logger
import
KindConstant
from
gajim.common.const
import
Position
,
LineElement
,
LineType
...
...
@@ -69,7 +70,7 @@ def _create_tags(self):
'pixels-below-lines'
:
4
,
'pixels-above-lines'
:
8
},
{
'name'
:
'status-message'
,
'style'
:
Pango
.
Style
.
ITALIC
,
'pixels-below-lines'
:
4
,
'pixels-above-lines'
:
8
},
{
'name'
:
'icon'
,
'rise'
:
Pango
.
SCALE
*
-
4
},
{
'name'
:
'icon'
,
'rise'
:
Pango
.
SCALE
*
-
2
},
{
'name'
:
'time'
,
'family'
:
'Monospace'
,
'scale'
:
0.8
},
{
'name'
:
'muc-subject'
,
'style'
:
Pango
.
Style
.
ITALIC
,
'foreground'
:
app
.
config
.
get
(
'statusmsgcolor'
)},
{
'name'
:
'incoming'
,
'foreground'
:
app
.
config
.
get
(
'inmsgtxtcolor'
)},
...
...
@@ -502,14 +503,19 @@ def _remove_line(self):
class
Icons
(
Gtk
.
Box
):
def
__init__
(
self
):
Gtk
.
Box
.
__init__
(
self
)
self
.
_encryption_image
=
Gtk
.
Image
.
new_from_icon_name
(
'network-wireless-encrypted-symbolic'
,
Gtk
.
IconSize
.
MENU
)
icon_theme
=
Gtk
.
IconTheme
.
get_default
()
scale
=
self
.
get_scale_factor
()
print
(
scale
)
surface
=
icon_theme
.
load_surface
(
'network-wireless-encrypted-symbolic'
,
12
,
scale
,
None
,
Gtk
.
IconLookupFlags
.
FORCE_SIZE
)
self
.
_encryption_image
=
Gtk
.
Image
.
new_from_surface
(
surface
)
self
.
_encryption_image
.
set_no_show_all
(
True
)
self
.
_correction_image
=
Gtk
.
Image
.
new_from_icon_name
(
'document-edit-symbolic'
,
Gtk
.
IconSize
.
MENU
)
surface
=
icon_theme
.
load_surface
(
'document-edit-symbolic'
,
12
,
scale
,
None
,
Gtk
.
IconLookupFlags
.
FORCE_SIZE
)
self
.
_correction_image
=
Gtk
.
Image
.
new_from_surface
(
surface
)
self
.
_correction_image
.
set_no_show_all
(
True
)
self
.
_receipt_image
=
Gtk
.
Image
.
new_from_icon_name
(
'object-select-symbolic'
,
Gtk
.
IconSize
.
MENU
)
surface
=
icon_theme
.
load_surface
(
'object-select-symbolic'
,
12
,
scale
,
None
,
Gtk
.
IconLookupFlags
.
FORCE_SIZE
)
self
.
_receipt_image
=
Gtk
.
Image
.
new_from_surface
(
surface
)
self
.
_receipt_image
.
set_no_show_all
(
True
)
self
.
add
(
self
.
_encryption_image
)
self
.
add
(
self
.
_correction_image
)
...
...
@@ -548,6 +554,10 @@ def __init__(self, textview, type_, event):
self
.
nick
=
textview
.
contact
.
get_shown_name
()
elif
type_
==
LineType
.
GC_MESSAGE
:
self
.
nick
=
event
.
nick
if
event
.
name
==
'mam-decrypted-message-received'
:
self
.
jid
=
event
.
with_
+
'/'
+
event
.
nick
else
:
self
.
jid
=
event
.
fjid
else
:
if
event
.
name
==
'message-sent'
:
self
.
nick
=
app
.
nicks
[
event
.
account
]
...
...
@@ -570,13 +580,26 @@ def _show(self):
def
set_text
(
self
,
text
):
_iter
=
self
.
_get_iter_from_name
(
'start-text'
)
if
self
.
_type_
==
LineType
.
GC_MESSAGE
:
self
.
_buffer
.
insert
(
_iter
,
text
)
tag
=
self
.
_get_color_tag
(
self
.
jid
)
self
.
_buffer
.
insert_with_tags
(
_iter
,
text
,
tag
)
else
:
self
.
_buffer
.
insert_with_tags_by_name
(
_iter
,
text
,
self
.
kind
)
def
_remove_line
(
self
):
self
.
is_nickname_visible
=
False
def
_get_color_tag
(
self
,
jid
):
tag_name
=
'%s-color'
%
jid
tag
=
self
.
_buffer
.
get_tag_table
().
lookup
(
tag_name
)
if
tag
is
not
None
:
return
tag
color
=
get_color_for_jid
(
jid
)
print
(
color
)
tag_config
=
{
'name'
:
tag_name
,
'foreground-gdk'
:
color
}
color_tag
=
Gtk
.
TextTag
(
**
tag_config
)
self
.
_buffer
.
get_tag_table
().
add
(
color_tag
)
return
color_tag
class
StatusMessage
(
TextViewLine
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment