From e358219a999d271f489dc6e3821aa9b76b2d39fe Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Tue, 28 Mar 2017 17:55:13 +0300 Subject: [PATCH] Added automatic text flipping option for text readability in TextNode refs #7112 Change-Id: I6027ff66e3bc60d81385088fcf072e09dff7e6a7 --- .../simantics/diagram/elements/TextNode.java | 160 ++++++------------ 1 file changed, 48 insertions(+), 112 deletions(-) diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java index 85923bc35..4554decee 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java @@ -34,7 +34,6 @@ import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.io.IOException; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.util.ArrayList; @@ -75,13 +74,7 @@ import org.simantics.ui.dnd.PlaintextTransfer; import org.simantics.ui.fonts.Fonts; import org.simantics.utils.threads.AWTThread; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Element; -import com.lowagie.text.Rectangle; -import com.lowagie.text.pdf.FontMapper; -import com.lowagie.text.pdf.PdfFormField; import com.lowagie.text.pdf.PdfWriter; -import com.lowagie.text.pdf.TextField; import gnu.trove.list.array.TIntArrayList; @@ -99,7 +92,6 @@ import gnu.trove.list.array.TIntArrayList; * TODO: * o proper support for defining clipping bounds for the text (needed for page templates) (currently through fixedWidth) * o fix editing xOffset to work with fixed width and multi-line text - * o * * @see Line * @see TextLayout @@ -108,6 +100,12 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L private static final long serialVersionUID = 654692698101485672L; + public static enum TextFlipping { + Disabled, + VerticalTextUpwards, + VerticalTextDownwards, + } + /** * TODO: justify existence for this */ @@ -191,6 +189,8 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L protected transient static final int STATE_X_OFFSET_IS_DIRTY = (1 << 7); protected static final int STATE_ALWAYS_ADD_LISTENERS = (1 << 8); protected static final int STATE_LISTENERS_ADDED = (1 << 9); + protected static final int STATE_AUTOMATIC_TEXT_FLIP_ENABLED = (1 << 10); + protected static final int STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN = (1 << 11); /** * A combination of all the STATE_ constants defined in this class, @@ -413,6 +413,21 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L resetCaches(); } + public void setAutomaticTextFlipping(TextFlipping type) { + switch (type) { + case Disabled: + clearState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED | STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN); + break; + case VerticalTextDownwards: + setState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED | STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN); + break; + case VerticalTextUpwards: + setState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED); + clearState(STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN); + break; + } + } + @SyncField({"paddingX", "paddingY"}) public void setPadding(double x, double y) { this.paddingX = x; @@ -628,7 +643,8 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L // Safety for not rendering when the scale of this text is too small. // When the scale is too small it will cause internal exceptions while // stroking fonts. - double currentScale = GeometryUtils.getScale(g.getTransform()); + AffineTransform curTr = g.getTransform(); + double currentScale = GeometryUtils.getScale(curTr); //System.out.println("currentScale: " + currentScale); if (currentScale < 1e-6) return; @@ -652,6 +668,27 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L r.setRect(x, y, w, h); } + if (hasState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED)) { + boolean needsXFlip; + boolean needsYFlip; + if (curTr.getScaleX() != 0) { + needsXFlip = curTr.getScaleX() < 0.0; + needsYFlip = curTr.getScaleY() < 0.0; + } else { + boolean flipAll = !hasState(STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN); + needsXFlip = (curTr.getShearY() < 0.0) ^ flipAll; + needsYFlip = (curTr.getShearX() > 0.0) ^ flipAll; + } + if (needsXFlip || needsYFlip) { + double centerX = r.getWidth()*0.5 + r.getX(); + double centerY = r.getHeight()*0.5 + r.getY(); + + g.translate(centerX, centerY); + g.scale(needsXFlip ? -1.0 : 1.0, needsYFlip ? -1.0 : 1.0); + g.translate(-centerX, -centerY); + } + } + Rectangle2D textClip = r.getBounds2D(); expandBoundsUnscaled(r); @@ -674,22 +711,12 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L // PDF PdfWriter writer = (PdfWriter) g.getRenderingHint(G2DPDFRenderingHints.KEY_PDF_WRITER); boolean isRenderingPdf = writer != null; - boolean isPdfField = false; - String fieldName = null; - if (writer != null) { - // TODO: replace this hack with proper text field name field - fieldName = NodeUtil.getNodeName(this); - isPdfField = ( fieldName.equals("approved_by") || - fieldName.equals("checked_by") || - fieldName.equals("designer name") || - fieldName.equals("created_by") ); - } + /// PDF Color backgroundColor = hasState(STATE_VALID) ? this.backgroundColor : Color.red; // RENDER - if ( !isPdfField ) { - + { // Fill background if necessary if (backgroundColor != null) { g.setColor(backgroundColor); @@ -727,10 +754,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L g.setClip(clip); - // Caret - renderCaret(g); - } else { @@ -740,95 +764,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L } } - } else { - // PDF - // TODO: multiline support -// try { - AffineTransform at = g.getTransform(); - float height = writer.getPageSize().getHeight(); - Rectangle2D rr = textClip; - // Point2D pt1 = new Point2D.Double(rr.getX(), rr.getY()+rr.getHeight()); - // Point2D pt2 = new Point2D.Double(rr.getX()+rr.getWidth(), rr.getY()); - Point2D pt1 = new Point2D.Double(0, 0); - Point2D pt2 = new Point2D.Double(47.f/*+rr.getWidth()*/, -rr.getHeight()); - pt1 = at.transform(pt1, pt1); - pt2 = at.transform(pt2, pt2); - Rectangle rectangle = new Rectangle( - (float) pt1.getX(), - height-(float) pt1.getY(), - (float) pt2.getX(), - height-(float) pt2.getY()); - - FontMapper mapper = (FontMapper) g.getRenderingHint(G2DPDFRenderingHints.KEY_PDF_FONTMAPPER); -// FontMetrics fm = g.getFontMetrics(font); - - // TODO Oikea leveys - // TODO Uniikki nimi - /* - PdfFormField field = PdfFormField.createTextField(writer, false, false, 20); - field.setFieldName(this.getId().toString()); - field.setWidget(rectangle, PdfAnnotation.HIGHLIGHT_NONE); - field.setQuadding(PdfFormField.Q_RIGHT); - field.setFieldFlags(PdfFormField.FF_READ_ONLY); - field.setRotate(90); - writer.addAnnotation(field); - */ - - - // Signature Field - /* - if (text==null) { - PdfFormField field = PdfFormField.createSignature(writer); - field.setWidget(rectangle, PdfAnnotation.HIGHLIGHT_NONE); - field.setFieldName(fieldName); - field.setQuadding(PdfFormField.Q_LEFT); - field.setFlags(PdfAnnotation.FLAGS_PRINT); - //field.setFieldFlags(PdfFormField.FF_READ_ONLY) - field.setFieldFlags(PdfFormField.FF_EDIT); - field.setPage(); - field.setMKBackgroundColor( backgroundColor!=null?Color.WHITE:backgroundColor ); - PdfAppearance tp = PdfAppearance.createAppearance(writer, 72, 48); - tp.rectangle(rectangle); - tp.stroke(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); - writer.addAnnotation(field); - } else */ - { - // Text Field - try { - TextField textField = new TextField(writer, rectangle, fieldName); - textField.setFieldName(fieldName); - textField.setFont(mapper.awtToPdf(font)); - textField.setBorderStyle(0); - //textField.setAlignment(Element.ALIGN_LEFT); - textField.setAlignment(Element.ALIGN_BOTTOM); - textField.setRotation(90); - textField.setOptions(TextField.EDIT|TextField.DO_NOT_SPELL_CHECK); - if ( text!=null ) { - textField.setText(text); - } - if ( color!=null ) { - textField.setTextColor(color); - } - textField.setBackgroundColor( backgroundColor!=null?Color.WHITE:backgroundColor ); - PdfFormField field = textField.getTextField(); - writer.addAnnotation(field); - } catch (IOException e) { - e.printStackTrace(); - } catch (DocumentException e) { - e.printStackTrace(); - } - } - -// } catch (IOException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (DocumentException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } } - /// PDF g.setClip(clipSave); -- 2.43.2