/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.views;
import java.net.URL;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.internal.util.BundleUtility;
import org.xmind.core.internal.dom.NumberUtils;
import org.xmind.core.style.IStyle;
import org.xmind.core.style.IStyleSheet;
import org.xmind.gef.draw2d.geometry.Geometry;
import org.xmind.gef.draw2d.geometry.PrecisionPoint;
import org.xmind.gef.draw2d.geometry.PrecisionPointPair;
import org.xmind.gef.draw2d.geometry.PrecisionRectangle;
import org.xmind.gef.draw2d.graphics.GradientPattern;
import org.xmind.gef.draw2d.graphics.GraphicsUtils;
import org.xmind.gef.draw2d.graphics.Path;
import org.xmind.ui.internal.svgsupport.SvgFileLoader;
import org.xmind.ui.internal.svgsupport.SvgPathParser;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;
import org.xmind.ui.style.StyleUtils;
import org.xmind.ui.style.Styles;
public class StyleFigureUtils {
public static final int BOUNDARY_STEP = 16;
public static final int BOUNDARY_PADDING = 8;
public static final float CALLOUT_RRECT_PARAM = 0.2f;
public static final float CALLOUT_ELLIPSE_STARTANGLE = -130;
public static final float CALLOUT_ELLIPSE_ARCANGLE = 345;
public static final int SPINY_WIDTH = 2;
public static final int ROUNDED_CORNER = 7;
public static final int ROUNDED_CORNER_ADAPTER = 30;
private static final IStyleSheet defaultStyles = MindMapUI
.getResourceManager().getDefaultStyleSheet();
public static final IStyle defaultSheetStyle = findOrCreateDefaultStyle(
Styles.FAMILY_MAP, IStyle.MAP);
public static final IStyle defaultCentralStyle = findOrCreateDefaultStyle(
Styles.FAMILY_CENTRAL_TOPIC, IStyle.TOPIC);
public static final IStyle defaultMainStyle = findOrCreateDefaultStyle(
Styles.FAMILY_MAIN_TOPIC, IStyle.TOPIC);
public static final IStyle defaultRelationshipStyle = findOrCreateDefaultStyle(
Styles.FAMILY_RELATIONSHIP, IStyle.RELATIONSHIP);
private StyleFigureUtils() {
}
private static IStyle findOrCreateDefaultStyle(String family, String type) {
IStyle style = defaultStyles.findStyle(family);
if (style == null)
style = defaultStyles.createStyle(type);
return style;
}
public static void angledRel(Path shape, Rectangle relBounds, Point c1,
Point c2) {
int dx = relBounds.width / 8;
int dy = relBounds.height / 8;
shape.moveTo(relBounds.getBottomLeft());
c1.setLocation(relBounds.getCenter().translate(-dx, -dy));
shape.lineTo(c1);
c2.setLocation(relBounds.getCenter().translate(dx, dy));
shape.lineTo(c2);
shape.lineTo(relBounds.getTopRight());
}
public static void calloutEllipse(Path shape, Rectangle r) {
Rectangle outlineBox = r;
shape.addArc(outlineBox.x, outlineBox.y, outlineBox.width,
outlineBox.height, CALLOUT_ELLIPSE_STARTANGLE,
CALLOUT_ELLIPSE_ARCANGLE);
float h = outlineBox.height;
shape.lineTo(outlineBox.x, outlineBox.y + h);
shape.close();
}
public static void calloutRoundRect(Path shape, Rectangle r) {
Rectangle box = r;
float x = box.x;
float y = box.y;
float w = box.width;
float h = box.height;
float dy = h - box.height / 4.0f;
float c = getAppliedCorner(r);
shape.moveTo(x + w * CALLOUT_RRECT_PARAM, y + dy);
shape.lineTo(x + w - c, y + dy);
shape.addArc(x + w - c, y + dy - c, c, c, -90, 90);
shape.lineTo(x + w, y + c);
shape.addArc(x + w - c, y, c, c, 0, 90);
shape.lineTo(x + c, y);
shape.addArc(x, y, c, c, 90, 90);
shape.lineTo(x, y + dy - c);
shape.addArc(x, y + dy - c, c, c, 180, 90);
shape.lineTo(box.x, box.y + h);
shape.close();
}
protected static int getAppliedCorner(Rectangle r) {
int t = Math.min(r.height, r.width);
return ROUNDED_CORNER * t / ROUNDED_CORNER_ADAPTER;
}
public static void circle(Path shape, Rectangle r) {
shape.addArc(r, 0, 360);
}
public static void parallelogram(Path shape, Rectangle r) {
shape.moveTo(r.x + r.height * 0.5f, r.y);
shape.lineTo(r.getBottomLeft());
shape.lineTo(r.right() - r.height * 0.5f, r.bottom());
shape.lineTo(r.getTopRight());
shape.close();
}
public static void cloud(Path path, Rectangle r) {
URL url = BundleUtility.find("org.xmind.ui", //$NON-NLS-1$
"shapes/topic-shape-cloud.svg"); //$NON-NLS-1$
SvgFileLoader loader = SvgFileLoader.getInstance();
String svgPath = loader.loadSvgFile(url);
SvgPathParser parser = SvgPathParser.getInstance();
parser.parseSvgPath(path, r.getCenter().x, r.getCenter().y, r.width,
r.height, svgPath);
}
public static void strokeCircle(Path path, Rectangle r) {
URL url = BundleUtility.find("org.xmind.ui", //$NON-NLS-1$
"shapes/topic-shape-stroke-circle.svg"); //$NON-NLS-1$
SvgFileLoader loader = SvgFileLoader.getInstance();
String svgPath = loader.loadSvgFile(url);
SvgPathParser parser = SvgPathParser.getInstance();
parser.parseSvgPath(path, r.getCenter().x, r.getCenter().y, r.width,
r.height, svgPath);
}
public static void curvedRel(Path shape, Rectangle relBounds, Point c1,
Point c2) {
// int dx = -relBounds.width / 10;
// int dy = relBounds.height / 10;
// shape.moveTo(relBounds.getBottomLeft());
int dx = -relBounds.width / 4;
int dy = relBounds.height / 4;
shape.moveTo(relBounds.getTopLeft());
Point p1 = relBounds.getTop().translate(-dx, -dy);
Point p2 = relBounds.getBottom().translate(dx, dy);
shape.cubicTo(p1, p2, relBounds.getTopRight());
c1.setLocation(p1.translate(0, dy));
c2.setLocation(p2.translate(0, -dy));
}
public static void diamondTopic(Path shape, Rectangle r) {
Rectangle r2 = r;
shape.moveTo(r2.getLeft());
shape.lineTo(r2.getBottom());
shape.lineTo(r2.getRight());
shape.lineTo(r2.getTop());
shape.close();
}
public static void diamondArrow(Path shape, Point head, double angle,
int lineWidth) {
int side1 = lineWidth + 3;
int side2 = lineWidth + 2;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle, side1);
PrecisionPoint p2 = p.getMoved(angle - Math.PI / 2, side2);
PrecisionPoint p3 = p.getMoved(angle + Math.PI, side1);
PrecisionPoint p4 = p.getMoved(angle + Math.PI / 2, side2);
shape.moveTo(p1);
shape.lineTo(p2);
shape.lineTo(p3);
shape.lineTo(p4);
shape.close();
}
public static void dotArrow(Path shape, Point head, double angle,
int lineWidth) {
PrecisionRectangle bounds = new PrecisionRectangle(head.x, head.y, 0, 0)
.expand(lineWidth, lineWidth);
shape.addArc(bounds, 0, 360);
}
public static void drawArrow(Graphics graphics, String arrowValue,
Point head, Point tail, int lineWidth) {
Path shape = new Path(Display.getCurrent());
boolean fill = true;
double angle = new PrecisionPoint(tail)
.getAngle(new PrecisionPoint(head));
if (Styles.ARROW_SHAPE_DIAMOND.equals(arrowValue)) {
diamondArrow(shape, head, angle, lineWidth);
} else if (Styles.ARROW_SHAPE_DOT.equals(arrowValue)) {
dotArrow(shape, head, angle, lineWidth);
} else if (Styles.ARROW_SHAPE_HERRINGBONE.equals(arrowValue)) {
herringBone(shape, head, angle, lineWidth);
fill = false;
} else if (Styles.ARROW_SHAPE_SPEARHEAD.equals(arrowValue)) {
spearhead(shape, head, angle, lineWidth);
} else if (Styles.ARROW_SHAPE_SQUARE.equals(arrowValue)) {
square(shape, head, angle, lineWidth);
} else if (Styles.ARROW_SHAPE_TRIANGLE.equals(arrowValue)) {
triangle(shape, head, angle, lineWidth);
} else {
normalArrow(shape, head, angle, lineWidth);
fill = false;
}
Color fgColor = graphics.getForegroundColor();
if (fgColor != null) {
if (fill) {
graphics.setBackgroundColor(fgColor);
graphics.fillPath(shape);
}
graphics.drawPath(shape);
}
shape.dispose();
}
public static void drawBoundary(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template) {
drawBoundary(graphics, bounds, null, style, template);
}
public static void drawBoundary(Graphics graphics, Rectangle bounds,
HashMap<String, String> existedStyle, IStyle style,
IStyle template) {
Rectangle boundaryBounds = boundaryBounds(bounds);
Path shape = new Path(Display.getCurrent());
String shapeValue = getValue(existedStyle, Styles.ShapeClass, style,
template);
if (shapeValue == null
|| Styles.BOUNDARY_SHAPE_ROUNDEDRECT.equals(shapeValue)) {
roundedRect(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_RECT.equals(shapeValue)) {
rectangle(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_SCALLOPS.equals(shapeValue)) {
scallops(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_TENSION.equals(shapeValue)) {
tension(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_WAVES.equals(shapeValue)) {
waves(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_POLYGON.equals(shapeValue)) {
polygon(shape, boundaryBounds);
} else if (Styles.BOUNDARY_SHAPE_ROUNDEDPOLYGON.equals(shapeValue)) {
roundedPolygon(shape, boundaryBounds);
} else {
roundedRect(shape, boundaryBounds);
}
String fillColorValue = getValue(existedStyle, Styles.FillColor, style,
template);
if (fillColorValue != null) {
Color fillColor = ColorUtils.getColor(fillColorValue);
if (fillColor != null) {
String opacityValue = getValue(existedStyle, Styles.Opacity,
style, template);
double opacity = NumberUtils.safeParseDouble(opacityValue, 1);
int alpha = (int) (opacity * 0xff);
graphics.setAlpha(alpha);
graphics.setBackgroundColor(fillColor);
graphics.fillPath(shape);
}
}
Color lineColor = getLineColor(existedStyle, style, template,
ColorConstants.gray);
String lineWidthValue = getValue(existedStyle, Styles.LineWidth, style,
template);
lineWidthValue = StyleUtils.trimNumber(lineWidthValue);
int lineWidth = NumberUtils.safeParseInt(lineWidthValue, 3);
graphics.setLineWidth(lineWidth);
String linePatternValue = getValue(existedStyle, Styles.LinePattern,
style, template);
int linePattern = StyleUtils.toSWTLineStyle(linePatternValue,
SWT.LINE_DASH);
graphics.setLineStyle(linePattern);
graphics.setAlpha(0xff);
graphics.setForegroundColor(lineColor);
graphics.drawPath(shape);
shape.dispose();
}
public static void drawMainBranches(Graphics graphics, Rectangle bounds,
boolean spiny, boolean rainbow) {
PrecisionPoint center = new PrecisionPoint(bounds.getCenter());
double length = Math.min(bounds.width, bounds.height) / 3;
for (int i = 0; i < 6; i++) {
double angle = Math.PI * (i - 1) / 3;
PrecisionPoint p = center.getMoved(angle, length);
if (p.y < center.y)
p.y += (center.y - p.y) / 6;
else if (p.y > center.y)
p.y -= (p.y - center.y) / 6;
if (Math.abs(p.y - center.y) > 0.000001) {
if (p.x < center.x)
p.x -= (center.x - p.x) / 6;
else if (p.y > center.x)
p.x += (p.x - center.x) / 6;
}
Color c = rainbow ? ColorUtils.getRainbowColor(i, 6)
: ColorConstants.gray;
graphics.setAlpha(0xff);
graphics.setForegroundColor(c);
graphics.setLineWidth(1);
graphics.setLineStyle(SWT.LINE_SOLID);
if (spiny) {
PrecisionPoint c1 = center.getMoved(angle + Math.PI / 3,
SPINY_WIDTH);
PrecisionPoint c2 = center.getMoved(angle - Math.PI / 3,
SPINY_WIDTH);
Path shape = new Path(Display.getCurrent());
shape.moveTo(p);
shape.lineTo(c1);
shape.lineTo(c2);
shape.close();
graphics.setBackgroundColor(c);
graphics.fillPath(shape);
graphics.drawPath(shape);
shape.dispose();
} else {
graphics.drawLine(center.toDraw2DPoint(), p.toDraw2DPoint());
}
graphics.setBackgroundColor(ColorConstants.white);
Rectangle oval = new PrecisionRectangle(center, center)
.getExpanded(4, 3).toDraw2DRectangle();
graphics.fillOval(oval);
}
}
public static void drawSheetBackground(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template) {
drawSheetBackground(graphics, bounds, null, style, template, true);
}
public static void drawSheetBackground(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template, boolean withMainBranches) {
drawSheetBackground(graphics, bounds, null, style, template,
withMainBranches);
}
public static void drawSheetBackground(Graphics graphics, Rectangle bounds,
HashMap<String, String> existedStyle, IStyle style, IStyle template,
boolean withMainBranches) {
Rectangle sheetBounds = sheetBounds(bounds);
Color fillColor = null;
String fillColorValue = getValue(existedStyle, Styles.FillColor, style,
template);
if (fillColorValue != null)
fillColor = ColorUtils.getColor(fillColorValue);
if (fillColor != null) {
graphics.setAlpha(0xff);
graphics.setBackgroundColor(fillColor);
graphics.fillRectangle(sheetBounds);
}
// if (fillColor == null)
// fillColor = ColorUtils.getColor("#e0e0e0"); //$NON-NLS-1$
// if (withMainBranches) {
// String spinyValue = getValue(Styles.SPINY_LINES, style, template);
// String rainbowValue = getValue(Styles.RAINBOWCOLOR, style, template);
// boolean spiny = Boolean.parseBoolean(spinyValue);
// boolean rainbow = Boolean.parseBoolean(rainbowValue);
// if (spiny || rainbow) {
// drawMainBranches(graphics, bounds, spiny, rainbow);
// }
// }
}
public static void drawRelationship(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template) {
drawRelationship(graphics, bounds, null, style, template);
}
public static void drawRelationship(Graphics graphics, Rectangle bounds,
HashMap<String, String> existedStyle, IStyle style,
IStyle template) {
Rectangle relBounds = relBounds(bounds);
Path shape = new Path(Display.getCurrent());
Point c1 = new Point();
Point c2 = new Point();
String shapeValue = getValue(existedStyle, Styles.ShapeClass, style,
template);
if (Styles.REL_SHAPE_ANGLED.equals(shapeValue)) {
angledRel(shape, relBounds, c1, c2);
} else if (Styles.REL_SHAPE_STRAIGHT.equals(shapeValue)) {
straightRel(shape, relBounds, c1, c2);
} else {
curvedRel(shape, relBounds, c1, c2);
}
Color lineColor = getLineColor(existedStyle, style, template,
ColorConstants.gray);
String lineWidthValue = getValue(existedStyle, Styles.LineWidth, style,
template);
lineWidthValue = StyleUtils.trimNumber(lineWidthValue);
int lineWidth = NumberUtils.safeParseInt(lineWidthValue, 3);
graphics.setLineWidth(lineWidth);
String linePatternValue = getValue(existedStyle, Styles.LinePattern,
style, template);
int linePattern = StyleUtils.toSWTLineStyle(linePatternValue,
SWT.LINE_DOT);
graphics.setLineStyle(linePattern);
graphics.setAlpha(0xff);
graphics.setForegroundColor(lineColor);
graphics.drawPath(shape);
shape.dispose();
graphics.setLineStyle(SWT.LINE_SOLID);
String beginArrowValue = getValue(existedStyle, Styles.ArrowBeginClass,
style, template);
if (beginArrowValue != null
&& !Styles.ARROW_SHAPE_NONE.equals(beginArrowValue)) {
drawArrow(graphics, beginArrowValue, relBounds.getBottomLeft(), c1,
lineWidth);
}
String endArrowValue = getValue(existedStyle, Styles.ArrowEndClass,
style, template);
if (endArrowValue == null)
endArrowValue = Styles.ARROW_SHAPE_NORMAL;
if (!Styles.ARROW_SHAPE_NONE.equals(endArrowValue)) {
drawArrow(graphics, endArrowValue, relBounds.getTopRight(), c2,
lineWidth);
}
}
public static Color getBranchConnectionColor(IStyle style, IStyle template,
IStyle parentStyle, IStyle parentTemplate, int preferredIndex,
Color defaultLineColor) {
Color lineColor = null;
if (preferredIndex >= 0 && parentStyle != null) {
String multiColors = getValue(Styles.MultiLineColors, parentStyle,
parentTemplate);
if (multiColors == null)
multiColors = template.getProperty(Styles.MultiLineColors);
if (multiColors != null) {
multiColors = multiColors.trim();
String[] colors = multiColors.split("[\\s]+"); //$NON-NLS-1$
if (colors.length > 0) {
preferredIndex %= colors.length;
String color = colors[preferredIndex].trim();
lineColor = ColorUtils.getColor(color);
}
}
}
if (lineColor == null) {
lineColor = getLineColor(style, template, defaultLineColor);
}
return lineColor;
}
public static Color getLineColor(IStyle style, IStyle template,
Color defaultLineColor) {
return getLineColor(null, style, template, defaultLineColor);
}
public static Color getLineColor(HashMap<String, String> existedStyle,
IStyle style, IStyle template, Color defaultLineColor) {
Color lineColor = null;
String lineColorValue = getValue(existedStyle, Styles.LineColor, style,
template);
if (lineColorValue != null)
lineColor = ColorUtils.getColor(lineColorValue);
if (lineColor == null) {
lineColor = defaultLineColor;
}
return lineColor;
}
public static String getValue(String key, IStyle style, IStyle template) {
return getValue(null, key, style, template);
}
public static String getValue(HashMap<String, String> existedStyle,
String key, IStyle style, IStyle template) {
String value = existedStyle == null ? null : existedStyle.get(key);
value = style != null ? style.getProperty(key, value) : value;
if (value == null) {
value = template == null ? null : template.getProperty(key);
}
return value;
}
public static void drawLine(Graphics g, Rectangle srcBounds,
IStyle srcStyle, IStyle srcTemplate, boolean srcCenterUnderline,
Rectangle tgtBounds, IStyle tgtStyle, IStyle tgtTemplate,
boolean tgtCenterUnderline, boolean tapered) {
String line = getValue(Styles.LineClass, srcStyle, srcTemplate);
if (Styles.BRANCH_CONN_NONE.equals(line))
return;
String lineWidth = getValue(Styles.LineWidth, srcStyle, srcTemplate);
lineWidth = StyleUtils.trimNumber(lineWidth);
int width = NumberUtils.safeParseInt(lineWidth, 1);
srcBounds = srcBounds.getExpanded(-width / 2, -width / 2);
int tgtWidth = NumberUtils.safeParseInt(StyleUtils.trimNumber(
getValue(Styles.LineWidth, tgtStyle, tgtTemplate)), 1);
tgtBounds = tgtBounds.getExpanded(-tgtWidth / 2, -tgtWidth / 2);
String srcShape = getValue(Styles.ShapeClass, srcStyle, srcTemplate);
String tgtShape = getValue(Styles.ShapeClass, tgtStyle, tgtTemplate);
Point srcPos = getSourcePos(srcBounds, srcShape, tgtBounds, tgtShape,
srcCenterUnderline);
Point tgtPos = getTargetPos(tgtBounds, tgtShape, srcBounds, srcShape,
tgtCenterUnderline);
Path shape = new Path(Display.getCurrent());
if (Styles.BRANCH_CONN_ELBOW.equals(line)) {
elbow(shape, srcPos, tgtPos, tapered, width);
} else if (Styles.BRANCH_CONN_ROUNDEDELBOW.equals(line)) {
roundElbow(shape, srcPos, tgtPos, tapered, width);
} else if (Styles.BRANCH_CONN_CURVE.equals(line)
|| Styles.BRANCH_CONN_ARROWED_CURVE.equals(line)) {
curveConn(shape, srcPos, tgtPos, tapered, width);
} else { // Straight and other unidentifiable line types
straightConn(shape, srcPos, tgtPos, tapered, width);
}
g.setLineWidth(width);
g.setLineStyle(SWT.LINE_SOLID);
g.setAlpha(0xff);
Color fgColor = g.getForegroundColor();
if (fgColor != null) {
if (tapered) {
g.setBackgroundColor(fgColor);
g.fillPath(shape);
} else
g.drawPath(shape);
}
shape.dispose();
}
public static Point getSourcePos(Rectangle srcBounds, String srcShape,
Rectangle tgtBounds, String tgtShape, boolean centerUnderline) {
if (Styles.TOPIC_SHAPE_UNDERLINE.equals(srcShape)) {
if (centerUnderline) {
if (tgtBounds.getCenter().x < srcBounds.getCenter().x)
return srcBounds.getLeft();
return srcBounds.getRight();
} else {
if (tgtBounds.getCenter().x < srcBounds.getCenter().x)
return srcBounds.getBottomLeft();
return srcBounds.getBottomRight();
}
}
return Geometry.getChopBoxLocation(tgtBounds.getCenter(), srcBounds);
}
public static Point getTargetPos(Rectangle tgtBounds, String tgtShape,
Rectangle srcBounds, String srcShape, boolean centerUnderline) {
if (Styles.TOPIC_SHAPE_UNDERLINE.equals(tgtShape)) {
if (centerUnderline) {
if (tgtBounds.getCenter().x < srcBounds.getCenter().x)
return tgtBounds.getRight();
return tgtBounds.getLeft();
} else {
if (tgtBounds.getCenter().x < srcBounds.getCenter().x)
return tgtBounds.getBottomRight();
return tgtBounds.getBottomLeft();
}
}
if (tgtBounds.getCenter().x < srcBounds.getCenter().x)
return tgtBounds.getRight();
return tgtBounds.getLeft();
// return Geometry.getChopBoxLocation( srcBounds.getCenter(), tgtBounds );
}
public static void drawTopic(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template, boolean centerUnderline) {
drawTopic(graphics, bounds, style, template, centerUnderline, false);
}
public static void drawTopic(Graphics graphics, Rectangle bounds,
IStyle style, IStyle template, boolean centerUnderline,
boolean isGradientColor) {
drawTopic(graphics, bounds, null, style, template, centerUnderline,
isGradientColor);
}
public static void drawTopic(Graphics graphics, Rectangle bounds,
HashMap<String, String> existedStyle, IStyle style, IStyle template,
boolean centerUnderline, boolean isGradientColor) {
Rectangle topicBounds = topicBounds(bounds);
Path shape = new Path(Display.getCurrent());
boolean outline = true;
boolean fill = true;
String shapeValue = getValue(existedStyle, Styles.ShapeClass, style,
template);
if (shapeValue == null
|| Styles.TOPIC_SHAPE_ROUNDEDRECT.equals(shapeValue)) {
roundedRect(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_ELLIPSE.equals(shapeValue)) {
ellipse(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_RECT.equals(shapeValue)) {
rectangle(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_UNDERLINE.equals(shapeValue)) {
underline(shape, topicBounds, centerUnderline);
fill = false;
} else if (Styles.TOPIC_SHAPE_NO_BORDER.equals(shapeValue)) {
noBorder(shape, topicBounds);
outline = false;
} else if (Styles.TOPIC_SHAPE_DIAMOND.equals(shapeValue)) {
diamondTopic(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_CALLOUT_ELLIPSE.equals(shapeValue)) {
calloutEllipse(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_CALLOUT_ROUNDEDRECT.equals(shapeValue)) {
calloutRoundRect(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_CIRCLE.equals(shapeValue)) {
Rectangle circleTopicBounds = circleTopicBounds(bounds);
circle(shape, circleTopicBounds);
} else if (Styles.TOPIC_SHAPE_PARALLELOGRAM.equals(shapeValue)) {
parallelogram(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_CLOUD.equals(shapeValue)) {
cloud(shape, topicBounds);
} else if (Styles.TOPIC_SHAPE_STROKE_CIRCLE.equals(shapeValue)) {
strokeCircle(shape, topicBounds);
} else {
roundedRect(shape, topicBounds);
}
String fillColorValue = getValue(existedStyle, Styles.FillColor, style,
template);
graphics.setAlpha(0xff);
if (fillColorValue != null) {
Color fillColor = ColorUtils.getColor(fillColorValue);
if (fillColor != null) {
Path newPath = new Path(Display.getCurrent(),
shape.getPathData());
if (!fill) {
rectangle(newPath, topicBounds.expand(0, -1));
}
int x = topicBounds.x;
int y1 = topicBounds.y - topicBounds.height / 4;
int y2 = topicBounds.y + topicBounds.height;
if (isGradientColor) {
GradientPattern bgPattern = new GradientPattern(
Display.getCurrent(), x, y1, x, y2,
ColorConstants.white, 0xff, fillColor, 0xff);
graphics.setBackgroundPattern(bgPattern);
graphics.fillPath(newPath);
bgPattern.dispose();
} else {
graphics.setBackgroundColor(fillColor);
graphics.fillPath(newPath);
}
newPath.dispose();
}
}
if (outline) {
Color lineColor = getLineColor(style, template,
ColorConstants.gray);
String lineColorValue = getValue(existedStyle,
Styles.BorderLineColor, style, template);
if (lineColorValue != null)
lineColor = ColorUtils.getColor(lineColorValue);
if (lineColor != null) {
String lineWidthValue = getValue(existedStyle,
Styles.BorderLineWidth, style, template);
lineWidthValue = StyleUtils.trimNumber(lineWidthValue);
if (lineWidthValue == null)
lineWidthValue = getValue(existedStyle, Styles.LineWidth,
style, template);
int lineWidth = NumberUtils.safeParseInt(lineWidthValue, 1);
if (lineWidth > 0) {
graphics.setLineWidth(lineWidth);
graphics.setLineStyle(SWT.LINE_SOLID);
graphics.setForegroundColor(lineColor);
graphics.drawPath(shape);
}
}
}
shape.dispose();
}
public static void ellipse(Path shape, Rectangle r) {
shape.addArc(r, 0, 360);
}
public static int getBoundaryPadding() {
return BOUNDARY_PADDING;
}
public static void elbow(Path shape, Point p1, Point p2, boolean tapered,
int width) {
Point c = new Point(p1.x, p2.y);
if (tapered) {
PrecisionPoint _c = new PrecisionPoint(c);
PrecisionPoint _p1 = new PrecisionPoint(p1);
PrecisionPoint _p2 = new PrecisionPoint(p2);
PrecisionPointPair _cc = Geometry.calculatePositionPair(_c, _p2,
0.5);
PrecisionPointPair _pp2 = Geometry
.calculatePositionPair(_p2, _c, 0.5).swap();
PrecisionPointPair _pp1 = Geometry.calculatePositionPair(_p1, _c,
width);
double d = (p1.x > p2.x == p1.y > p2.y) ? width * 0.5
: -width * 0.5;
_cc.p1().x -= d;
_cc.p2().x += d;
shape.moveTo(_pp1.p1());
shape.lineTo(_cc.p1());
shape.lineTo(_pp2.p1());
shape.lineTo(_pp2.p2());
shape.lineTo(_cc.p2());
shape.lineTo(_pp1.p2());
shape.close();
} else {
shape.moveTo(p1);
shape.lineTo(c);
shape.lineTo(p2);
}
}
public static void roundElbow(Path shape, Point p1, Point p2,
boolean tapered, int width) {
Point c = new Point(p1.x, p2.y);
int corner = getAppliedCorner(new Rectangle(p1, p2)) * 2;
Point q1 = new Point(c.x, p1.y > p2.y ? c.y + corner : c.y - corner);
Point q2 = new Point(p1.x > p2.x ? c.x - corner : c.x + corner, c.y);
if (tapered) {
PrecisionPoint _p1 = new PrecisionPoint(p1);
PrecisionPoint _p2 = new PrecisionPoint(p2);
PrecisionPoint _q1 = new PrecisionPoint(q1);
PrecisionPoint _q2 = new PrecisionPoint(q2);
PrecisionPoint _c1 = new PrecisionPoint(_q1.x,
_q1.y + (c.y - _q1.y) * 3 / 4);
PrecisionPoint _c2 = new PrecisionPoint(
_q2.x + (c.x - _q2.x) * 3 / 4, _q2.y);
PrecisionPoint _pc1 = new PrecisionPoint(_p1.x,
_p1.y + (_c1.y - _p1.y) * 2);
PrecisionPoint _pc2 = new PrecisionPoint(
_p2.x + (_c2.x - _p2.x) * 2, _p2.y);
PrecisionPointPair _pp1 = Geometry.calculatePositionPair(_p1, _c1,
width);
PrecisionPointPair _qq1 = Geometry.calculatePositionPair(_q1, _c1,
width);
PrecisionPointPair _cc1 = Geometry.calculatePositionPair(_c1, _pc1,
width);
PrecisionPointPair _pp2 = Geometry
.calculatePositionPair(_p2, _c2, 0.5).swap();
PrecisionPointPair _qq2 = Geometry
.calculatePositionPair(_q2, _c2, 0.5).swap();
PrecisionPointPair _cc2 = Geometry
.calculatePositionPair(_c2, _pc2, 0.5).swap();
double d = (p1.x > p2.x == p1.y > p2.y) ? width * 0.5
: -width * 0.5;
_qq2.p1().x -= d;
_qq2.p2().x += d;
_cc2.p1().x -= d;
_cc2.p2().x += d;
shape.moveTo(_pp1.p1());
shape.lineTo(_qq1.p1());
shape.cubicTo(_cc1.p1(), _cc2.p1(), _qq2.p1());
shape.lineTo(_pp2.p1());
shape.lineTo(_pp2.p2());
shape.lineTo(_qq2.p2());
shape.cubicTo(_cc2.p2(), _cc1.p2(), _qq1.p2());
shape.lineTo(_pp1.p2());
shape.close();
} else {
shape.moveTo(p1);
shape.lineTo(q1);
shape.cubicTo(q1.x, q1.y + (c.y - q1.y) * 3 / 4,
q2.x + (c.x - q2.x) * 3 / 4, q2.y, q2.x, q2.y);
shape.lineTo(p2);
}
}
public static void straightConn(Path shape, Point p1, Point p2,
boolean tapered, int width) {
if (tapered) {
PrecisionPoint _p1 = new PrecisionPoint(p1);
PrecisionPoint _p2 = new PrecisionPoint(p2);
PrecisionPointPair _pp1 = Geometry.calculatePositionPair(_p1, _p2,
width);
PrecisionPointPair _pp2 = Geometry
.calculatePositionPair(_p2, _p1, 0.5).swap();
shape.moveTo(_pp1.p1());
shape.lineTo(_pp2.p1());
shape.lineTo(_pp2.p2());
shape.moveTo(_pp1.p2());
shape.close();
} else {
shape.moveTo(p1);
shape.lineTo(p2);
}
}
public static void curveConn(Path shape, Point p1, Point p2,
boolean tapered, int width) {
if (tapered) {
PrecisionPoint _p1 = new PrecisionPoint(p1);
PrecisionPoint _p2 = new PrecisionPoint(p2);
PrecisionPoint _c = new PrecisionPoint(
_p1.x + (_p2.x - _p1.x) * 2 / 10, _p2.y);
PrecisionPointPair _pp1 = Geometry.calculatePositionPair(_p1, _p2,
width);
PrecisionPointPair _pp2 = Geometry
.calculatePositionPair(_p2, _c, 0.5).swap();
PrecisionPointPair _cc = Geometry.calculatePositionPair(_c, _p2,
0.5);
double d = (p1.x > p2.x == p1.y > p2.y) ? width * 0.5
: -width * 0.5;
_cc.p1().x -= d;
_cc.p2().x += d;
shape.moveTo(_pp1.p1());
shape.quadTo(_cc.p1(), _pp2.p1());
shape.lineTo(_pp2.p2());
shape.quadTo(_cc.p2(), _pp1.p2());
shape.close();
} else {
Point c = new Point(p1.x, p2.y);
c.x += (p2.x - c.x) * 2 / 10;
shape.moveTo(p1);
shape.quadTo(c, p2);
}
}
public static void herringBone(Path shape, Point head, double angle,
int lineWidth) {
int l = lineWidth * 2 + 4;
int w = lineWidth * 2 + 2;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle, l / 2);
PrecisionPoint p2 = p.getMoved(angle, l);
PrecisionPoint p01 = p.getMoved(angle - Math.PI * 2 / 3, w);
PrecisionPoint p02 = p.getMoved(angle + Math.PI * 2 / 3, w);
PrecisionPoint p11 = p1.getMoved(angle - Math.PI * 2 / 3, w);
PrecisionPoint p12 = p1.getMoved(angle + Math.PI * 2 / 3, w);
PrecisionPoint p21 = p2.getMoved(angle - Math.PI * 2 / 3, w);
PrecisionPoint p22 = p2.getMoved(angle + Math.PI * 2 / 3, w);
shape.moveTo(p01);
shape.lineTo(head);
shape.lineTo(p02);
shape.moveTo(p11);
shape.lineTo(p1);
shape.lineTo(p12);
shape.moveTo(p21);
shape.lineTo(p2);
shape.lineTo(p22);
shape.moveTo(head);
shape.lineTo(p2);
}
public static void noBorder(Path shape, Rectangle r) {
shape.addRectangle(r);
}
public static void normalArrow(Path shape, Point head, double angle,
int lineWidth) {
int side = lineWidth * 2 + 4;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle - Math.PI / 6, side);
PrecisionPoint p2 = p.getMoved(angle + Math.PI / 6, side);
shape.moveTo(p1);
shape.lineTo(head);
shape.lineTo(p2);
}
public static void rectangle(Path shape, Rectangle r) {
shape.addRectangle(r);
}
public static void roundedRect(Path shape, Rectangle r) {
shape.addRoundedRectangle(r, getAppliedCorner(r));
}
public static void scallops(Path shape, Rectangle box) {
int margin = getBoundaryPadding() * 3 / 5;
if (box.width <= margin * 2 || box.height <= margin * 2)
return;
float width = box.width - margin * 2;
float height = box.height - margin * 2;
float stepX = BOUNDARY_STEP;
float stepY = BOUNDARY_STEP * 6 / 8;
int numX = Math.max(1, (int) (width / stepX));
int numY = Math.max(1, (int) (height / stepY));
stepX = width / numX;
stepY = height / numY;
float x = box.x + margin;
float y = box.y + margin;
shape.moveTo(x, y);
for (int i = 0; i < numX; i++) {
shape.cubicTo(x + stepX / 4, y - margin, x + stepX * 3 / 4,
y - margin, x + stepX, y);
x += stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x + margin, y + stepY / 4, x + margin,
y + stepY * 3 / 4, x, y + stepY);
y += stepY;
}
for (int i = 0; i < numX; i++) {
shape.cubicTo(x - stepX / 4, y + margin, x - stepX * 3 / 4,
y + margin, x - stepX, y);
x -= stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x - margin, y - stepY / 4, x - margin,
y - stepY * 3 / 4, x, y - stepY);
y -= stepY;
}
shape.close();
}
public static void spearhead(Path shape, Point head, double angle,
int lineWidth) {
int side = lineWidth * 2 + 6;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle - Math.PI / 8, side);
PrecisionPoint p2 = p.getMoved(angle + Math.PI / 8, side);
PrecisionPoint cp = p.getMoved(angle, side / 2);
shape.moveTo(head);
shape.lineTo(p1);
shape.quadTo(cp, p2);
shape.close();
}
public static void square(Path shape, Point head, double angle,
int lineWidth) {
int side = lineWidth + 2;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle - Math.PI / 4, side);
PrecisionPoint p2 = p.getMoved(angle - Math.PI * 3 / 4, side);
PrecisionPoint p3 = p.getMoved(angle + Math.PI * 3 / 4, side);
PrecisionPoint p4 = p.getMoved(angle + Math.PI / 4, side);
shape.moveTo(p1);
shape.lineTo(p2);
shape.lineTo(p3);
shape.lineTo(p4);
shape.close();
}
public static void straightRel(Path shape, Rectangle relBounds, Point c1,
Point c2) {
Point p = relBounds.getBottomLeft();
shape.moveTo(p);
c2.setLocation(p);
p = relBounds.getTopRight();
c1.setLocation(p);
shape.lineTo(p);
}
public static void tension(Path shape, Rectangle box) {
int margin = getBoundaryPadding() / 2;
int margin2 = Math.max(1, margin / 4);
if (box.width <= margin * 2 || box.height <= margin * 2)
return;
float width = box.width - margin2 * 2;
float height = box.height - margin2 * 2;
float stepX = BOUNDARY_STEP;
float stepY = BOUNDARY_STEP;
int numX = Math.max(1, (int) (width / stepX));
int numY = Math.max(1, (int) (height / stepY));
stepX = width / numX;
stepY = height / numY;
float x = box.x + margin2;
float y = box.y + margin2;
shape.moveTo(x, y);
for (int i = 0; i < numX; i++) {
shape.cubicTo(x + stepX / 4, y + margin, x + stepX * 3 / 4,
y + margin, x + stepX, y);
x += stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x - margin, y + stepY / 4, x - margin,
y + stepY * 3 / 4, x, y + stepY);
y += stepY;
}
for (int i = 0; i < numX; i++) {
shape.cubicTo(x - stepX / 4, y - margin, x - stepX * 3 / 4,
y - margin, x - stepX, y);
x -= stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x + margin, y - stepY / 4, x + margin,
y - stepY * 3 / 4, x, y - stepY);
y -= stepY;
}
shape.close();
}
public static void triangle(Path shape, Point head, double angle,
int lineWidth) {
int side = lineWidth * 2 + 4;
PrecisionPoint p = new PrecisionPoint(head);
PrecisionPoint p1 = p.getMoved(angle - Math.PI / 6, side);
PrecisionPoint p2 = p.getMoved(angle + Math.PI / 6, side);
shape.moveTo(p1);
shape.lineTo(head);
shape.lineTo(p2);
shape.close();
}
public static void underline(Path shape, Rectangle r, boolean center) {
Rectangle r2 = r;
if (center) {
shape.moveTo(r2.getLeft());
shape.lineTo(r2.getRight());
} else {
shape.moveTo(r2.getBottomLeft());
shape.lineTo(r2.getBottomRight());
}
}
public static void waves(Path shape, Rectangle box) {
int margin = getBoundaryPadding() / 4;
if (box.width <= margin * 2 || box.height <= margin * 2)
return;
float width = box.width - margin * 2;
float height = box.height - margin * 2;
float stepX = BOUNDARY_STEP;
float stepY = BOUNDARY_STEP;
int numX = Math.max(1, (int) (width / stepX));
int numY = Math.max(1, (int) (height / stepY));
stepX = width / numX;
stepY = height / numY;
float x = box.x + margin;
float y = box.y + margin;
float h = ((float) getBoundaryPadding()) / 4;
shape.moveTo(x, y);
for (int i = 0; i < numX; i++) {
shape.cubicTo(x + stepX / 8, y - h, x + stepX * 3 / 8, y - h,
x + stepX / 2, y);
shape.cubicTo(x + stepX * 5 / 8, y + h, x + stepX * 7 / 8, y + h,
x + stepX, y);
x += stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x + h, y + stepY / 8, x + h, y + stepY * 3 / 8, x,
y + stepY / 2);
shape.cubicTo(x - h, y + stepY * 5 / 8, x - h, y + stepY * 7 / 8, x,
y + stepY);
y += stepY;
}
for (int i = 0; i < numX; i++) {
shape.cubicTo(x - stepX / 8, y + h, x - stepX * 3 / 8, y + h,
x - stepX / 2, y);
shape.cubicTo(x - stepX * 5 / 8, y - h, x - stepX * 7 / 8, y - h,
x - stepX, y);
x -= stepX;
}
for (int i = 0; i < numY; i++) {
shape.cubicTo(x - h, y - stepY / 8, x - h, y - stepY * 3 / 8, x,
y - stepY / 2);
shape.cubicTo(x + h, y - stepY * 5 / 8, x + h, y - stepY * 7 / 8, x,
y - stepY);
y -= stepY;
}
shape.close();
}
public static void polygon(Path shape, Rectangle box) {
shape.moveTo(box.x + box.width / 2, box.y);
shape.lineTo(box.x, box.y + box.height / 4);
shape.lineTo(box.x, box.bottom() - box.height / 4);
shape.lineTo(box.x + box.width / 2, box.bottom());
shape.lineTo(box.getBottomRight());
shape.lineTo(box.getTopRight());
shape.close();
}
public static void roundedPolygon(Path shape, Rectangle box) {
int corner = 4;
Point p0 = calcRoundedPoint(box.getTop(), box.getTopRight(), corner);
shape.moveTo(p0);
cubicAndLine(shape, box.getTopRight(), box.getTop(),
box.getTopLeft().getTranslated(0, box.height / 4), corner);
cubicAndLine(shape, box.getTop(),
box.getTopLeft().getTranslated(0, box.height / 4),
box.getBottomLeft().getTranslated(0, -box.height / 4), corner);
cubicAndLine(shape, box.getTopLeft().getTranslated(0, box.height / 4),
box.getBottomLeft().getTranslated(0, -box.height / 4),
box.getBottom(), corner);
cubicAndLine(shape,
box.getBottomLeft().getTranslated(0, -box.height / 4),
box.getBottom(), box.getBottomRight(), corner);
cubicAndLine(shape, box.getBottom(), box.getBottomRight(),
box.getTopRight(), corner);
cubicAndLine(shape, box.getBottomRight(), box.getTopRight(),
box.getTop(), corner);
shape.close();
}
private static void cubicAndLine(Path shape, Point p0, Point p1, Point p2,
int corner) {
Point p3 = calcRoundedPoint(p1, p0, corner);
Point p4 = calcRoundedPoint(p1, p2, corner);
Point c1 = calcControlPoint(p3, p1);
Point c2 = calcControlPoint(p4, p1);
shape.cubicTo(c1, c2, p4);
shape.lineTo(calcRoundedPoint(p2, p1, corner));
}
private static Point calcRoundedPoint(Point p1, Point p2, int corner) {
int dx = p2.x - p1.x;
int dy = p2.y - p1.y;
if (dx == 0) {
if (dy > 0)
return p1.getTranslated(0, corner);
return p1.getTranslated(0, -corner);
} else if (dy == 0) {
if (dx > 0)
return p1.getTranslated(corner, 0);
return p1.getTranslated(-corner, 0);
} else {
double l = p1.getDistance(p2);
double x = dx / l * corner;
double y = dy / l * corner;
return p1.getTranslated(x, y);
}
}
private static Point calcControlPoint(Point p1, Point p2) {
double dx = p2.x - p1.x;
double dy = p2.y - p1.y;
return p1.getTranslated(dx * 0.447715f, dy * 0.447715f);
}
private static void drawtext(Graphics graphics, String text,
Rectangle parentRect, IStyle style, IStyle template, Font font) {
drawtext(graphics, text, parentRect, null, style, template, font);
}
private static void drawtext(Graphics graphics, String text,
Rectangle parentRect, HashMap<String, String> existedStyle,
IStyle style, IStyle template, Font font) {
String fontColor = getValue(existedStyle, Styles.TextColor, style,
template);
RGB fontColorRGB = ColorUtils.toRGB(fontColor);
if (fontColorRGB == null)
return;
graphics.setForegroundColor(ColorUtils.getColor(fontColorRGB));
String textAlign = getValue(existedStyle, Styles.TextAlign, style,
template);
String textCase = getValue(existedStyle, Styles.TextCase, style,
template);
boolean isStrikedThrough = isStrikeout(existedStyle, style);
boolean isUnderlined = isUnderline(existedStyle, style);
if (Styles.UPPERCASE.equals(textCase)) {
text = text.toUpperCase();
} else if (Styles.LOWERCASE.equals(textCase)) {
text = text.toLowerCase();
} else if (Styles.CAPITALIZE.equals(textCase)) {
text = capitalize(text);
}
Dimension textSize = GraphicsUtils.getAdvanced().getTextSize(text,
font);
graphics.setFont(font);
int x = parentRect.x + (parentRect.width - textSize.width) / 4;
int y = parentRect.y + (parentRect.height - textSize.height) / 2;
if (Styles.ALIGN_CENTER.equals(textAlign)) {
x += (parentRect.width - textSize.width) / 4;
} else if (Styles.ALIGN_RIGHT.equals(textAlign)) {
x += (parentRect.width - textSize.width) / 2;
}
graphics.drawText(text, x, y);
y += textSize.height;
if (isUnderlined) {
Path underline = new Path(Display.getCurrent());
underline.moveTo(x, y - 1);
underline.lineTo(x + textSize.width, y - 1);
graphics.drawPath(underline);
underline.dispose();
}
if (isStrikedThrough) {
Path strikeOutLine = new Path(Display.getCurrent());
strikeOutLine.moveTo(x, y - textSize.height / 2);
strikeOutLine.lineTo(x + textSize.width, y - textSize.height / 2);
graphics.drawPath(strikeOutLine);
strikeOutLine.dispose();
}
font.dispose();
}
private static String capitalize(String str) {
StringBuffer stringbf = new StringBuffer();
Matcher m = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$
.matcher(str);
while (m.find()) {
m.appendReplacement(stringbf,
m.group(1).toUpperCase() + m.group(2).toLowerCase());
}
return m.appendTail(stringbf).toString();
}
public static void drawThemeText(Graphics graphics, String text,
Rectangle parentRect, IStyle style, IStyle template) {
String fontName = getFontName(style, template);
int fontDataStyle = getFontDataStyle(style);
Font font = new Font(null, fontName, 2, fontDataStyle);
drawtext(graphics, text, parentRect, style, template, font);
font.dispose();
}
public static void drawStyleText(Graphics graphics, String text,
Rectangle bounds, HashMap<String, String> existedStyle,
IStyle style, IStyle template) {
Rectangle parentRect = topicBounds(bounds);
String fontName = getFontName(existedStyle, style, template);
int fontDataStyle = getFontDataStyle(style);
Font font = new Font(null, fontName, 7, fontDataStyle);
drawtext(graphics, text, parentRect, existedStyle, style, template,
font);
font.dispose();
}
private static int getFontDataStyle(HashMap<String, String> existedStyle,
IStyle style) {
boolean isBold = isBold(existedStyle, style);
boolean isItalic = isItalic(existedStyle, style);
int fontDataStyle = SWT.NORMAL;
if (isBold)
fontDataStyle |= SWT.BOLD;
if (isItalic)
fontDataStyle |= SWT.ITALIC;
return fontDataStyle;
}
private static boolean isBold(HashMap<String, String> existedStyle,
IStyle style) {
String weight = getValue(existedStyle, Styles.FontWeight, style, null);
return weight != null && weight.contains(Styles.FONT_WEIGHT_BOLD);
}
private static boolean isItalic(HashMap<String, String> existedStyle,
IStyle style) {
String weight = getValue(existedStyle, Styles.FontStyle, style, null);
return weight != null && weight.contains(Styles.FONT_STYLE_ITALIC);
}
private static boolean isUnderline(HashMap<String, String> existedStyle,
IStyle style) {
String weight = getValue(existedStyle, Styles.TextDecoration, style,
null);
return weight != null
&& weight.contains(Styles.TEXT_DECORATION_UNDERLINE);
}
private static boolean isStrikeout(HashMap<String, String> existedStyle,
IStyle style) {
String weight = getValue(existedStyle, Styles.TextDecoration, style,
null);
return weight != null
&& weight.contains(Styles.TEXT_DECORATION_LINE_THROUGH);
}
private static int getFontDataStyle(IStyle style) {
return getFontDataStyle(null, style);
}
private static String getFontName(IStyle style, IStyle template) {
return getFontName(null, style, template);
}
private static String getFontName(HashMap<String, String> existedStyle,
IStyle style, IStyle template) {
String fontName = getValue(existedStyle, Styles.FontFamily, style,
template);
String availableFontName = FontUtils.getAAvailableFontNameFor(fontName);
fontName = availableFontName != null ? availableFontName : fontName;
if (Styles.SYSTEM.equals(fontName)) {
fontName = JFaceResources.getDefaultFont().getFontData()[0]
.getName();
}
return fontName;
}
private static Rectangle topicBounds(Rectangle r) {
int width = r.width * 7 / 8;
int height = width * 9 / 20;
int x = r.x + r.width / 2 - width / 2;
int y = r.y + r.height / 2 - height / 2;
return new Rectangle(x, y, width, height);
}
private static Rectangle circleTopicBounds(Rectangle r) {
int width = Math.min(r.width * 6 / 8, r.height * 6 / 8);
int height = width;
int x = r.x + r.width / 2 - width / 2;
int y = r.y + r.height / 2 - height / 2;
return new Rectangle(x, y, width, height);
}
private static Rectangle boundaryBounds(Rectangle r) {
int width = r.width * 7 / 8;
int height = width * 7 / 10;
int x = r.x + r.width / 2 - width / 2;
int y = r.y + r.height / 2 - height / 2;
return new Rectangle(x, y, width, height);
}
private static Rectangle relBounds(Rectangle r) {
int width = r.width * 6 / 8;
int height = width * 7 / 10;
int x = r.x + r.width / 2 - width / 2;
int y = r.y + r.height / 2 - height / 2;
return new Rectangle(x, y, width, height);
}
private static Rectangle sheetBounds(Rectangle r) {
int width = r.width * 7 / 8;
int height = width * 7 / 8;
int x = r.x + r.width / 2 - width / 2;
int y = r.y + r.height / 2 - height / 2;
return new Rectangle(x, y, width, height);
}
}