/* GanttProject is an opensource project management tool. License: GPL3 Copyright (C) 2003-2012 GanttProject Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package biz.ganttproject.core.chart.render; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.List; import java.util.Properties; import com.google.common.base.Supplier; import biz.ganttproject.core.chart.canvas.FontChooser; import biz.ganttproject.core.chart.canvas.Canvas.HAlignment; import biz.ganttproject.core.chart.canvas.Canvas.Label; import biz.ganttproject.core.chart.canvas.Canvas.Text; import biz.ganttproject.core.chart.canvas.Canvas.TextGroup; import biz.ganttproject.core.chart.canvas.Canvas.VAlignment; /** * Paints text labels. * @author Dmitry Barashev */ public class TextPainter { private Graphics2D myGraphics; private final Properties myProperties; private final TextLengthCalculatorImpl myTextLengthCalculator; private final Supplier<Font> myBaseFont; public TextPainter(Properties props, Supplier<Font> baseFont) { myProperties = props; myTextLengthCalculator = new TextLengthCalculatorImpl(null); myBaseFont = baseFont; } public void setGraphics(Graphics2D graphics) { myGraphics = graphics; myTextLengthCalculator.setGraphics(myGraphics); } public void paint(Text next) { Color foreColor = next.getForegroundColor(); if (foreColor == null) { foreColor = Color.BLACK; } myGraphics.setColor(foreColor); Style style = Style.getStyle(myProperties, next.getStyle()); Label[] labels = next.getLabels(myTextLengthCalculator); if (labels.length == 0) { return; } Label label = labels[0]; if (label == null) { return; } paint(next.getLeftX(), next.getBottomY(), next.getHAlignment(), next.getVAlignment(), next, label, style); } private void paint(int xleft, int ybottom, HAlignment alignHor, VAlignment alignVer, Text text, Label label, Style style) { label.setVisible(true); int textHeight = myGraphics.getFont().getSize(); Style.Padding padding = style.getPadding(); switch (alignHor) { case LEFT: xleft += padding.getLeft(); break; case CENTER: xleft = xleft - (label.lengthPx + padding.getX()) / 2 + padding.getLeft(); break; case RIGHT: xleft = xleft - (label.lengthPx + padding.getRight()); break; } switch (alignVer) { case CENTER: ybottom = ybottom + (textHeight + padding.getY()) / 2 - padding.getBottom(); break; case TOP: ybottom = ybottom + (textHeight + padding.getY()) + padding.getTop(); break; case BOTTOM: ybottom -= (padding.getBottom() + myGraphics.getFontMetrics().getDescent()); break; } Style.Color background = style.getBackgroundColor(text); Style.Borders border = style.getBorder(text); if (border != null || background != null) { int x = xleft - padding.getLeft(), y = ybottom - textHeight - padding.getTop(), w = label.lengthPx + padding.getX(), h = textHeight + padding.getY(); Color savedColor = myGraphics.getColor(); if (background != null) { myGraphics.setColor(background.get()); myGraphics.fillRect(x, y, w, h); } if (border != null) { RectangleRenderer.renderBorders(myGraphics, border, x, y, w, h); } myGraphics.setColor(savedColor); } myGraphics.drawString(label.text, xleft, ybottom); } public void paint(TextGroup textGroup) { TextLengthCalculatorImpl calculator = new TextLengthCalculatorImpl((Graphics2D) myGraphics.create()); FontChooser fontChooser = new FontChooser(myProperties, calculator, myBaseFont); textGroup.setFonts(fontChooser); for (int i = 0; i < textGroup.getLineCount(); i++) { paintTextLine(textGroup, i); } } private void paintTextLine(TextGroup textGroup, int lineNum) { List<Text> line = textGroup.getLine(lineNum); Font savedFont = myGraphics.getFont(); Color savedColor = myGraphics.getColor(); if (textGroup.getFont(lineNum) == null) { return; } myGraphics.setFont(textGroup.getFont(lineNum)); myGraphics.setColor(textGroup.getColor(lineNum)); List<Label[]> labelList = new ArrayList<Label[]>(); int maxIndex = Integer.MAX_VALUE; for (Text t : line) { Label[] labels = t.getLabels(myTextLengthCalculator); maxIndex = Math.min(maxIndex, labels.length); if (maxIndex == 0) { return; } labelList.add(labels); } for (int i = 0; i < labelList.size(); i++) { Label longest = labelList.get(i)[maxIndex - 1]; Text t = line.get(i); Style style = new Style(myProperties, t.getStyle()); paint(textGroup.getLeftX() + t.getLeftX(), textGroup.getBottomY(lineNum), t.getHAlignment(), t.getVAlignment(), t, longest, style); } myGraphics.setFont(savedFont); myGraphics.setColor(savedColor); } }