import java.awt.Dimension;
import java.awt.Font;
+import java.awt.font.TextLayout;
+import java.awt.geom.Rectangle2D;
import javax.swing.Icon;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
+import org.scilab.forge.jlatexmath.TeXIcon;
import org.scilab.forge.scirenderer.shapes.appearance.Appearance;
import org.scilab.forge.scirenderer.shapes.appearance.Color;
import org.scilab.forge.scirenderer.texture.TextEntity;
/**
* Scilab text margin.
*/
- private static final int MARGIN = 2;
+ private static final int HMARGIN = 2;
+ private static final int VMARGIN = 2;
+ private static final int SPACEWIDTH = (int) Math.ceil(new TextEntity("_").getSize().getWidth()) - 2;
private Appearance appearance;
private int thickness;
private final Object[][] entities;
private float alignmentFactor;
- private final int spaceWidth;
private final int[] lineHeight;
private final int[] columnWidth;
+ private final float[] lineAscent;
private final int width;
private final int height;
* @param textObject the scilab {@see Text} to draw.
*/
public TextObjectSpriteDrawer(final ColorMap colorMap, final TextObject textObject) {
- this.spaceWidth = computeSpaceWidth();
-
String[][] stringArray = computeTextData(textObject);
int columnNumber = -1;
for (String[] stringLine : stringArray) {
int lineNumber = stringArray.length;
this.lineHeight = new int[lineNumber];
+ this.lineAscent = new float[lineNumber];
this.columnWidth = new int[columnNumber];
this.entities = new Object[columnNumber][lineNumber];
fillEntityMatrix(stringArray, fractionalFont, textColor, font);
- this.width = sum(columnWidth) + MARGIN * (columnNumber + 1) + 2 * thickness + spaceWidth * (columnNumber - 1);
- this.height = sum(lineHeight) + MARGIN * (lineNumber + 1) + 2 * thickness;
+ this.width = sum(columnWidth) + HMARGIN * (columnNumber + 1) + 2 * thickness + SPACEWIDTH * (columnNumber - 1);
+ this.height = sum(lineHeight) + VMARGIN * (lineNumber + 1) + 2 * thickness;
}
/**
* @param scaleFactor the scale factor to apply.
*/
public TextObjectSpriteDrawer(final ColorMap colorMap, final TextObject textObject, double scaleFactor) {
- this.spaceWidth = computeSpaceWidth();
-
String[][] stringArray = computeTextData(textObject);
int columnNumber = -1;
for (String[] stringLine : stringArray) {
int lineNumber = stringArray.length;
this.lineHeight = new int[lineNumber];
+ this.lineAscent = new float[lineNumber];
this.columnWidth = new int[columnNumber];
this.entities = new Object[columnNumber][lineNumber];
/* Fill the entity matrix */
fillEntityMatrix(stringArray, fractionalFont, textColor, font);
- this.width = (int)((double)sum(columnWidth) + scaleFactor * (double)(MARGIN * (columnNumber + 1)) + 2 * thickness + scaleFactor * (double)(spaceWidth * (columnNumber - 1)));
- this.height = (int)((double)sum(lineHeight) + scaleFactor * (double)(MARGIN * (lineNumber + 1)) + 2 * thickness);
+ this.width = (int)((double)sum(columnWidth) + scaleFactor * (double)(HMARGIN * (columnNumber + 1)) + 2 * thickness + scaleFactor * (double)(SPACEWIDTH * (columnNumber - 1)));
+ this.height = (int)((double)sum(lineHeight) + scaleFactor * (double)(VMARGIN * (lineNumber + 1)) + 2 * thickness);
}
/**
if (text != null) {
Dimension dimension = null;
Icon icon = null;
+ float ascent = 0;
if (isLatex(text)) {
LoadClassPath.loadOnUse("graphics_latex_textrendering");
try {
TeXFormula formula = new TeXFormula(text.substring(1, text.length() - 1));
formula.setColor(textColor);
icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, font.getSize());
+ ascent = ((TeXIcon) icon).getIconHeight() - ((TeXIcon) icon).getIconDepth();
} catch (Exception e) { }
} else if (isMathML(text)) {
LoadClassPath.loadOnUse("graphics_mathml_textrendering");
try {
icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, font.getSize(), textColor);
+ ScilabSpecialTextUtilities.SpecialIcon si = (ScilabSpecialTextUtilities.SpecialIcon) icon;
+ ascent = si.getIconHeight() - si.getIconDepth();
} catch (Exception e) { }
}
textEntity.setFont(font);
entities[column][line] = textEntity;
dimension = textEntity.getSize();
+ ascent = textEntity.getLayout().getAscent();
}
+ lineAscent[line] = Math.max(lineAscent[line], ascent);
+
if (dimension != null) {
columnWidth[column] = Math.max(columnWidth[column], dimension.width);
lineHeight[line] = Math.max(lineHeight[line], dimension.height);
drawingTools.clear(appearance.getFillColor());
}
- int currentMargin = getMargin();
- int currentSpaceWidth = getSpaceWidth();
+ final int currentHMargin = getHMargin();
+ final int currentVMargin = getVMargin();
+ final int currentSpaceWidth = getSpaceWidth();
// Draw text.
- int x = currentMargin + thickness;
+ int x = currentHMargin + thickness;
int column = 0;
for (Object[] entitiesLine : entities) {
- int y = currentMargin + thickness;
+ int y = currentVMargin + thickness;
int line = 0;
for (Object entity : entitiesLine) {
if (entity != null) {
if (entity instanceof TextEntity) {
TextEntity textEntity = (TextEntity) entity;
+ TextLayout layout = textEntity.getLayout();
double deltaX = alignmentFactor * (columnWidth[column] - textEntity.getSize().getWidth());
- drawingTools.draw(textEntity, (int) (x + deltaX), y);
- y += lineHeight[line] + currentMargin;
+ drawingTools.draw(textEntity, (int) (x + deltaX), Math.round(y - layout.getAscent() + lineAscent[line]));
+ y += lineHeight[line] + currentVMargin;
line++;
} else if (entity instanceof Icon) {
Icon icon = (Icon) entity;
double deltaX = alignmentFactor * (columnWidth[column] - icon.getIconWidth());
- drawingTools.draw(icon, (int) (x + deltaX), y);
- y += lineHeight[line] + currentMargin;
+ if (icon instanceof TeXIcon) {
+ TeXIcon tex = (TeXIcon) icon;
+ float ascent = tex.getIconHeight() - tex.getIconDepth();
+ drawingTools.draw(icon, (int) (x + deltaX), Math.round(y - ascent + lineAscent[line]));
+ } else {
+ // MathML
+ ScilabSpecialTextUtilities.SpecialIcon si = (ScilabSpecialTextUtilities.SpecialIcon) icon;
+ int ascent = si.getIconHeight() - si.getIconDepth();
+ drawingTools.draw(icon, (int) (x + deltaX), y - ascent + Math.round(lineAscent[line]));
+ }
+ y += lineHeight[line] + currentVMargin;
line++;
}
}
}
- x += columnWidth[column] + currentMargin + currentSpaceWidth;
+ x += columnWidth[column] + currentHMargin + currentSpaceWidth;
column++;
}
this.thickness = thickness;
}
- public int getMargin() {
- return MARGIN;
+ public int getHMargin() {
+ return HMARGIN;
+ }
+
+ public int getVMargin() {
+ return VMARGIN;
}
public int getSpaceWidth() {
- return spaceWidth;
+ return SPACEWIDTH;
}
/**
* @return the {@see Font} adapted to the given Scilab text.
*/
private Font computeFont(final TextObject text, double scaleFactor) {
- Font font = FontManager.getSciFontManager().getFontFromIndex(text.getFontStyle(), 1.0);
+ Font font = FontManager.getSciFontManager().getFontFromIndex(text.getFontStyle(), 1.0);
return font.deriveFont(font.getSize2D() * (float)scaleFactor);
}
}
/**
- * Compute and return the width of the space character.
- * @return the width of the space character.
- */
- private int computeSpaceWidth() {
- TextEntity spaceText = new TextEntity("_");
- return (int) Math.ceil(spaceText.getSize().getWidth());
- }
-
- /**
* Util function.
* Return sum of the element of the given array.
* @param values the given array.
*/
private Font font;
+ private TextLayout layout;
+
/**
* Default constructor.
* @param text the text content.
*/
public void setText(String text) {
this.text = text;
+ this.layout = null;
}
/**
*/
public void setFont(Font font) {
this.font = font;
+ this.layout = null;
}
/**
*/
public void setTextAntiAliased(boolean textAntiAliased) {
this.textAntiAliased = textAntiAliased;
+ this.layout = null;
}
/**
*/
public void setTextUseFractionalMetrics(boolean textUseFractionalMetrics) {
this.textUseFractionalMetrics = textUseFractionalMetrics;
+ this.layout = null;
}
/**
);
}
+ public TextLayout getLayout() {
+ if (layout == null) {
+ FontRenderContext frc = new FontRenderContext(null, isTextAntiAliased(), isTextUseFractionalMetrics());
+ layout = new TextLayout(getText(), getFont(), frc);
+ }
+
+ return layout;
+ }
+
/**
* Return the dimension in pixel of the text entity.
* @return the dimension in pixel of the text entity.
*/
public Dimension getSize() {
if (isValid()) {
- FontRenderContext frc = new FontRenderContext(null, isTextAntiAliased(), isTextUseFractionalMetrics());
- TextLayout textLayout = new TextLayout(getText(), getFont(), frc);
+ TextLayout textLayout = getLayout();
Dimension dimension = new Dimension();
Rectangle2D r = textLayout.getBounds();
/* +1 added to fix rendering of ticks labels, a pixel row/column was missing */
- dimension.setSize(r.getWidth() + 2, r.getHeight() + 1);
+ dimension.setSize(r.getWidth() + 2, textLayout.getAscent() + textLayout.getDescent() + 1);
return dimension;
} else {
return new Dimension(0, 0);