| // Copyright 2016 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Package unit defines units of length such as inches or pixels. | |
| // | |
| // Functions like Inches and Pixels return a Value in the corresponding unit. | |
| // For example: | |
| // | |
| // v := unit.Inches(4.5) | |
| // | |
| // represents four and a half inches. | |
| // | |
| // Converting between pixels (px), physical units (dp, pt, in, mm) and | |
| // font-face-relative measures (em, ex, ch) depends on the context, such as the | |
| // screen's DPI resolution and the active font face. That context is | |
| // represented by the Converter type. | |
| // | |
| // Conversions may be lossy. Converting 4.5 inches to pixels and back may | |
| // result in something slightly different than 4.5. Similarly, converting 4 | |
| // inches and 0.5 inches to pixels and then adding the results won't | |
| // necessarily equal the conversion of 4.5 inches to pixels. | |
| // | |
| // Note that what CSS (Cascading Style Sheets) calls "px" differs from what | |
| // this package calls "px". For legacy reasons, the CSS semantics are that 1 | |
| // inch should roughly equal 96csspx regardless of the actual DPI resolution, | |
| // as per https://developer.mozilla.org/en/docs/Web/CSS/length. This package's | |
| // semantics are that 1px means exactly one physical pixel, always. This | |
| // package represents 1csspx as 1.666666667dp, since there are 160 density | |
| // independent pixels per inch, the same definition as Android. | |
| package unit | |
| import ( | |
| "fmt" | |
| "golang.org/x/image/math/fixed" | |
| ) | |
| const ( | |
| DensityIndependentPixelsPerInch = 160 | |
| MillimetresPerInch = 25.4 | |
| PointsPerInch = 72 | |
| ) | |
| // Converter converts values from one unit to another. Conversions may be | |
| // lossy. | |
| type Converter interface { | |
| // Convert converts v to the given unit. | |
| Convert(v Value, to Unit) Value | |
| // Pixels converts v to a 26.6 fixed-point number of physical pixels. | |
| Pixels(v Value) fixed.Int26_6 | |
| } | |
| // Value is a number and a unit. | |
| type Value struct { | |
| F float64 | |
| U Unit | |
| } | |
| // String implements the fmt.Stringer interface. | |
| func (v Value) String() string { | |
| return fmt.Sprintf("%f%s", v.F, names[v.U]) | |
| } | |
| var names = [...]string{ | |
| Px: "px", | |
| Dp: "dp", | |
| Pt: "pt", | |
| In: "in", | |
| Mm: "mm", | |
| Em: "em", | |
| Ex: "ex", | |
| Ch: "ch", | |
| } | |
| // Unit is a unit of length, such as inches or pixels. | |
| type Unit uint8 | |
| const ( | |
| // Px is a physical pixel, regardless of the DPI resolution. | |
| Px Unit = iota | |
| // Dp is 1 density independent pixel: 1/160th of an inch. | |
| Dp | |
| // Pt is 1 point: 1/72th of an inch. | |
| Pt | |
| // Mm is 1 millimetre: 1/25.4th of an inch. | |
| Mm | |
| // In is 1 inch. | |
| // | |
| // If the context does not specify a DPI resolution, the recommended | |
| // fallback value for conversion is 72 pixels per inch. | |
| In | |
| // Em is the height of the active font face, disregarding extra leading | |
| // such as from double-spaced lines of text. | |
| // | |
| // If the context does not specify an active font face, the recommended | |
| // fallback value for conversion is 12pt. | |
| Em | |
| // Ex is the x-height of the active font face. | |
| // | |
| // If the context does not specify an x-height, the recommended fallback | |
| // value for conversion is 0.5em. | |
| Ex | |
| // Ch is the character width of the numeral zero glyph '0' of the active | |
| // font face. | |
| // | |
| // If the context does not specify a '0' glyph, the recommended fallback | |
| // value for conversion is 0.5em. | |
| Ch | |
| ) | |
| // Pixels returns the given number of Px as a Value. | |
| func Pixels(f float64) Value { return Value{f, Px} } | |
| // DIPs returns the given number of Dp as a Value. | |
| func DIPs(f float64) Value { return Value{f, Dp} } | |
| // Points returns the given number of Pt as a Value. | |
| func Points(f float64) Value { return Value{f, Pt} } | |
| // Millimetres returns the given number of Mm as a Value. | |
| func Millimetres(f float64) Value { return Value{f, Mm} } | |
| // Inches returns the given number of In as a Value. | |
| func Inches(f float64) Value { return Value{f, In} } | |
| // Ems returns the given number of Em as a Value. | |
| func Ems(f float64) Value { return Value{f, Em} } | |
| // Exs returns the given number of Ex as a Value. | |
| func Exs(f float64) Value { return Value{f, Ex} } | |
| // Chs returns the given number of Ch as a Value. | |
| func Chs(f float64) Value { return Value{f, Ch} } |