kerry
3 years ago
10 changed files with 127 additions and 4161 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@
|
||||
package com.fr.design.fit.common; |
||||
|
||||
import com.fr.base.DefaultAutoChangeLine; |
||||
import com.fr.base.Style; |
||||
import com.fr.stable.unit.UNIT; |
||||
|
||||
import java.awt.Font; |
||||
import java.util.List; |
||||
|
||||
public class NewUIModeAutoChangeLine extends DefaultAutoChangeLine { |
||||
@Override |
||||
public List<String> textAutoChangeLine(String text, Font font, Style style, UNIT unitWidth, int resolution) { |
||||
return autoChangeLine(text, font, style, unitWidth, resolution); |
||||
} |
||||
|
||||
protected double calculateShowWidth(double paintWidth, Style style, int resolution) { |
||||
return paintWidth - style.getPaddingLeft() - style.getPaddingRight() - style.getBorderLeftWidth(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,69 @@
|
||||
package com.fr.design.fit.common; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.DefaultRotationTextDrawProvider; |
||||
import com.fr.base.GraphHelper; |
||||
import com.fr.base.Style; |
||||
import com.fr.design.mainframe.PX; |
||||
import com.fr.stable.Constants; |
||||
|
||||
import java.awt.Font; |
||||
import java.awt.FontMetrics; |
||||
import java.awt.Graphics2D; |
||||
import java.util.List; |
||||
|
||||
public class NewUIModeRotationDraw extends DefaultRotationTextDrawProvider { |
||||
@Override |
||||
public void drawRotationText(Graphics2D g2d, String text, Style style, Font rfont, int width, int height, int horizontalAlignment, int resolution) { |
||||
FontMetrics cellFM = GraphHelper.getFontMetrics(rfont); |
||||
List lineTextList = BaseUtils.getLineTextList(text, style, rfont, height, width, resolution, new NewUIModeAutoChangeLine()); |
||||
drawRotationText(g2d, lineTextList, style, cellFM, width, height, horizontalAlignment, resolution); |
||||
} |
||||
|
||||
|
||||
protected int calculateTextWidth(int width, Style style) { |
||||
return width - style.getPaddingRight(); |
||||
} |
||||
|
||||
protected double calculateTextX(Style style, int width, int textWidth, int horizontalAlignment, int resolution) { |
||||
double textX = padding2PixExcludeRight(style.getPaddingLeft(), resolution); |
||||
if (horizontalAlignment == Constants.CENTER) { |
||||
textX += (width - textWidth - textX) / 2f; |
||||
} else if (horizontalAlignment == Constants.RIGHT) { |
||||
textX = width - style.getPaddingRight() - textWidth; |
||||
} |
||||
return textX; |
||||
} |
||||
|
||||
protected int toPXWithResolution(double pt, int resolution) { |
||||
return (int) PX.toPixWithResolution(pt, resolution); |
||||
} |
||||
|
||||
protected double padding2PixExcludeRight(int padding, int resolution) { |
||||
return PX.toPixWithResolution(padding, resolution); |
||||
} |
||||
|
||||
protected int calculateTextY(Style style, int height, int textHeight, int textAscent, List lineTextList, int resolution) { |
||||
// 计算Y的高度.
|
||||
int textY = 0; |
||||
int textAllHeight = textHeight * lineTextList.size(); |
||||
double spacingBefore = toPXWithResolution(style.getSpacingBefore(), resolution); |
||||
double spacingAfter = toPXWithResolution(style.getSpacingAfter(), resolution); |
||||
double lineSpacing = toPXWithResolution(style.getLineSpacing(), resolution); |
||||
textAllHeight += spacingBefore + spacingAfter + lineSpacing * lineTextList.size(); |
||||
if (style.getVerticalAlignment() == Constants.TOP) { |
||||
} else if (style.getVerticalAlignment() == Constants.CENTER) { |
||||
if (height > textAllHeight) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符.
|
||||
textY = (height - textAllHeight) / 2; |
||||
} |
||||
} else if (style.getVerticalAlignment() == Constants.BOTTOM) { |
||||
if (height > textAllHeight) { |
||||
textY = height - textAllHeight; |
||||
} |
||||
} |
||||
textY += textAscent;// 在绘画的时候,必须添加Ascent的高度.
|
||||
textY += spacingBefore + lineSpacing;//james:加上"段前间距"+“行间距”
|
||||
return textY; |
||||
} |
||||
|
||||
} |
@ -1,835 +0,0 @@
|
||||
/* |
||||
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. |
||||
*/ |
||||
package com.fr.design.fit.common; |
||||
|
||||
import com.fr.base.AutoChangeLineAndDrawManager; |
||||
import com.fr.base.BaseFormula; |
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.GraphHelper; |
||||
import com.fr.base.ImageProvider; |
||||
import com.fr.base.Painter; |
||||
import com.fr.base.Style; |
||||
import com.fr.base.Utils; |
||||
import com.fr.base.background.ColorBackground; |
||||
import com.fr.base.chart.BaseChartCollection; |
||||
import com.fr.base.chart.result.WebChartIDInfo; |
||||
import com.fr.code.BarcodeImpl; |
||||
import com.fr.code.bar.BarcodeException; |
||||
import com.fr.code.bar.core.BarCodeUtils; |
||||
import com.fr.code.bar.core.BarcodeAttr; |
||||
import com.fr.data.DataUtils; |
||||
import com.fr.data.PresentationType; |
||||
import com.fr.data.condition.ListCondition; |
||||
import com.fr.file.ResultChangeWhenExport; |
||||
import com.fr.form.ui.Widget; |
||||
import com.fr.general.Background; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.general.FRFont; |
||||
import com.fr.general.ImageWithSuffix; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.ExtraClassManager; |
||||
import com.fr.report.cell.CellElement; |
||||
import com.fr.report.cell.FloatElement; |
||||
import com.fr.report.cell.TemplateCellElement; |
||||
import com.fr.report.cell.cellattr.CellExpandAttr; |
||||
import com.fr.report.cell.cellattr.CellGUIAttr; |
||||
import com.fr.report.cell.cellattr.core.CellUtils; |
||||
import com.fr.report.cell.cellattr.core.ResultSubReport; |
||||
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||
import com.fr.report.core.Html2ImageUtils; |
||||
import com.fr.report.core.ReportUtils; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.Constants; |
||||
import com.fr.stable.CoreConstants; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.bridge.ObjectHolder; |
||||
import com.fr.stable.fun.AutoChangeLineAndDrawProcess; |
||||
import com.fr.stable.fun.FontProcessor; |
||||
import com.fr.stable.html.Tag; |
||||
import com.fr.stable.unit.FU; |
||||
import com.fr.stable.unit.PT; |
||||
import com.fr.stable.unit.UNIT; |
||||
import com.fr.stable.web.Repository; |
||||
|
||||
import javax.swing.ImageIcon; |
||||
import java.awt.AlphaComposite; |
||||
import java.awt.Color; |
||||
import java.awt.Font; |
||||
import java.awt.FontMetrics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.Image; |
||||
import java.awt.Paint; |
||||
import java.awt.Rectangle; |
||||
import java.awt.font.TextAttribute; |
||||
import java.awt.geom.GeneralPath; |
||||
import java.awt.image.BufferedImage; |
||||
import java.util.Hashtable; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* The util for paint. |
||||
*/ |
||||
public class PaintUtils { |
||||
// Add by Denny
|
||||
public static final int CELL_MARK_SIZE = 6; |
||||
public static final Color CELL_HIGHT_LIGHT_MARK_COLOR = new Color(255, 0, 55); |
||||
public static final Color CELL_PRESENT_MARK_COLOR = new Color(0, 255, 200); |
||||
public static final Color CELL_PAGINATION_MARK_COLOR = new Color(55, 255, 0); |
||||
public static final Color CELL_RESULT_MARK_COLOR = new Color(200, 0, 255); |
||||
public static final Color CELL_CONDITION_FILTER_MARK_COLOR = new Color(255, 200, 0); |
||||
public static final Color CELL_PARAMETER_FILTER_MARK_CONLR = new Color(0, 55, 255); |
||||
|
||||
public static final Color CELL_DIRECTION_MARK_COLOR = Color.gray; |
||||
private static final int UNIT_SIZE = 4; |
||||
|
||||
//原值是15,矩形线条会缺失,加1px绘制没问题。这地方有水印,但是貌似不是水印影响,未找到线条被挡住的原因
|
||||
private static final int WIDGET_WIDTH = 16; |
||||
private static final int WIDGET_HEIGHT = 16; |
||||
|
||||
// Suppresses default constructor, ensuring non-instantiability.
|
||||
private PaintUtils() { |
||||
} |
||||
|
||||
// font attributes map cache
|
||||
private static Hashtable fontAttributeMapCache = new Hashtable(); |
||||
|
||||
/* |
||||
* 用于在Grid里面画CellElement的Content + Background |
||||
* |
||||
* 不画Border,是因为在Grid里面先画所有单元格的Content + Background,再画所有单元格的Border(peter认为这可以提高速度) |
||||
*/ |
||||
public static void paintGridCellContent(Graphics2D g2d, TemplateCellElement cell, int width, int height, int resolution) { |
||||
int cell_mark_size = CELL_MARK_SIZE; |
||||
// denny_Grid
|
||||
// 左上角: 条件高亮, 形态
|
||||
int leftUpCount = 0; |
||||
int rightUpCount = 0; |
||||
int leftDownCount = 0; |
||||
GraphHelper.applyRenderingHints(g2d); |
||||
if (paintHighlightGroupMarkWhenExsit(g2d, cell, leftUpCount)) { |
||||
leftUpCount++; |
||||
} |
||||
if (paintPresentMarkWhenExsit(g2d, cell, leftUpCount)) { |
||||
leftUpCount++; |
||||
} |
||||
if (paintPaginationMarkWhenExsit(g2d, cell, width, rightUpCount)) { |
||||
rightUpCount++; |
||||
} |
||||
paintWidgetMarkWhenExsit(g2d, cell, width, height); |
||||
paintExpandMarkWhenExsit(g2d, cell); |
||||
Object value = cell.getValue(); |
||||
if (value == null) {// 先判断是否是空.
|
||||
return; |
||||
} |
||||
if (paintResultMarkWhenExsit(g2d, value, width, rightUpCount)) { |
||||
rightUpCount++; |
||||
} |
||||
|
||||
if (paintDSColumnParametermarkWhenExsit(g2d, value, height, leftDownCount)) { |
||||
leftDownCount++; |
||||
} |
||||
|
||||
if (paintDSColumnConditionmarkWhenExsit(g2d, value, height, leftDownCount)) { |
||||
leftDownCount++; |
||||
} |
||||
// 画value,但因为是在Grid里面画,所以画Formula.content
|
||||
if (value instanceof BaseFormula) { |
||||
value = ((BaseFormula) value).getContent(); |
||||
} |
||||
if (value instanceof ImageWithSuffix) { |
||||
value = ((ImageWithSuffix) value).getFineImage(); |
||||
} |
||||
if (value instanceof BaseChartCollection) { |
||||
value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); |
||||
} |
||||
// Carl:当是子报表时,在格子里画一个子报表的图
|
||||
/* |
||||
* alex:TODO 此处在Grid里面画ChartCollection和SubReport都只画一个图表,这种做法,很不雅 |
||||
*/ |
||||
if (value instanceof ResultSubReport) { |
||||
value = BaseUtils.readImage("/com/fr/base/images/report/painter/subReport.png"); |
||||
GraphHelper.paintImage(g2d, width, height, (Image) value, Constants.IMAGE_CENTER, |
||||
BaseUtils.getAlignment4Horizontal(cell.getStyle(), value), cell.getStyle().getVerticalAlignment(), |
||||
width > 16 ? 16 : width, height > 16 ? 16 : height); |
||||
} else { |
||||
renderContent(g2d, value, cell.getStyle(), width, height, resolution); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static void renderContent(Graphics2D g2d, Object value, Style style, int width, int height, int resolution) { |
||||
if (value != null && width != 0 && height != 0) { |
||||
if (style == null) { |
||||
style = Style.DEFAULT_STYLE.deriveImageLayout(1); |
||||
} |
||||
|
||||
if (value instanceof BaseFormula) { |
||||
value = ((BaseFormula) value).getResult(); |
||||
} |
||||
|
||||
if (value instanceof Painter) { |
||||
((Painter)value).paint(g2d, width, height, resolution, style); |
||||
} else if (value instanceof ImageProvider) { |
||||
Style.paintImageContent(g2d, ((ImageProvider) value).getImage(), style, width, height, resolution); |
||||
} else if (value instanceof Image) { |
||||
Style.paintImageContent(g2d, (Image) value, style, width, height, resolution); |
||||
} else { |
||||
String var6 = Style.valueToText(value, style.getFormat()); |
||||
NewFormStyle.paintCellStyleString2(g2d, width, height, var6, style, resolution); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
|
||||
private static boolean paintHighlightGroupMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { |
||||
if (cell.getHighlightGroup() != null && cell.getHighlightGroup().size() > 0) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_HIGHT_LIGHT_MARK_COLOR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(0, 0); |
||||
polyline.lineTo(0, CELL_MARK_SIZE); |
||||
polyline.lineTo(CELL_MARK_SIZE, 0); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private static boolean paintPresentMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int left_up_count) { |
||||
if (cell.getPresent() != null) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_PRESENT_MARK_COLOR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(0 + left_up_count * CELL_MARK_SIZE, 0); |
||||
polyline.lineTo(0 + left_up_count * CELL_MARK_SIZE, 6); |
||||
polyline.lineTo(CELL_MARK_SIZE + left_up_count * CELL_MARK_SIZE, 0); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private static boolean paintPaginationMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int ringt_up_count) { |
||||
// 右上角: 标记是否有分页
|
||||
if (isRightTopMarker(cell)) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_PAGINATION_MARK_COLOR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, 0); |
||||
polyline.lineTo(width - 1 - ringt_up_count * CELL_MARK_SIZE, CELL_MARK_SIZE); |
||||
polyline.lineTo(width - 1 - (ringt_up_count + 1) * CELL_MARK_SIZE, 0); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private static boolean isRightTopMarker(TemplateCellElement cell) { |
||||
return cell.getCellPageAttr() != null && (cell.getCellPageAttr().isPageAfterColumn() |
||||
|| cell.getCellPageAttr().isPageBeforeColumn() |
||||
|| cell.getCellPageAttr().isPageAfterRow() |
||||
|| cell.getCellPageAttr().isPageBeforeRow()); |
||||
} |
||||
|
||||
private static boolean paintResultMarkWhenExsit(Graphics2D g2d, Object value, int width, int ringt_up_count) { |
||||
//右上角标记是否自定义显示
|
||||
if (value instanceof DSColumn && ((DSColumn) value).getResult() != null) { |
||||
if (!ComparatorUtils.equals(((DSColumn) value).getResult(), "$$$")) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_RESULT_MARK_COLOR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(width - ringt_up_count * CELL_MARK_SIZE - 1, 0); |
||||
polyline.lineTo(width - ringt_up_count * CELL_MARK_SIZE - 1, CELL_MARK_SIZE); |
||||
polyline.lineTo(width - (ringt_up_count + 1) * CELL_MARK_SIZE - 1, 0); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private static void paintWidgetMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell, int width, int height) { |
||||
// 右下角:是否填报, 设置为4时,三角太小了,不知何故,设置为6
|
||||
if (cell.getWidget() != null) { |
||||
Widget widget = cell.getWidget(); |
||||
Image img = ((ImageIcon) ReportUtils.createWidgetIcon(widget.getClass())).getImage(); |
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.67f)); |
||||
g2d.drawImage(img, width - 15, height - 15, WIDGET_WIDTH, WIDGET_HEIGHT, null); |
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); |
||||
} |
||||
} |
||||
|
||||
private static void paintExpandMarkWhenExsit(Graphics2D g2d, TemplateCellElement cell) { |
||||
CellExpandAttr cellExpandAttr = cell.getCellExpandAttr(); |
||||
if (cellExpandAttr != null) { |
||||
if (cellExpandAttr.getDirection() == Constants.TOP_TO_BOTTOM) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
g2d.setPaint(CELL_DIRECTION_MARK_COLOR); |
||||
GraphHelper.drawLine(g2d, 2, 0, 2, 5); |
||||
GraphHelper.drawLine(g2d, 2, 5, 0, 2); |
||||
GraphHelper.drawLine(g2d, 2, 5, 4, 2); |
||||
g2d.setPaint(oldPaint); |
||||
} else if (cellExpandAttr.getDirection() == Constants.LEFT_TO_RIGHT) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
g2d.setPaint(CELL_DIRECTION_MARK_COLOR); |
||||
GraphHelper.drawLine(g2d, 0, 2, 5, 2); |
||||
GraphHelper.drawLine(g2d, 5, 2, 2, 0); |
||||
GraphHelper.drawLine(g2d, 5, 2, 2, 4); |
||||
g2d.setPaint(oldPaint); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static boolean paintDSColumnConditionmarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { |
||||
// 左下角:数据列(DSColumn)相关:比如条件过滤
|
||||
if (value instanceof DSColumn && ((DSColumn) value).getCondition() != null) { |
||||
if (((DSColumn) value).getCondition() instanceof ListCondition && |
||||
((ListCondition) ((DSColumn) value).getCondition()).getJoinConditionCount() == 0) { |
||||
// do nothing
|
||||
} else { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_CONDITION_FILTER_MARK_COLOR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); |
||||
polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); |
||||
polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private static boolean paintDSColumnParametermarkWhenExsit(Graphics2D g2d, Object value, int height, int left_dowm_count) { |
||||
// 左下角:动态注入参数
|
||||
if (value instanceof DSColumn && ((DSColumn) value).getParameters() != null) { |
||||
if (((DSColumn) value).getParameters().length > 0) { |
||||
Paint oldPaint = g2d.getPaint(); |
||||
|
||||
g2d.setPaint(CELL_PARAMETER_FILTER_MARK_CONLR); |
||||
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 3); |
||||
polyline.moveTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 1); |
||||
polyline.lineTo((left_dowm_count + 1) * CELL_MARK_SIZE + 1, height - 1); |
||||
polyline.lineTo(0 + left_dowm_count * CELL_MARK_SIZE, height - 2 - CELL_MARK_SIZE); |
||||
GraphHelper.fill(g2d, polyline); |
||||
|
||||
g2d.setPaint(oldPaint); |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/* |
||||
* 画悬浮元素 |
||||
* |
||||
* 仅根据宽度 + 高度画 |
||||
*/ |
||||
//b:此方法在grid和tohtml的时候都被调用,所以对formula会有冲突,暂时这么改,应该考虑分开的,也可以根据result来判断,但是那么写好像不妥
|
||||
public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, int width, int height, int resolution) { |
||||
Style.paintBackground(g2d, flotEl.getStyle(), width, height); |
||||
|
||||
Object value = flotEl.getValue(); |
||||
if (value instanceof BaseFormula) { |
||||
value = ((BaseFormula) value).getContent(); |
||||
} |
||||
if (value instanceof BaseChartCollection) { |
||||
value = ((BaseChartCollection) value).createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), WebChartIDInfo.createEmptyDesignerInfo(), width, height); |
||||
} |
||||
//图片需要切割一下
|
||||
if (value instanceof Image) { |
||||
value = CellUtils.value2ImageWithBackground(value, resolution, flotEl.getStyle(), width, height); |
||||
} |
||||
Style.paintContent(g2d, value, flotEl.getStyle(), width, height, resolution); |
||||
|
||||
Style.paintBorder(g2d, flotEl.getStyle(), width, height); |
||||
} |
||||
|
||||
/* |
||||
* 画悬浮元素flotEl |
||||
* |
||||
* 也就是画三个东西:背景 + 内容 + 边框 |
||||
*/ |
||||
public static void paintFloatElement(Graphics2D g2d, FloatElement flotEl, Rectangle paintRectangle, Rectangle clipRectangle, int resolution) { |
||||
// 画悬浮元素的背景
|
||||
Style.paintBackground(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||
|
||||
Object value = flotEl.getValue(); |
||||
if (value instanceof ResultChangeWhenExport) { |
||||
value = ((ResultChangeWhenExport) value).changeThis(); |
||||
} |
||||
// 画悬浮元素的内容
|
||||
Style.paintContent(g2d, value, resolution, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||
// 画悬浮元素的边框
|
||||
Style.paintBorder(g2d, flotEl.getStyle(), paintRectangle, clipRectangle); |
||||
} |
||||
|
||||
public static void paintHTMLContent(Graphics2D g2d, String value, int resolution, Style style, Rectangle paintRectangle, Rectangle clipRectangle) { |
||||
Style.paintContent(g2d, createHTMLContentBufferedImage(value, paintRectangle, 0, 0, style), resolution, style, paintRectangle, clipRectangle); |
||||
} |
||||
|
||||
public static void paintTag(Painter painter, Repository repo, int width, int height, Style style, Tag tag) { |
||||
painter.paintTag(repo, width, height, style, tag); |
||||
} |
||||
|
||||
/** |
||||
* 如果用户希望以HTML方式展示String,这个时候先value变成图片 |
||||
* |
||||
* @param value 值 |
||||
* @param paintRectangle 绘制范围 |
||||
* @param x x坐标 |
||||
* @param y y坐标 |
||||
* @param style 当前格子样式 |
||||
* @return BufferedImage 返回图片. |
||||
*/ |
||||
public static BufferedImage createHTMLContentBufferedImage(String value, Rectangle paintRectangle, int x, int y, Style style) { |
||||
return Html2ImageUtils.createHTMLContentBufferedImage(value, paintRectangle, x, y, style); |
||||
} |
||||
|
||||
/** |
||||
* see <code>BaseUtils.getLineTextList</code>, 等于BaseUtils.getLineTextList().size() |
||||
* Denny: 为了提高速度和性能,才单独拿出来的 |
||||
* TODO: 重构 |
||||
* |
||||
* @param text 文本 |
||||
* @param style 样式 |
||||
* @param paintWidth 单元格宽度 |
||||
* @return paintWidth 单位为PT |
||||
*/ |
||||
public static int getLineTextCount(String text, Style style, UNIT paintWidth) { |
||||
if (style.getRotation() != 0) { |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
if (style.getTextStyle() != Style.TEXTSTYLE_WRAPTEXT) { |
||||
return dealNotWrapTextCount(text.toCharArray()); |
||||
} else {// 自动换行
|
||||
return dealWrapTextCount(text, style, paintWidth); |
||||
} |
||||
} |
||||
|
||||
private static int dealNotWrapTextCount(char[] text_chars) { |
||||
boolean remain_chars = false; |
||||
int count = 0; |
||||
for (int t = 0; t < text_chars.length; t++) { |
||||
if (text_chars[t] == '\\') {// 判断是否是 "\n"
|
||||
if (t + 1 < text_chars.length && text_chars[t + 1] == 'n') { |
||||
// 是"\n"字符串,但不是换行符.
|
||||
t++; |
||||
count++; |
||||
if (remain_chars) { |
||||
remain_chars = false; |
||||
} |
||||
} else { |
||||
if (!remain_chars) { |
||||
remain_chars = true; |
||||
} |
||||
} |
||||
} else if (text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n')) { |
||||
count++; |
||||
if (remain_chars) { |
||||
remain_chars = false; |
||||
} |
||||
} else { |
||||
if (!remain_chars) { |
||||
remain_chars = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 最后一个
|
||||
if (remain_chars) { |
||||
count++; |
||||
} |
||||
|
||||
return count; |
||||
} |
||||
|
||||
// 自动换行
|
||||
//neil:style里面, 默认值padding right = 2时, 默认不生效, 这边算行高时也不要计算入内
|
||||
//临时处理, 去掉左边框线, 因为浏览器计算时需要考虑左边框线宽度, 但这边还是存在问题的
|
||||
//同样需要考虑的是导出和web端展示, padding计算方式也不一致.
|
||||
private static int dealWrapTextCount(String text, Style style, UNIT unitWidth) { |
||||
AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); |
||||
if (process != null) { |
||||
return process.getAutoChangeLineCount(text, new ObjectHolder(style), unitWidth); |
||||
} |
||||
int count = 0; |
||||
char[] text_chars = text.toCharArray(); |
||||
FontMetrics fontMetrics = getFontMetrics(style); |
||||
double paintWidth = unitWidth.toPixD(Constants.FR_PAINT_RESOLUTION); |
||||
double width = paintWidth - style.getPaddingLeft() - (style.getPaddingRight() == Style.DEFAULT_PADDING ? 0 : style.getPaddingRight()) - style.getBorderLeftWidth(); |
||||
boolean remain_lineText = false; |
||||
int lineTextWidth = 0; |
||||
int wordWidth = 0; |
||||
for (int t = 0, len = text_chars.length; t < len; t++) { |
||||
if (t != 0 && BaseUtils.isNumOrLetter(text_chars[t]) && BaseUtils.isNumOrLetter(text_chars[t - 1])) { |
||||
if (wordWidth + fontMetrics.charWidth(text_chars[t]) > width) { |
||||
if (lineTextWidth > 0) { |
||||
count++; |
||||
remain_lineText = false; |
||||
lineTextWidth = 0; |
||||
} |
||||
count++; |
||||
wordWidth = 0; |
||||
} |
||||
wordWidth += fontMetrics.charWidth(text_chars[t]); |
||||
} else if (isSwitchLine(text_chars, t) || isLN(text_chars, t)) {// 判断是否是 "\n"
|
||||
if (isLN(text_chars, t)) { |
||||
t++;// 忽略'n'字符.// 是"\n"字符串,但不是换行符,依然需要换行.
|
||||
} |
||||
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||
count += 2; |
||||
} else { |
||||
count++; |
||||
} |
||||
remain_lineText = false; |
||||
lineTextWidth = 0; |
||||
wordWidth = 0; |
||||
} else { |
||||
if (text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == '\\') {// 判断是否是转义字符'\'
|
||||
t++;// _denny: 增加了转义字符'\\'用来表示\,使"\n"可以输入
|
||||
} |
||||
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||
count++; |
||||
lineTextWidth = isPunctuationAtLineHead(t, text_chars) ? dealLineWidthWithPunctuation(t, text_chars, fontMetrics) : 0; |
||||
} |
||||
remain_lineText = true; |
||||
lineTextWidth += wordWidth; |
||||
wordWidth = fontMetrics.charWidth(text_chars[t]); |
||||
} |
||||
} |
||||
if (lineTextWidth + wordWidth > width && remain_lineText) { |
||||
count += 2; |
||||
} else { |
||||
count++; |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
/** |
||||
* 标点符号是否在换行后的行首 |
||||
*/ |
||||
private static boolean isPunctuationAtLineHead(int t, char[] text_chars) { |
||||
if (t > 1 && BaseUtils.isPunctuation(text_chars[t - 1])) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* 防止有连续多个标点符号,要找一个非标点符号字符 |
||||
* |
||||
* @date 2014-4-17 |
||||
*/ |
||||
private static int dealLineWidthWithPunctuation(int t, char[] text_chars, FontMetrics fontMetrics) { |
||||
if (t < 2) { |
||||
return 0; |
||||
} |
||||
int lineWidth = 0; |
||||
for (int index = t - 2; index >= 0; index--) { |
||||
lineWidth += fontMetrics.charWidth(text_chars[index]); |
||||
if (!BaseUtils.isPunctuation(text_chars[index])) { |
||||
break; |
||||
} |
||||
} |
||||
return lineWidth; |
||||
} |
||||
|
||||
private static boolean isSwitchLine(char[] text_chars, int t) { |
||||
return text_chars[t] == '\n' || (text_chars[t] == '\r' && t + 1 < text_chars.length - 1 && text_chars[t + 1] != '\n'); |
||||
} |
||||
|
||||
private static boolean isLN(char[] text_chars, int t) { |
||||
return text_chars[t] == '\\' && t + 1 < text_chars.length && text_chars[t + 1] == 'n'; |
||||
} |
||||
|
||||
/** |
||||
* Gets the preferred width. |
||||
*/ |
||||
public static UNIT getPreferredWidth(CellElement cell, UNIT height) { |
||||
if (cell == null) { |
||||
return UNIT.ZERO; |
||||
} |
||||
|
||||
Object value = cell.getShowValue(); |
||||
// 只接受Text,Number,和SeparatorPainter
|
||||
// got the text
|
||||
if (value instanceof BaseFormula) { |
||||
if (((BaseFormula) value).getResult() != null) { |
||||
value = ((BaseFormula) value).getResult(); |
||||
} else { |
||||
value = StringUtils.EMPTY; |
||||
} |
||||
} |
||||
Style style = cell.getStyle(); |
||||
if (style == null) { |
||||
style = Style.DEFAULT_STYLE; |
||||
} |
||||
CellGUIAttr cg = cell.getCellGUIAttr() == null ? new CellGUIAttr() : cell.getCellGUIAttr(); |
||||
value = Utils.resolveOtherValue(value, cg.isShowAsImage(), PresentationType.EXPORT); |
||||
String text = Style.valueToText(value, style.getFormat()); |
||||
|
||||
FontMetrics cellFM = getFontMetrics(style); |
||||
//bug 12151 有边框线的单元格 自动调整列宽 会多一行
|
||||
UNIT padding = new PT(style.getPaddingLeft() + style.getPaddingRight()); |
||||
|
||||
if (cg.isShowAsHTML()) { |
||||
return Html2ImageUtils.getHtmlWidth(text, height, style); |
||||
} |
||||
|
||||
return FU.valueOfPix(cellFM.stringWidth(text) + UNIT_SIZE, Constants.FR_PAINT_RESOLUTION).add(padding); |
||||
} |
||||
|
||||
private static FontMetrics getFontMetrics(Style style) { |
||||
Font font = style.getFRFont().applyResolutionNP(Constants.FR_PAINT_RESOLUTION); |
||||
FontProcessor processor = ExtraClassManager.getInstance().getSingle(FontProcessor.MARK_STRING); |
||||
if (processor != null) { |
||||
font = processor.readExtraFont(font); |
||||
} |
||||
return GraphHelper.getFontMetrics(font); |
||||
} |
||||
|
||||
/** |
||||
* Preferred height. (Got the shrink preferred height of CellElement). |
||||
* 单位格的预计算高度 |
||||
* |
||||
* @param cellElement 单元格内容 |
||||
* @param paintWidth 画的宽度 |
||||
* @return UNIT 单位 |
||||
*/ |
||||
public static UNIT analyzeCellElementPreferredHeight(CellElement cellElement, UNIT paintWidth) { |
||||
// 计算高度用显示值
|
||||
Object value = cellElement.getShowValue(); |
||||
// 只接受Text,Number,和SeparatorPainter
|
||||
Style style = cellElement.getStyle(); |
||||
// got the text
|
||||
if (value instanceof BaseFormula) { |
||||
if (((BaseFormula) value).getResult() != null) { |
||||
value = ((BaseFormula) value).getResult(); |
||||
} else { |
||||
value = StringUtils.EMPTY; |
||||
} |
||||
} |
||||
CellGUIAttr cg = cellElement.getCellGUIAttr() == null ? new CellGUIAttr() : cellElement.getCellGUIAttr(); |
||||
if (!(value instanceof String) && !(value instanceof Integer)) { |
||||
value = DataUtils.resolveOtherValue(value, cg.isShowAsImage(), cg.isShowAsDownload(), null, true); |
||||
} |
||||
String text = Style.valueToText(value, style.getFormat()); |
||||
|
||||
if (cg.isShowAsHTML()) { |
||||
return Html2ImageUtils.getHtmlHeight(text, paintWidth, style); |
||||
} |
||||
|
||||
return PaintUtils.analyzeCellElementPreferredHeight(text, style, paintWidth, cg.isShowAsHTML()); |
||||
} |
||||
|
||||
/** |
||||
* 单位格的预计算高度 |
||||
* 单位PT |
||||
* |
||||
* @param text 文本 |
||||
* @param style 格式 |
||||
* @param paintWidth 画的宽度 |
||||
* @param isShowAsHtml 是否以html展示 |
||||
* @return 返回 单位 |
||||
*/ |
||||
private static UNIT analyzeCellElementPreferredHeight(String text, Style style, UNIT paintWidth, boolean isShowAsHtml) { |
||||
if (style == null) { |
||||
//peter:获取默认的Style.
|
||||
style = Style.DEFAULT_STYLE; |
||||
} |
||||
|
||||
// got the text
|
||||
if (text == null || text.length() <= 0) { |
||||
return PT.valueOf(0); |
||||
} |
||||
|
||||
// 变成Line Text List.
|
||||
if (style.getRotation() != 0) { // more easy to paint.
|
||||
// attribute map.
|
||||
return PT.valueOf((float) GraphHelper.stringDimensionWithRotation(text, style.getFRFont(), -style.getRotation(), |
||||
CoreConstants.DEFAULT_FRC).getHeight()); |
||||
} |
||||
// 先获得FontMetics.
|
||||
int lineCount = getLineTextCount(text, style, paintWidth); |
||||
AutoChangeLineAndDrawProcess process = AutoChangeLineAndDrawManager.getProcess(); |
||||
if (process != null) { |
||||
//算了这两个接口分开做
|
||||
return process.getLinedTextHeight(lineCount, new ObjectHolder(style)); |
||||
} |
||||
|
||||
// carl:和paint那边一致,添上段前段后和行间距
|
||||
PT lineSpacing = PT.valueOf(style.getSpacingAfter() + style.getSpacingBefore() + style.getLineSpacing() * lineCount); |
||||
FontMetrics fontMetrics = getFontMetrics(style); |
||||
int textHeight = fontMetrics.getHeight(); |
||||
FU allTextHeight = FU.valueOfPix(textHeight * lineCount, Constants.FR_PAINT_RESOLUTION); |
||||
return lineSpacing.add(allTextHeight);// 需要给底部添加Leading.
|
||||
} |
||||
|
||||
/** |
||||
* 截取文字,只考虑了垂直方向,水平方向没意义且难度大. |
||||
* |
||||
* @param value 画的值 |
||||
* @param style 字体样式格式. |
||||
* @param blockArea 冻结的范围 |
||||
* @param resolution 分辨率 |
||||
* @return 返回的字符串 |
||||
*/ |
||||
public static String clipBlockValue(Object value, Style style, Rectangle primitiveArea, Rectangle blockArea, int resolution, boolean isShowAsHTML) { |
||||
if (value == null) { |
||||
return null; |
||||
} |
||||
if (value instanceof BaseFormula) { |
||||
value = ((BaseFormula) value).getResult(); |
||||
} |
||||
if (blockArea.y >= primitiveArea.height || blockArea.y + blockArea.height <= 0) { |
||||
return null; |
||||
} |
||||
//截取位置,相对于clipArea
|
||||
int startY = blockArea.y > 0 ? blockArea.y : 0; |
||||
int endY = blockArea.y + blockArea.height < primitiveArea.height ? blockArea.y + blockArea.height : primitiveArea.height; |
||||
if (blockArea.x >= primitiveArea.width || blockArea.x + blockArea.width <= 0) { |
||||
return null; |
||||
} |
||||
if (isShowAsHTML) { |
||||
return Html2ImageUtils.clipHtmlContent(value, style, primitiveArea, resolution, startY, endY); |
||||
} |
||||
List lineList = BaseUtils.getLineTextList((String) value, style, style.getFRFont().applyResolutionNP(resolution), primitiveArea.width, resolution); |
||||
if (lineList.isEmpty()) { |
||||
return null; |
||||
} |
||||
double spacingBefore = PT.pt2pix(style.getSpacingBefore(), resolution); |
||||
double spacingAfter = PT.pt2pix(style.getSpacingAfter(), resolution); |
||||
double lineSpacing = PT.pt2pix(style.getLineSpacing(), resolution); |
||||
double lineHeight = lineSpacing + GraphHelper.getFontMetrics(style.getFRFont().applyResolutionNP(resolution)).getHeight(); |
||||
int textAllHeight = (int) (lineHeight * lineList.size() + spacingBefore + spacingAfter); |
||||
//第一行文字距区域高度
|
||||
int textStartY = (int) spacingBefore; |
||||
|
||||
if (style.getVerticalAlignment() == Constants.BOTTOM) { |
||||
textStartY += (primitiveArea.height - textAllHeight); |
||||
} |
||||
if (endY <= textStartY || startY >= textStartY + lineHeight * lineList.size()) { |
||||
return null; |
||||
} |
||||
int lineStart = getLineStart(lineList, lineHeight, textStartY, startY);//截取区域起始行
|
||||
int lineEnd = getLineEnd(lineList, lineHeight, endY, textStartY);//截取区域结束行
|
||||
String text = ""; |
||||
for (; lineStart <= lineEnd; lineStart++) { |
||||
text += lineList.get(lineStart); |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
private static int getLineStart(List lineList, double lineHeight, int textStartY, int startY) { |
||||
int lineStart = 0; |
||||
for (int i = 0; i < lineList.size(); i++) { |
||||
if (textStartY + lineHeight * (i) <= startY && textStartY + lineHeight * (i + 1) > startY) {//压线
|
||||
if (startY - textStartY - lineHeight * (i) > lineHeight / 2) { |
||||
lineStart = i + 1; |
||||
} else { |
||||
lineStart = i; |
||||
} |
||||
} |
||||
} |
||||
return lineStart; |
||||
} |
||||
|
||||
private static int getLineEnd(List lineList, double lineHeight, int endY, int textStartY) { |
||||
int lineEnd = lineList.size() - 1; |
||||
for (int i = 0; i < lineList.size(); i++) { |
||||
if (textStartY + lineHeight * (i) < endY && textStartY + lineHeight * (i + 1) >= endY) {//压线
|
||||
//neil:仿宋,12号字, 行间距8为例, 转为px的行间距大小为10.666, 这边算出的应该有31.98行, 因此要进位
|
||||
if (endY - textStartY - lineHeight * (i) >= lineHeight / 2) { |
||||
lineEnd = i; |
||||
} else { |
||||
lineEnd = i - 1; |
||||
} |
||||
} |
||||
} |
||||
return lineEnd; |
||||
} |
||||
|
||||
/** |
||||
* paintBarcode |
||||
*/ |
||||
public static void paintBarcode(Graphics2D g2d, int width, int height, String text, Style style, BarcodeAttr barcodeAttr) { |
||||
BarcodeImpl barcodeImpl; |
||||
try { |
||||
barcodeImpl = BarCodeUtils.getBarcodeImpl(barcodeAttr, text); |
||||
} catch (BarcodeException exp) { |
||||
try { |
||||
//设置默认值.
|
||||
barcodeImpl = BarCodeUtils.getBarcodeImpl(new BarcodeAttr(), null); |
||||
} catch (BarcodeException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
//字体
|
||||
if (style.getFRFont() != null) { |
||||
barcodeImpl.setFont(style.getFRFont()); |
||||
barcodeImpl.setForeground(style.getFRFont().getForeground()); |
||||
} |
||||
//背景
|
||||
Background background = style.getBackground(); |
||||
if (background != null && background instanceof ColorBackground) { |
||||
barcodeImpl.setBackground(((ColorBackground) background).getColor()); |
||||
} |
||||
|
||||
//根据宽度和高度来确定起始点
|
||||
int pointX = (width - barcodeImpl.getWidth()) / 2; |
||||
int pointY = (height - barcodeImpl.getHeight()) / 2; |
||||
|
||||
barcodeImpl.draw(g2d, pointX, pointY); |
||||
} |
||||
|
||||
/** |
||||
* create font attribute map, 创建属性map |
||||
* |
||||
* @param font 字体 |
||||
* @return map 返回字体创建的Map |
||||
*/ |
||||
public static Map createFontAttributeMap(Font font) { |
||||
Map returnFontAttributeMap = (Map) fontAttributeMapCache.get(font); |
||||
if (returnFontAttributeMap == null) {// create
|
||||
// returnFontAttributeMap.
|
||||
returnFontAttributeMap = font.getAttributes(); |
||||
fontAttributeMapCache.put(font, returnFontAttributeMap); |
||||
} |
||||
|
||||
if (font instanceof FRFont) { |
||||
FRFont frFont = (FRFont) font; |
||||
|
||||
// Strikethrough
|
||||
if (frFont.isStrikethrough()) { |
||||
returnFontAttributeMap.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); |
||||
} |
||||
} |
||||
|
||||
return returnFontAttributeMap; |
||||
} |
||||
|
||||
} |
@ -1,27 +0,0 @@
|
||||
package com.fr.design.fit; |
||||
|
||||
|
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.fit.common.PaintUtils; |
||||
import com.fr.design.mainframe.JForm; |
||||
import com.fr.grid.CellElementPainter; |
||||
import com.fr.report.cell.TemplateCellElement; |
||||
import com.fr.report.elementcase.ElementCase; |
||||
|
||||
import java.awt.Graphics2D; |
||||
|
||||
/** |
||||
* Created by kerry on 2020-04-21 |
||||
*/ |
||||
public class AdaptiveCellElementPainter extends CellElementPainter { |
||||
|
||||
public void paintContent(Graphics2D g2d, ElementCase report, TemplateCellElement ce, int width, int height, int resolution) { |
||||
if (HistoryTemplateListCache.getInstance().getCurrentEditingTemplate() instanceof JForm) { |
||||
PaintUtils.paintGridCellContent(g2d, ce, width, height, resolution); |
||||
}else { |
||||
super.paintContent(g2d, report, ce, width, height, resolution); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.fr.design.fit; |
||||
|
||||
import com.fr.design.fit.common.NewUIModeRotationDraw; |
||||
import com.fr.grid.CellElementPainter; |
||||
import com.fr.report.cell.TemplateCellElement; |
||||
import com.fr.report.core.PaintUtils; |
||||
import com.fr.report.elementcase.ElementCase; |
||||
|
||||
import java.awt.Graphics2D; |
||||
|
||||
/** |
||||
* Created by kerry on 2020-04-21 |
||||
*/ |
||||
public class NewUIModeCellElementPainter extends CellElementPainter { |
||||
|
||||
public void paintContent(Graphics2D g2d, ElementCase report, TemplateCellElement ce, int width, int height, int resolution) { |
||||
PaintUtils.paintGridCellContent(g2d, ce, width, height, resolution, new NewUIModeRotationDraw()); |
||||
} |
||||
|
||||
|
||||
} |
Loading…
Reference in new issue