net.sf.jasperreports.engine.fill.ComplexTextLineWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2022 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.engine.fill;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.AttributedString;
import java.text.BreakIterator;
import java.text.CharacterIterator;
import java.util.Iterator;
import java.util.Map;
import net.sf.jasperreports.engine.JRCommonText;
import net.sf.jasperreports.engine.util.JRStyledText;
import net.sf.jasperreports.engine.util.MaxFontSizeFinder;
/**
* @author Teodor Danciu ([email protected])
*/
public class ComplexTextLineWrapper implements TextLineWrapper
{
private TextMeasureContext context;
private MaxFontSizeFinder maxFontSizeFinder;
private AttributedCharacterIterator allParagraphs;
private Map globalAttributes;
private AttributedCharacterIterator paragraph;
private LineBreakMeasurer lineMeasurer;
public ComplexTextLineWrapper()
{
}
protected ComplexTextLineWrapper(ComplexTextLineWrapper parent)
{
this.context = parent.context;
this.maxFontSizeFinder = parent.maxFontSizeFinder;
this.allParagraphs = parent.allParagraphs;
this.globalAttributes = parent.globalAttributes;
}
@Override
public void init(TextMeasureContext context)
{
this.context = context;
boolean isStyledText = !JRCommonText.MARKUP_NONE.equals(context.getElement().getMarkup());
maxFontSizeFinder = MaxFontSizeFinder.getInstance(isStyledText);
}
@Override
public boolean start(JRStyledText styledText)
{
globalAttributes = styledText.getGlobalAttributes();
allParagraphs = styledText.getAwtAttributedString(context.getJasperReportsContext(),
context.isIgnoreMissingFont()).getIterator();
return true;
}
@Override
public void startParagraph(int paragraphStart, int paragraphEnd, boolean truncateAtChar)
{
AttributedCharacterIterator paragraph = new AttributedString(allParagraphs,
paragraphStart, paragraphEnd).getIterator();
startParagraph(paragraph, truncateAtChar);
}
@Override
public void startEmptyParagraph(int paragraphStart)
{
Map attributes = new AttributedString(allParagraphs,
paragraphStart, paragraphStart + 1).getIterator().getAttributes();
AttributedCharacterIterator paragraph = new AttributedString(" ", attributes).getIterator();
startParagraph(paragraph, false);
}
protected void startParagraph(AttributedCharacterIterator paragraph, boolean truncateAtChar)
{
this.paragraph = paragraph;
BreakIterator breakIt = truncateAtChar ? BreakIterator.getCharacterInstance()
: BreakIterator.getLineInstance();
lineMeasurer = new LineBreakMeasurer(paragraph, breakIt, context.getFontRenderContext());
}
@Override
public int paragraphPosition()
{
return lineMeasurer.getPosition();
}
@Override
public int paragraphEnd()
{
return paragraph.getEndIndex();
}
@Override
public TextLine nextLine(float width, int endLimit, boolean requireWord)
{
TextLayout textLayout = lineMeasurer.nextLayout(width, endLimit, requireWord);
return textLayout == null ? null : new TextLayoutLine(textLayout);
}
@Override
public TextLine baseTextLine(int index)
{
AttributedString tmpText = new AttributedString(paragraph, index, index + 1);
LineBreakMeasurer lbm = new LineBreakMeasurer(tmpText.getIterator(), context.getFontRenderContext());
TextLayout tlyt = lbm.nextLayout(100);//FIXME what is this? why 100?
return new TextLayoutLine(tlyt);
}
@Override
public float maxFontsize(int start, int end)
{
return maxFontSizeFinder.findMaxFontSize(
new AttributedString(paragraph, start, end).getIterator(),
context.getElement().getFontsize());
}
@Override
public String getLineText(int start, int end)
{
StringBuilder lineText = new StringBuilder();
allParagraphs.setIndex(start);
while (allParagraphs.getIndex() < end
&& allParagraphs.current() != '\n')
{
lineText.append(allParagraphs.current());
allParagraphs.next();
}
return lineText.toString();
}
@Override
public char charAt(int index)
{
return allParagraphs.setIndex(index);
}
@Override
public TextLineWrapper lastLineWrapper(String lineText, int start, int textLength, boolean truncateAtChar)
{
AttributedString attributedText = new AttributedString(lineText);
//set original attributes for the text part
AttributedCharacterIterator textAttributes = new AttributedString(allParagraphs,
start, start + textLength).getIterator();
setAttributes(attributedText, textAttributes, 0);
//set global attributes for the suffix part
setAttributes(attributedText, globalAttributes, textLength, lineText.length());
AttributedCharacterIterator lineParagraph = attributedText.getIterator();
ComplexTextLineWrapper lastLineWrapper = new ComplexTextLineWrapper(this);
lastLineWrapper.startParagraph(lineParagraph, truncateAtChar);
return lastLineWrapper;
}
protected void setAttributes(AttributedString string, AttributedCharacterIterator attributes,
int stringOffset)
{
for (char c = attributes.first(); c != CharacterIterator.DONE; c = attributes.next())
{
for (Iterator> it = attributes.getAttributes().entrySet().iterator(); it.hasNext();)
{
Map.Entry attributeEntry = it.next();
AttributedCharacterIterator.Attribute attribute = attributeEntry.getKey();
if (attributes.getRunStart(attribute) == attributes.getIndex())
{
Object attributeValue = attributeEntry.getValue();
string.addAttribute(
attribute,
attributeValue,
attributes.getIndex() + stringOffset,
attributes.getRunLimit(attribute) + stringOffset
);
}
}
}
}
protected void setAttributes(AttributedString string, Map attributes,
int startIndex, int endIndex)
{
for (Iterator> it = attributes.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = it.next();
Attribute attribute = entry.getKey();
Object attributeValue = entry.getValue();
string.addAttribute(attribute, attributeValue, startIndex, endIndex);
}
}
}