gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/unit/unit.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  /*
     4  Package unit implements device independent units.
     5  
     6  Device independent pixel, or dp, is the unit for sizes independent of
     7  the underlying display device.
     8  
     9  Scaled pixels, or sp, is the unit for text sizes. An sp is like dp with
    10  text scaling applied.
    11  
    12  Finally, pixels, or px, is the unit for display dependent pixels. Their
    13  size vary between platforms and displays.
    14  
    15  To maintain a constant visual size across platforms and displays, always
    16  use dps or sps to define user interfaces. Only use pixels for derived
    17  values.
    18  */
    19  package unit
    20  
    21  import (
    22  	"math"
    23  )
    24  
    25  // Metric converts Values to device-dependent pixels, px. The zero
    26  // value represents a 1-to-1 scale from dp, sp to pixels.
    27  type Metric struct {
    28  	// PxPerDp is the device-dependent pixels per dp.
    29  	PxPerDp float32
    30  	// PxPerSp is the device-dependent pixels per sp.
    31  	PxPerSp float32
    32  }
    33  
    34  type (
    35  	// Dp represents device independent pixels. 1 dp will
    36  	// have the same apparent size across platforms and
    37  	// display resolutions.
    38  	Dp float32
    39  	// Sp is like UnitDp but for font sizes.
    40  	Sp float32
    41  )
    42  
    43  // Dp converts v to pixels, rounded to the nearest integer value.
    44  func (c Metric) Dp(v Dp) int {
    45  	return int(math.Round(float64(nonZero(c.PxPerDp)) * float64(v)))
    46  }
    47  
    48  // Sp converts v to pixels, rounded to the nearest integer value.
    49  func (c Metric) Sp(v Sp) int {
    50  	return int(math.Round(float64(nonZero(c.PxPerSp)) * float64(v)))
    51  }
    52  
    53  // DpToSp converts v dp to sp.
    54  func (c Metric) DpToSp(v Dp) Sp {
    55  	return Sp(float32(v) * nonZero(c.PxPerDp) / nonZero(c.PxPerSp))
    56  }
    57  
    58  // SpToDp converts v sp to dp.
    59  func (c Metric) SpToDp(v Sp) Dp {
    60  	return Dp(float32(v) * nonZero(c.PxPerSp) / nonZero(c.PxPerDp))
    61  }
    62  
    63  // PxToSp converts v px to sp.
    64  func (c Metric) PxToSp(v int) Sp {
    65  	return Sp(float32(v) / nonZero(c.PxPerSp))
    66  }
    67  
    68  // PxToDp converts v px to dp.
    69  func (c Metric) PxToDp(v int) Dp {
    70  	return Dp(float32(v) / nonZero(c.PxPerDp))
    71  }
    72  
    73  func nonZero(v float32) float32 {
    74  	if v == 0. {
    75  		return 1
    76  	}
    77  	return v
    78  }