Closed c4da closed 3 years ago
Hey @c4da,
it could easily be the case that there is still something missing here. I implemented the vertical text cells a long long time ago merely for playing around. Therefore I also mention its experimental state.
Without having had a closer look I guess it shouldn't be too hard to correct this bug or missing code.
If I find some time I will look a bit deeper into it.
Best, Stefan
Hi @vandeseer it seems that I have found the missing pieces and fixed it. Should I post the code here?
Yes, please! Or just open a pull request :)
package org.vandeseer.easytable.drawing.cell;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.vandeseer.easytable.drawing.DrawingContext;
import org.vandeseer.easytable.settings.VerticalAlignment;
import org.vandeseer.easytable.structure.cell.VerticalTextCell;
import org.vandeseer.easytable.util.PdfUtil;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import static org.vandeseer.easytable.settings.HorizontalAlignment.*;
/**
* Allows vertical text drawing. Note that this class is still not fully
* developed, e.g. there is no support for text alignment settings yet.
*/
@NoArgsConstructor
public class VerticalTextCellDrawer extends AbstractCellDrawer<VerticalTextCell> {
public VerticalTextCellDrawer(VerticalTextCell cell) {
this.cell = cell;
}
/**
* Does not yet support the settings of alignments.
*
* @param drawingContext
*/
@Override
@SneakyThrows
public void drawContent(DrawingContext drawingContext) {
final float startX = drawingContext.getStartingPoint().x;
final float startY = drawingContext.getStartingPoint().y;
final PDFont currentFont = cell.getFont();
final int currentFontSize = cell.getFontSize();
final Color currentTextColor = cell.getTextColor();
float yOffset = startY + cell.getPaddingBottom();
float height = cell.getRow().getHeight();
if (cell.getRowSpan() > 1) {
float rowSpanAdaption = cell.calculateHeightForRowSpan() - cell.getRow().getHeight();
yOffset -= rowSpanAdaption;
height = cell.calculateHeightForRowSpan();
}
final List<String> lines = cell.isWordBreak()
? PdfUtil.getOptimalTextBreakLines(cell.getText(), currentFont, currentFontSize, (height - cell.getVerticalPadding()))
: Collections.singletonList(cell.getText());
float textHeight = 0;
for (String line: lines) {
float currentHeight = PdfUtil.getStringWidth(line, currentFont, currentFontSize);
textHeight = currentHeight>textHeight?currentHeight:textHeight;
}
if (cell.isVerticallyAligned(VerticalAlignment.MIDDLE)) {
yOffset += (height - textHeight - cell.getPaddingTop() - cell.getPaddingBottom()) / 2;
}else if (cell.isVerticallyAligned(VerticalAlignment.TOP)) {
yOffset += (height - textHeight - cell.getPaddingTop() - cell.getPaddingBottom());
}
float xOffset = startX + cell.getPaddingLeft() - PdfUtil.getFontHeight(currentFont, currentFontSize);
float textWidth = (PdfUtil.getFontHeight(currentFont, currentFontSize) // font height
+ PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing())*lines.size(); // line spacing;
if (cell.isHorizontallyAligned(CENTER)) {
xOffset = xOffset + ((cell.getWidth() - cell.getPaddingRight() - cell.getPaddingLeft())/ 2 - textWidth/2) ;
} else if (cell.isHorizontallyAligned(RIGHT)) {
xOffset = xOffset + cell.getWidth() - cell.getPaddingRight() - cell.getPaddingLeft() - textWidth;
}
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
xOffset += (
PdfUtil.getFontHeight(currentFont, currentFontSize) // font height
+ (i > 0 ? PdfUtil.getFontHeight(currentFont, currentFontSize) * cell.getLineSpacing() : 0f) // line spacing
);
drawText(line, currentFont, currentFontSize, currentTextColor, xOffset, yOffset, drawingContext.getContentStream());
}
}
// TODO this is currently not used!
@Override
protected float calculateInnerHeight() {
return 0;
}
protected void drawText(String text, PDFont font, int fontSize, Color color, float x, float y, PDPageContentStream contentStream) throws IOException {
// Rotate by 90 degrees counter clockwise
final AffineTransform transform = AffineTransform.getTranslateInstance(x, y);
transform.concatenate(AffineTransform.getRotateInstance(Math.PI * 0.5));
transform.concatenate(AffineTransform.getTranslateInstance(-x, -y - fontSize));
contentStream.moveTo(x, y);
contentStream.beginText();
// Do the transformation :)
contentStream.setTextMatrix(transform);
contentStream.setNonStrokingColor(color);
contentStream.setFont(font, fontSize);
contentStream.newLineAtOffset(x, y);
contentStream.showText(text);
contentStream.endText();
contentStream.setCharacterSpacing(0);
}
}
Thanks a lot, I will have look!
Looks good to me! :+1: :smiley:
I will push the change to the develop
branch and the next release of easytable will contain it.
Thanks for your help! Mentioned you in the README kudos section :wink:
Hi, It seems that using .horizontalAlignment(HorizontalAlignment.CENTER).verticalAlignment(VerticalAlignment.MIDDLE) on VerticalTextCell has no effect.
The text in VerticalTextCell is always aligned to the bottom left. I have tried this also on the example code. Am I doing something wrong?