| Author | DaveJarvis <email> |
|---|---|
| Date | 2020-07-19 20:25:57 GMT-0700 |
| Commit | 897e2e5ffb05a8555e8da41227633b6fbcab76bb |
| Parent | 0cc89ce |
| */ | ||
| public class HardwareComponent<S, I extends Image> extends JComponent { | ||
| - private final static Insets INSET_PROJECTED = | ||
| - new Insets( 3, 7, 6, 7 ); | ||
| + /** | ||
| + * Default insets, has no padding. | ||
| + */ | ||
| + private final static Insets INSETS_EMPTY = | ||
| + new Insets( 0, 0, 0, 0 ); | ||
| private final Map<S, I> mStateImages = new HashMap<>(); | ||
| /** | ||
| - * Active state. | ||
| + * State that corresponds with the {@link Image} to paint. | ||
| */ | ||
| private S mState; | ||
| + | ||
| + /** | ||
| + * Available space on the image for drawing. This | ||
| + */ | ||
| + private final Insets mInsets; | ||
| /** | ||
| * Constructs a new {@link HardwareComponent} without an initial state. The | ||
| * initial state must be set by calling {@link #setState(Object)} before | ||
| * drawing the image. | ||
| */ | ||
| public HardwareComponent() { | ||
| + this( INSETS_EMPTY ); | ||
| } | ||
| - /** | ||
| - * Associates a new (or existing) state with the given image. If the | ||
| - * state already exists for the image, the image is updated for that | ||
| - * state. After calling this method, the active state changes to the | ||
| - * given state as a convenience. | ||
| - * | ||
| - * @param state The state to associate with an image. | ||
| - * @param image The image to paint when the given state is selected. | ||
| - */ | ||
| - public void put( final S state, final I image ) { | ||
| - getStateImages().put( state, image ); | ||
| - setState( state ); | ||
| + public HardwareComponent( final Insets insets ) { | ||
| + mInsets = insets; | ||
| } | ||
| @Override | ||
| public Insets getInsets() { | ||
| - return INSET_PROJECTED; | ||
| + return mInsets; | ||
| } | ||
| @Override | ||
| protected void paintComponent( final Graphics graphics ) { | ||
| super.paintComponent( graphics ); | ||
| final var g = (Graphics2D) graphics.create(); | ||
| g.drawImage( getActiveImage(), 0, 0, this ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Associates a new (or existing) state with the given image. If the | ||
| + * state already exists for the image, the image is updated for that | ||
| + * state. After calling this method, the active state changes to the | ||
| + * given state as a convenience. | ||
| + * | ||
| + * @param state The state to associate with an image. | ||
| + * @param image The image to paint when the given state is selected. | ||
| + */ | ||
| + public void put( final S state, final I image ) { | ||
| + getStateImages().put( state, image ); | ||
| + setState( state ); | ||
| } | ||
| package com.whitemagicsoftware.kmcaster; | ||
| +import com.whitemagicsoftware.kmcaster.ui.DimensionTuple; | ||
| +import com.whitemagicsoftware.kmcaster.util.Pair; | ||
| + | ||
| import java.awt.*; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
| import static com.whitemagicsoftware.kmcaster.HardwareState.ANY_KEY; | ||
| import static com.whitemagicsoftware.kmcaster.HardwareSwitch.*; | ||
| import static com.whitemagicsoftware.kmcaster.exceptions.Rethrowable.rethrow; | ||
| +import static java.lang.Boolean.FALSE; | ||
| +import static java.lang.Boolean.TRUE; | ||
| import static java.lang.String.format; | ||
| * large, the application's window will adjust to fit. | ||
| */ | ||
| - private final Dimension mDimension = new Dimension( 1024, 60 ); | ||
| + private final Dimension mDimension = new Dimension( 1024, 120 ); | ||
| - /** | ||
| - * Constructs an enumerated type that represents the different types of | ||
| - * images shown when keyboard and mouse events are triggered. | ||
| - */ | ||
| public HardwareImages() { | ||
| - final var mouseStates = new HardwareComponent<HardwareState, Image>(); | ||
| + final var mouseStates = createHardwareComponent(); | ||
| for( int i = 1; i <= 3; i++ ) { | ||
| final var s = Integer.toString( i ); | ||
| mouseStates.put( state( MOUSE, s ), mouseImage( s ) ); | ||
| } | ||
| mouseStates.put( state( MOUSE, "1-3" ), mouseImage( "1-3" ) ); | ||
| - mouseStates.put( state( MOUSE, false ), mouseImage( "0" ) ); | ||
| + mouseStates.put( state( MOUSE, FALSE.toString() ), mouseImage( "0" ) ); | ||
| mSwitches.put( MOUSE, mouseStates ); | ||
| - final var altStates = new HardwareComponent<HardwareState, Image>(); | ||
| - altStates.put( state( KEY_ALT, true ), keyDnImage( "medium" ) ); | ||
| - altStates.put( state( KEY_ALT, false ), keyUpImage( "medium" ) ); | ||
| - mSwitches.put( KEY_ALT, altStates ); | ||
| + final var fileNamePrefixes = Map.of( | ||
| + KEY_ALT, "medium", | ||
| + KEY_CTRL, "medium", | ||
| + KEY_SHIFT, "long", | ||
| + KEY_REGULAR, "short" | ||
| + ); | ||
| - final var ctrlStates = new HardwareComponent<HardwareState, Image>(); | ||
| - ctrlStates.put( state( KEY_CTRL, true ), keyDnImage( "medium" ) ); | ||
| - ctrlStates.put( state( KEY_CTRL, false ), keyUpImage( "medium" ) ); | ||
| - mSwitches.put( KEY_CTRL, ctrlStates ); | ||
| + for( final var key : HardwareSwitch.keyboardKeys() ) { | ||
| + final var hardwareComponent = createHardwareComponent(); | ||
| + final var stateNameOn = key == KEY_REGULAR ? ANY_KEY : TRUE.toString(); | ||
| - final var shiftStates = new HardwareComponent<HardwareState, Image>(); | ||
| - shiftStates.put( state( KEY_SHIFT, true ), keyDnImage( "long" ) ); | ||
| - shiftStates.put( state( KEY_SHIFT, false ), keyUpImage( "long" ) ); | ||
| - mSwitches.put( KEY_SHIFT, shiftStates ); | ||
| + final var stateOn = state( key, stateNameOn ); | ||
| + final var stateOff = state( key, FALSE.toString() ); | ||
| + final var imageDn = keyDnImage( fileNamePrefixes.get( key ) ); | ||
| + final var imageUp = keyUpImage( fileNamePrefixes.get( key ) ); | ||
| - final var regularStates = new HardwareComponent<HardwareState, Image>(); | ||
| - regularStates.put( state( KEY_REGULAR, ANY_KEY ), keyDnImage( "short" ) ); | ||
| - regularStates.put( state( KEY_REGULAR, false ), keyUpImage( "short" ) ); | ||
| - mSwitches.put( KEY_REGULAR, regularStates ); | ||
| + hardwareComponent.put( stateOn, imageDn.getKey() ); | ||
| + hardwareComponent.put( stateOff, imageUp.getKey() ); | ||
| + | ||
| + mSwitches.put( key, hardwareComponent ); | ||
| + } | ||
| + } | ||
| + | ||
| + private HardwareComponent<HardwareState, Image> createHardwareComponent() { | ||
| + return new HardwareComponent<>(); | ||
| } | ||
| public HardwareComponent<HardwareState, Image> get( | ||
| final HardwareSwitch hwSwitch ) { | ||
| return mSwitches.get( hwSwitch ); | ||
| - } | ||
| - | ||
| - private HardwareState state( | ||
| - final HardwareSwitch name, final boolean state ) { | ||
| - return state( name, Boolean.toString( state ) ); | ||
| } | ||
| private HardwareState state( | ||
| final HardwareSwitch name, final String state ) { | ||
| return new HardwareState( name, state ); | ||
| } | ||
| private Image mouseImage( final String prefix ) { | ||
| - return createImage( format( "%s/%s", DIR_IMAGES_MOUSE, prefix ) ); | ||
| + final var imagePair = | ||
| + createImage( format( "%s/%s", DIR_IMAGES_MOUSE, prefix ) ); | ||
| + | ||
| + return imagePair.getKey(); | ||
| } | ||
| - private Image keyImage( | ||
| + private Pair<Image, DimensionTuple> keyImage( | ||
| final String state, final String prefix ) { | ||
| return createImage( | ||
| format( "%s/%s/%s", DIR_IMAGES_KEYBOARD, state, prefix ) | ||
| ); | ||
| } | ||
| - private Image keyUpImage( final String prefix ) { | ||
| + private Pair<Image, DimensionTuple> keyUpImage( final String prefix ) { | ||
| return keyImage( "up", prefix ); | ||
| } | ||
| - private Image keyDnImage( final String prefix ) { | ||
| + private Pair<Image, DimensionTuple> keyDnImage( final String prefix ) { | ||
| return keyImage( "dn", prefix ); | ||
| } | ||
| - private Image createImage( final String path ) { | ||
| + private Pair<Image, DimensionTuple> createImage( final String path ) { | ||
| final var resource = format( "%s.svg", path ); | ||
| try { | ||
| final var diagram = sRasterizer.loadDiagram( resource ); | ||
| final var scale = sRasterizer.calculateScale( diagram, mDimension ); | ||
| final var image = sRasterizer.rasterize( diagram, mDimension ); | ||
| - | ||
| - // TODO: Scale insets. | ||
| - return image; | ||
| + return new Pair<>( image, scale ); | ||
| } catch( final Exception ex ) { | ||
| rethrow( ex ); | ||
| * given {@code modifiers} value. | ||
| */ | ||
| - public boolean isPressed( final int modifiers ) { | ||
| + public boolean isModifierPressed( final int modifiers ) { | ||
| assert isModifier(); | ||
| return KEY_REGULAR; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns a list of all keyboard keys. | ||
| + * | ||
| + * @return The complete list of keyboard keys. | ||
| + */ | ||
| + public static HardwareSwitch[] keyboardKeys() { | ||
| + return new HardwareSwitch[]{KEY_ALT, KEY_CTRL, KEY_SHIFT, KEY_REGULAR}; | ||
| } | ||
| import com.kitfox.svg.SVGException; | ||
| import com.kitfox.svg.SVGUniverse; | ||
| -import com.whitemagicsoftware.kmcaster.ui.KmDimension; | ||
| +import com.whitemagicsoftware.kmcaster.ui.ScalableDimension; | ||
| +import com.whitemagicsoftware.kmcaster.ui.DimensionTuple; | ||
| import java.awt.*; | ||
| import java.awt.image.BufferedImage; | ||
| import java.net.URL; | ||
| -import java.util.AbstractMap; | ||
| import java.util.Map; | ||
| * @param diagram A 2-dimensional vector graphic having a width and height. | ||
| * @param dstDim The image's target dimensions. | ||
| - * @return A key-value pair of the source image dimensions with the | ||
| - * scaled image dimensions. | ||
| + * @return A key-value pair of the source image dimensions (key) and the | ||
| + * scaled image dimensions (value). | ||
| */ | ||
| - public Map.Entry<Dimension, Dimension> calculateScale( | ||
| + public DimensionTuple calculateScale( | ||
| final SVGDiagram diagram, final Dimension dstDim ) { | ||
| - final var srcDim = new KmDimension( | ||
| + final var srcDim = new ScalableDimension( | ||
| (int) diagram.getWidth(), (int) diagram.getHeight() | ||
| ); | ||
| - final var scaled = srcDim.scaleTo( dstDim ); | ||
| + final var scaled = srcDim.scale( dstDim ); | ||
| - return new AbstractMap.SimpleEntry<>( srcDim, scaled ); | ||
| + return new DimensionTuple( srcDim, scaled ); | ||
| } | ||
| /** | ||
| * Rasterizes a vector graphic to a given size using a {@link BufferedImage}. | ||
| * The rendering hints are set to produce high quality output. | ||
| * | ||
| - * @param diagram The diagram to rasterize. | ||
| - * @param dimensions The output image dimensions. | ||
| + * @param diagram The diagram to rasterize. | ||
| + * @param tuple The source and destination image dimensions. | ||
| * @return The rasterized {@link Image}. | ||
| * @throws SVGException Could not open, read, parse, or render SVG data. | ||
| */ | ||
| public BufferedImage rasterize( | ||
| - final SVGDiagram diagram, | ||
| - final Map.Entry<Dimension, Dimension> dimensions ) throws SVGException { | ||
| - final var scaled = dimensions.getValue(); | ||
| + final SVGDiagram diagram, final DimensionTuple tuple ) | ||
| + throws SVGException { | ||
| + final var scaled = tuple.getValue(); | ||
| final var wScaled = (int) scaled.getWidth(); | ||
| final var hScaled = (int) scaled.getHeight(); | ||
| final var image = new BufferedImage( wScaled, hScaled, TYPE_INT_ARGB ); | ||
| final var graphics = image.createGraphics(); | ||
| graphics.setRenderingHints( RENDERING_HINTS ); | ||
| - final var srcDim = dimensions.getKey(); | ||
| final var transform = graphics.getTransform(); | ||
| - transform.setToScale( wScaled / srcDim.getWidth(), | ||
| - hScaled / srcDim.getHeight() ); | ||
| + transform.setToScale( tuple.getWidthRatio(), tuple.getHeightRatio() ); | ||
| graphics.setTransform( transform ); | ||
| private void updateModifiers( final NativeKeyEvent e ) { | ||
| for( final var key : mModifiers.keySet() ) { | ||
| - final boolean down = key.isPressed( e.getModifiers() ); | ||
| + final boolean down = key.isModifierPressed( e.getModifiers() ); | ||
| tryFire( key, mModifiers.get( key ), down ); | ||
| mModifiers.put( key, down ); |
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster.ui; | ||
| + | ||
| +import com.whitemagicsoftware.kmcaster.util.Pair; | ||
| + | ||
| +import java.awt.*; | ||
| + | ||
| +/** | ||
| + * Convenience class for pairing two dimensions together. | ||
| + */ | ||
| +public class DimensionTuple extends Pair<Dimension, Dimension> { | ||
| + /** | ||
| + * Associates a new {@link Dimension} tuple. | ||
| + * | ||
| + * @param key The key for this key-value pairing. | ||
| + * @param value The value for this key-value pairing. | ||
| + */ | ||
| + public DimensionTuple( final Dimension key, final Dimension value ) { | ||
| + super( key, value ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the ratio of the value width to the key width. | ||
| + * | ||
| + * @return A unit-less ratio between the value and key widths. | ||
| + */ | ||
| + public double getWidthRatio() { | ||
| + return getValue().getWidth() / getKey().getWidth(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the ratio of the value height to the key height. | ||
| + * | ||
| + * @return A unit-less ratio between the value and key heights. | ||
| + */ | ||
| + public double getHeightRatio() { | ||
| + return getValue().getHeight() / getKey().getHeight(); | ||
| + } | ||
| +} | ||
| -/* | ||
| - * Copyright 2020 White Magic Software, Ltd. | ||
| - * | ||
| - * All rights reserved. | ||
| - * | ||
| - * Redistribution and use in source and binary forms, with or without | ||
| - * modification, are permitted provided that the following conditions are met: | ||
| - * | ||
| - * o Redistributions of source code must retain the above copyright | ||
| - * notice, this list of conditions and the following disclaimer. | ||
| - * | ||
| - * o Redistributions in binary form must reproduce the above copyright | ||
| - * notice, this list of conditions and the following disclaimer in the | ||
| - * documentation and/or other materials provided with the distribution. | ||
| - * | ||
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| - */ | ||
| -package com.whitemagicsoftware.kmcaster.ui; | ||
| - | ||
| -import java.awt.*; | ||
| - | ||
| -/** | ||
| - * Provides the ability to scale a dimension in relation to another | ||
| - * dimension. The dimensions are unit-less. | ||
| - */ | ||
| -public final class KmDimension extends Dimension { | ||
| - | ||
| - /** | ||
| - * Delegates construction to the superclass. | ||
| - * | ||
| - * @param w The dimension's width. | ||
| - * @param h The dimension's height. | ||
| - */ | ||
| - public KmDimension( final int w, final int h ) { | ||
| - super( w, h ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Delegates construction to this class. | ||
| - * | ||
| - * @param w The width, cast to an integer. | ||
| - * @param h The height, cast to an integer. | ||
| - */ | ||
| - @SuppressWarnings("unused") | ||
| - public KmDimension( final double w, final double h ) { | ||
| - this( (int) w, (int) h ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Scales the given source {@link Dimension} to the destination | ||
| - * {@link Dimension}, maintaining the aspect ratio with respect to | ||
| - * the best fit. | ||
| - * | ||
| - * @param dst The desired image dimensions to scale. | ||
| - * @return The given source dimensions scaled to the destination dimensions, | ||
| - * maintaining the aspect ratio. | ||
| - */ | ||
| - public Dimension scaleTo( final Dimension dst ) { | ||
| - final var srcWidth = getWidth(); | ||
| - final var srcHeight = getHeight(); | ||
| - | ||
| - // Determine the ratio that will have the best fit. | ||
| - final var ratio = Math.min( | ||
| - dst.getWidth() / srcWidth, dst.getHeight() / srcHeight | ||
| - ); | ||
| - | ||
| - // Scale both dimensions with respect to the best fit ratio. | ||
| - return new KmDimension( (int) (srcWidth * ratio), | ||
| - (int) (srcHeight * ratio) ); | ||
| - } | ||
| -} | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster.ui; | ||
| + | ||
| +import java.awt.*; | ||
| + | ||
| +/** | ||
| + * Provides the ability to scale a dimension in relation to another | ||
| + * dimension. The dimensions are unit-less. | ||
| + */ | ||
| +public final class ScalableDimension extends Dimension { | ||
| + | ||
| + /** | ||
| + * Delegates construction to the superclass. | ||
| + * | ||
| + * @param w The dimension's width. | ||
| + * @param h The dimension's height. | ||
| + */ | ||
| + public ScalableDimension( final int w, final int h ) { | ||
| + super( w, h ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Delegates construction to this class. | ||
| + * | ||
| + * @param w The width, cast to an integer. | ||
| + * @param h The height, cast to an integer. | ||
| + */ | ||
| + @SuppressWarnings("unused") | ||
| + public ScalableDimension( final double w, final double h ) { | ||
| + this( (int) w, (int) h ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Scales the given source {@link Dimension} to the destination | ||
| + * {@link Dimension}, maintaining the aspect ratio with respect to | ||
| + * the best fit. | ||
| + * | ||
| + * @param dst The desired image dimensions to scale. | ||
| + * @return The given source dimensions scaled to the destination dimensions, | ||
| + * maintaining the aspect ratio. | ||
| + */ | ||
| + public Dimension scale( final Dimension dst ) { | ||
| + final var srcWidth = getWidth(); | ||
| + final var srcHeight = getHeight(); | ||
| + | ||
| + // Determine the ratio that will have the best fit. | ||
| + final var ratio = Math.min( | ||
| + dst.getWidth() / srcWidth, dst.getHeight() / srcHeight | ||
| + ); | ||
| + | ||
| + // Scale both dimensions with respect to the best fit ratio. | ||
| + return new ScalableDimension( (int) (srcWidth * ratio), | ||
| + (int) (srcHeight * ratio) ); | ||
| + } | ||
| +} | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster.util; | ||
| + | ||
| +import java.util.AbstractMap; | ||
| +import java.util.Map; | ||
| + | ||
| +/** | ||
| + * Convenience class for pairing two objects together; this is a synonym for | ||
| + * {@link Map.Entry}. | ||
| + * | ||
| + * @param <K> The type of key to store in this pair. | ||
| + * @param <V> The type of value to store in this pair. | ||
| + */ | ||
| +public class Pair<K, V> extends AbstractMap.SimpleImmutableEntry<K, V> { | ||
| + /** | ||
| + * Associates a new key-value pair. | ||
| + * | ||
| + * @param key The key for this key-value pairing. | ||
| + * @param value The value for this key-value pairing. | ||
| + */ | ||
| + public Pair( final K key, final V value ) { | ||
| + super( key, value ); | ||
| + } | ||
| +} | ||
| Delta | 289 lines added, 151 lines removed, 138-line increase |
|---|