Skip to content

Commit 1fd6077

Browse files
mavwolverineSteve Canny
authored and
Steve Canny
committed
dml: add ColorFormat.rgb getter
1 parent 478c68b commit 1fd6077

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

docx/dml/color.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@ class ColorFormat(ElementProxy):
2424
def __init__(self, rPr_parent):
2525
super(ColorFormat, self).__init__(rPr_parent)
2626

27+
@property
28+
def rgb(self):
29+
"""
30+
An |RGBColor| value or |None| if no RGB color is specified.
31+
32+
When :attr:`type` is `MSO_COLOR_TYPE.RGB`, the value of this property
33+
will always be an |RGBColor| value. It may also be an |RGBColor|
34+
value if :attr:`type` is `MSO_COLOR_TYPE.THEME`, as Word writes the
35+
current value of a theme color when one is assigned. In that case,
36+
the RGB value should be interpreted as no more than a good guess
37+
however, as the theme color takes precedence at rendering time. Its
38+
value is |None| whenever :attr:`type` is either |None| or
39+
`MSO_COLOR_TYPE.AUTO`.
40+
41+
Assigning an |RGBColor| value causes :attr:`type` to become
42+
`MSO_COLOR_TYPE.RGB` and any theme color is removed. Assigning |None|
43+
causes any color to be removed such that the effective color is
44+
inherited from the style hierarchy.
45+
"""
46+
color = self._color
47+
if color is None:
48+
return None
49+
if color.val == ST_HexColorAuto.AUTO:
50+
return None
51+
return color.val
52+
2753
@property
2854
def type(self):
2955
"""
@@ -32,14 +58,22 @@ def type(self):
3258
|None| if no color is applied at this level, which causes the
3359
effective color to be inherited from the style hierarchy.
3460
"""
35-
rPr = self._element.rPr
36-
if rPr is None:
37-
return None
38-
color = rPr.color
61+
color = self._color
3962
if color is None:
4063
return None
4164
if color.themeColor is not None:
4265
return MSO_COLOR_TYPE.THEME
4366
if color.val == ST_HexColorAuto.AUTO:
4467
return MSO_COLOR_TYPE.AUTO
4568
return MSO_COLOR_TYPE.RGB
69+
70+
@property
71+
def _color(self):
72+
"""
73+
Return `w:rPr/w:color` or |None| if not present. Helper to factor out
74+
repetitive element access.
75+
"""
76+
rPr = self._element.rPr
77+
if rPr is None:
78+
return None
79+
return rPr.color

features/txt-font-color.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ Feature: Get and set font color
1616
| a theme | THEME |
1717

1818

19-
@wip
2019
Scenario Outline: Get font RGB color
2120
Given a font having <type> color
2221
Then font.color.rgb is <value>

tests/dml/test_color.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from docx.enum.dml import MSO_COLOR_TYPE
1212
from docx.dml.color import ColorFormat
13+
from docx.shared import RGBColor
1314

1415
from ..unitutil.cxml import element
1516

@@ -22,8 +23,26 @@ def it_knows_its_color_type(self, type_fixture):
2223
color_format, expected_value = type_fixture
2324
assert color_format.type == expected_value
2425

26+
def it_knows_its_RGB_value(self, rgb_get_fixture):
27+
color_format, expected_value = rgb_get_fixture
28+
assert color_format.rgb == expected_value
29+
2530
# fixtures ---------------------------------------------
2631

32+
@pytest.fixture(params=[
33+
('w:r', None),
34+
('w:r/w:rPr', None),
35+
('w:r/w:rPr/w:color{w:val=auto}', None),
36+
('w:r/w:rPr/w:color{w:val=4224FF}', '4224ff'),
37+
('w:r/w:rPr/w:color{w:val=auto,w:themeColor=accent1}', None),
38+
('w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}', 'f00ba9'),
39+
])
40+
def rgb_get_fixture(self, request):
41+
r_cxml, rgb = request.param
42+
color_format = ColorFormat(element(r_cxml))
43+
expected_value = None if rgb is None else RGBColor.from_string(rgb)
44+
return color_format, expected_value
45+
2746
@pytest.fixture(params=[
2847
('w:r', None),
2948
('w:r/w:rPr', None),

0 commit comments

Comments
 (0)