00001 package edu.stanford.hci.r3.render.regions;
00002
00003 import java.awt.Color;
00004 import java.awt.Font;
00005 import java.awt.Graphics2D;
00006 import java.awt.font.FontRenderContext;
00007 import java.awt.font.LineBreakMeasurer;
00008 import java.awt.font.LineMetrics;
00009 import java.awt.font.TextAttribute;
00010 import java.awt.font.TextLayout;
00011 import java.text.AttributedCharacterIterator;
00012 import java.text.AttributedString;
00013
00014 import edu.stanford.hci.r3.paper.regions.TextRegion;
00015 import edu.stanford.hci.r3.render.RegionRenderer;
00016 import edu.stanford.hci.r3.units.Points;
00017
00029 public class TextRenderer extends RegionRenderer {
00030
00031 private Font font;
00032
00036 private LineMetrics lineMetrics;
00037
00038 private String text;
00039
00043 private Color textColor;
00044
00048 public TextRenderer(TextRegion tr) {
00049 super(tr);
00050 region = tr;
00051 text = tr.getText();
00052 font = tr.getFont();
00053 textColor = tr.getColor();
00054 lineMetrics = font.getLineMetrics(text, new FontRenderContext(null, true, true));
00055 }
00056
00060 public Points getAscentInPoints() {
00061 return new Points(lineMetrics.getAscent());
00062 }
00063
00067 public Points getLineHeightInPoints() {
00068 return new Points(lineMetrics.getHeight());
00069 }
00070
00074 public void renderToG2D(Graphics2D g2d) {
00075 if (RegionRenderer.DEBUG_REGIONS) {
00076 super.renderToG2D(g2d);
00077 }
00078
00079 final TextRegion tr = (TextRegion) region;
00080
00081
00082 final Font oldFont = g2d.getFont();
00083
00084 g2d.setColor(textColor);
00085
00086 if (!tr.isLineWrapped()) {
00087 g2d.setFont(tr.getFont());
00088
00089
00090 final double offset = getAscentInPoints().getValue();
00091 final double textLineHeight = getLineHeightInPoints().getValue();
00092
00093
00094 final String[] linesOfText = tr.getLinesOfText();
00095 final int xOffset = (int) Math.round(tr.getX().getValueInPoints());
00096 double yOffset = tr.getY().getValueInPoints() + offset;
00097 for (String line : linesOfText) {
00098 g2d.drawString(line, xOffset, (int) Math.round(yOffset));
00099 yOffset += textLineHeight;
00100 }
00101
00102 } else {
00103 float xOffset, yOffset, maxYOffset, wrappingWidth, linebreakOffset;
00104 xOffset = (float) tr.getX().getValueInPoints();
00105 yOffset = (float) tr.getY().getValueInPoints();
00106 maxYOffset = yOffset + (float) tr.getHeight().getValueInPoints();
00107 wrappingWidth = (float) tr.getWidth().getValueInPoints();
00108
00109 FontRenderContext frc = g2d.getFontRenderContext();
00110
00111 final String[] linesOfText = tr.getLinesOfText();
00112
00113
00114
00115
00116
00117 boolean done = false;
00118 int lineCount = 0;
00119 linebreakOffset = 0.0f;
00120 for (String line : linesOfText) {
00121
00122
00123 if (line.length() == 0) line = " ";
00124
00125
00126 AttributedString styledText = new AttributedString(line);
00127 AttributedCharacterIterator styledTextIterator = styledText.getIterator();
00128 styledText.addAttribute(TextAttribute.FONT, tr.getFont());
00129
00130 LineBreakMeasurer measurer = new LineBreakMeasurer(styledTextIterator, frc);
00131
00132 while (measurer.getPosition() < styledTextIterator.getEndIndex()) {
00133
00134 TextLayout layout = measurer.nextLayout(wrappingWidth);
00135 linebreakOffset = (layout.getAscent() + layout.getDescent() + layout.getLeading())/2;
00136 yOffset += (layout.getAscent());
00137 float dx = layout.isLeftToRight() ? 0 : (wrappingWidth - layout.getAdvance());
00138
00139
00140 if (yOffset > maxYOffset) {
00141 done = true;
00142 break;
00143 }
00144
00145
00146 layout.draw(g2d, xOffset + dx, yOffset);
00147
00148
00149 yOffset += layout.getDescent() + layout.getLeading();
00150 lineCount++;
00151 if (tr.getMaxLines() > 0 && lineCount >= tr.getMaxLines()) {
00152 done = true;
00153 break;
00154 }
00155 }
00156
00157 yOffset += linebreakOffset;
00158
00159 if (done) break;
00160 }
00161
00162 }
00163
00164
00165 g2d.setFont(oldFont);
00166 }
00167
00168 }