diff --git a/src/main/java/net/kemitix/text/fit/NotEnoughSpace.java b/src/main/java/net/kemitix/text/fit/NotEnoughSpace.java new file mode 100644 index 0000000..f3defe5 --- /dev/null +++ b/src/main/java/net/kemitix/text/fit/NotEnoughSpace.java @@ -0,0 +1,10 @@ +package net.kemitix.text.fit; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class NotEnoughSpace extends RuntimeException { + private final int excessWordCount; +} diff --git a/src/main/java/net/kemitix/text/fit/TextLineWrapImpl.java b/src/main/java/net/kemitix/text/fit/TextLineWrapImpl.java index 2357acb..001b5f3 100644 --- a/src/main/java/net/kemitix/text/fit/TextLineWrapImpl.java +++ b/src/main/java/net/kemitix/text/fit/TextLineWrapImpl.java @@ -41,7 +41,7 @@ class TextLineWrapImpl implements WordWrapper { List boxes ) { Deque wordQ = new ArrayDeque<>(words); - return boxes.stream() + List> wrappings = boxes.stream() .map(rectangle2D -> { double width = rectangle2D.getWidth(); double height = rectangle2D.getHeight(); @@ -68,6 +68,10 @@ class TextLineWrapImpl implements WordWrapper { lines.add(wordsAsString(lineQ)); return removeBlankLines(lines); }).collect(Collectors.toList()); + if (wordQ.isEmpty()) { + return wrappings; + } + throw new NotEnoughSpace(wordQ.size()); } private List removeBlankLines(List lines) { diff --git a/src/main/java/net/kemitix/text/fit/WordWrapper.java b/src/main/java/net/kemitix/text/fit/WordWrapper.java index b17ffa1..cd41e7f 100644 --- a/src/main/java/net/kemitix/text/fit/WordWrapper.java +++ b/src/main/java/net/kemitix/text/fit/WordWrapper.java @@ -5,12 +5,37 @@ import java.awt.geom.Rectangle2D; import java.util.List; public interface WordWrapper { + /** + * Wraps the text using the font in the graphics context to fit within the + * width. + * + * @param text the text to be line wrapped + * @param font the font to calculate character widths from + * @param graphics2D the context into which the font would be rendered + * @param width the maximum width of each line in pixels + * @return a list of the each line of text + * @throws NotEnoughSpace if there are more than {@link Integer#MAX_VALUE} + * lines - so not likely. + */ List wrap( String text, Font font, Graphics2D graphics2D, int width ); + + /** + * Wraps the text using the font in the graphics context to fit within the + * boxes, filling them in order. + * + * @param text the text to be line wrapped + * @param font the font to calculate character widths from + * @param graphics2D the context into which the font would be rendered + * @param boxes the list of rectangles to fit each line within. + * @return a list of the each line of text + * @throws NotEnoughSpace if there are more lines than can be fitted in the + * boxes provided. + */ List> wrap( String text, Font font, diff --git a/src/test/java/net/kemitix/text/fit/TextLineWrapTest.java b/src/test/java/net/kemitix/text/fit/TextLineWrapTest.java index 8314a2c..30ac6b8 100644 --- a/src/test/java/net/kemitix/text/fit/TextLineWrapTest.java +++ b/src/test/java/net/kemitix/text/fit/TextLineWrapTest.java @@ -199,9 +199,12 @@ public class TextLineWrapTest @DisplayName("Text overflows the box") public void tooManyLinesForBox() { String lineOfWords = words(wordsPerLine, WORD); - assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> - words(linesPerBox + 1, lineOfWords)); + String input = words(linesPerBox + 1, lineOfWords); + assertThatExceptionOfType(NotEnoughSpace.class) + .isThrownBy(() -> wrap(input)) + .satisfies(error -> + assertThat(error.getExcessWordCount()) + .isEqualTo(wordsPerLine)); } }