Commit d175f6d2 authored by Bartosz Borucki's avatar Bartosz Borucki

Merge branch 'TextGlyph_formatting' into 'develop'

text glyph UI, formatting, complex and vector components done

Closes #86

See merge request !94
parents d2132757 7ffc4b97
Pipeline #29768535 passed with stage
in 0 seconds
......@@ -260,8 +260,10 @@ public class CellSetGeometry extends OpenBranchGroup
for (int m = Cell.getNProperCellTypesUpto1D(); m < Cell.getNProperCellTypesUpto2D(); m++) {
CellArray ar = cellSet.getBoundaryCellArray(CellType.getType(m));
if (ar == null)
if (ar == null || ar.getNCells() == 0 || ar.getDim() != 2)
continue;
if (ar.getCellNormals() == null)
createBoundaryCellNormals();
float[] cNormals = ar.getCellNormals().getData();
for (int i = 0; i < ar.getNCells(); i++) {
try {
......
......@@ -46,6 +46,8 @@ import javax.swing.event.ChangeListener;
import javax.vecmath.Color3f;
import pl.edu.icm.visnow.geometries.utils.transform.LocalToWindow;
import static org.apache.commons.math3.util.FastMath.*;
import static pl.edu.icm.visnow.geometries.parameters.FontParams.Decoration.*;
import static pl.edu.icm.visnow.geometries.parameters.FontParams.Position.*;
/**
*
......@@ -54,15 +56,107 @@ import static org.apache.commons.math3.util.FastMath.*;
public class FontParams
{
public enum Position
{
RADIAL ( 0, 0, 0, 0, 0, 0),
N ( 0, 1, 0, -1, 1, -1),
NE ( 1, 1, 1, -1, 1, -1),
E ( 1, 0, 1, 0, 1, -1),
SE ( 1, -1, 1, 1, 1, 1),
S ( 0, -1, 0, 1, 1, 1),
SW (-1, -1, -1, 1, -1, -1),
W (-1, 0, -1, 0, -1, -1),
NW (-1, 1, -1, -1, -1, -1),
AT_POINT( 0, 0, -1, -1, 0, 0) ;
private final int xShift;
private final int yShift;
private final int xFrameShift;
private final int yFrameShift;
private final int xEdgeShift;
private final int yEdgeShift;
private Position(int xShift, int yShift, int xFrameShift, int yFrameShift, int xEdgeShift, int yEdgeShift)
{
this.xShift = xShift;
this.yShift = yShift;
this.xFrameShift = xFrameShift;
this.yFrameShift = yFrameShift;
this.xEdgeShift = xEdgeShift;
this.yEdgeShift = yEdgeShift;
}
public int getxShift() {
return xShift;
}
public int getyShift() {
return yShift;
}
public int getxFrameShift() {
return xFrameShift;
}
public int getyFrameShift() {
return yFrameShift;
}
public int getxEdgeShift()
{
return xEdgeShift;
}
public int getyEdgeShift()
{
return yEdgeShift;
}
public static Position getPosition(float x, float y)
{
double phi = Math.atan2(y, x) / Math.PI;
if (phi < 0)
phi += 2;
int dir = (int)(4 * phi + .5);
if (dir >= 8)
dir = 0;
switch (dir) {
case 0:
return E;
case 1:
return NE;
case 2:
return N;
case 3:
return NW;
case 4:
return W;
case 5:
return SW;
case 6:
return S;
default:
return SE;
}
}
}
public enum Decoration {FRAME, EDGE, NONE}
private boolean threeDimensional = false;
private float size = .02f; //size of text glyps relative to the window size (2D) or field diameter (3d)
private float precision = 3; //precision of font model used for 3d fonts
private float font3DSize = 1;
private String fontName = "sans-serif";
private int fontSize = 12; //font size in pixels for 2d labels
private int fontSize = 15; //font size in pixels for 2d labels
private int fontType = Font.PLAIN;
private Color color = Color.WHITE;
private float colorCorrection = 1;
private Position position = RADIAL;
private Decoration decoration = FRAME;
private float opacity = .5f;
private float shift = 1f;
private Color bgColor = Color.BLACK;
public FontParams() {
}
......@@ -76,18 +170,16 @@ public class FontParams
this.color = color;
}
public void createFontMetrics(LocalToWindow localToWindow, int w, int h)
{
fontSize = max(5, (int) (h * size));
fontSize = max(12, (int) (h * size));
float z = localToWindow.transformPt(new double[]{0, 0, 0}, new int[2]);
float[] xl = localToWindow.reverseTransformPt(w / 2, (h - fontSize) / 2, z);
float[] xu = localToWindow.reverseTransformPt(w / 2, (h + fontSize) / 2, z);
font3DSize = (float) (sqrt((xu[0] - xl[0]) * (xu[0] - xl[0]) +
(xu[1] - xl[1]) * (xu[1] - xl[1]) +
(xu[2] - xl[2]) * (xu[2] - xl[2])));
(xu[1] - xl[1]) * (xu[1] - xl[1]) +
(xu[2] - xl[2]) * (xu[2] - xl[2])));
}
/**
......@@ -116,6 +208,27 @@ public class FontParams
fireStateChanged();
}
/**
* Get the value of bgColor
*
* @return the value of transparent background color
*/
public Color getBgColor()
{
return bgColor;
}
/**
* Set the value of bgColor
*
* @param bgColor new value of bgColor
*/
public void setBgColor(Color bgColor)
{
this.bgColor = bgColor;
fireStateChanged();
}
/**
* Set the value of fontType
*
......@@ -257,6 +370,93 @@ public class FontParams
fireStateChanged();
}
/**
* Get the value of position
*
* @return the value of position of text relative to anchor point
*/
public Position getPosition()
{
return position;
}
/**
* Set the value of position
*
* @param position new value of position
*/
public void setPosition(Position position)
{
this.position = position;
fireStateChanged();
}
/**
* Get the value of decoration
*
* @return the value of decoration
*/
public Decoration getDecoration()
{
return decoration;
}
/**
* Set the value of decoration
*
* @param decoration new value of decoration
*/
public void setDecoration(Decoration decoration)
{
this.decoration = decoration;
fireStateChanged();
}
/**
* Get the value of opacity
*
* @return the value of opacity
*/
public float getOpacity()
{
return opacity;
}
/**
* Set the value of opacity
*
* @param opacity new value of opacity
*/
public void setOpacity(float opacity)
{
this.opacity = opacity;
fireStateChanged();
}
/**
* Get the value of shift
*
* @return the value of shift
*/
public float getShift()
{
return shift;
}
/**
* Set the value of shift
*
* @param shift new value of shift
*/
public void setShift(float shift)
{
this.shift = shift;
fireStateChanged();
}
/**
* A flag indicating if state change will be forwarded to listeners.
*/
......
//<editor-fold defaultstate="collapsed" desc=" COPYRIGHT AND LICENSE ">
/* VisNow
Copyright (C) 2006-2013 University of Warsaw, ICM
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
University of Warsaw, Interdisciplinary Centre for Mathematical and
Computational Modelling, Pawinskiego 5a, 02-106 Warsaw, Poland.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
//</editor-fold>
package pl.edu.icm.visnow.geometries.textUtils;
import java.awt.*;
import javax.media.j3d.J3DGraphics2D;
import pl.edu.icm.visnow.geometries.parameters.FontParams;
import pl.edu.icm.visnow.geometries.parameters.FontParams.Position;
import static pl.edu.icm.visnow.geometries.parameters.FontParams.Position.*;
import static pl.edu.icm.visnow.geometries.parameters.FontParams.Decoration.*;
/**
*
* @author Krzysztof S. Nowinski, University of Warsaw, ICM
*/
public class CXYZString
{
protected String[] text;
protected int fontSize = 12;
protected Font font = new Font("Dialog", Font.PLAIN, fontSize);
protected float[] coords = new float[3];
protected float[] sCoords = new float[3];
protected float relativeHeight = .01f;
/**
* Creates a new instance of CXYZString
*/
public CXYZString(String[] s, Color c, float[] coords, Font font, float relativeHeight)
{
this.coords = coords;
this.font = font;
this.relativeHeight = relativeHeight;
this.text = s;
}
public CXYZString(String[] s, float[] coords, FontParams params)
{
this(s, params.getColor(), coords, params.getFont2D(), params.getSize());
}
public void update(pl.edu.icm.visnow.geometries.utils.transform.LocalToWindow ltw)
{
if (ltw == null)
return;
float depth = ltw.transformPt(coords, sCoords);
sCoords[2] = 1 -Math.max(0, depth);
// System.out.printf("%6.3f%n", depth);
}
@Override
public String toString()
{
StringBuilder b = new StringBuilder();
if (text.length > 1) b.append("[");
for (int i = 0; i < text.length; i++)
b.append(text[i] + (i < text.length - 1 ? "," : text.length < 2 ? "" : "]" ));
return text + " at(" + sCoords[0] + "," + sCoords[1] + ")";
}
public String[] getString()
{
return text;
}
public float[] getSCoords()
{
return sCoords;
}
/**
*
* @param vGraphics
* @param params
* @param fm
* @param width
* @param height
*/
public void draw(J3DGraphics2D vGraphics, FontParams params, FontMetrics fm, int width, int height)
{
if (text == null || text.length == 0)
return;
String[][]texts = new String[text.length][];
int effectiveTextsLength = 0;
for (int i = 0; i < texts.length; i++) {
texts[i] = text[i].split("\\\\n");
for (String text1 : texts[i])
if (!text1.isEmpty())
effectiveTextsLength += 1;
}
String[] effectiveTexts = new String[effectiveTextsLength];
for (int i = 0, k = 0; i < texts.length; i++)
for (String text1 : texts[i])
if (!text1.isEmpty()) {
effectiveTexts[k] = text1;
k += 1;
}
float depth = 1 - sCoords[2] / 2;
if (depth <= .01)
return;
int textW = 0;
for (int i = 0; i < effectiveTexts.length; i++) {
int k = fm.stringWidth(effectiveTexts[i]);
if (k > textW)
textW = k;
}
textW += 8;
int textH = effectiveTexts.length * (params.getFontSize() + 1) + 8;
float[] fc = new float[3];
float[] bc = new float[3];
params.getColor().getRGBColorComponents(fc);
params.getBgColor().getRGBColorComponents(bc);
int anchorX = (int)sCoords[0], anchorY = (int)sCoords[1];
int glyphX, glyphY;
int stemEndX, stemEndY;
float shift = params.getShift();
Position effectivePosition = params.getPosition();
if (params.getPosition() == RADIAL) {
effectivePosition = Position.getPosition(anchorX - width / 2, height / 2 - anchorY);
stemEndX = (int)(width / 2 + (anchorX - width / 2) * (1. + shift / 10));
stemEndY = height - (int)(height / 2 - (anchorY - height / 2) * (1. + shift / 10));
}
else {
stemEndX = (int)(anchorX + effectivePosition.getxShift() * shift * params.getFontSize());
stemEndY = (int)(anchorY - effectivePosition.getyShift() * shift * params.getFontSize());
}
int glyphShiftX = params.getDecoration() == FRAME ? effectivePosition.getxFrameShift() - 1 : effectivePosition.getxEdgeShift() - 1;
int glyphShiftY = params.getDecoration() == FRAME ? effectivePosition.getyFrameShift() + 1 : effectivePosition.getyEdgeShift() + 1;
glyphX = stemEndX + textW * glyphShiftX / 2;
glyphY = stemEndY + textH * glyphShiftY/ 2;
vGraphics.setColor(new Color(bc[0], bc[1], bc[2], params.getOpacity()));
vGraphics.fillRect(glyphX, glyphY - textH, textW, textH);
vGraphics.setColor(new Color(depth * fc[0] + (1 - depth) * bc[0],
depth * fc[1] + (1 - depth) * bc[1],
depth * fc[2] + (1 - depth) * bc[2]));
switch (params.getDecoration()) {
case FRAME:
vGraphics.drawRect(glyphX, glyphY - textH, textW, textH);
break;
case EDGE:
vGraphics.drawLine(glyphX, glyphY, glyphX + textW, glyphY);
vGraphics.drawLine(glyphX, glyphY, glyphX, glyphY - textH);
break;
default:
}
vGraphics.drawLine(anchorX, anchorY, stemEndX, stemEndY);
for (int i = 0; i < effectiveTexts.length; i++)
vGraphics.drawString(effectiveTexts[i], glyphX + 4, glyphY - 4 - (params.getFontSize() + 1) * (effectiveTexts.length - 1 - i));
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-49,0,0,0,-16"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="pl.edu.icm.visnow.gui.widgets.FloatSlider" name="shiftSlider">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="shift from anchor point"/>
</Border>
</Property>
<Property name="max" type="float" value="3.0"/>
<Property name="showingFields" type="boolean" value="false"/>
<Property name="val" type="float" value="1.0"/>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="shiftSliderStateChanged"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="pl.edu.icm.visnow.gui.widgets.FloatSlider" name="opacitySlider">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="background opacity"/>
</Border>
</Property>
<Property name="showingFields" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="opacitySliderStateChanged"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="4" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.Box$Filler" name="filler1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.6"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="jPanel1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="0"/>
<Property name="rows" type="int" value="1"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel4">
<Properties>
<Property name="text" type="java.lang.String" value=" background color"/>
</Properties>
</Component>
<Container class="pl.edu.icm.visnow.gui.widgets.ColorEditor" name="bgColorEditor">
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="bgColorEditorStateChanged"/>
</Events>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel2">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="0"/>
<Property name="rows" type="int" value="2"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="text" type="java.lang.String" value="position"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="positionCombo">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="positionComboItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<Property name="text" type="java.lang.String" value="decoration"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="decorationCombo">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="decorationComboItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>
This diff is collapsed.
//<editor-fold defaultstate="collapsed" desc=" COPYRIGHT AND LICENSE ">
/* VisNow
Copyright (C) 2006-2013 University of Warsaw, ICM
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
University of Warsaw, Interdisciplinary Centre for Mathematical and
Computational Modelling, Pawinskiego 5a, 02-106 Warsaw, Poland.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version.
*/
//</editor-fold>
package pl.edu.icm.visnow.geometries.textUtils;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import javax.media.j3d.J3DGraphics2D;