Код: Выделить всё
public void adicionarNovaTab(Ebook ebookSelecionado) {
try (PDDocument document = Loader.loadPDF(ebookSelecionado.getConteudo())) {
PDPageTree pages = document.getPages();
CustomTab customTab = new CustomTab(ebookSelecionado.getNome());
int pageNumber = 1;
ScrollPane scrollPane = new ScrollPane();
VBox vBox = new VBox();
vBox.setSpacing(20);
vBox.setMinWidth(Region.USE_COMPUTED_SIZE);
vBox.setMinHeight(Region.USE_COMPUTED_SIZE);
vBox.setMaxWidth(Region.USE_COMPUTED_SIZE);
vBox.setMaxHeight(Region.USE_COMPUTED_SIZE);
for (PDPage page : pages) {
Pane pane = new Pane();
Background background = new Background(new BackgroundFill(Paint.valueOf("WHITE"), null, null));
pane.setBackground(background);
double pageWidth = page.getMediaBox().getWidth();
double pageHeight = page.getMediaBox().getHeight();
pane.setPrefSize(pageWidth, pageHeight);
pane.setMinSize(pageWidth, pageHeight);
pane.setMaxSize(pageWidth, pageHeight);
List textoComCoordenadas = extrairTextoDaPagina(pageNumber, page, document);
textoComCoordenadas.forEach(texto -> {
Text text = new Text(String.valueOf(texto.getCaractere()));
text.setX(texto.getX());
text.setY(texto.getY());
if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(), texto.getFontSize());
text.setFont(font);
} else {
Font font = Font.font(texto.getFonte() != null && texto.getFonte().getNome() != null ? texto.getFonte().getNome() : "Arial",
texto.isBold() ? FontWeight.BOLD : FontWeight.NORMAL,
texto.isItalic() ? FontPosture.ITALIC : FontPosture.REGULAR,
texto.getFontSize());
text.setFont(font);
}
pane.getChildren().add(text);
});
vBox.getChildren().add(pane);
pageNumber++;
scrollPane.setContent(vBox);
scrollPane.setFitToWidth(true); // Ajusta a largura do conteúdo ao ScrollPane
scrollPane.setFitToHeight(true); // Ajusta a altura do conteúdo ao ScrollPane
customTab.setContent(scrollPane);
if (!tabPaneVisualizador.getTabs().contains(customTab)) {
tabPaneVisualizador.getTabs().add(customTab);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Код: Выделить всё
private List extrairTextoDaPagina(int numeroDaPagina, PDPage page, PDDocument document) throws IOException {
List textosComCoordenadas = new ArrayList();
PDResources resources = page.getResources();
Iterable fontNames = resources.getFontNames();
fontNames.forEach(font -> {
try {
PDFont pdFont = resources.getFont(font);
String nomeFonte = pdFont.getName();
boolean temMesmoNome = fontesDosEbooks.stream().anyMatch(fonte -> fonte.getNome().equals(nomeFonte));
if (!temMesmoNome && pdFont.getFontDescriptor() != null && pdFont.getFontDescriptor().getFontFile() != null) {
COSInputStream cosInputStream = pdFont.getFontDescriptor().getFontFile().createInputStream();
FonteDoEbook fonte = FonteDoEbook.builder().nome(nomeFonte).inputStream(cosInputStream).build();
fontesDosEbooks.add(fonte);
System.out.println("Adicionado uma fonte: " + nomeFonte);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
PDFTextStripper textStripper = new PDFTextStripper() {
@Override
protected void writeString(String text, List textPositions) throws IOException {
for (int i = 0; i < textPositions.size(); i++) {
TextPosition textPosition = textPositions.get(i);
float x = textPosition.getXDirAdj();
float y = textPosition.getYDirAdj();
boolean italic = false;
boolean forceBold = false;
float fontSize = textPosition.getFontSize();
final String nomeDaFonte = textPositions.get(i).getFont().getName();
if (textPosition.getFont().getFontDescriptor() != null) {
italic = textPosition.getFont().getFontDescriptor().isItalic();
forceBold = textPosition.getFont().getFontDescriptor().isForceBold();
if (!italic && nomeDaFonte.toLowerCase().contains("-it")) {
italic = true;
}
if (!forceBold && nomeDaFonte.toLowerCase().contains("bold")) {
forceBold = true;
}
}
TextoComCoordenadas.TextoComCoordenadasBuilder textoComCoordenadasBuilder =
TextoComCoordenadas.builder()
.caractere(text.charAt(i))
.x(x)
.y(y)
.fontSize(fontSize)
.bold(forceBold)
.italic(italic);
Optional first = fontesDosEbooks.stream()
.filter(fonte -> fonte.getNome().equals(nomeDaFonte)).findFirst();
if (first.isPresent())
textoComCoordenadasBuilder.fonte(first.get());
else {
FonteDoEbook fonte = FonteDoEbook.builder().nome(nomeDaFonte).build();
fontesDosEbooks.add(fonte);
}
textosComCoordenadas.add(textoComCoordenadasBuilder.build());
}
}
};
textStripper.setStartPage(numeroDaPagina);
textStripper.setEndPage(numeroDaPagina);
textStripper.getText(document);
return textosComCoordenadas;
}
Я думаю, что это настоящая проблема это правильный интервал между словами и шрифтом, и я не знаю, почему, потому что я использую этот foreach, чтобы получить все шрифты из PDF-файла, которые добавляются в PDF, потому что это не стандартный шрифт:
Код: Выделить всё
package br.com.danielschiavo.livrariavirtual.util;
import lombok.*;
import java.io.InputStream;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(of = "nome")
public class FonteDoEbook {
private InputStream inputStream;
private String nome;
}
Код: Выделить всё
package br.com.danielschiavo.livrariavirtual.util;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class TextoComCoordenadas {
private char caractere;
private float x;
private float y;
private float fontSize;
private boolean bold;
private boolean italic;
private FonteDoEbook fonte;
}
Код: Выделить всё
CESPXI+NimbusSanL-Regu
JNISHD+MinionPro-It
ADEOBE+MinionPro-Bold
QFIOSQ+NimbusMonL-Regu
SHIDIU+MinionPro-Regular
F81
CESPXI+NimbusSanL-Regu
Код: Выделить всё
05:48:46.158 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a99 (99) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a108 (108) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a97 (97) in font F81
05:48:46.160 [JavaFX Application Thread] WARN org.apache.pdfbox.pdmodel.font.PDSimpleFont -- No Unicode mapping for a115 (115) in font F81
Электронная книга открыта в моем приложении
Я уже пробовал, вместо использования объект COS InputStream, используя новый ByteArrayInputStream (здесь байты), но это тоже не сработало
Я уже записываю байты одного шрифта, которые я получаю из функции PDFBox, в foreach, который я упомянутое выше, в файл ttf и успешно открыл файл в FontForge.
Я уже пытался установить шрифт в текстовом объекте с помощью этого метода:
Код: Выделить всё
if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(), texto.getFontSize());
text.setStyle("-fx-font-family: " + texto.getFonte().getNome() + "; -fx-font-size: " + texto.getFontSize() + ";");
Код: Выделить всё
if (texto.getFonte() != null && texto.getFonte().getInputStream() != null) {
Font font = Font.loadFont(texto.getFonte().getInputStream(),texto.getFontSize());
text.setFont(font);
Подробнее здесь: https://stackoverflow.com/questions/785 ... -correctly
Мобильная версия