FontUtils { public static List<String> wrapLines(String rawLabel, PDFont font, float fontSize, double maxWidth, PDDocument document) throws TaskIOException { List<String> lines = new ArrayList<>(); String label = org.sejda.commons.util.StringUtils.normalizeWhitespace(rawLabel); StringBuilder currentString = new StringBuilder(); double currentWidth = 0; List<TextWithFont> resolvedStringsToFonts = FontUtils.resolveFonts(label, font, document); for (TextWithFont stringAndFont : resolvedStringsToFonts) { try { PDFont resolvedFont = stringAndFont.getFont(); String resolvedLabel = stringAndFont.getText(); if (isNull(resolvedFont)) { throw new UnsupportedTextException( "Unable to find suitable font for string \"" + resolvedLabel + "\"", resolvedLabel); } String[] words = visualToLogical(resolvedLabel).split("(?<=\\b)"); for (String word : words) { double textWidth = getSimpleStringWidth(word, resolvedFont, fontSize); if (textWidth > maxWidth || word.length() > 10) { Iterator<Integer> codePointIterator = word.codePoints().iterator(); while (codePointIterator.hasNext()) { int codePoint = codePointIterator.next(); String ch = new String(Character.toChars(codePoint)); double chWidth = getSimpleStringWidth(ch, resolvedFont, fontSize); if (currentWidth + chWidth > maxWidth) { currentString.append("-"); lines.add(currentString.toString().trim()); currentString = new StringBuilder(); currentWidth = 0; } currentWidth += chWidth; currentString.append(ch); } } else { if (currentWidth + textWidth > maxWidth) { lines.add(currentString.toString().trim()); currentString = new StringBuilder(); currentWidth = 0; } currentWidth += textWidth; currentString.append(word); } } } catch (IOException e) { throw new TaskIOException(e); } } if (!currentString.toString().isEmpty()) { lines.add(currentString.toString().trim()); } return lines; } private  FontUtils(); static PDType1Font getStandardType1Font(StandardType1Font st1Font); static PDFont fontOrFallback(String text, PDFont font, PDDocument document); static void clearLoadedFontCache(); static void clearLoadedFontCache(PDDocument document); static PDFont loadFont(PDDocument document, FontResource font); static final PDFont findFontFor(PDDocument document, String text); static boolean isOnlyWhitespace(String text); static String removeWhitespace(String text); static boolean canDisplaySpace(PDFont font); static boolean canDisplay(String text, PDFont font); static double calculateBBoxHeight(String text, PDFont font); static boolean isBold(PDFont font); static boolean isItalic(PDFont font); static List<String> wrapLines(String rawLabel, PDFont font, float fontSize, double maxWidth,
            PDDocument document); static double getSimpleStringWidth(String text, PDFont font, double fontSize); static List<TextWithFont> resolveFonts(String label, PDFont font, PDDocument document); static String removeUnsupportedCharacters(String text, PDDocument doc); static String replaceUnsupportedCharacters(String text, PDDocument doc, String replacement); static PDFont HELVETICA; static final FontResource[] TYPE0FONTS; }
@Test public void wrapping_Lines() throws TaskIOException { PDDocument doc = new PDDocument(); List<String> lines = FontUtils.wrapLines( "This is a long line that cannot fit on a single line and could be wrapped", HELVETICA, 10, 191, doc); assertThat(lines, is(Arrays.asList("This is a long line that cannot fit on a", "single line and could be wrapped"))); }
@Test public void wrapping_Lines_Without_Word_Break() throws TaskIOException { PDDocument doc = new PDDocument(); List<String> lines = FontUtils.wrapLines( "This_is_a_long_line_that_cannot_fit_on_a_single_line_and_could_be_wrapped", HELVETICA, 10, 191, doc); assertThat(lines, is(Arrays.asList("This_is_a_long_line_that_cannot_fit_on_a-", "_single_line_and_could_be_wrapped"))); }
@Test public void wrapping_Lines_Without_Word_Break_Or_Other_Delimiters() throws TaskIOException { PDDocument doc = new PDDocument(); List<String> lines = FontUtils.wrapLines("Thisisalonglinethatcannotfitonasinglelineandcouldbewrapped", HELVETICA, 10, 191, doc); assertThat(lines, is(Arrays.asList("Thisisalonglinethatcannotfitonasinglelinean-", "dcouldbewrapped"))); }
@Test public void wrapping_Lines_Words_Mixed_With_Super_Long_Words() throws TaskIOException { PDDocument doc = new PDDocument(); List<String> lines = FontUtils.wrapLines("This is a long linethatcannotfitonasinglelineandcouldbe wrapped", HELVETICA, 10, 191, doc); assertThat(lines, is(Arrays.asList("This is a long linethatcannotfitonasingleline-", "andcouldbe wrapped"))); }
@Test(expected = UnsupportedTextException.class) public void wrappingLinesUnableToFindFont() throws TaskIOException { PDDocument doc = new PDDocument(); FontUtils.wrapLines("This_is_a_long_line_that_cannot_fit_on_a_single_line_and_could_be_wrapped_հայերէն", HELVETICA, 10, 191, doc); }