/usr/lib/python3/dist-packages/kivy/metrics.py is in python3-kivy 1.9.0-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | '''
Metrics
=======
.. versionadded:: 1.5.0
A screen is defined by its physical size, density and resolution. These
factors are essential for creating UI's with correct size everywhere.
In Kivy, all the graphics pipelines work with pixels. But using pixels as a
measurement unit is problematic because sizes change according to the
screen.
Dimensions
----------
If you want to design your UI for different screen sizes, you will want better
measurement units to work with. Kivy provides some more scalable alternatives.
:Units:
`pt`
Points - 1/72 of an inch based on the physical size of the screen.
Prefer to use sp instead of pt.
`mm`
Millimeters - Based on the physical size of the screen.
`cm`
Centimeters - Based on the physical size of the screen.
`in`
Inches - Based on the physical size of the screen.
`dp`
Density-independent Pixels - An abstract unit that is based on the
physical density of the screen. With a :attr:`~MetricsBase.density` of
1, 1dp is equal to 1px. When running on a higher density screen, the
number of pixels used to draw 1dp is scaled up a factor appropriate to
the screen's dpi, and the inverse for a lower dpi.
The ratio of dp-to-pixels will change with the screen density, but not
necessarily in direct proportion. Using the dp unit is a simple
solution to making the view dimensions in your layout resize
properly for different screen densities. In others words, it
provides consistency for the real-world size of your UI across
different devices.
`sp`
Scale-independent Pixels - This is like the dp unit, but it is also
scaled by the user's font size preference. We recommend you use this
unit when specifying font sizes, so the font size will be adjusted to
both the screen density and the user's preference.
Examples
--------
Here is an example of creating a label with a sp font_size and setting the
height manually with a 10dp margin::
#:kivy 1.5.0
<MyWidget>:
Label:
text: 'Hello world'
font_size: '15sp'
size_hint_y: None
height: self.texture_size[1] + dp(10)
Manual control of metrics
-------------------------
The metrics cannot be changed at runtime. Once a value has been converted to
pixels, you can't retrieve the original value anymore. This stems from the fact
that the DPI and density of a device cannot be changed at runtime.
We provide some environment variables to control metrics:
- `KIVY_METRICS_DENSITY`: if set, this value will be used for
:attr:`~MetricsBase.density` instead of the systems one. On android,
the value varies between 0.75, 1, 1.5 and 2.
- `KIVY_METRICS_FONTSCALE`: if set, this value will be used for
:attr:`~MetricsBase.fontscale` instead of the systems one. On android, the
value varies between 0.8 and 1.2.
- `KIVY_DPI`: if set, this value will be used for :attr:`~MetricsBase.dpi`.
Please
note that setting the DPI will not impact the dp/sp notation because these
are based on the screen density.
For example, if you want to simulate a high-density screen (like the HTC One
X)::
KIVY_DPI=320 KIVY_METRICS_DENSITY=2 python main.py --size 1280x720
Or a medium-density (like Motorola Droid 2)::
KIVY_DPI=240 KIVY_METRICS_DENSITY=1.5 python main.py --size 854x480
You can also simulate an alternative user preference for fontscale as follows::
KIVY_METRICS_FONTSCALE=1.2 python main.py
'''
__all__ = ('Metrics', 'MetricsBase', 'pt', 'inch', 'cm', 'mm', 'dp', 'sp',
'metrics')
from os import environ
from kivy.utils import reify, platform
from kivy.properties import dpi2px
def pt(value):
'''Convert from points to pixels
'''
return dpi2px(value, 'pt')
def inch(value):
'''Convert from inches to pixels
'''
return dpi2px(value, 'in')
def cm(value):
'''Convert from centimeters to pixels
'''
return dpi2px(value, 'cm')
def mm(value):
'''Convert from millimeters to pixels
'''
return dpi2px(value, 'mm')
def dp(value):
'''Convert from density-independent pixels to pixels
'''
return dpi2px(value, 'dp')
def sp(value):
'''Convert from scale-independent pixels to pixels
'''
return dpi2px(value, 'sp')
class MetricsBase(object):
'''Class that contains the default attributes for Metrics. Don't use this
class directly, but use the `Metrics` instance.
'''
@reify
def dpi(self):
'''Return the DPI of the screen. Depending on the platform, the DPI can
be taken from the Window provider (Desktop mainly) or from a
platform-specific module (like android/ios).
'''
custom_dpi = environ.get('KIVY_DPI')
if custom_dpi:
return float(custom_dpi)
if platform == 'android':
import android
return android.get_dpi()
elif platform == 'ios':
import ios
return ios.get_dpi()
# for all other platforms..
from kivy.base import EventLoop
EventLoop.ensure_window()
return EventLoop.window.dpi
@reify
def dpi_rounded(self):
'''Return the DPI of the screen, rounded to the nearest of 120, 160,
240 or 320.
'''
dpi = self.dpi
if dpi < 140:
return 120
elif dpi < 200:
return 160
elif dpi < 280:
return 240
return 320
@reify
def density(self):
'''Return the density of the screen. This value is 1 by default
on desktops but varies on android depending on the screen.
'''
custom_density = environ.get('KIVY_METRICS_DENSITY')
if custom_density:
return float(custom_density)
if platform == 'android':
import jnius
Hardware = jnius.autoclass('org.renpy.android.Hardware')
return Hardware.metrics.scaledDensity
elif platform == 'ios':
# 0.75 is for mapping the same density as android tablet
import ios
return ios.get_scale() * 0.75
elif platform == 'macosx':
from kivy.base import EventLoop
EventLoop.ensure_window()
return EventLoop.window.dpi / 96.
return 1.0
@reify
def fontscale(self):
'''Return the fontscale user preference. This value is 1 by default but
can vary between 0.8 and 1.2.
'''
custom_fontscale = environ.get('KIVY_METRICS_FONTSCALE')
if custom_fontscale:
return float(custom_fontscale)
if platform == 'android':
from jnius import autoclass
PythonActivity = autoclass('org.renpy.android.PythonActivity')
config = PythonActivity.mActivity.getResources().getConfiguration()
return config.fontScale
return 1.0
#: Default instance of :class:`MetricsBase`, used everywhere in the code
#: .. versionadded:: 1.7.0
Metrics = MetricsBase()
#: default instance of :class:`MetricsBase`, used everywhere in the code
#: (deprecated, use `Metrics` instead.)
metrics = Metrics
|