0
# Dimensions and Measurements
1
2
Comprehensive measurement system providing units, calculations, layout dimensions, and precise positioning for document elements. The dimension system enables exact control over spacing, sizing, and positioning with support for both absolute and relative measurements.
3
4
## Capabilities
5
6
### Dimension Class
7
8
Core dimension class providing measurement values with units and calculation capabilities.
9
10
```python { .api }
11
class Dimension:
12
"""
13
Measurement value with unit specification and calculation support.
14
15
Represents distances, sizes, and positions with associated units,
16
providing arithmetic operations and unit conversions for layout calculations.
17
18
Parameters:
19
- value: float or int, numeric measurement value
20
- unit: DimensionUnit, unit specification (PT, MM, CM, INCH, etc.)
21
"""
22
def __init__(self, value=0, unit=None): ...
23
24
@property
25
def value(self): ... # Numeric value
26
@property
27
def unit(self): ... # Unit specification
28
29
# Arithmetic operations
30
def __add__(self, other): ... # Addition with other dimensions
31
def __sub__(self, other): ... # Subtraction with other dimensions
32
def __mul__(self, scalar): ... # Multiplication by scalar
33
def __rmul__(self, scalar): ... # Right multiplication by scalar
34
def __truediv__(self, scalar): ... # Division by scalar
35
def __neg__(self): ... # Negation
36
37
# Comparison operations
38
def __eq__(self, other): ... # Equality comparison
39
def __lt__(self, other): ... # Less than comparison
40
def __le__(self, other): ... # Less than or equal
41
def __gt__(self, other): ... # Greater than comparison
42
def __ge__(self, other): ... # Greater than or equal
43
44
# Conversion and calculation
45
def to_points(self, total_dimension=None): ... # Convert to points
46
def grow(self, value): ... # Increase by specified amount
47
48
# String representation
49
def __str__(self): ... # Human-readable string
50
def __repr__(self): ... # Developer representation
51
```
52
53
### Absolute Units
54
55
Physical measurement units with fixed relationships to real-world dimensions.
56
57
```python { .api }
58
# Point unit (1/72 inch) - typography standard
59
PT = <DimensionUnit>
60
"""
61
Points - traditional typography unit.
62
1 point = 1/72 inch = 0.3528 mm
63
Most common unit for font sizes and fine measurements.
64
"""
65
66
# Pica unit (12 points) - typography standard
67
PICA = <DimensionUnit>
68
"""
69
Picas - typography unit for line measures.
70
1 pica = 12 points = 1/6 inch = 4.233 mm
71
Used for column widths and larger typography measurements.
72
"""
73
74
# Imperial units
75
INCH = <DimensionUnit>
76
"""
77
Inches - imperial measurement unit.
78
1 inch = 72 points = 6 picas = 25.4 mm
79
Standard for paper sizes and margins in US documents.
80
"""
81
82
# Metric units
83
MM = <DimensionUnit>
84
"""
85
Millimeters - metric unit.
86
1 mm = 2.834 points ≈ 0.0394 inches
87
Precise metric measurements for international documents.
88
"""
89
90
CM = <DimensionUnit>
91
"""
92
Centimeters - metric unit.
93
1 cm = 10 mm = 28.346 points ≈ 0.394 inches
94
Common for page dimensions and larger measurements.
95
"""
96
```
97
98
### Relative Units
99
100
Proportional measurement units that calculate values based on context or container dimensions.
101
102
```python { .api }
103
PERCENT = <DimensionUnit>
104
"""
105
Percentage unit - relative to container or parent dimension.
106
Calculated as percentage of available space or reference dimension.
107
Example: 50*PERCENT = 50% of container width/height
108
"""
109
110
QUARTERS = <DimensionUnit>
111
"""
112
Quarter units - relative fractional measurements.
113
Divides available space into quarters for flexible layouts.
114
Example: 3*QUARTERS = 3/4 of available space
115
"""
116
```
117
118
### Unit Creation and Conversion
119
120
Functions and utilities for creating custom units and performing conversions between different measurement systems.
121
122
```python { .api }
123
def create_unit(name, points_per_unit):
124
"""
125
Create custom dimension unit.
126
127
Parameters:
128
- name: str, unit name identifier
129
- points_per_unit: float, conversion factor to points
130
131
Returns:
132
- DimensionUnit for use in Dimension creation
133
"""
134
...
135
136
def convert_dimension(dimension, target_unit, reference_dimension=None):
137
"""
138
Convert dimension to different unit.
139
140
Parameters:
141
- dimension: Dimension, source dimension to convert
142
- target_unit: DimensionUnit, target unit for conversion
143
- reference_dimension: Dimension, reference for relative units
144
145
Returns:
146
- Dimension in target unit
147
"""
148
...
149
150
class DimensionUnit:
151
"""
152
Unit specification for dimension calculations.
153
154
Encapsulates unit properties including name, conversion factors,
155
and calculation methods for different unit types.
156
"""
157
158
def __init__(self, name, points_per_unit=None, relative=False): ...
159
160
@property
161
def name(self): ... # Unit name
162
@property
163
def is_relative(self): ... # Whether unit is relative
164
165
def to_points(self, value, reference=None): ... # Convert to points
166
```
167
168
### Dimension Calculations
169
170
Advanced calculation functions for common layout and spacing operations.
171
172
```python { .api }
173
def max_dimension(*dimensions):
174
"""
175
Get maximum dimension from multiple dimensions.
176
177
Parameters:
178
- *dimensions: Dimension objects to compare
179
180
Returns:
181
- Dimension with maximum value
182
"""
183
...
184
185
def min_dimension(*dimensions):
186
"""
187
Get minimum dimension from multiple dimensions.
188
189
Parameters:
190
- *dimensions: Dimension objects to compare
191
192
Returns:
193
- Dimension with minimum value
194
"""
195
...
196
197
def sum_dimensions(*dimensions):
198
"""
199
Sum multiple dimensions.
200
201
Parameters:
202
- *dimensions: Dimension objects to sum
203
204
Returns:
205
- Dimension with total value
206
"""
207
...
208
209
def distribute_space(total_space, *proportions):
210
"""
211
Distribute space proportionally.
212
213
Parameters:
214
- total_space: Dimension, total space to distribute
215
- *proportions: float values for proportional distribution
216
217
Returns:
218
- list of Dimension objects with distributed space
219
"""
220
...
221
```
222
223
### Spacing and Layout
224
225
Specialized classes and functions for managing spacing, margins, and layout calculations.
226
227
```python { .api }
228
class Spacing:
229
"""
230
Spacing configuration for margins, padding, and gaps.
231
232
Manages spacing around elements with support for different
233
values for top, right, bottom, and left sides.
234
235
Parameters:
236
- top: Dimension, top spacing
237
- right: Dimension, right spacing (defaults to top)
238
- bottom: Dimension, bottom spacing (defaults to top)
239
- left: Dimension, left spacing (defaults to right)
240
"""
241
def __init__(self, top, right=None, bottom=None, left=None): ...
242
243
@property
244
def top(self): ... # Top spacing
245
@property
246
def right(self): ... # Right spacing
247
@property
248
def bottom(self): ... # Bottom spacing
249
@property
250
def left(self): ... # Left spacing
251
252
@property
253
def horizontal(self): ... # Total horizontal spacing (left + right)
254
@property
255
def vertical(self): ... # Total vertical spacing (top + bottom)
256
257
class Margins(Spacing):
258
"""Margin specification for page and element margins."""
259
260
class Padding(Spacing):
261
"""Padding specification for interior element spacing."""
262
263
def calculate_available_space(container_size, margins, padding=None):
264
"""
265
Calculate available content space within container.
266
267
Parameters:
268
- container_size: Dimension, total container size
269
- margins: Margins, margin specification
270
- padding: Padding, optional padding specification
271
272
Returns:
273
- Dimension with available content space
274
"""
275
...
276
```
277
278
### Paper and Page Dimensions
279
280
Predefined paper sizes and page dimension calculations for document layout.
281
282
```python { .api }
283
def get_paper_dimensions(paper_name, orientation='portrait'):
284
"""
285
Get dimensions for standard paper size.
286
287
Parameters:
288
- paper_name: str, paper size name ('A4', 'LETTER', etc.)
289
- orientation: str, 'portrait' or 'landscape'
290
291
Returns:
292
- (width, height) tuple of Dimension objects
293
"""
294
...
295
296
def calculate_content_area(paper_size, margins):
297
"""
298
Calculate content area within page margins.
299
300
Parameters:
301
- paper_size: (width, height) tuple of page dimensions
302
- margins: Margins, page margin specification
303
304
Returns:
305
- (width, height) tuple of content area dimensions
306
"""
307
...
308
309
# Common paper size calculations
310
A4_WIDTH = 210*MM # A4 paper width
311
A4_HEIGHT = 297*MM # A4 paper height
312
LETTER_WIDTH = 8.5*INCH # US Letter width
313
LETTER_HEIGHT = 11*INCH # US Letter height
314
```
315
316
## Usage Examples
317
318
### Basic Dimension Operations
319
320
```python
321
from rinohtype.dimension import Dimension, PT, MM, CM, INCH
322
323
# Create dimensions with different units
324
font_size = 12*PT
325
margin = 25*MM
326
width = 6*INCH
327
height = 4*CM
328
329
# Arithmetic operations
330
total_height = height + 2*margin
331
scaled_width = width * 1.5
332
half_margin = margin / 2
333
334
# Comparison operations
335
if font_size > 10*PT:
336
print("Large font")
337
338
# Convert between units
339
margin_in_points = margin.to_points()
340
width_in_mm = width.to_points() * MM.to_points(1) # Approximate conversion
341
```
342
343
### Unit Conversions
344
345
```python
346
from rinohtype.dimension import convert_dimension
347
348
# Convert measurements between units
349
page_width_mm = 210*MM
350
page_width_inches = convert_dimension(page_width_mm, INCH)
351
page_width_points = convert_dimension(page_width_mm, PT)
352
353
print(f"A4 width: {page_width_mm} = {page_width_inches} = {page_width_points}")
354
355
# Working with different units in calculations
356
left_margin = 1*INCH
357
right_margin = 25*MM
358
total_horizontal_margin = left_margin + right_margin # Automatic unit handling
359
```
360
361
### Relative Dimensions
362
363
```python
364
from rinohtype.dimension import PERCENT, QUARTERS
365
366
# Percentage-based dimensions
367
half_width = 50*PERCENT # 50% of container width
368
three_quarters = 75*PERCENT # 75% of container
369
370
# Quarter-based fractional dimensions
371
one_quarter = 1*QUARTERS # 1/4 of container
372
three_quarters_alt = 3*QUARTERS # 3/4 of container
373
374
# Calculate relative dimensions with reference
375
container_width = 200*MM
376
actual_half_width = half_width.to_points(container_width)
377
```
378
379
### Spacing Configuration
380
381
```python
382
from rinohtype.dimension import Spacing, Margins, Padding
383
384
# Uniform spacing
385
uniform_margin = Margins(25*MM) # 25mm on all sides
386
387
# Different spacing per side
388
custom_margins = Margins(
389
top=30*MM,
390
right=20*MM,
391
bottom=25*MM,
392
left=20*MM
393
)
394
395
# Shorthand for horizontal/vertical
396
page_margins = Margins(25*MM, 20*MM) # 25mm top/bottom, 20mm left/right
397
398
# Element padding
399
element_padding = Padding(
400
top=6*PT,
401
right=12*PT,
402
bottom=6*PT,
403
left=12*PT
404
)
405
406
# Calculate total spacing
407
total_horizontal = custom_margins.horizontal # left + right
408
total_vertical = custom_margins.vertical # top + bottom
409
```
410
411
### Layout Calculations
412
413
```python
414
from rinohtype.dimension import calculate_available_space, distribute_space
415
416
# Calculate available content space
417
page_size = (210*MM, 297*MM) # A4 dimensions
418
page_margins = Margins(25*MM)
419
content_area = calculate_available_space(page_size[0], page_margins)
420
421
print(f"Content width: {content_area}") # 210mm - 50mm = 160mm
422
423
# Distribute space proportionally
424
total_width = 200*MM
425
column_widths = distribute_space(total_width, 2, 1, 2) # 2:1:2 ratio
426
# Result: [80mm, 40mm, 80mm]
427
428
# Multi-column layout calculation
429
available_width = 160*MM
430
gutter_width = 5*MM
431
num_columns = 3
432
433
total_gutter_width = gutter_width * (num_columns - 1)
434
column_width = (available_width - total_gutter_width) / num_columns
435
```
436
437
### Advanced Dimension Operations
438
439
```python
440
from rinohtype.dimension import max_dimension, min_dimension, sum_dimensions
441
442
# Find maximum dimension
443
widths = [120*MM, 4.5*INCH, 300*PT]
444
max_width = max_dimension(*widths)
445
446
# Find minimum dimension
447
heights = [150*MM, 6*INCH, 400*PT]
448
min_height = min_dimension(*heights)
449
450
# Sum dimensions
451
spacing_values = [6*PT, 3*MM, 0.1*INCH]
452
total_spacing = sum_dimensions(*spacing_values)
453
454
# Complex calculations for grid layouts
455
def calculate_grid_dimensions(container_width, columns, gutter):
456
"""Calculate grid column widths with gutters."""
457
total_gutter = gutter * (columns - 1)
458
available_width = container_width - total_gutter
459
column_width = available_width / columns
460
461
return {
462
'column_width': column_width,
463
'gutter_width': gutter,
464
'total_width': container_width
465
}
466
467
grid = calculate_grid_dimensions(200*MM, 4, 5*MM)
468
```
469
470
### Custom Units
471
472
```python
473
from rinohtype.dimension import create_unit, DimensionUnit
474
475
# Create custom unit for specific use case
476
# Example: Creating a unit for a specific grid system
477
GRID_UNIT = create_unit('grid', 18) # 18 points per grid unit
478
479
# Use custom unit
480
element_width = 5*GRID_UNIT # 5 grid units = 90 points
481
element_height = 3*GRID_UNIT # 3 grid units = 54 points
482
483
# Custom typographic unit
484
# Cicero (European typography unit ≈ 1.063 picas)
485
CICERO = create_unit('cicero', 12.79) # Approximately 12.79 points
486
487
line_measure = 20*CICERO # 20 ciceros wide
488
```
489
490
### Document Layout Calculations
491
492
```python
493
def setup_document_dimensions():
494
"""Calculate document layout dimensions."""
495
# Page setup
496
paper_width = 210*MM # A4 width
497
paper_height = 297*MM # A4 height
498
499
# Margins
500
top_margin = 25*MM
501
bottom_margin = 25*MM
502
left_margin = 20*MM
503
right_margin = 20*MM
504
505
# Calculate content area
506
content_width = paper_width - left_margin - right_margin
507
content_height = paper_height - top_margin - bottom_margin
508
509
# Typography settings
510
base_font_size = 11*PT
511
line_height = base_font_size * 1.2
512
513
# Calculate lines per page
514
lines_per_page = int(content_height.to_points() / line_height.to_points())
515
516
return {
517
'page_size': (paper_width, paper_height),
518
'content_area': (content_width, content_height),
519
'margins': Margins(top_margin, right_margin, bottom_margin, left_margin),
520
'typography': {
521
'font_size': base_font_size,
522
'line_height': line_height,
523
'lines_per_page': lines_per_page
524
}
525
}
526
527
layout = setup_document_dimensions()
528
```
529
530
### Responsive Dimensions
531
532
```python
533
def responsive_dimension(base_dimension, scale_factors):
534
"""Create responsive dimensions for different contexts."""
535
return {
536
'small': base_dimension * scale_factors.get('small', 0.8),
537
'medium': base_dimension * scale_factors.get('medium', 1.0),
538
'large': base_dimension * scale_factors.get('large', 1.2)
539
}
540
541
# Responsive font sizes
542
base_size = 11*PT
543
heading_sizes = responsive_dimension(base_size, {
544
'small': 1.2,
545
'medium': 1.5,
546
'large': 2.0
547
})
548
549
# Responsive margins
550
base_margin = 20*MM
551
responsive_margins = responsive_dimension(base_margin, {
552
'small': 0.75,
553
'medium': 1.0,
554
'large': 1.25
555
})
556
```
557
558
### Error Handling and Validation
559
560
```python
561
def validate_dimension(dimension, min_value=None, max_value=None):
562
"""Validate dimension within acceptable range."""
563
if min_value and dimension < min_value:
564
raise ValueError(f"Dimension {dimension} below minimum {min_value}")
565
566
if max_value and dimension > max_value:
567
raise ValueError(f"Dimension {dimension} exceeds maximum {max_value}")
568
569
return True
570
571
def safe_dimension_operation(op, *dimensions):
572
"""Perform dimension operation with error handling."""
573
try:
574
return op(*dimensions)
575
except (TypeError, ValueError) as e:
576
print(f"Dimension operation error: {e}")
577
return None
578
579
# Usage
580
try:
581
validate_dimension(font_size, min_value=6*PT, max_value=72*PT)
582
result = safe_dimension_operation(sum_dimensions, 10*PT, 5*MM, 0.1*INCH)
583
except ValueError as e:
584
print(f"Validation error: {e}")
585
```