1
24 package net.sf.jasperreports.engine.util;
25
26 import java.util.Locale;
27
28 import net.sf.jasperreports.annotations.properties.Property;
29 import net.sf.jasperreports.annotations.properties.PropertyScope;
30 import net.sf.jasperreports.engine.JRCommonText;
31 import net.sf.jasperreports.engine.JRException;
32 import net.sf.jasperreports.engine.JRPrintText;
33 import net.sf.jasperreports.engine.JRPropertiesHolder;
34 import net.sf.jasperreports.engine.JRPropertiesUtil;
35 import net.sf.jasperreports.engine.JRRuntimeException;
36 import net.sf.jasperreports.engine.JRStyledTextAttributeSelector;
37 import net.sf.jasperreports.engine.JasperReportsContext;
38 import net.sf.jasperreports.engine.fill.JRMeasuredText;
39 import net.sf.jasperreports.engine.fill.JRTextMeasurer;
40 import net.sf.jasperreports.properties.PropertyConstants;
41
42
49 public final class JRTextMeasurerUtil
50 {
51 private final JasperReportsContext jasperReportsContext;
52 private final JRStyledTextAttributeSelector noBackcolorSelector;
53 private final JRStyledTextUtil styledTextUtil;
54
55
56
59 private JRTextMeasurerUtil(JasperReportsContext jasperReportsContext)
60 {
61 this.jasperReportsContext = jasperReportsContext;
62 this.noBackcolorSelector = JRStyledTextAttributeSelector.getNoBackcolorSelector(jasperReportsContext);
63 this.styledTextUtil = JRStyledTextUtil.getInstance(jasperReportsContext);
64 }
65
66
67
70 public static JRTextMeasurerUtil getInstance(JasperReportsContext jasperReportsContext)
71 {
72 return new JRTextMeasurerUtil(jasperReportsContext);
73 }
74
75
76
98 @Property(
99 category = PropertyConstants.CATEGORY_FILL,
100 defaultValue = "net.sf.jasperreports.engine.fill.TextMeasurerFactory",
101 scopes = {PropertyScope.CONTEXT, PropertyScope.REPORT, PropertyScope.TEXT_ELEMENT},
102 sinceVersion = PropertyConstants.VERSION_2_0_3
103 )
104 public static final String PROPERTY_TEXT_MEASURER_FACTORY =
105 JRPropertiesUtil.PROPERTY_PREFIX + "text.measurer.factory";
106
107 private static final JRSingletonCache<JRTextMeasurerFactory> cache =
108 new JRSingletonCache<JRTextMeasurerFactory>(JRTextMeasurerFactory.class);
109
110
121 public JRTextMeasurer createTextMeasurer(JRCommonText text)
122 {
123 JRPropertiesHolder propertiesHolder =
124 text instanceof JRPropertiesHolder ? (JRPropertiesHolder) text : null;
125 return createTextMeasurer(text, propertiesHolder);
126 }
127
128
136 public JRTextMeasurer createTextMeasurer(JRCommonText text, JRPropertiesHolder propertiesHolder)
137 {
138 JRTextMeasurerFactory factory = getFactory(propertiesHolder);
139 return factory.createMeasurer(jasperReportsContext, text);
140 }
141
142
148 public JRTextMeasurerFactory getFactory(JRPropertiesHolder propertiesHolder)
149 {
150 String factoryClass = getTextMeasurerFactoryClass(propertiesHolder);
151 try
152 {
153 return cache.getCachedInstance(factoryClass);
154 }
155 catch (JRException e)
156 {
157 throw new JRRuntimeException(e);
158 }
159 }
160
161 protected String getTextMeasurerFactoryClass(JRPropertiesHolder propertiesHolder)
162 {
163 String factory = JRPropertiesUtil.getInstance(jasperReportsContext).getProperty(propertiesHolder, PROPERTY_TEXT_MEASURER_FACTORY);
164 String factoryClassProperty = PROPERTY_TEXT_MEASURER_FACTORY + '.' + factory;
165 String factoryClass = JRPropertiesUtil.getInstance(jasperReportsContext).getProperty(propertiesHolder, factoryClassProperty);
166 if (factoryClass == null)
167 {
168 factoryClass = factory;
169 }
170 return factoryClass;
171 }
172
173
174
177 public void measureTextElement(JRPrintText printText)
178 {
179 String text = styledTextUtil.getTruncatedText(printText);
180
181 JRTextMeasurer textMeasurer = createTextMeasurer(printText);
182
183 if (text == null)
184 {
185 text = "";
186 }
187 Locale textLocale = JRStyledTextAttributeSelector.getTextLocale(printText);
188 JRStyledText styledText =
189 JRStyledTextParser.getInstance().getStyledText(
190 noBackcolorSelector.getStyledTextAttributes(printText),
191 text,
192 JRCommonText.MARKUP_STYLED_TEXT.equals(printText.getMarkup()),
193 textLocale
194 );
195
196 JRStyledText processedStyledText = styledTextUtil.resolveFonts(styledText, textLocale);
197 JRMeasuredText measuredText = textMeasurer.measure(
198 processedStyledText,
199 0,
200 0,
201 true,
202 false
203 );
204 printText.setTextHeight(measuredText.getTextHeight() < printText.getHeight() ? measuredText.getTextHeight() : printText.getHeight());
205 printText.setLeadingOffset(measuredText.getLeadingOffset());
206 printText.setLineSpacingFactor(measuredText.getLineSpacingFactor());
207
208 int textEnd = measuredText.getTextOffset();
209 String printedText;
210 if (JRCommonText.MARKUP_STYLED_TEXT.equals(printText.getMarkup()))
211 {
212 printedText = JRStyledTextParser.getInstance().write(styledText, 0, textEnd);
213 }
214 else
215 {
216 printedText = text.substring(0, textEnd);
217 }
218 printText.setText(printedText);
219 }
220 }
221