001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * RevalidateTextEllipseProcessStep.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.layout.process;
030:
031: import org.jfree.report.layout.TextCache;
032: import org.jfree.report.layout.model.RenderBox;
033: import org.jfree.report.layout.model.InlineRenderBox;
034: import org.jfree.report.layout.model.RenderNode;
035: import org.jfree.report.layout.model.context.StaticBoxLayoutProperties;
036: import org.jfree.report.layout.model.context.BoxDefinition;
037: import org.jfree.report.layout.output.OutputProcessorMetaData;
038: import org.jfree.report.layout.text.RenderableTextFactory;
039: import org.jfree.report.layout.text.DefaultRenderableTextFactory;
040: import org.jfree.report.style.StyleSheet;
041: import org.jfree.report.style.TextStyleKeys;
042: import org.jfree.fonts.encoding.CodePointBuffer;
043: import org.jfree.fonts.encoding.manual.Utf16LE;
044:
045: /**
046: * Creation-Date: 31.07.2007, 19:09:52
047: *
048: * @author Thomas Morgner
049: */
050: public class RevalidateTextEllipseProcessStep extends
051: IterateStructuralProcessStep {
052: private long contentAreaX1;
053: private long contentAreaX2;
054: private TextCache textCache;
055: private RenderableTextFactory textFactory;
056: private CodePointBuffer buffer;
057:
058: public RevalidateTextEllipseProcessStep(
059: final OutputProcessorMetaData metaData) {
060: this .textCache = new TextCache();
061: this .textFactory = new DefaultRenderableTextFactory(metaData);
062: }
063:
064: public void compute(final RenderBox box, final long contentAreaX1,
065: final long contentAreaX2) {
066: this .contentAreaX1 = contentAreaX1;
067: this .contentAreaX2 = contentAreaX2;
068: startProcessing(box);
069: }
070:
071: public long getContentAreaX1() {
072: return contentAreaX1;
073: }
074:
075: public long getContentAreaX2() {
076: return contentAreaX2;
077: }
078:
079: protected boolean startInlineBox(final InlineRenderBox box) {
080: // compute the box's text-ellipse if necessary.
081: if (box.getTextEllipseBox() != null) {
082: return false;
083: }
084:
085: final StaticBoxLayoutProperties sblp = box
086: .getStaticBoxLayoutProperties();
087: final BoxDefinition bdef = box.getBoxDefinition();
088: final long boxContentX2 = (box.getX() + box.getWidth()
089: - bdef.getPaddingRight() - sblp.getBorderRight());
090: if (boxContentX2 > getContentAreaX2()) {
091: // This is an overflow. Compute the text-ellipse ..
092: final RenderBox textEllipseBox = processTextEllipse(box,
093: getContentAreaX2());
094: box.setTextEllipseBox(textEllipseBox);
095: }
096: return true;
097: }
098:
099: private RenderBox processTextEllipse(final RenderBox box,
100: final long x2) {
101: final StyleSheet style = box.getStyleSheet();
102: final String reslit = (String) style
103: .getStyleProperty(TextStyleKeys.RESERVED_LITERAL);
104: if (reslit == null || "".equals(reslit)) {
105: // oh, no ellipse. Thats nice.
106: return null;
107: }
108:
109: final RenderBox textEllipse = (RenderBox) box.derive(false);
110: final TextCache.Result result = textCache.get(style.getId(),
111: style.getChangeTracker(), reslit);
112: if (result != null) {
113: textEllipse.addGeneratedChilds(result.getText());
114: textEllipse.addGeneratedChilds(result.getFinish());
115: performTextEllipseLayout(textEllipse, x2);
116: return textEllipse;
117: }
118: if (buffer != null) {
119: buffer.setCursor(0);
120: }
121:
122: buffer = Utf16LE.getInstance().decodeString(reslit, buffer);
123: final int[] data = buffer.getBuffer();
124:
125: textFactory.startText();
126: final RenderNode[] renderNodes = textFactory.createText(data,
127: 0, buffer.getLength(), style);
128: final RenderNode[] finishNodes = textFactory.finishText();
129:
130: textEllipse.addGeneratedChilds(renderNodes);
131: textEllipse.addGeneratedChilds(finishNodes);
132: textCache.store(style.getId(), style.getChangeTracker(),
133: reslit, style, renderNodes, finishNodes);
134: performTextEllipseLayout(textEllipse, x2);
135: return textEllipse;
136: }
137:
138: private void performTextEllipseLayout(final RenderBox box,
139: final long x2) {
140: // we do assume that the text-ellipse box is a simple box with no sub-boxes.
141: if (box == null) {
142: return;
143: }
144: long x = x2;
145: RenderNode node = box.getLastChild();
146: while (node != null) {
147: final long nodeWidth = node.getMaximumBoxWidth();
148: node.setX(x - nodeWidth);
149: node.setWidth(node.getMaximumBoxWidth());
150: node.setY(box.getY());
151: node.setHeight(box.getHeight());
152:
153: node = node.getNext();
154: x -= nodeWidth;
155: }
156: box.setX(x);
157: box.setWidth(x2 - x);
158: box.setContentAreaX1(x);
159: box.setContentAreaX2(x2 - x);
160: }
161:
162: }
|