View Javadoc
1   /**
2    * 
3    */
4   package de.japrost.excerpt;
5   
6   import java.awt.Font;
7   import java.awt.Graphics2D;
8   import java.awt.Rectangle;
9   import java.awt.font.FontRenderContext;
10  import java.awt.font.LineBreakMeasurer;
11  import java.awt.font.TextAttribute;
12  import java.awt.font.TextLayout;
13  import java.text.AttributedCharacterIterator;
14  import java.text.AttributedString;
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  
19  /**
20   *
21   */
22  public class TextBlock implements RenderLine {
23  
24  	// +-+-+-+ "final" values
25  	private String text;
26  	private Font font;
27  	private Graphics2D graphics;
28  	private int pageWidth;
29  	private int lineSpace = 8;
30  
31  	// -+-+-+- properties
32  	private int align = 0;
33  
34  	// -+-+-+-+ other fields
35  	private Rectangle bounds = null;
36  	private TextLayout tl;
37  	private List<Line> textLines = new ArrayList<Line>();
38  	private boolean initialized = false;
39  	private int paragraphStart;
40  	private int paragraphEnd;
41  	private LineBreakMeasurer lineMeasurer;
42  
43  	public TextBlock() {
44  	};
45  
46  	public TextBlock(final String text, final ImageMaker maker, final Graphics2D g, final int align) {
47  		super();
48  		this.text = text;
49  		graphics = g;
50  		this.align = align;
51  		font = new Font("Times New Roman", Font.ITALIC, maker.getSizeBase());
52  		init();
53  	}
54  
55  	public void init() {
56  		FontRenderContext frc = graphics.getFontRenderContext();
57  		float heigth = 0;
58  		float width = 0;
59  		// TODO allow empty lines?
60  		// TODO allow higher line width
61  		// TODO line hight more constant!
62  		String[] forcedLines = text.split("\\\\"); //$NON-NLS-1$
63  		for (String forcedLine : forcedLines) {
64  			if (forcedLine.startsWith("/")) {
65  				forcedLine = forcedLine.substring(1);
66  				textLines.get(textLines.size() - 1).lineSpace = lineSpace * 2;
67  				heigth += lineSpace;
68  			}
69  
70  			AttributedString aText = new AttributedString(forcedLine.trim());
71  			aText.addAttribute(TextAttribute.FONT, font);
72  			AttributedCharacterIterator paragraph = aText.getIterator();
73  			paragraphStart = paragraph.getBeginIndex();
74  			paragraphEnd = paragraph.getEndIndex();
75  
76  			lineMeasurer = new LineBreakMeasurer(paragraph, frc);
77  			lineMeasurer.setPosition(paragraphStart);
78  			while (lineMeasurer.getPosition() < paragraphEnd) {
79  				TextLayout layout = lineMeasurer.nextLayout(pageWidth);
80  
81  				System.out.println("###### " + layout.toString());
82  				Line line = new Line();
83  				line.lineSpace = lineSpace;
84  				line.textLayout = layout;
85  				textLines.add(line);
86  				// FIXME hight / BASE calculation is not accurate
87  				heigth += layout.getPixelBounds(frc, 0f, 0f).height + line.lineSpace;
88  				width = layout.getPixelBounds(frc, 0f, 0f).width > width ? layout.getPixelBounds(frc, 0f, 0f).width : width;
89  			}
90  
91  		}
92  		bounds = new Rectangle((int)width, (int)heigth);
93  		initialized = true;
94  	}
95  
96  	public void render(final Rectangle borders) {
97  		System.out.println("tb start " + borders);
98  		int currX = borders.x;
99  		int currY = borders.y;
100 		for (Line line : textLines) {
101 			TextLayout textLayout = line.textLayout;
102 			// FIXME later: rethink correctness (on pixelbase) of calculations
103 			float realY = (float)(currY - textLayout.getBounds().getY());
104 			System.out.println("L-B" + textLayout.getBounds());
105 			System.out.println("L-X" + textLayout.getBounds().getX());
106 			float realX = currX;
107 			if (align == 0) {
108 				realX = (float)((currX + borders.width / 2) - (textLayout.getBounds().getWidth() / 2));
109 			} else if (align == 1) {
110 				realX = (float)((currX + borders.width) - (textLayout.getBounds().getWidth()));
111 			}
112 
113 			System.out.println("L-Rx" + realX);
114 			textLayout.draw(graphics, realX, realY);
115 			currY = currY + textLayout.getPixelBounds(graphics.getFontRenderContext(), 0f, 0f).height + line.lineSpace;
116 		}
117 	}
118 
119 	public Rectangle getBounds() {
120 		System.out.println("tb bounds" + bounds);
121 		return bounds;
122 	}
123 
124 	/**
125 	 * {@inheritDoc}
126 	 */
127 	@Override
128 	public int expand() {
129 		return 0;
130 	}
131 
132 	/**
133 	 * {@inheritDoc}
134 	 */
135 	@Override
136 	public int height() {
137 		System.out.println("TextBlock-Bounds:" + bounds);
138 		System.out.println("TextBlock-height:" + bounds.height);
139 		return bounds.height;
140 	}
141 
142 	/**
143 	 * {@inheritDoc}
144 	 */
145 	public int align() {
146 		return getAlign();
147 	}
148 
149 	/**
150 	 * {@inheritDoc}
151 	 */
152 	@Override
153 	public int width() {
154 		return bounds.width;
155 	}
156 
157 	// +-+-+-+-+- Setters for inital configuration (with getters) +-+-+-+-+-+-
158 
159 	public String getText() {
160 		return text;
161 	}
162 
163 	public void setText(final String text) {
164 		if (initialized) {
165 			throw new IllegalStateException("Text of TextBlock already initialized");
166 		}
167 		this.text = text;
168 	}
169 
170 	public Font getFont() {
171 		return font;
172 	}
173 
174 	public void setFont(final Font font) {
175 		if (initialized) {
176 			throw new IllegalStateException("Text of TextBlock already initialized");
177 		}
178 		this.font = font;
179 	}
180 
181 	public Graphics2D getGraphics() {
182 		return graphics;
183 	}
184 
185 	public void setGraphics(final Graphics2D graphics) {
186 		if (initialized) {
187 			throw new IllegalStateException("Text of TextBlock already initialized");
188 		}
189 		this.graphics = graphics;
190 	}
191 
192 	// +-+-+-+-+- Getters and Setters  +-+-+-+-+-+-
193 
194 	public int getAlign() {
195 		return align;
196 	}
197 
198 	public void setAlign(final int align) {
199 		this.align = align;
200 	}
201 
202 	/**
203 	 * @param pageWidth the pageWidth to set
204 	 */
205 	public void setPageWidth(final int pageWidth) {
206 		this.pageWidth = pageWidth;
207 	}
208 
209 	/**
210 	 * Get the pageWidth.
211 	 * 
212 	 * @return the pageWidth.
213 	 */
214 	public int getPageWidth() {
215 		return pageWidth;
216 	}
217 
218 	class Line {
219 
220 		TextLayout textLayout;
221 		int lineSpace;
222 	}
223 }