Skip to content

Commit f910801

Browse files
authored
Add getOptionalCharacterWidth-method (#4)
1 parent 87f0a37 commit f910801

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<!-- === Project Coordinates === -->
88
<groupId>io.github.chrimle</groupId>
99
<artifactId>fontmeter</artifactId>
10-
<version>0.1.0-alpha.2</version>
10+
<version>0.1.0-alpha.3</version>
1111
<packaging>jar</packaging>
1212

1313
<!-- === Project Metadata === -->

src/main/java/io/github/chrimle/fontmeter/fonts/IFontMetrics.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.chrimle.fontmeter.fonts;
22

33
import java.util.Map;
4+
import java.util.Optional;
45

56
/**
67
* Just an abstraction-layer for {@link FontMetrics}. Contains the interfaces for the {@link
@@ -47,6 +48,46 @@ default Double getNullableCharacterWidth(final Character character, final int fo
4748
Double getNullableCharacterWidth(final char character, final int fontSize)
4849
throws IllegalArgumentException;
4950

51+
/**
52+
* Gets the <strong>width</strong> of the given {@code character} and {@code fontSize}. If the
53+
* {@code character} is not supported, {@link Optional#empty()} is returned. if the
54+
* <strong>width</strong> cannot be determined, by not having it pre-calculated, or if <em>this
55+
* instance</em> does not support "on-demand" calculations, then {@link Optional#empty()} is
56+
* returned.
57+
*
58+
* @param character to get the <strong>width</strong> of. <strong>MUST NOT</strong> be {@code
59+
* null}.
60+
* @param fontSize of the {@code character}. <strong>MUST</strong> be positive.
61+
* @return the width of the {@code character}, in <em>points (pt)</em>. <strong>MAY</strong> be
62+
* {@link Optional#empty()} if the {@code width} cannot be determined.
63+
* @throws NullPointerException if {@code character} is {@code null}.
64+
* @throws IllegalArgumentException if {@code fontSize} is negative, or zero.
65+
* @since 0.1.0
66+
*/
67+
default Optional<Double> getOptionalCharacterWidth(
68+
final Character character, final int fontSize) {
69+
return getOptionalCharacterWidth(character.charValue(), fontSize);
70+
}
71+
72+
/**
73+
* Gets the <strong>width</strong> of the given {@code character} and {@code fontSize}. If the
74+
* {@code character} is not supported, {@link Optional#empty()} is returned. if the
75+
* <strong>width</strong> cannot be determined, by not having it pre-calculated, or if <em>this
76+
* instance</em> does not support "on-demand" calculations, then {@link Optional#empty()} is
77+
* returned.
78+
*
79+
* @param character to get the <strong>width</strong> of. <strong>MUST NOT</strong> be {@code
80+
* null}.
81+
* @param fontSize of the {@code character}. <strong>MUST</strong> be positive.
82+
* @return the width of the {@code character}, in <em>points (pt)</em>. <strong>MAY</strong> be
83+
* {@link Optional#empty()} if the {@code width} cannot be determined.
84+
* @throws IllegalArgumentException if {@code fontSize} is negative, or zero.
85+
* @since 0.1.0
86+
*/
87+
default Optional<Double> getOptionalCharacterWidth(final char character, final int fontSize) {
88+
return Optional.ofNullable(getNullableCharacterWidth(character, fontSize));
89+
}
90+
5091
/**
5192
* The <em>Builder</em>-step for configuring the <em>baseline</em> for {@link IFontMetrics}. The
5293
* <em>baseline</em> is a {@link Map} of supported {@link Character}s and their respective

src/test/java/io/github/chrimle/fontmeter/fonts/FontMetricsTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,67 @@ void testSupportedFontSizeReturnsExpectedWidth() {
135135
}
136136
}
137137
}
138+
139+
@Nested
140+
class GetOptionalCharacterWidthTests {
141+
142+
private final IFontMetrics fontMetrics =
143+
FontMetrics.builder()
144+
.setBaseline(7, Map.of('x', 42d))
145+
.skipPreCalculation()
146+
.disableOnDemandCalculations()
147+
.build();
148+
149+
@Nested
150+
class CharacterTests {
151+
@Test
152+
void testNullCharacterThrowsNPE() {
153+
assertThrows(
154+
NullPointerException.class, () -> fontMetrics.getOptionalCharacterWidth(null, 7));
155+
}
156+
157+
@Test
158+
void testUnsupportedCharacterReturnsEmpty() {
159+
assertTrue(fontMetrics.getOptionalCharacterWidth('z', 7).isEmpty());
160+
}
161+
162+
@Test
163+
void testSupportedCharacterReturnsExpectedWidth() {
164+
assertEquals(42d, fontMetrics.getOptionalCharacterWidth('x', 7).orElseThrow());
165+
}
166+
}
167+
168+
@Nested
169+
class FontSizeTests {
170+
@ParameterizedTest
171+
@ValueSource(ints = {Integer.MIN_VALUE, -42, -7, -1})
172+
void testNegativeFontSizeThrowsIAE(final int fontSize) {
173+
assertThrows(
174+
IllegalArgumentException.class,
175+
() -> fontMetrics.getOptionalCharacterWidth('x', fontSize));
176+
}
177+
178+
@Test
179+
void testZeroFontSizeThrowsIAE() {
180+
assertThrows(
181+
IllegalArgumentException.class, () -> fontMetrics.getOptionalCharacterWidth('x', 0));
182+
}
183+
184+
@ParameterizedTest
185+
@ValueSource(ints = {1, 3, 7, 11, 42, Integer.MAX_VALUE})
186+
void testPositiveFontSizeDoesNotThrow(final int fontSize) {
187+
assertDoesNotThrow(() -> fontMetrics.getOptionalCharacterWidth('x', fontSize));
188+
}
189+
190+
@Test
191+
void testUnsupportedFontSizeReturnsEmpty() {
192+
assertTrue(fontMetrics.getOptionalCharacterWidth('x', 11).isEmpty());
193+
}
194+
195+
@Test
196+
void testSupportedFontSizeReturnsExpectedWidth() {
197+
assertEquals(42d, fontMetrics.getOptionalCharacterWidth('x', 7).orElseThrow());
198+
}
199+
}
200+
}
138201
}

0 commit comments

Comments
 (0)