Skip to content

Commit 226b699

Browse files
author
Steve Canny
committed
shr: add DescribeLength
1 parent 08152f9 commit 226b699

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

docx/shared.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Length(int):
1717
_EMUS_PER_INCH = 914400
1818
_EMUS_PER_CM = 360000
1919
_EMUS_PER_MM = 36000
20-
_EMUS_PER_PX = 12700
20+
_EMUS_PER_PT = 12700
2121
_EMUS_PER_TWIP = 635
2222

2323
def __new__(cls, emu):
@@ -52,10 +52,11 @@ def mm(self):
5252
return self / float(self._EMUS_PER_MM)
5353

5454
@property
55-
def px(self):
56-
# round can somtimes return values like x.999999 which are truncated
57-
# to x by int(); adding the 0.1 prevents this
58-
return int(round(self / float(self._EMUS_PER_PX)) + 0.1)
55+
def pt(self):
56+
"""
57+
Floating point length in points
58+
"""
59+
return self / float(self._EMUS_PER_PT)
5960

6061
@property
6162
def twips(self):
@@ -104,23 +105,12 @@ def __new__(cls, mm):
104105
return Length.__new__(cls, emu)
105106

106107

107-
class Pt(int):
108-
"""
109-
Convenience class for setting font sizes in points
110-
"""
111-
_UNITS_PER_POINT = 100
112-
113-
def __new__(cls, pts):
114-
units = int(pts * Pt._UNITS_PER_POINT)
115-
return int.__new__(cls, units)
116-
117-
118-
class Px(Length):
108+
class Pt(Length):
119109
"""
120-
Convenience constructor for length in pixels.
110+
Convenience value class for specifying a length in points
121111
"""
122-
def __new__(cls, px):
123-
emu = int(px * Length._EMUS_PER_PX)
112+
def __new__(cls, points):
113+
emu = int(points * Length._EMUS_PER_PT)
124114
return Length.__new__(cls, emu)
125115

126116

tests/test_shared.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import pytest
1212

1313
from docx.opc.part import XmlPart
14-
from docx.shared import ElementProxy
14+
from docx.shared import ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, Twips
1515

1616
from .unitutil.cxml import element
1717
from .unitutil.mock import instance_mock
@@ -70,3 +70,46 @@ def other_proxy_(self, request):
7070
@pytest.fixture
7171
def part_(self, request):
7272
return instance_mock(request, XmlPart)
73+
74+
75+
class DescribeLength(object):
76+
77+
def it_can_construct_from_convenient_units(self, construct_fixture):
78+
UnitCls, units_val, emu = construct_fixture
79+
length = UnitCls(units_val)
80+
assert isinstance(length, Length)
81+
assert length == emu
82+
83+
def it_can_self_convert_to_convenient_units(self, units_fixture):
84+
emu, units_prop_name, expected_length_in_units, type_ = units_fixture
85+
length = Length(emu)
86+
length_in_units = getattr(length, units_prop_name)
87+
assert length_in_units == expected_length_in_units
88+
assert isinstance(length_in_units, type_)
89+
90+
# fixtures -------------------------------------------------------
91+
92+
@pytest.fixture(params=[
93+
(Length, 914400, 914400),
94+
(Inches, 1.1, 1005840),
95+
(Cm, 2.53, 910799),
96+
(Emu, 9144.9, 9144),
97+
(Mm, 13.8, 496800),
98+
(Pt, 24.5, 311150),
99+
(Twips, 360, 228600),
100+
])
101+
def construct_fixture(self, request):
102+
UnitCls, units_val, emu = request.param
103+
return UnitCls, units_val, emu
104+
105+
@pytest.fixture(params=[
106+
(914400, 'inches', 1.0, float),
107+
(914400, 'cm', 2.54, float),
108+
(914400, 'emu', 914400, int),
109+
(914400, 'mm', 25.4, float),
110+
(914400, 'pt', 72.0, float),
111+
(914400, 'twips', 1440, int),
112+
])
113+
def units_fixture(self, request):
114+
emu, units_prop_name, expected_length_in_units, type_ = request.param
115+
return emu, units_prop_name, expected_length_in_units, type_

0 commit comments

Comments
 (0)