Add API to support multiple boxes
This commit is contained in:
parent
0af994b707
commit
ccae310017
3 changed files with 151 additions and 42 deletions
|
@ -5,6 +5,7 @@ import java.awt.font.FontRenderContext;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -17,12 +18,30 @@ class TextLineWrapImpl implements WordWrapper {
|
||||||
Graphics2D graphics2D,
|
Graphics2D graphics2D,
|
||||||
int width
|
int width
|
||||||
) {
|
) {
|
||||||
String source = String.join(" ", text.split("\n"));
|
return wrap(text, font, graphics2D,
|
||||||
List<Word> words = wordLengths(source.split(" "), font, graphics2D);
|
Collections.singletonList(
|
||||||
return wrapWords(words, width);
|
new Rectangle(width, width)))
|
||||||
|
.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> wrapWords(List<Word> words, int width) {
|
@Override
|
||||||
|
public List<List<String>> wrap(
|
||||||
|
String text,
|
||||||
|
Font font,
|
||||||
|
Graphics2D graphics2D,
|
||||||
|
List<Rectangle2D> boxes
|
||||||
|
) {
|
||||||
|
String source = String.join(" ", text.split("\n"));
|
||||||
|
List<Word> words = wordLengths(source.split(" "), font, graphics2D);
|
||||||
|
return wrapWords(words, boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<String>> wrapWords(
|
||||||
|
List<Word> words,
|
||||||
|
List<Rectangle2D> boxes
|
||||||
|
) {
|
||||||
|
Rectangle2D rectangle2D = boxes.get(0);
|
||||||
|
double width = rectangle2D.getWidth();
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
int end = 0;
|
int end = 0;
|
||||||
List<String> line = new ArrayList<>();
|
List<String> line = new ArrayList<>();
|
||||||
|
@ -36,9 +55,10 @@ class TextLineWrapImpl implements WordWrapper {
|
||||||
end += word.width;
|
end += word.width;
|
||||||
}
|
}
|
||||||
lines.add(String.join(" ", line));
|
lines.add(String.join(" ", line));
|
||||||
return lines.stream()
|
return Collections.singletonList(
|
||||||
.filter(l -> l.length() > 0)
|
lines.stream()
|
||||||
.collect(Collectors.toList());
|
.filter(l -> l.length() > 0)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Word> wordLengths(String[] words, Font font, Graphics2D graphics2D) {
|
private List<Word> wordLengths(String[] words, Font font, Graphics2D graphics2D) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.kemitix.text.fit;
|
package net.kemitix.text.fit;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface WordWrapper {
|
public interface WordWrapper {
|
||||||
|
@ -10,4 +11,10 @@ public interface WordWrapper {
|
||||||
Graphics2D graphics2D,
|
Graphics2D graphics2D,
|
||||||
int width
|
int width
|
||||||
);
|
);
|
||||||
|
List<List<String>> wrap(
|
||||||
|
String text,
|
||||||
|
Font font,
|
||||||
|
Graphics2D graphics2D,
|
||||||
|
List<Rectangle2D> boxes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
package net.kemitix.text.fit;
|
package net.kemitix.text.fit;
|
||||||
|
|
||||||
import org.assertj.core.api.WithAssertions;
|
import org.assertj.core.api.WithAssertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TextLineWrapTest
|
public class TextLineWrapTest
|
||||||
|
@ -30,44 +36,49 @@ public class TextLineWrapTest
|
||||||
.deriveFont(Font.PLAIN, fontSize);
|
.deriveFont(Font.PLAIN, fontSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> invoke(String in) {
|
@Nested
|
||||||
return textLineWrap.wrap(in, font, graphics2D, imageSize);
|
@DisplayName("Single box")
|
||||||
}
|
public class SingleBox {
|
||||||
|
|
||||||
@Test
|
private List<String> invoke(String in) {
|
||||||
@DisplayName("Empty String give empty List")
|
return textLineWrap.wrap(in, font, graphics2D, imageSize);
|
||||||
public void emptyStringEmptyList() {
|
}
|
||||||
assertThat(invoke("")).isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Short string fits on one line")
|
@DisplayName("Empty String give empty List")
|
||||||
public void shortStringOnOneLine() {
|
public void emptyStringEmptyList() {
|
||||||
assertThat(invoke("x")).containsExactly("x");
|
assertThat(invoke("")).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Longer string fits on two lines")
|
@DisplayName("Short string fits on one line")
|
||||||
public void longerStringOnTwoLines() {
|
public void shortStringOnOneLine() {
|
||||||
assertThat(invoke(
|
assertThat(invoke("x")).containsExactly("x");
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
}
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
|
||||||
.containsExactly(
|
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx",
|
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Longer string fits on three lines")
|
@DisplayName("Longer string fits on two lines")
|
||||||
public void longerStringOnThreeLines() {
|
public void longerStringOnTwoLines() {
|
||||||
assertThat(invoke(
|
assertThat(invoke(
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
.containsExactly(
|
||||||
.containsExactly(
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx",
|
"xxxxxxxxxxx xxxxxxxxxxxx");
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx",
|
}
|
||||||
"xxxxxxxxxxx xxxxxxxxxxxx");
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Longer string fits on three lines")
|
||||||
|
public void longerStringOnThreeLines() {
|
||||||
|
assertThat(invoke(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
||||||
|
.containsExactly(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Graphics2D graphics(int width, int height) {
|
private Graphics2D graphics(int width, int height) {
|
||||||
|
@ -78,4 +89,75 @@ public class TextLineWrapTest
|
||||||
private BufferedImage image(int width, int height) {
|
private BufferedImage image(int width, int height) {
|
||||||
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Overflowing Boxes")
|
||||||
|
public class OverflowingBoxes {
|
||||||
|
|
||||||
|
private List<Rectangle2D> boxes = new ArrayList<>();
|
||||||
|
|
||||||
|
private List<List<String>> invoke(String in) {
|
||||||
|
return textLineWrap.wrap(in, font, graphics2D, boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Single box")
|
||||||
|
public class SingleBox {
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
boxes.add(new Rectangle(imageSize, imageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Empty String give empty List")
|
||||||
|
public void emptyStringEmptyList() {
|
||||||
|
assertThat(invoke("")).containsExactly(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Short string fits on one line")
|
||||||
|
public void shortStringOnOneLine() {
|
||||||
|
assertThat(invoke("x"))
|
||||||
|
.containsExactly(Collections.singletonList("x"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Longer string fits on two lines")
|
||||||
|
public void longerStringOnTwoLines() {
|
||||||
|
assertThat(invoke(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
||||||
|
.containsExactly(Arrays.asList(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Longer string fits on three lines")
|
||||||
|
public void longerStringOnThreeLines() {
|
||||||
|
assertThat(invoke(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx " +
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx"))
|
||||||
|
.containsExactly(Arrays.asList(
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx",
|
||||||
|
"xxxxxxxxxxx xxxxxxxxxxxx"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Two boxes of equal width")
|
||||||
|
public class TwoEqualWidthBoxes {
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
Rectangle box = new Rectangle(imageSize, imageSize);
|
||||||
|
boxes.add(box);
|
||||||
|
boxes.add(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue