github.com/richardwilkes/toolbox@v1.121.0/xmath/geom/size.go (about)

     1  // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, version 2.0. If a copy of the MPL was not distributed with
     5  // this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  //
     7  // This Source Code Form is "Incompatible With Secondary Licenses", as
     8  // defined by the Mozilla Public License, version 2.0.
     9  
    10  package geom
    11  
    12  import (
    13  	"fmt"
    14  
    15  	"github.com/richardwilkes/toolbox/xmath"
    16  )
    17  
    18  // Size defines a width and height.
    19  type Size[T xmath.Numeric] struct {
    20  	Width  T `json:"w"`
    21  	Height T `json:"h"`
    22  }
    23  
    24  // NewSize creates a new Size.
    25  func NewSize[T xmath.Numeric](width, height T) Size[T] {
    26  	return Size[T]{
    27  		Width:  width,
    28  		Height: height,
    29  	}
    30  }
    31  
    32  // ConvertSize converts a Size of type F into one of type T.
    33  func ConvertSize[T, F xmath.Numeric](s Size[F]) Size[T] {
    34  	return NewSize(T(s.Width), T(s.Height))
    35  }
    36  
    37  // Add returns a new Size which is the result of adding this Size with the provided Size.
    38  func (s Size[T]) Add(size Size[T]) Size[T] {
    39  	return Size[T]{Width: s.Width + size.Width, Height: s.Height + size.Height}
    40  }
    41  
    42  // Sub returns a new Size which is the result of subtracting the provided Size from this Size.
    43  func (s Size[T]) Sub(size Size[T]) Size[T] {
    44  	return Size[T]{Width: s.Width - size.Width, Height: s.Height - size.Height}
    45  }
    46  
    47  // Mul returns a new Size which is the result of multiplying this Size by the value.
    48  func (s Size[T]) Mul(value T) Size[T] {
    49  	return Size[T]{Width: s.Width * value, Height: s.Height * value}
    50  }
    51  
    52  // Div returns a new Size which is the result of dividing this Size by the value.
    53  func (s Size[T]) Div(value T) Size[T] {
    54  	return Size[T]{Width: s.Width / value, Height: s.Height / value}
    55  }
    56  
    57  // Floor returns a new Size with its width and height floored.
    58  func (s Size[T]) Floor() Size[T] {
    59  	return Size[T]{Width: xmath.Floor(s.Width), Height: xmath.Floor(s.Height)}
    60  }
    61  
    62  // Ceil returns a new Size with its width and height ceiled.
    63  func (s Size[T]) Ceil() Size[T] {
    64  	return Size[T]{Width: xmath.Ceil(s.Width), Height: xmath.Ceil(s.Height)}
    65  }
    66  
    67  // Min returns the smallest Size between itself and 'other'.
    68  func (s Size[T]) Min(other Size[T]) Size[T] {
    69  	return Size[T]{Width: min(s.Width, other.Width), Height: min(s.Height, other.Height)}
    70  }
    71  
    72  // Max returns the largest Size between itself and 'other'.
    73  func (s Size[T]) Max(other Size[T]) Size[T] {
    74  	return Size[T]{Width: max(s.Width, other.Width), Height: max(s.Height, other.Height)}
    75  }
    76  
    77  // ConstrainForHint returns a size no larger than the hint value. Hint values less than one are ignored.
    78  func (s Size[T]) ConstrainForHint(hint Size[T]) Size[T] {
    79  	w := s.Width
    80  	if hint.Width >= 1 && w > hint.Width {
    81  		w = hint.Width
    82  	}
    83  	h := s.Height
    84  	if hint.Height >= 1 && h > hint.Height {
    85  		h = hint.Height
    86  	}
    87  	return Size[T]{Width: w, Height: h}
    88  }
    89  
    90  // String implements fmt.Stringer.
    91  func (s Size[T]) String() string {
    92  	return fmt.Sprintf("%#v,%#v", s.Width, s.Height)
    93  }