/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package feuille.scripting;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.table.DefaultTableModel;
import feuille.drawing.lib.BSpline;
import feuille.drawing.lib.Bezier;
import feuille.drawing.lib.ControlPoint;
import feuille.drawing.lib.IShape;
import feuille.drawing.lib.Layer;
import feuille.drawing.lib.Line;
import feuille.drawing.lib.Move;
import feuille.drawing.lib.Point;
import feuille.drawing.lib.ReStart;
import feuille.drawing.lib.Sheet;
import feuille.karaoke.lib.AssIO;
import feuille.karaoke.lib.AssStyle;
import feuille.karaoke.lib.AssStyle.AssStyleType;
import feuille.karaoke.lib.AssStyleCollection;
import feuille.karaoke.lib.Calcul;
import feuille.karaoke.lib.FxObject;
import feuille.karaoke.lib.ProblemFont;
import feuille.karaoke.lib.ProgramLine;
import feuille.karaoke.lib.Time;
import feuille.theme.Theme;
import feuille.theme.ThemeCollection;
/**
*
* @author The Wingate 2940
*/
public class ScriptPlugin {
private static String actualPath = null;
private static List<Object> sobjectList = new ArrayList<Object>();
JRubyScript ruby;
JythonScript python;
static String fxScripts = "E:\\Dev\\Projets\\Java\\AssFxMaker\\src\\assfxmaker\\docs\\";
static String script = "E:\\Dev\\Projets\\Java\\AssFxMaker\\src\\assfxmaker\\docs\\sample.rb";
static String docsPath = "E:\\Dev\\Projets\\Java\\AssFxMaker\\src\\assfxmaker\\docs\\";
static ProblemFont pf = new ProblemFont();
static int videoHeight = 720, videoWidth = 1280;
static DefaultTableModel orgModel, resModel;
static AssStyleCollection ascScript;
Frame frame; //We have to display dialog on program (error message)
public ScriptPlugin(Frame frame){
this.frame = frame;
ruby = new JRubyScript(frame);
python = new JythonScript(frame);
}
public ScriptPlugin(Frame frame, String fxPath, String scriptPath, String docsPath){
this.frame = frame;
fxScripts = fxPath;
script = scriptPath;
ScriptPlugin.docsPath = docsPath;
ruby = new JRubyScript(frame);
python = new JythonScript(frame);
}
/** <p>Search for all script of this directory.<br />
* Recherche tous les scripts du répertoire.</p>
* @param directory */
public void searchForScript(String directory){
sobjectList.clear(); //Security
File dir = new File(directory);
for(File f : dir.listFiles()){
if(f.getPath().endsWith(".rb")){
actualPath = f.getPath();
ruby.runRubyScript(actualPath);
}
if(f.getPath().endsWith(".py")){
actualPath = f.getPath();
python.runPythonScript(actualPath);
}
actualPath = "";
}
}
public void runScript(Object o){
if(o instanceof SButton){
SButton sb = (SButton)o;
if(sb.getPath().endsWith(".rb")){
ruby.runRubyScript(sb.getPath());
}else if(sb.getPath().endsWith(".py")){
python.runPythonScript(sb.getPath());
}
}else if(o instanceof STab){
STab st = (STab)o;
if(st.getPath().endsWith(".rb")){
ruby.runRubyScript(st.getPath());
}else if(st.getPath().endsWith(".py")){
python.runPythonScript(st.getPath());
}
}else if(o instanceof FxObject){
FxObject fxo = (FxObject)o;
if(fxo.getScriptPathname().endsWith(".rb")){
ruby.runRubyScript(fxo.getScriptPathname());
}else if(fxo.getScriptPathname().endsWith(".py")){
python.runPythonScript(fxo.getScriptPathname());
}
}
}
public void runScriptAndDo(Object o){
if(o instanceof SButton){
SButton sb = (SButton)o;
if(sb.getPath().endsWith(".rb")){
ruby.runRubyScriptAndDo(sb.getPath(), sb.getFunction());
}else if(sb.getPath().endsWith(".py")){
python.runPythonScriptAndDo(sb.getPath(), sb.getFunction());
}
}else if(o instanceof STab){
STab st = (STab)o;
if(st.getPath().endsWith(".rb")){
ruby.runRubyScriptAndDo(st.getPath(), st.getFunction());
}else if(st.getPath().endsWith(".py")){
python.runPythonScriptAndDo(st.getPath(), st.getFunction());
}
}else if(o instanceof FxObject){
FxObject fxo = (FxObject)o;
if(fxo.getScriptPathname().endsWith(".rb")){
ruby.runRubyScriptAndDo(fxo.getScriptPathname(), fxo.getFunction());
}else if(fxo.getScriptPathname().endsWith(".py")){
python.runPythonScriptAndDo(fxo.getScriptPathname(), fxo.getFunction());
}
}else if(o instanceof DrawingScript){
DrawingScript scr = (DrawingScript)o;
if(scr.getScriptPathname().endsWith(".rb")){
ruby.runRubyScriptAndDo(scr.getScriptPathname(), scr.getFunction());
}else if(scr.getScriptPathname().endsWith(".py")){
python.runPythonScriptAndDo(scr.getScriptPathname(), scr.getFunction());
}
}
}
public String runCodeAndDo(Object o){
String value = "";
if(o instanceof SButton){
SButton sb = (SButton)o;
if(sb.getPath().endsWith(".rb")){
value = ruby.runRubyCodeAndDo(sb.getPath(), sb.getFunction());
}else if(sb.getPath().endsWith(".py")){
value = python.runPythonCodeAndDo(sb.getPath(), sb.getFunction());
}
}else if(o instanceof STab){
STab st = (STab)o;
if(st.getPath().endsWith(".rb")){
value = ruby.runRubyCodeAndDo(st.getPath(), st.getFunction());
}else if(st.getPath().endsWith(".py")){
value = python.runPythonCodeAndDo(st.getPath(), st.getFunction());
}
}else if(o instanceof FxObject){
FxObject fxo = (FxObject)o;
if(fxo.getScriptPathname().endsWith(".rb")){
value = ruby.runRubyCodeAndDo(fxo.getScriptPathname(), fxo.getFunction());
}else if(fxo.getScriptPathname().endsWith(".py")){
value = python.runPythonCodeAndDo(fxo.getScriptPathname(), fxo.getFunction());
}
}
return value;
}
public String runFxCodeAndDo(String code, String function){
String value;
if(code.contains("):") | code.contains("# python")){
value = python.runPythonCodeAndDo(code, function);
}else{
value = ruby.runRubyCodeAndDo(code, function);
}
return value;
}
/** <p>Register a function of a ruby script.<br />
* Enregistre une fonction d'un script ruby.</p>
* @param oname The display name for your effect. (required)
* @param ofunction The def function's name to use. (required)
* @param oversion Your revision.
* @param odescription A small description to explain your function.
* @param oauthor Your name or team name.
* @param ofirstlayer The fisrt layer to apply effect.
* @param onblayers Number of layers that effect produce.
*/
public static void rubyRegister(Object oname, Object ofunction,
Object oversion, Object odescription, Object oauthor,
Object ofirstlayer, Object onblayers){
if(actualPath!=null && actualPath.equals("")==false){
FxObject fxo = new FxObject(oname.toString(),
odescription.toString(), actualPath,
ofunction.toString());
fxo.setFxObjectType(actualPath);
fxo.setVersion(oversion.toString());
fxo.setAuthor(oauthor.toString());
fxo.setFirstLayer(ofirstlayer.toString());
fxo.setNbLayers(onblayers.toString());
sobjectList.add(fxo);
}
}
/** <p>Register a function of a python script.<br />
* Enregistre une fonction d'un script pythun.</p>
* @param oname The display name for your effect. (required)
* @param ofunction The def function's name to use. (required)
* @param oversion Your revision.
* @param odescription A small description to explain your function.
* @param oauthor Your name or team name.
* @param ofirstlayer The fisrt layer to apply effect.
* @param onblayers Number of layers that effect produce.
*/
public static void pythonRegister(Object oname, Object ofunction,
Object oversion, Object odescription, Object oauthor,
Object ofirstlayer, Object onblayers){
if(actualPath!=null && actualPath.equals("")==false){
FxObject fxo = new FxObject(oname.toString(),
odescription.toString(), actualPath,
ofunction.toString());
fxo.setFxObjectType(actualPath);
fxo.setVersion(oversion.toString());
fxo.setAuthor(oauthor.toString());
fxo.setFirstLayer(ofirstlayer.toString());
fxo.setNbLayers(onblayers.toString());
sobjectList.add(fxo);
}
}
public static void addButton(Object opluginname, Object odisplayname,
Object ofunction, Object oversion, Object odescription, Object oauthor,
Object ohelp, Object otype){
if(actualPath!=null && actualPath.equals("")==false){
SButton sb = new SButton(opluginname.toString(), odisplayname.toString(),
actualPath, ofunction.toString(), oversion.toString(),
odescription.toString(), oauthor.toString(),
ohelp.toString(), otype.toString());
sobjectList.add(sb);
}
}
public static void addTab(Object opluginname, Object odisplayname,
Object ofunction, Object oversion, Object odescription, Object oauthor,
Object ohelp){
if(actualPath!=null){
STab st = new STab(opluginname.toString(), odisplayname.toString(),
actualPath, ofunction.toString(), oversion.toString(),
odescription.toString(), oauthor.toString(), ohelp.toString());
sobjectList.add(st);
}
}
public static void addTheme(Object onimbusBase, Object ocontrol, Object oname){
Color c1 = fromHTMLColor(onimbusBase.toString());
Color c2 = fromHTMLColor(ocontrol.toString());
ThemeCollection.addExternalTheme(new Theme(c1,c2,oname.toString()));
}
public static void addTheme(Object onimbusBase, Object ocontrol, Object otext, Object oname){
Color c1 = fromHTMLColor(onimbusBase.toString());
Color c2 = fromHTMLColor(ocontrol.toString());
Color c3 = fromHTMLColor(otext.toString());
ThemeCollection.addExternalTheme(new Theme(c1,c2,c3,oname.toString()));
}
public static void addTheme(Object onimbusBase, Object ocontrol, Object otext, Object oinfo, Object oname){
Color c1 = fromHTMLColor(onimbusBase.toString());
Color c2 = fromHTMLColor(ocontrol.toString());
Color c3 = fromHTMLColor(otext.toString());
Color c4 = fromHTMLColor(oinfo.toString());
ThemeCollection.addExternalTheme(new Theme(c1,c2,oname.toString()));
}
public List<Object> getSObjectList(){
return sobjectList;
}
public void clearSObjectList(){
sobjectList.clear();
}
//==========================================================================
//****************************************************************IO Methods
//==========================================================================
public void setPaths(String fxPath, String scriptPath, String docsPath){
ScriptPlugin.fxScripts = fxPath;
ScriptPlugin.script = scriptPath;
ScriptPlugin.docsPath = docsPath;
}
public void setModelsForManagement(DefaultTableModel org, DefaultTableModel res){
ScriptPlugin.orgModel = org;
ScriptPlugin.resModel = res;
}
public void setVideoSize(int videoWidth, int videoHeight){
ScriptPlugin.videoWidth = videoWidth;
ScriptPlugin.videoHeight = videoHeight;
}
public void setAssStyleCollection(AssStyleCollection asc){
ScriptPlugin.ascScript = asc;
}
public void setFrameReference(Frame frame){
this.frame = frame;
ruby = new JRubyScript(frame);
python = new JythonScript(frame);
}
//==========================================================================
//****************************************************************** Methods
//==========================================================================
private static Color fromHTMLColor(String HTMLColor){
// HTML -> RRGGBB
if(HTMLColor.startsWith("#")){HTMLColor=HTMLColor.substring(1);}
String red = HTMLColor.substring(0, 2);
String green = HTMLColor.substring(2, 4);
String blue = HTMLColor.substring(4);
return new Color(
Integer.parseInt(red, 16),
Integer.parseInt(green, 16),
Integer.parseInt(blue, 16));
}
//==========================================================================
//**************************************************************** Functions
//****************************************************** From KaraModeFunsub
//==========================================================================
/** <p>Set the path of actual ruby script.<br />
* Définit le chemin du script ruby actuel.</p> */
public static void setScript(Object opath){
script = opath.toString();
}
/** <p>Get the path of the last ruby script.<br />
* Obtient le chemin du dernier script ruby.</p> */
public static String getScript(){
return script;
}
/** <p>Get the absolute path of all scripts.<br />
* Obtient le chemin de l'endroit où sont sauvegardés tous les scripts.</p> */
public static String getScriptsPath(){
return fxScripts;
}
/** <p>Get the absolute path of all documents.<br />
* Obtient le chemin de l'endroit où sont sauvegardés tous les documents.</p> */
public static String getDocsPath(){
return docsPath;
}
/** <p>Return a multi-dimension array from a sentence<br />
* Retourne un tableau multi-dimension depuis une phrase.<br /><br />
* Sentence/Phrase :<br />"{\k31}ra{\k25}shi{\k15}n{\k14}ba{\k25}n {\k25}na{\k15}n
* {\k140}te {\k41}jyu{\k20}ta{\k15}i {\k35}no {\k38}mo{\k55}to"<br /><br />
* Array/Tableau :<br />ra | shi | n | ba | n | na | n | te | jyu |
* ta | i | no | mo | to | -> syllables/syllabes<br />
* 31 | 25 | 15 | 14 | 25 | 25 | 15 | 140 | 41 | 20 | 15 |
* 35 | 38 | 55 | -> hundredths/centièmes<br />
* 310 | 250 | 150 | 140 | 250 | 250 | 150 | 1400 | 410 | 200 | 150 |
* 350 | 380 | 550 | -> thousandths/millièmes<br />
* 0 | 310 | 560 | 710 | 850 | 1100 | 1350 | 1500 | 2900 | 3310 | 3510 |
* 3660 | 4010 | 4390 | -> thousandths start/millièmes début<br />
* 310 | 560 | 710 | 850 | 1100 | 1350 | 1500 | 2900 | 3310 | 3510 | 3660 |
* 4010 | 4390 | 4940 | -> thousandths end/millièmes fin</p>
* <p>Original version @ KaraModeFunsub - 2006-2008</p>
* @param sentence The sentence that contains the karaoke.
* @return An array of useful data for XFX and ruby script. */
public static Object[][] phKaraoke(String sentence){
//{\k31}ra
//(?<temps>\d+)\}(?<syllabe>[^\{]*) en vb.net
//(\\d+)\\}([^\\{]*) en java
Pattern p = Pattern.compile("(\\d+)\\}([^\\{]*)");
Matcher m = p.matcher(sentence);
List<String> syl = new ArrayList<String>();
List<Integer> time = new ArrayList<Integer>();
while(m.find()){
time.add(Integer.parseInt(m.group(1)));
syl.add(m.group(2));
}
Object[][] data = new Object[syl.size()][5];
int iEnd = 0;
for(int i=0;i<syl.size();i++){
data[i][0] = syl.get(i); //Syllabe
data[i][1] = time.get(i); //Centi. (total time)
data[i][2] = time.get(i)*10; //Milli. (total time)
data[i][3] = iEnd; //Milli. (start time)
iEnd += time.get(i)*10;
data[i][4] = iEnd; //Milli. (end time)
}
return data;
}
/** <p>Get a new head with modified time if the moment isn't 'Meantime'.<br />
* Obtient une nouvelle entête avec des temps modifiés si le moment
* n'est pas 'Pendant'.</p>
* @param head The actual head of the ass line.
* @param moment The moment requested.
* @param time The time for the new period (start -> end) of the head.
* @return The new head of your ass line. You have to regroup the head and the sentence to have your new ass line.
* @see getSentence()
* @see getHead()
* @see getAssLineOf() */
public static String phBeforeAfter(String head, String moment, String time){
if(moment.equalsIgnoreCase("Meantime")==false){
//regex en vb.net "(?<hh>\d+):(?<mm>\d+):(?<ss>\d+).(?<cc>\d+)"
//regex en java "(\\d+):(\\d+):(\\d+).(\\d+)"
Pattern p = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher m = p.matcher(head);
Time start = new Time();
Time end = new Time();
Time t = new Time();
Time new_start = new Time();
Time new_end = new Time();
t = t.fromMillisecondsTime(Integer.parseInt(time));
boolean endTime = false;
while(m.find()){
if (endTime == false){
start.setHours(Integer.parseInt(m.group(1)));
start.setMinutes(Integer.parseInt(m.group(2)));
start.setSeconds(Integer.parseInt(m.group(3)));
start.setMilliseconds(Integer.parseInt(m.group(4))*10);
}else{
end.setHours(Integer.parseInt(m.group(1)));
end.setMinutes(Integer.parseInt(m.group(2)));
end.setSeconds(Integer.parseInt(m.group(3)));
end.setMilliseconds(Integer.parseInt(m.group(4))*10);
}
endTime = true;
}
if (moment.equalsIgnoreCase("Before")){
new_start = start.substract(t, start);
new_end = start;
}else if (moment.equalsIgnoreCase("After")){
new_start = end;
new_end = end.addition(end, t);
}
String[] hdata = head.split(",");
if(hdata.length==9){
return hdata[0] + "," + new_start.toASSTime() + ","
+ new_end.toASSTime() + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return hdata[0] + "," + new_start.toASSTime() + ","
+ new_end.toASSTime() + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + ",";
}
}else{
return head;
}
}
/** <p>Get a new head with modified time if the moment isn't 'Meantime'.<br />
* Obtient une nouvelle entête avec des temps modifiés si le moment
* n'est pas 'Pendant'.</p>
* @param head The actual head of the ass line.
* @param moment The moment requested.
* @param time The time for the new period (start -> end) of the head.
* @return The new head of your ass line. You have to regroup the head and the sentence to have your new ass line.
* @see getSentence()
* @see getHead()
* @see getAssLineOf() */
public static String phShift(String head, String time){
//regex en vb.net "(?<hh>\d+):(?<mm>\d+):(?<ss>\d+).(?<cc>\d+)"
//regex en java "(\\d+):(\\d+):(\\d+).(\\d+)"
Pattern p = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher m = p.matcher(head);
Time start = new Time();
Time end = new Time();
Time t = new Time();
t = t.fromMillisecondsTime(Integer.parseInt(time));
boolean endTime = false;
while(m.find()){
if (endTime == false){
start.setHours(Integer.parseInt(m.group(1)));
start.setMinutes(Integer.parseInt(m.group(2)));
start.setSeconds(Integer.parseInt(m.group(3)));
start.setMilliseconds(Integer.parseInt(m.group(4))*10);
}else{
end.setHours(Integer.parseInt(m.group(1)));
end.setMinutes(Integer.parseInt(m.group(2)));
end.setSeconds(Integer.parseInt(m.group(3)));
end.setMilliseconds(Integer.parseInt(m.group(4))*10);
}
endTime = true;
}
Time new_start = start.addition(t, start);
Time new_end = end.addition(t, end);
String[] hdata = head.split(",");
if(hdata.length==9){
return hdata[0] + "," + new_start.toASSTime() + ","
+ new_end.toASSTime() + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return hdata[0] + "," + new_start.toASSTime() + ","
+ new_end.toASSTime() + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + ",";
}
}
/** <p>Change the layer of the given head.<br />
* Change la couche de l'entête.</p> */
public static String phChangeLayer(String head, String firstLayer){
String[] hdata = head.split(",");
if(hdata.length==9){
return "Dialogue: "+ firstLayer + "," + hdata[1] + ","
+ hdata[2] + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return "Dialogue: "+ firstLayer + "," + hdata[1] + ","
+ hdata[2] + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + ",";
}
}
/** <p>Change the style name of the given head.<br />
* Change le nom du style de l'entête.</p> */
public static String phChangeStyle(String head, String styleName){
String[] hdata = head.split(",");
if(hdata.length==9){
return hdata[0] + "," + hdata[1] + "," + hdata[2] +
"," + styleName + "," + hdata[4] + "," + hdata[5] +
"," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return hdata[0] + "," + hdata[1] + "," + hdata[2] +
"," + styleName + "," + hdata[4] + "," + hdata[5] +
"," + hdata[6] + "," + hdata[7] + ",";
}
}
/** <p>Change the start time of the given head.<br />
* Change le temps de début de l'entête.</p> */
public static String phChangeStart(String head, String start){
String[] hdata = head.split(",");
try{
Time t = new Time();
t = t.fromMillisecondsTime(Integer.parseInt(start));
start = t.toASSTime();
}catch(NumberFormatException nbe){
}
if(hdata.length==9){
return hdata[0] + "," + start + ","
+ hdata[2] + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return hdata[0] + "," + start + ","
+ hdata[2] + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + ",";
}
}
/** <p>Change the end time of the given head.<br />
* Change le temps de fin de l'entête.</p> */
public static String phChangeEnd(String head, String end){
String[] hdata = head.split(",");
try{
Time t = new Time();
t = t.fromMillisecondsTime(Integer.parseInt(end));
end = t.toASSTime();
}catch(NumberFormatException nbe){
}
if(hdata.length==9){
return hdata[0] + "," + hdata[1] + ","
+ end + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + "," + hdata[8];
}else{
return hdata[0] + "," + hdata[1] + ","
+ end + "," + hdata[3] + "," + hdata[4] + ","
+ hdata[5] + "," + hdata[6] + "," + hdata[7] + ",";
}
}
public static String phGetMillisecondsStart(String head){
//regex en vb.net "(?<hh>\d+):(?<mm>\d+):(?<ss>\d+).(?<cc>\d+)"
//regex en java "(\\d+):(\\d+):(\\d+).(\\d+)"
Pattern p = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher m = p.matcher(head);
Time start = new Time();
Time end = new Time();
boolean endTime = false;
while(m.find()){
if (endTime == false){
start.setHours(Integer.parseInt(m.group(1)));
start.setMinutes(Integer.parseInt(m.group(2)));
start.setSeconds(Integer.parseInt(m.group(3)));
start.setMilliseconds(Integer.parseInt(m.group(4))*10);
}else{
end.setHours(Integer.parseInt(m.group(1)));
end.setMinutes(Integer.parseInt(m.group(2)));
end.setSeconds(Integer.parseInt(m.group(3)));
end.setMilliseconds(Integer.parseInt(m.group(4))*10);
}
endTime = true;
}
return Long.toString(start.toMillisecondsTime(start));
}
public static String phGetMillisecondsEnd(String head){
//regex en vb.net "(?<hh>\d+):(?<mm>\d+):(?<ss>\d+).(?<cc>\d+)"
//regex en java "(\\d+):(\\d+):(\\d+).(\\d+)"
Pattern p = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher m = p.matcher(head);
Time start = new Time();
Time end = new Time();
boolean endTime = false;
while(m.find()){
if (endTime == false){
start.setHours(Integer.parseInt(m.group(1)));
start.setMinutes(Integer.parseInt(m.group(2)));
start.setSeconds(Integer.parseInt(m.group(3)));
start.setMilliseconds(Integer.parseInt(m.group(4))*10);
}else{
end.setHours(Integer.parseInt(m.group(1)));
end.setMinutes(Integer.parseInt(m.group(2)));
end.setSeconds(Integer.parseInt(m.group(3)));
end.setMilliseconds(Integer.parseInt(m.group(4))*10);
}
endTime = true;
}
return Long.toString(end.toMillisecondsTime(end));
}
/** <p>Return a new sentence with karaoke per letter from a given sentence.<br />
* Retourne une nouvelle phrase avec un karaoke par lettre à partir de la phrase fournie</p>
* <p>Original version @ KaraModeFunsub - 2006-2008</p> */
public static String phPerLetterKara(String sentence){
String new_sentence = "";
int first, last, countLetters;
//On récupère le tableau de syllabes afin de recréer la chaine et
// de pouvoir calculer les durées de syllabes.
//Calcul d'une syllabe : tps syl / nb lettres =(première lettre) |
// tps syl - ((nb lettres - 1) * première lettre) =(dernière lettre)
Object[][] syl = phKaraoke(sentence);
for (int i=0; i<syl.length;i++){
countLetters = getCountLetters(syl[i][0].toString());
if (countLetters>1){
//On traite les syllabes à plusieurs lettres (espace non compté)
first = Integer.parseInt(syl[i][1].toString()) / countLetters;
last = Integer.parseInt(syl[i][1].toString()) -
((countLetters - 1) * first);
for (int j=0;j<countLetters;j++){
if(j!=countLetters-1){
new_sentence += "{\\k" + first + "}" +
(syl[i][0].toString()).substring(j,j+1);
}else{
new_sentence += "{\\k" + last + "}" +
(syl[i][0].toString()).substring(j);
}
}
}else{
new_sentence += "{\\k" + syl[i][1].toString() +
"}" + syl[i][0].toString();
}
}
return new_sentence;
}
/** <p>Return the index of the origin syllables for each letter (to reuse
* the output of phKaraoke).<br /> Retourne les index de la syllabe
* d'origine pour chaque lettre (en vue de pouvoir réutiliser la sortie
* de phKaraoke)<br /><br />Request/Demande : <br />"{\k31}ra{\k25}shi{\k15}n
* {\k14}ba{\k25}n {\k25}na{\k15}n{\k140}te {\k41}jyu{\k20}ta{\k15}i
* {\k35}no {\k38}mo{\k55}to"<br /><br />Return an indexes table, example
* on rashinban/Retourne une table d'index, exemple sur rashinban :<br />
* 0(r);0(a);1(s);1(h);1(i);2(n);3(b);3(a);4(n);</p>
* <p>Original version @ KaraModeFunsub - 2006-2008</p> */
public static int[] phPerLetterKaraCrossIndex(String sentence){
Object[][] syl = phKaraoke(sentence);
List<Integer> listCrossIndex = new ArrayList<Integer>();
int countLetters;
for (int i=0; i<syl.length;i++){
countLetters = getCountLetters(syl[i][0].toString());
for (int j=0;j<countLetters;j++){
listCrossIndex.add(i);
}
if(syl[i][0].toString().isEmpty()){
listCrossIndex.add(i);
}
}
int[] data = new int[listCrossIndex.size()];
for (int k=0;k<listCrossIndex.size();k++){
data[k] = listCrossIndex.get(k);
}
return data;
}
/** <p>Get the count of letters in this syllables.<br />
* Obtient le nombre de lettres dans cette syllabes.</p> */
public static int getCountLetters(String syllabe){
Pattern p = Pattern.compile("[^0-9a-zA-Z]*([0-9a-zA-Z]*)");
Matcher m = p.matcher(syllabe);
m.find();
return m.group().length();
}
/** <p>Get the header of a ASS/SSA line.<br />
* Obtient l'entête de cette ligne ASS/SSA.</p> */
public static String getHead(String assline){
Pattern p = Pattern.compile("([^:]+:\\s[a-zA-Z=]*\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"[^,]+,[^,]*," +
"\\d+,\\d+,\\d+,[^,]*),(.*)");
Matcher m = p.matcher(assline);
m.find();
return m.group(1);
}
/** <p>Get the sentence of a ASS/SSA line.<br />
* Obtient la phrase de cette ligne ASS/SSA.</p> */
public static String getSentence(String assline){
Pattern p = Pattern.compile("([^:]+:\\s[a-zA-Z=]*\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"[^,]+,[^,]*," +
"\\d+,\\d+,\\d+,[^,]*),(.*)");
Matcher m = p.matcher(assline);
m.find();
return m.group(2);
}
/** <p>Get a complete ASS line from a head and a sentence.<br />
* Obrient une ligne complète en regroupant entête et phrase.</p> */
public static String getAssLineOf(String head, String sentence){
return head + "," + sentence;
}
/** <p>Replace all parameters of sentence and do calculation.<br />
* Remplace tous les paramètres de cette phrase et fait les calculs.</p>
* @param expression The commands for this line (object of the plugin).
* @param syl Syllabes or letters table (obtain it with phKaraoke() or
* phPerLetterKara()).
* @param currentIndex The actual index of syllabe in line.
* @param head Head of line (obtain it with getHead()).
* @param osyl Syllabes table when letters mode is used
* (obtain it with phKaraoke()).
* @param currentCrossIndex The index of syllabes when letters mode is used
* (obtain an integer by using phPerLetterKaraCrossIndex()).
* @return A new sentence.
* @see getSentence()
* @see phKaraoke()
* @see getHead() */
public static String phReplaceParameters(String expression,
Object[][] syl, int currentIndex, String head,
Object[][] osyl, int currentCrossIndex){
//First step : change all parameters
/* List of parameters :
* %sK start Karaoke when syllabe must start highlight
* %eK end Karaoke when syllabe must stop highlight
* %dK during Karaoke
* %osK start Karaoke as original %sK (if perletter mode)
* %oeK end Karaoke as original %eK (if perletter mode)
* %odK during Karaoke as original %dK (if perletter mode)
* %dP during sentence
* %posAF[] randomized position
* %num[] randomized number
*/
try{
//%sK - start Karaoke
expression = expression.replaceAll("%sK",
syl[currentIndex][3].toString());
//%eK - end Karaoke
expression = expression.replaceAll("%eK",
syl[currentIndex][4].toString());
//%dK - during Karaoke
expression = expression.replaceAll("%dK",
syl[currentIndex][2].toString());
if(osyl != null && Integer.valueOf(currentCrossIndex) != -1){
//%osK - start Karaoke
expression = expression.replaceAll("%osK",
osyl[currentCrossIndex][3].toString());
//%oeK - end Karaoke
expression = expression.replaceAll("%oeK",
osyl[currentCrossIndex][4].toString());
//%odK - during Karaoke
expression = expression.replaceAll("%odK",
osyl[currentCrossIndex][2].toString());
}
if(head != null){
Pattern p = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher m = p.matcher(head);
Time start = new Time();
Time end = new Time();
Time t = new Time();
boolean endTime = false;
while(m.find()){
if (endTime == false){
start.setHours(Integer.parseInt(m.group(1)));
start.setMinutes(Integer.parseInt(m.group(2)));
start.setSeconds(Integer.parseInt(m.group(3)));
start.setMilliseconds(Integer.parseInt(m.group(4))*10);
}else{
end.setHours(Integer.parseInt(m.group(1)));
end.setMinutes(Integer.parseInt(m.group(2)));
end.setSeconds(Integer.parseInt(m.group(3)));
end.setMilliseconds(Integer.parseInt(m.group(4))*10);
}
endTime = true;
}
t = t.substract(start, end);
//%dP - during sentence
expression = expression.replaceAll("%dP",
Long.toString(t.toMillisecondsTime(t)));
}
//%posAF[] - randomized position
while(expression.contains("%posAF[")){
Pattern p = Pattern.compile("(\\d+),(\\d+),(\\d+),(\\d+)");
Matcher m = p.matcher(expression);
m.find();
int x1 = Integer.parseInt(m.group(1));
int y1 = Integer.parseInt(m.group(2));
int x2 = Integer.parseInt(m.group(3));
int y2 = Integer.parseInt(m.group(4));
double x = x1+Math.round((x2-x1)*Math.random());
double y = y1+Math.round((y2-y1)*Math.random());
int index0 = expression.indexOf("%posAF[");
int index1 = expression.indexOf("]",index0);
expression = expression.substring(0, index0) + x + "," + y +
expression.substring(index1+1);
}
//%num[] - randomized number
while(expression.contains("%num[")){
Pattern p = Pattern.compile("(\\d+),(\\d+)");
Matcher m = p.matcher(expression);
m.find();
int a1 = Integer.parseInt(m.group(1));
int a2 = Integer.parseInt(m.group(2));
double a = a1+Math.round((a2-a1)*Math.random());
int index0 = expression.indexOf("%num[");
int index1 = expression.indexOf("]",index0);
expression = expression.substring(0, index0) + a +
expression.substring(index1+1);
}
//Second step : calculate everything but calcul with constant
//`` (result in float)
while(expression.contains("`")){
Calcul calc = new Calcul();
int index0 = expression.indexOf("`");
int index1 = expression.indexOf("`",index0+1);
String aCalcul = expression.substring(index0+1, index1);
String aResult = calc.doCalcul(aCalcul,true);
expression = expression.substring(0, index0) + aResult +
expression.substring(index1+1);
}
//~~ (result in integer)
while(expression.contains("~")){
Calcul calc = new Calcul();
int index0 = expression.indexOf("~");
int index1 = expression.indexOf("~",index0+1);
String aCalcul = expression.substring(index0+1, index1);
String aResult = calc.doCalcul(aCalcul,false);
expression = expression.substring(0, index0) + aResult +
expression.substring(index1+1);
}
//Treatment of error \t(0,0,<effects>)
while(expression.contains("t(0,0")){
Pattern p = Pattern.compile("t\\(0,0,([^\\)]+)\\)");
Matcher m = p.matcher(expression);
m.find();
int index0 = expression.indexOf("\\t(0,0");
int index1 = expression.indexOf(")",index0+1);
expression = expression.substring(0, index0) + m.group(1) +
expression.substring(index1+1);
}
}catch(NullPointerException npe){
}catch(Exception exc){
}
//Second step : calculate
// Calcul calc = new Calcul();
// System.out.println("Le résultat de -(-20.001*-2.3)--8 est : " +
// calc.doCalcul("-(-20.001*-2.3)--8"));
return expression;
}
/** <p>Return the request line of the 'Original tab' table or a fake line
* if there is an error. Use it with scripts and XFX.<br />
* Retourne la ligne voulue de la table 'Original' ou, si non trouvé,
* une fausse ligne. A utiliser avec les scripts et les XFX.</p>
* @param row A line number.
* @return A line in ASS format. */
public static String getOrgLine(int row){
try{
String[] s = new String[12];
for (int i=0; i<12; i++){
s[i] = (String)orgModel.getValueAt(row, i);
}
ProgramLine pl = AssIO.Format(s, AssIO.ModeFormat.ProgramToASS);
return pl.toAssLine();
}catch(Exception ex){
return "Dialogue: 0,0:00:00.00,0:00:00.00,NoStyle,," +
"0000,0000,0000,,ERROR: "+ex.getMessage();
}
}
/** <p>Return the next selected line of the 'Original tab' table or a fake
* line if there is an error. Use it with scripts and XFX.<br />
* Retourne la ligne sélectionnée de la table 'Original' ou, si non trouvé,
* une fausse ligne. A utiliser avec les scripts et les XFX.</p>
* @return A line in ASS format. */
public static String getSelectedOrgLine(){
if(feuille.karaoke.KaraokePanel.getLastSelectedRow()!=-1){
String[] s = new String[12];
for (int i=0; i<12; i++){
s[i] = (String)orgModel.getValueAt(feuille.karaoke.KaraokePanel.getLastSelectedRow(), i);
}
ProgramLine pl = AssIO.Format(s, AssIO.ModeFormat.ProgramToASS);
return pl.toAssLine();
}else{
return "Dialogue: 0,0:00:00.00,0:00:00.00,NoStyle,," +
"0000,0000,0000,,ERROR: No selected line to process.";
}
}
/** <p>Return the selected lines of the 'Original tab' table.
* Use it with scripts and XFX.<br />
* Retourne les lignes sélectionnées de la table 'Original'.
* A utiliser avec les scripts et les XFX.</p>
* @return The lines in ASS format. */
public static String[] getSelectedOrgLines(){
String[] table = new String[feuille.karaoke.KaraokePanel.getSelectedRows().length];
int count = 0;
for(int index : feuille.karaoke.KaraokePanel.getSelectedRows()){
String[] s = new String[12];
for (int i=0; i<12; i++){
s[i] = (String)orgModel.getValueAt(index, i);
}
ProgramLine pl = AssIO.Format(s, AssIO.ModeFormat.ProgramToASS);
table[count] = pl.toAssLine();
count += 1;
}
return table;
}
/** <p>Return the moment of this XMLPreset (XFX) or 'undefined?'.
* <br />Moment can be :<br />
* <li><code>Before</code></li>
* <li><code>Meantime</code></li>
* <li><code>After</code></li><br /></p>
* <p>Retourne le moment de ce XFX ou la chaine d'erreur 'undefined?'.
* <br />Le moment peut être :<br />
* <li><code>Avant</code></li>
* <li><code>Pendant</code></li>
* <li><code>Après</code></li></p> */
public static String getFxoMoment(String xmlpresetname){
// for (FxObject fxo : (FxObject[])fxModel.toArray()){
for (FxObject fxo : feuille.karaoke.KaraokePanel.getFxObjectListFromFxTree()){
if(fxo.getName().equals(xmlpresetname)){
return fxo.getMoment();
}
}
return "undefined?";
}
/** <p>Return the time of this XMLPreset (XFX) or 'undefined?'.<br />
* Retourne le temps de ce XFX ou revoit la chaine d'erreur 'undefined?'.</p> */
public static String getFxoTime(String xmlpresetname){
for (FxObject fxo : feuille.karaoke.KaraokePanel.getFxObjectListFromFxTree()){
if(fxo.getName().equals(xmlpresetname)){
return fxo.getTime();
}
}
return "undefined?";
}
/** <p>Return the first layer of this XMLPreset (XFX) or 'undefined?'.<br />
* Retourne la première couche de ce XFX ou revoit la chaine d'erreur 'undefined?'.</p> */
public static String getFxoFirstLayer(String xmlpresetname){
for (FxObject fxo : feuille.karaoke.KaraokePanel.getFxObjectListFromFxTree()){
if(fxo.getName().equals(xmlpresetname)){
return fxo.getFirstLayer();
}
}
return "undefined?";
}
/** <p>Return the number of layers of this XMLPreset (XFX) or 'undefined?'.<br />
* Retourne le nombre de couches de ce XFX ou revoit la chaine d'erreur 'undefined?'.</p> */
public static String getFxoNbLayers(String xmlpresetname){
for (FxObject fxo : feuille.karaoke.KaraokePanel.getFxObjectListFromFxTree()){
if(fxo.getName().equals(xmlpresetname)){
return fxo.getNbLayers();
}
}
return "undefined?";
}
/** <p>Return the style of this XMLPreset (XFX) or 'undefined?'.<br />
* Retourne le style de ce XFX ou revoit la chaine d'erreur 'undefined?'.</p> */
public static String getFxoStyle(String xmlpresetname){
for (FxObject fxo : feuille.karaoke.KaraokePanel.getFxObjectListFromFxTree()){
if(fxo.getName().equals(xmlpresetname)){
return fxo.getStyle();
}
}
return "undefined?";
}
/** <p>Return a table of abscissa :<br />
* [i][0] : abscissa of x on the left of the syllable in course.<br />
* [i][1] : abscissa of x on the right of the syllable in course.<br />
* [i][2] : abscissa of x on the middle of the syllable in course.<br />
* Attention : The text is in the left.<br /><br />
* Retourne un tableau d'abscisse :<br />
* [i][0] : abscisse de x sur la gauche de la syllabe en cours.<br />
* [i][1] : abscisse de x sur la droite de la syllabe en cours.<br />
* [i][2] : abscisse de x sur le milieu de la syllabe en cours.<br />
* Attention : Le texte est à gauche.</p> */
public static double[][] phXAbscissas(Font font, String sentence){
//{\k31}ra
//(?<temps>\d+)\}(?<syllabe>[^\{]*) en vb.net
//(\\d+)\\}([^\\{]*) en java
Pattern p = Pattern.compile("(\\d+)\\}([^\\{]*)");
Matcher m = p.matcher(sentence);
List<String> syl = new ArrayList<String>();
while(m.find()){
syl.add(m.group(2));
}
// fake frame but I need it to work with FontMetrics in static
java.awt.Frame frm = new java.awt.Frame();
FontMetrics fm=frm.getFontMetrics(font);
double[][] xAbscisse = new double[syl.size()][3];
double pX = 0;
double coef = pf.coefProblemFont(font);
for(int i=0;i<syl.size();i++){
int width = (int)(fm.stringWidth(syl.get(i))*coef);
xAbscisse[i][0] = pX; //x coté gauche
xAbscisse[i][1] = width+pX;//x coté droit
xAbscisse[i][2] = width/2+pX;//x milieu
System.out.println(">>> "+xAbscisse[i][0]+" "
+xAbscisse[i][1]+" "+xAbscisse[i][2]+" <<<");
pX = xAbscisse[i][1];
}
return xAbscisse;
}
/** <p>Return a table of ordinate :<br />
* [0] : ordinate of y on the bottom of the line.<br />
* [1] : ordinate of y on the top of the line.<br />
* [2] : ordinate of y on the middle of the line.<br />
* Attention : The text is at top.<br /><br />
* Retourne un tableau d'ordonné :<br />
* [0] : ordonné de y sur le bas de la ligne.<br />
* [1] : ordonné de y sur le haut de la ligne.<br />
* [2] : ordonné de y sur le milieu de la ligne.<br />
* Attention : Le texte est en haut.</p> */
public static double[] phYOrdinates(Font font){
// fake frame but I need it to work with FontMetrics in static
java.awt.Frame frm = new java.awt.Frame();
FontMetrics fm=frm.getFontMetrics(font);
double[] yOrdinates = new double[3];
yOrdinates[0] = fm.getHeight(); // bottom
yOrdinates[1] = 0; // top
yOrdinates[2] = fm.getHeight()/2; // middle
return yOrdinates;
}
/** <p>Get the width of the video (defined in the options).<br />
* Obtient la largeur de la vidéo (défini dans les options).</p> */
public static int getVideoWidth(){
return videoWidth;
}
/** <p>Get the height of the video (defined in the options).<br />
* Obtient la hauteur de la vidéo (défini dans les options).</p> */
public static int getVideoHeight(){
return videoHeight;
}
/** <p>Get a stripped sentence from a karaoke sentence.<br />
* Obtient une phrase sans temps de karaoke à partir d'une phrase avec des karaoke.</p> */
public static String getStrippedSentence(String sentence){
//{\k31}ra
//(?<temps>\d+)\}(?<syllabe>[^\{]*) en vb.net
//(\\d+)\\}([^\\{]*) en java
Pattern p = Pattern.compile("\\d+\\}([^\\{]*)");
Matcher m = p.matcher(sentence);
String newSentence = "";
while(m.find()){
newSentence = newSentence + m.group(1);
}
return newSentence;
}
/** <p>Get the width of the sentence.<br />
* Obtient la largeur de la phrase.</p> */
public static int getStringWidth(Font font, String sentence){
// fake frame but I need it to work with FontMetrics in static
java.awt.Frame frm = new java.awt.Frame();
FontMetrics fm=frm.getFontMetrics(font);
double coef = pf.coefProblemFont(font);
int sWidth = (int)(fm.stringWidth(getStrippedSentence(sentence))*coef);
return sWidth;
}
/** <p>Get the position of x from the style.<br />
* Obtient la position de x à partir du style.</p> */
public static int getPosXFromStyle(AssStyle as, String sentence){
int posX = -1;
Font font = as.getFont();//Search for font
int sentenceWidth = getStringWidth(font, sentence);
if(as.getAlignment()==1 | as.getAlignment()==4 | as.getAlignment()==7){
//if text is to the left then posX=marginL
return as.getMarginL();
}else if(as.getAlignment()==2 | as.getAlignment()==5 | as.getAlignment()==8){
//if text is to the center then posX=(videoWidth-sentenceWidth)/2
return (videoWidth-sentenceWidth)/2;
}else if(as.getAlignment()==3 | as.getAlignment()==6 | as.getAlignment()==9){
//if text is to the right then posX=videoWidth-(sentenceWidth+marginR)
return videoWidth-(sentenceWidth+as.getMarginR());
}
return posX; //error
}
/** <p>Get the position of y from the style.<br />
* Obtient la position de y à partir du style.</p> */
public static int getPosYFromStyle(AssStyle as){
int posY = -1;
//Font font = as.getFont();//Search for font
if(as.getAlignment()==1 | as.getAlignment()==2 | as.getAlignment()==3){
return videoHeight-as.getMarginB();
}else if(as.getAlignment()==4 | as.getAlignment()==5 | as.getAlignment()==6){
return videoHeight/2;
}else if(as.getAlignment()==7 | as.getAlignment()==8 | as.getAlignment()==9){
return as.getMarginT();
}
return posY; //error
}
/** <p>Replace all position parameters of sentence.<br />
* Remplace tous les paramètres de position de la phrase.</p>
* @param expression The sentence that contains parameters.
* @param abscissas A table of abscissas (phXAbscissas).
* @param ordinates A table of ordinates (phYOrdinates).
* @param offsetX A distance between sentence and the border on X (getPosXFromStyle).
* @param offsetY A distance between sentence and the border on Y (getPosYFromStyle).
* @param currentIndex The index in course.
* @see phXAbscissas()
* @see phYOrdinates()
* @see getPosXFromStyle()
* @see getPosYFromStyle()
* @return A sentence without parameters. */
public static String phReplacePosParameters(String expression,
double[][] abscissas, double[] ordinates, int offsetX, int offsetY,
int currentIndex){
/*
* %posXn where n = 1,2,3,4,5,6,7,8,9 (like ASS alignment)
* %posYn where n = 1,2,3,4,5,6,7,8,9 (like ASS alignment)
*/
//%posX1,4,7 - left
if(expression.contains("%posX1")
| expression.contains("%posX4") | expression.contains("%posX7")){
int posX = (int)abscissas[currentIndex][0]+offsetX;
expression = expression.replaceAll("%posX1",Integer.toString(posX));
expression = expression.replaceAll("%posX4",Integer.toString(posX));
expression = expression.replaceAll("%posX7",Integer.toString(posX));
}
//%posX2,5,8 - middle
if(expression.contains("%posX2")
| expression.contains("%posX5") | expression.contains("%posX8")){
int posX = (int)abscissas[currentIndex][2]+offsetX;
expression = expression.replaceAll("%posX2",Integer.toString(posX));
expression = expression.replaceAll("%posX5",Integer.toString(posX));
expression = expression.replaceAll("%posX8",Integer.toString(posX));
}
//%posX3,6,9 - right
if(expression.contains("%posX3")
| expression.contains("%posX6") | expression.contains("%posX9")){
int posX = (int)abscissas[currentIndex][1]+offsetX;
expression = expression.replaceAll("%posX3",Integer.toString(posX));
expression = expression.replaceAll("%posX6",Integer.toString(posX));
expression = expression.replaceAll("%posX9",Integer.toString(posX));
}
//%posY1,2,3 - bottom
if(expression.contains("%posY1")
| expression.contains("%posY2") | expression.contains("%posY3")){
int posY = videoHeight/2>offsetY? offsetY+(int)ordinates[0]:offsetY-(int)ordinates[0];
expression = expression.replaceAll("%posY1",Integer.toString(posY));
expression = expression.replaceAll("%posY2",Integer.toString(posY));
expression = expression.replaceAll("%posY3",Integer.toString(posY));
}
//%posY4,5,6 - middle
if(expression.contains("%posY4")
| expression.contains("%posY5") | expression.contains("%posY6")){
int posY = videoHeight/2>offsetY? offsetY+(int)ordinates[2]:offsetY-(int)ordinates[2];
expression = expression.replaceAll("%posY4",Integer.toString(posY));
expression = expression.replaceAll("%posY5",Integer.toString(posY));
expression = expression.replaceAll("%posY6",Integer.toString(posY));
}
//%posY7,8,9 - top
if(expression.contains("%posY7")
| expression.contains("%posY8") | expression.contains("%posY9")){
int posY = (int)ordinates[1]+offsetY;
expression = expression.replaceAll("%posY7",Integer.toString(posY));
expression = expression.replaceAll("%posY8",Integer.toString(posY));
expression = expression.replaceAll("%posY9",Integer.toString(posY));
}
return expression;
}
/** <p>Get a color from the style.<br />
* Obtient une couleur à partir du script.</p> */
public static String[] getColorFromStyle(String style){
try{
String[] colors = new String[4];
for (AssStyle as : ascScript.getMembers()){
if(as.getElement(AssStyle.AssStyleType.name).equals(style)){
String color1, color2, color3, color4;
color1 = as.getElement(AssStyle.AssStyleType.primarycolour, "+");
color2 = as.getElement(AssStyle.AssStyleType.secondarycolour, "+");
color3 = as.getElement(AssStyle.AssStyleType.outlinecolour, "+");
color4 = as.getElement(AssStyle.AssStyleType.backcolour, "+");
colors[0] = "H"+color1.substring(2);
colors[1] = "H"+color2.substring(2);
colors[2] = "H"+color3.substring(2);
colors[3] = "H"+color4.substring(2);
}
}
return colors;
}catch(Exception exc){
return null;
}
}
public static int[] phPosXSyllable(Object[][] kara, String assline, float poscor, int spacor, AssStyle astyle){
// AssStyle astyle = new AssStyle();
// //Get AssStyle from assline
// Pattern p = Pattern.compile("[^:]+:\\s[a-zA-Z=]*\\d+," +
// "\\d+:\\d+:\\d+.\\d+," +
// "\\d+:\\d+:\\d+.\\d+," +
// "([^,]+),[^,]*," +
// "\\d+,\\d+,\\d+,[^,]*,(.*)");
// Matcher m = p.matcher(assline); m.find();
// String style = m.group(1);
// for (AssStyle as : ascScript.getMembers()){
// if(as.getElement(AssStyleType.name).equals(style)){
// astyle = as;
// }
// }
//Create a false image from text measuring
java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(10, 10, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics gra = bi.getGraphics();
FontMetrics fm = gra.getFontMetrics(astyle.getFont());
int[] position = new int[kara.length];
float totalSize = 0;
for(int i=0;i<kara.length;i++){
String str = (String)kara[i][0];
int sylSize = Math.round(fm.stringWidth(str)/poscor);
position[i] = Math.round(totalSize+sylSize/2);
if(str.contains(" ")){
sylSize = sylSize + spacor;
}
totalSize += sylSize;
}
return position;
}
public static int[] phPosXSyllable(Object[][] kara, AssStyle astyle){
//Create a false image from text measuring
java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(10, 10, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics gra = bi.getGraphics();
FontMetrics fm = gra.getFontMetrics(astyle.getFont());
double coef = pf.coefProblemFont(astyle.getFont());
int[] position = new int[kara.length];
float totalSize = 0;
for(int i=0;i<kara.length;i++){
String str = (String)kara[i][0];
int sylSize = (int)(fm.stringWidth(str)*coef);
position[i] = Math.round(totalSize+sylSize/2);
totalSize += sylSize;
}
return position;
}
public static int phXSentenceWidth(Object[][] kara, String assline, float poscor, int spacor, AssStyle astyle){
// AssStyle astyle = new AssStyle();
// //Get AssStyle from assline
// Pattern p = Pattern.compile("[^:]+:\\s[a-zA-Z=]*\\d+," +
// "\\d+:\\d+:\\d+.\\d+," +
// "\\d+:\\d+:\\d+.\\d+," +
// "([^,]+),[^,]*," +
// "\\d+,\\d+,\\d+,[^,]*,(.*)");
// Matcher m = p.matcher(assline); m.find();
// String style = m.group(1);
// for (AssStyle as : ascScript.getMembers()){
// if(as.getElement(AssStyleType.name).equals(style)){
// astyle = as;
// }
// }
//Create a false image from text measuring
java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(10, 10, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics gra = bi.getGraphics();
FontMetrics fm = gra.getFontMetrics(astyle.getFont());
float totalSize = 0;
for(int i=0;i<kara.length;i++){
String str = (String)kara[i][0];
int sylSize = Math.round(fm.stringWidth(str)/poscor);
if(str.contains(" ")){
sylSize = sylSize + spacor;
}
totalSize += sylSize;
}
return Math.round(totalSize);
}
public static int phXSentenceWidth(Object[][] kara, AssStyle astyle){
//Create a false image from text measuring
java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(10, 10, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics gra = bi.getGraphics();
FontMetrics fm = gra.getFontMetrics(astyle.getFont());
double coef = pf.coefProblemFont(astyle.getFont());
float totalSize = 0;
for(int i=0;i<kara.length;i++){
String str = (String)kara[i][0];
int sylSize = (int)(fm.stringWidth(str)*coef);
totalSize += sylSize;
}
return Math.round(totalSize);
}
public static int phXCharsWidth(String sentence, AssStyle astyle){
//Create a false image from text measuring
java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(10, 10, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics gra = bi.getGraphics();
//Get the metrics for the used font
FontMetrics fm = gra.getFontMetrics(astyle.getFont());
int advance = gra.getFontMetrics().getMaxAdvance();
int width = getMaxWidth(fm);
//Calculation
int totalSize = 0; int emuSize = 0;
System.out.println("La phrase est : "+sentence);
System.out.println("La police est : "+astyle.getFontname());
System.out.println("La taile de la police est : "+astyle.getFont().getSize());
System.out.println("MaxAdvance : "+advance);
for(int i=0;i<sentence.length();i++){
char letter = sentence.charAt(i);
int letterSize = fm.charWidth(letter);
int letterSize2 = letterSize * advance / width - (advance*20/100);// + (advance*17/100)
System.out.println("Caractère en cours : '"+letter+"'");
System.out.println("La largeur de ce caractère est : "+letterSize);
System.out.println("La largeur émulée : "+letterSize2);
totalSize += letterSize;
emuSize += letterSize2;
}
System.out.println("Phrase émulée : "+emuSize);
return Math.round(emuSize);
}
public static int getMaxWidth(FontMetrics fm){
String alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int max = 0;
for(int i=0;i<alpha.length();i++){
char letter = alpha.charAt(i);
int letterSize = fm.charWidth(letter);
max = letterSize > max ? letterSize : max;
}
return max;
}
public static String getKaraokeStart(){
return feuille.karaoke.KaraokePanel.getKaraokeStart();
}
public static String getKaraokeEnd(){
return feuille.karaoke.KaraokePanel.getKaraokeEnd();
}
public static String getKaraokeDuration(){
return feuille.karaoke.KaraokePanel.getKaraokeDuration();
}
public static String getKaraokeOStart(){
return feuille.karaoke.KaraokePanel.getKaraokeOStart();
}
public static String getKaraokeOEnd(){
return feuille.karaoke.KaraokePanel.getKaraokeOEnd();
}
public static String getKaraokeODuration(){
return feuille.karaoke.KaraokePanel.getKaraokeODuration();
}
public static String getKaraokeSDuration(){
return feuille.karaoke.KaraokePanel.getKaraokeSDuration();
}
/** <p>Add a line at the end of lines of the 'Original tab' table.
* Use it with scripts and XFX.<br />
* Ajoute une ligne à la fin de la table 'Original'.
* A utiliser avec les scripts et les XFX.</p>
* @param oline Your line in ASS format. */
public static void addOrgLine(Object oline){
String s = (String)oline;
ProgramLine pl = AssIO.Format(s,AssIO.ModeFormat.ASSToProgram);
if(pl.getLineType().getLabel()
.equals(ProgramLine.LineType.Nothing.getLabel())==false){
orgModel.addRow(pl.toRow());
}
}
/** <p>Add a line at the end of lines of the 'Result tab' table.
* Use it with scripts and XFX.<br />
* Ajoute une ligne à la fin de la table 'Résultat'.
* A utiliser avec les scripts et les XFX.</p>
* @param oline Your line in ASS format. */
public static void addResLine(Object oline){
String s = (String)oline;
ProgramLine pl = AssIO.Format(s,AssIO.ModeFormat.ASSToProgram);
if(pl.getLineType().getLabel()
.equals(ProgramLine.LineType.Nothing.getLabel())==false){
resModel.addRow(pl.toRow());
}
}
public static AssStyle getAssStyle(String line){
//Get AssStyle from assline
Pattern p = Pattern.compile("[^:]+:\\s[a-zA-Z=]*\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"\\d+:\\d+:\\d+.\\d+," +
"([^,]+),[^,]*," +
"\\d+,\\d+,\\d+,[^,]*,(.*)");
Matcher m = p.matcher(line); m.find();
String style = m.group(1);
for (AssStyle as : ascScript.getMembers()){
if(as.getElement(AssStyleType.name).equals(style)){
return as;
}
}
return null;
}
public static void regenerateAssStyleCollection(){
ascScript = feuille.MainFrame.getAssStyleCollection();
}
/** <p>Launch the selected link and open a browser.<br />
* Lance le lien sélectionné et ou un navigateur.</p> */
public static void openLink(String link){
boolean hasResult = true;
if(java.awt.Desktop.isDesktopSupported()){
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
if(desktop.isSupported(java.awt.Desktop.Action.BROWSE)){
try {
try {
desktop.browse(new java.net.URI(link));
} catch (java.io.IOException ex) {hasResult = false;}
} catch (java.net.URISyntaxException ex) {hasResult = false;}
}else{
hasResult = false;
}
}else{
hasResult = false;
}
if(hasResult==false){
java.util.Properties sys = System.getProperties();
String os = sys.getProperty("os.name").toLowerCase();
try {
if(os.contains("windows")==true){
Process proc = Runtime.getRuntime().exec("cmd /c start "+link);
}else{
Process proc = Runtime.getRuntime().exec("start "+link);
}
} catch (java.io.IOException e) {
// unsupported
}
}
}
/** <p>Launch the selected link and open a browser.<br />
* Lance le lien sélectionné et ou un navigateur.</p> */
public static void openFile(String doc){
boolean hasResult = true;
if(java.awt.Desktop.isDesktopSupported()){
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
if(desktop.isSupported(java.awt.Desktop.Action.OPEN)){
try {
desktop.open(new File(doc));
} catch (Exception ex) {hasResult = false;}
}else{
hasResult = false;
}
}else{
hasResult = false;
}
if(hasResult==false){
java.util.Properties sys = System.getProperties();
String os = sys.getProperty("os.name").toLowerCase();
try {
if(os.contains("windows")==true){
Process proc = Runtime.getRuntime().exec("cmd /c start "+doc);
}else{
Process proc = Runtime.getRuntime().exec("start "+doc);
}
} catch (java.io.IOException e) {
// unsupported
}
}
}
//============================= DRAWING ====================================
/** <p>Register a function of a script. (JRuby-Jython)<br />
* Enregistre une fonction d'un script. (JRuby-Jython)</p>
* @param oname The display name for your effect. (required)
* @param ofunction The def function's name to use. (required)
* @param oversion Your revision.
* @param odescription A small description to explain your function.
* @param oauthor Your name or team name.
*/
public static void aspRegister(Object oname, Object ofunction,
Object oversion, Object odescription, Object oauthor){
if(actualPath!=null && actualPath.equals("")==false){
DrawingScript scr = new DrawingScript(
oname.toString(),
odescription.toString(),
oversion.toString(),
oauthor.toString(),
actualPath,
ofunction.toString());
sobjectList.add(scr);
}
}
public static void add_M_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
ReStart m = new ReStart(x+1000, y+1000, x+1000, y+1000);
lay.getShapesList().addShape(m); lay.addRemember(m);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_N_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
Move m = new Move(x+1000, y+1000, x+1000, y+1000);
lay.getShapesList().addShape(m); lay.addRemember(m);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_L_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
java.awt.Point point;
try{
point = lay.getShapesList().getLastPoint().getLastPoint();
}catch(Exception e){
point = lay.getShapesList().getLastShape().getLastPoint();
}
Point p = new Point(x+1000, y+1000);
lay.getShapesList().addShape(p); lay.addRemember(p);
Line l = new Line(point.x, point.y, x+1000, y+1000);
lay.getShapesList().addShape(l); lay.addRemember(l);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_B_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
java.awt.Point point;
try{
point = lay.getShapesList().getLastPoint().getLastPoint();
}catch(Exception e){
point = lay.getShapesList().getLastShape().getLastPoint();
}
Point p = new Point(x+1000, y+1000);
lay.getShapesList().addShape(p); lay.addRemember(p);
Bezier b = new Bezier(point.x, point.y, x+1000, y+1000);
lay.getShapesList().addShape(b); lay.addRemember(b);
ControlPoint cp1 = b.getControl1();
lay.getShapesList().addShape(cp1); lay.addRemember(cp1);
ControlPoint cp2 = b.getControl2();
lay.getShapesList().addShape(cp2); lay.addRemember(cp2);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_B_To(int x, int y, int cpx1, int cpy1, int cpx2, int cpy2){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
java.awt.Point point;
try{
point = lay.getShapesList().getLastPoint().getLastPoint();
}catch(Exception e){
point = lay.getShapesList().getLastShape().getLastPoint();
}
Point p = new Point(x+1000, y+1000);
lay.getShapesList().addShape(p); lay.addRemember(p);
Bezier b = new Bezier(point.x, point.y, cpx1+1000, cpy1+1000, cpx2+1000, cpy2+1000, x+1000, y+1000);
lay.getShapesList().addShape(b); lay.addRemember(b);
ControlPoint cp1 = b.getControl1();
lay.getShapesList().addShape(cp1); lay.addRemember(cp1);
ControlPoint cp2 = b.getControl2();
lay.getShapesList().addShape(cp2); lay.addRemember(cp2);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_S_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
java.awt.Point point;
try{
point = lay.getShapesList().getLastPoint().getLastPoint();
}catch(Exception e){
point = lay.getShapesList().getLastShape().getLastPoint();
}
Point p = new Point(x+1000, y+1000);
lay.getShapesList().addShape(p); lay.addRemember(p);
BSpline bs = new BSpline(point.x, point.y);
lay.getShapesList().addShape(bs); lay.addRemember(bs);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_S_To(int x, int y, int[] cpx, int[] cpy){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
java.awt.Point point;
try{
point = lay.getShapesList().getLastPoint().getLastPoint();
}catch(Exception e){
point = lay.getShapesList().getLastShape().getLastPoint();
}
Point p = new Point(x+1000, y+1000);
lay.getShapesList().addShape(p); lay.addRemember(p);
BSpline bs = new BSpline(point.x, point.y);
lay.getShapesList().addShape(bs); lay.addRemember(bs);
for(int i=0; i<cpx.length; i++){
try{
bs.addPoint(cpx[i], cpy[i]);
}catch(Exception e){}
}
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public static void add_P_To(int x, int y){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
IShape s = lay.getShapesList().getLastShape();
if(s instanceof BSpline){
BSpline bs = (BSpline)s;
bs.setNextPoint(x+1000, y+1000);
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
}
public static void add_C(){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
IShape s = lay.getShapesList().getLastShape();
if(s instanceof BSpline){
BSpline bs = (BSpline)s;
if(bs.isNextExist()==false){
bs.setClosed(true);
}
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
}
public static int createLayer(String name, int r, int g, int b){
return feuille.drawing.DrawingPanel.createLayer(name, r, g, b);
}
public static boolean changeLayer(int id){
return feuille.drawing.DrawingPanel.changeLayer(id);
}
public static void setLayerName(String name){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
lay.setName(name);
feuille.drawing.DrawingPanel.updateLayerList();
}
public static void setLayerColor(int r, int g, int b){
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
try{
lay.setColor(new Color(r,g,b));
}catch(Exception e){
lay.setColor(Color.green);
}
feuille.drawing.DrawingPanel.updateLayerList();
}
public static void addASSCommands(String asscommands){
feuille.drawing.DrawingPanel.shapesFromCommands(asscommands, null, 0, 0, null, 0);
Layer lay = feuille.drawing.DrawingPanel.getCurrentLayer();
Sheet sh = feuille.drawing.DrawingPanel.getSheet();
sh.updateGeneralPath(lay.getGeneralPath());
sh.updateShapesList(lay.getShapesList());
lay.setFirstPoint(lay.getLastPoint());
feuille.drawing.DrawingPanel.updateRemember(lay);
feuille.drawing.DrawingPanel.setAssCommands();
}
public List<Object> getObjectsList(){
return sobjectList;
}
}