Semi-functional new fonts collector, using jfs's freetype2 font finding engine. Only font copying and checking work... and stuff also needs general tweaking.

Originally committed to SVN as r1270.
This commit is contained in:
Rodrigo Braz Monteiro 2007-06-20 05:18:47 +00:00
parent de107f3108
commit fa293466d6
9 changed files with 516 additions and 358 deletions

View file

@ -163,6 +163,7 @@ aegisub_SOURCES = \
export_framerate.cpp \ export_framerate.cpp \
export_visible_lines.cpp \ export_visible_lines.cpp \
fft.cpp \ fft.cpp \
font_file_lister.cpp \
frame_main.cpp \ frame_main.cpp \
frame_main_events.cpp \ frame_main_events.cpp \
gl_text.cpp \ gl_text.cpp \

View file

@ -76,6 +76,7 @@ DialogAttachments::DialogAttachments(wxWindow *parent)
mainSizer->Add(buttonSizer,0,wxALL | wxEXPAND,5); mainSizer->Add(buttonSizer,0,wxALL | wxEXPAND,5);
mainSizer->SetSizeHints(this); mainSizer->SetSizeHints(this);
SetSizer(mainSizer); SetSizer(mainSizer);
CenterOnParent();
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro // Copyright (c) 2007, Rodrigo Braz Monteiro
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -40,9 +40,6 @@
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <wx/zipstrm.h> #include <wx/zipstrm.h>
#ifdef __WINDOWS__
#include <shlobj.h>
#endif
#include "ass_override.h" #include "ass_override.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
@ -53,6 +50,17 @@
#include "frame_main.h" #include "frame_main.h"
#include "subs_grid.h" #include "subs_grid.h"
#include "main.h" #include "main.h"
#include "font_file_lister.h"
#include "utils.h"
///////
// IDs
enum IDs {
START_BUTTON = 1150,
BROWSE_BUTTON,
RADIO_BOX
};
/////////////// ///////////////
@ -71,11 +79,6 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent)
} }
DestBox = new wxTextCtrl(this,-1,dest,wxDefaultPosition,wxSize(250,20),0); DestBox = new wxTextCtrl(this,-1,dest,wxDefaultPosition,wxSize(250,20),0);
BrowseButton = new wxButton(this,BROWSE_BUTTON,_("&Browse...")); BrowseButton = new wxButton(this,BROWSE_BUTTON,_("&Browse..."));
AttachmentCheck = new wxCheckBox(this,ATTACHMENT_CHECK,_("As attachments"),wxDefaultPosition);
AttachmentCheck->SetValue(Options.AsBool(_T("Fonts Collector Attachment")));
ArchiveCheck = new wxCheckBox(this,ARCHIVE_CHECK,_("As a zipped archive"),wxDefaultPosition);
ArchiveCheck->SetValue(Options.AsBool(_T("Fonts Collector Archive")));
if (ArchiveCheck->GetValue()) AttachmentCheck->SetValue(false);
wxSizer *DestBottomSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer *DestBottomSizer = new wxBoxSizer(wxHORIZONTAL);
DestLabel = new wxStaticText(this,-1,_("Choose the folder where the fonts will be collected to.\nIt will be created if it doesn't exist.")); DestLabel = new wxStaticText(this,-1,_("Choose the folder where the fonts will be collected to.\nIt will be created if it doesn't exist."));
DestBottomSizer->Add(DestBox,1,wxEXPAND | wxRIGHT,5); DestBottomSizer->Add(DestBox,1,wxEXPAND | wxRIGHT,5);
@ -83,11 +86,23 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent)
wxSizer *DestSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Destination")); wxSizer *DestSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Destination"));
DestSizer->Add(DestLabel,0,wxEXPAND | wxBOTTOM,5); DestSizer->Add(DestLabel,0,wxEXPAND | wxBOTTOM,5);
DestSizer->Add(DestBottomSizer,0,wxEXPAND,0); DestSizer->Add(DestBottomSizer,0,wxEXPAND,0);
DestSizer->Add(AttachmentCheck,0,wxTOP,5);
DestSizer->Add(ArchiveCheck,0,wxTOP,5); // Action radio box
wxArrayString choices;
choices.Add(_T("Check fonts for availability"));
choices.Add(_T("Copy fonts to folder"));
choices.Add(_T("Copy fonts to zipped archive"));
choices.Add(_T("Attach fonts to current subtitles"));
CollectAction = new wxRadioBox(this,RADIO_BOX,_T("Action"),wxDefaultPosition,wxDefaultSize,choices,1);
// Log box // Log box
LogBox = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(300,210),wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH); LogBox = new wxStyledTextCtrl(this,-1,wxDefaultPosition,wxSize(300,210),0,_T(""));
LogBox->SetWrapMode(wxSTC_WRAP_WORD);
LogBox->SetMarginWidth(1,0);
LogBox->SetReadOnly(true);
LogBox->StyleSetForeground(1,wxColour(0,200,0));
LogBox->StyleSetForeground(2,wxColour(200,0,0));
LogBox->StyleSetForeground(3,wxColour(200,100,0));
wxSizer *LogSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Log")); wxSizer *LogSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Log"));
LogSizer->Add(LogBox,1,wxEXPAND,0); LogSizer->Add(LogBox,1,wxEXPAND,0);
@ -107,6 +122,7 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent)
// Main sizer // Main sizer
wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL); wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
MainSizer->Add(CollectAction,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
MainSizer->Add(DestSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); MainSizer->Add(DestSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
MainSizer->Add(LogSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); MainSizer->Add(LogSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
MainSizer->Add(ButtonSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); MainSizer->Add(ButtonSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
@ -114,6 +130,7 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent)
// Set sizer // Set sizer
SetSizer(MainSizer); SetSizer(MainSizer);
MainSizer->SetSizeHints(this); MainSizer->SetSizeHints(this);
CenterOnParent();
// Run dummy event to update label // Run dummy event to update label
Update(); Update();
@ -123,45 +140,17 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent)
////////////// //////////////
// Destructor // Destructor
DialogFontsCollector::~DialogFontsCollector() { DialogFontsCollector::~DialogFontsCollector() {
FontFileLister::ClearData();
} }
////////////////////////////////
// Get fonts from ass overrides
void FontsCollectorThread::GetFonts (wxString tagName,int par_n,AssOverrideParameter *param,void *usr) {
if (tagName == _T("\\fn")) {
instance->AddFont(param->AsText(),false);
}
}
///////////////
// Adds a font
void FontsCollectorThread::AddFont(wxString fontname,bool isStyle) {
if (fonts.Index(fontname) == wxNOT_FOUND) {
fonts.Add(fontname);
// Dialogue
if (!isStyle) {
collector->LogBox->AppendText(wxString(_T("\"")) + fontname + _("\" found on dialogue line ") + wxString::Format(_T("%i"),curLine) + _T(".\n"));
}
}
}
///////////////////
// Static instance
FontsCollectorThread *FontsCollectorThread::instance;
/////////////// ///////////////
// Event table // Event table
BEGIN_EVENT_TABLE(DialogFontsCollector, wxDialog) BEGIN_EVENT_TABLE(DialogFontsCollector, wxDialog)
EVT_BUTTON(START_BUTTON,DialogFontsCollector::OnStart) EVT_BUTTON(START_BUTTON,DialogFontsCollector::OnStart)
EVT_BUTTON(BROWSE_BUTTON,DialogFontsCollector::OnBrowse) EVT_BUTTON(BROWSE_BUTTON,DialogFontsCollector::OnBrowse)
EVT_BUTTON(wxID_CLOSE,DialogFontsCollector::OnClose) EVT_BUTTON(wxID_CLOSE,DialogFontsCollector::OnClose)
EVT_CHECKBOX(ATTACHMENT_CHECK,DialogFontsCollector::OnCheckAttach) EVT_RADIOBOX(RADIO_BOX,DialogFontsCollector::OnRadio)
EVT_CHECKBOX(ARCHIVE_CHECK,DialogFontsCollector::OnCheckArchive)
END_EVENT_TABLE() END_EVENT_TABLE()
@ -171,19 +160,24 @@ void DialogFontsCollector::OnStart(wxCommandEvent &event) {
// Check if it's OK to do it // Check if it's OK to do it
wxString foldername = DestBox->GetValue(); wxString foldername = DestBox->GetValue();
wxFileName folder(foldername); wxFileName folder(foldername);
bool zipOut = ArchiveCheck->IsChecked(); int action = CollectAction->GetSelection();
// Make folder if it doesn't exist // Make folder if it doesn't exist
if (!zipOut && !folder.DirExists()) folder.Mkdir(0777,wxPATH_MKDIR_FULL); if (action == 1 && !folder.DirExists()) {
folder.Mkdir(0777,wxPATH_MKDIR_FULL);
if (!folder.DirExists()) {
wxMessageBox(_("Invalid destination"),_("Error"),wxICON_EXCLAMATION | wxOK);
return;
}
}
// Start // Start thread
if (zipOut || folder.DirExists()) { wxThread *worker = new FontsCollectorThread(AssFile::top,foldername,this);
// Start thread worker->Create();
wxThread *worker = new FontsCollectorThread(AssFile::top,foldername,this); worker->Run();
worker->Create();
worker->Run();
// Set options // Set options
if (action == 1 || action == 2) {
wxString dest = foldername; wxString dest = foldername;
wxFileName filename(AssFile::top->filename); wxFileName filename(AssFile::top->filename);
if (filename.GetPath() == dest) { if (filename.GetPath() == dest) {
@ -191,21 +185,16 @@ void DialogFontsCollector::OnStart(wxCommandEvent &event) {
} }
Options.SetText(_T("Fonts Collector Destination"),dest); Options.SetText(_T("Fonts Collector Destination"),dest);
Options.Save(); Options.Save();
// Set buttons
StartButton->Enable(false);
BrowseButton->Enable(false);
DestBox->Enable(false);
CloseButton->Enable(false);
AttachmentCheck->Enable(false);
ArchiveCheck->Enable(false);
if (!worker->IsDetached()) worker->Wait();
} }
// Folder not available // Set buttons
else { StartButton->Enable(false);
wxMessageBox(_("Invalid destination"),_("Error"),wxICON_EXCLAMATION | wxOK); BrowseButton->Enable(false);
} DestBox->Enable(false);
CloseButton->Enable(false);
CollectAction->Enable(false);
DestLabel->Enable(false);
if (!worker->IsDetached()) worker->Wait();
} }
@ -220,7 +209,7 @@ void DialogFontsCollector::OnClose(wxCommandEvent &event) {
// Browse location // Browse location
void DialogFontsCollector::OnBrowse(wxCommandEvent &event) { void DialogFontsCollector::OnBrowse(wxCommandEvent &event) {
// Chose file name // Chose file name
if (ArchiveCheck->IsChecked()) { if (CollectAction->GetSelection()==2) {
wxFileName fname(DestBox->GetValue()); wxFileName fname(DestBox->GetValue());
wxString dest = wxFileSelector(_("Select archive file name"),DestBox->GetValue(),fname.GetFullName(),_T(".zip"),_T("Zip Archives (*.zip)|*.zip"),wxFD_SAVE|wxFD_OVERWRITE_PROMPT); wxString dest = wxFileSelector(_("Select archive file name"),DestBox->GetValue(),fname.GetFullName(),_T(".zip"),_T("Zip Archives (*.zip)|*.zip"),wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
if (!dest.empty()) { if (!dest.empty()) {
@ -238,41 +227,34 @@ void DialogFontsCollector::OnBrowse(wxCommandEvent &event) {
} }
//////////////////// /////////////////////
// Check Attachment // Radio box changed
void DialogFontsCollector::OnCheckAttach(wxCommandEvent &event) { void DialogFontsCollector::OnRadio(wxCommandEvent &event) {
bool check = AttachmentCheck->IsChecked(); Update(event.GetInt());
BrowseButton->Enable(!check);
DestBox->Enable(!check);
if (check) {
ArchiveCheck->SetValue(false);
Update();
}
}
/////////////////
// Check Archive
void DialogFontsCollector::OnCheckArchive(wxCommandEvent &event) {
bool check = ArchiveCheck->IsChecked();
if (check) {
BrowseButton->Enable(check);
DestBox->Enable(check);
}
Update();
} }
/////////////////// ///////////////////
// Update controls // Update controls
void DialogFontsCollector::Update() { void DialogFontsCollector::Update(int value) {
bool check = ArchiveCheck->IsChecked(); // Get value if -1
if (check) { if (value == -1) {
AttachmentCheck->SetValue(false); value = CollectAction->GetSelection();
DestLabel->SetLabel(_("Enter the name of the destination zip file to collect the fonts to.\nIf a folder is entered, a default name will be used."));
} }
else {
// Set label // Check
if (value == 0) {
DestBox->Enable(false);
BrowseButton->Enable(false);
DestLabel->SetLabel(_T("N/A\n"));
DestLabel->Enable(false);
}
// Collect to folder
else if (value == 1) {
DestBox->Enable(true);
BrowseButton->Enable(true);
DestLabel->Enable(true);
DestLabel->SetLabel(_("Choose the folder where the fonts will be collected to.\nIt will be created if it doesn't exist.")); DestLabel->SetLabel(_("Choose the folder where the fonts will be collected to.\nIt will be created if it doesn't exist."));
// Remove filename from browser box // Remove filename from browser box
@ -288,61 +270,29 @@ void DialogFontsCollector::Update() {
else DestBox->SetValue(((AegisubApp*)wxTheApp)->folderName); else DestBox->SetValue(((AegisubApp*)wxTheApp)->folderName);
} }
} }
}
// Collect to zip
////////////////////// else if (value == 2) {
// Get font filenames DestBox->Enable(true);
wxArrayString FontsCollectorThread::GetFontFiles (wxString face) { BrowseButton->Enable(true);
wxArrayString files; DestLabel->Enable(true);
int n = 0; DestLabel->SetLabel(_("Enter the name of the destination zip file to collect the fonts to.\nIf a folder is entered, a default name will be used."));
for (FontMap::iterator entry = regFonts.begin();entry != regFonts.end();entry++) {
wxString curData = (*entry).first;
if (face == curData.Left(face.Length())) {
files.Add((*entry).second);
n++;
}
} }
if (n==0) throw wxString(_T("Font not found"));
return files; // Attach
else if (value == 3) {
DestBox->Enable(false);
BrowseButton->Enable(false);
DestLabel->Enable(false);
DestLabel->SetLabel(_T("N/A\n"));
}
} }
/////////////////////// ///////////////////////
// Collect font files // Collect font files
void FontsCollectorThread::CollectFontData () { void FontsCollectorThread::CollectFontData () {
#ifdef __WINDOWS__ FontFileLister::GatherData();
// Prepare key
wxRegKey *reg = new wxRegKey(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"));
// Try win9x
if (!reg->Exists()) {
delete reg;
reg = new wxRegKey(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts"));
if (!reg->Exists()) {
delete reg;
throw _T("Could not locate fonts directory");
}
}
wxString curName;
wxString curVal;
long index;
int n = 0;
// Iterate through
bool ok = reg->GetFirstValue(curName,index);
while (ok) {
reg->QueryValue(curName,curVal);
//AddFontData(curName,curVal);
regFonts[curName] = curVal;
ok = reg->GetNextValue(curName,index);
n++;
}
// Clean up
delete reg;
#endif
} }
@ -374,54 +324,20 @@ wxThread::ExitCode FontsCollectorThread::Entry() {
/////////// ///////////
// Collect // Collect
void FontsCollectorThread::Collect() { void FontsCollectorThread::Collect() {
// Prepare // Set destination folder
bool attaching; int oper = collector->CollectAction->GetSelection();
attaching = collector->AttachmentCheck->IsChecked(); destFolder = collector->DestBox->GetValue();
bool zipOut = collector->ArchiveCheck->IsChecked(); if (oper == 1 && !wxFileName::DirExists(destFolder)) {
AppendText(_("Invalid destination directory."),1);
// Make sure there is a separator at the end return;
if (!zipOut) destination += _T("\\");
// For zipped files, enter a default name if none was given
else {
wxFileName dest(destination);
wxString subsPath = subs->filename;
if (subsPath.IsEmpty()) subsPath = AegisubApp::folderName + _T("/unnamed.ass");
wxFileName subsname(subsPath);
// Folder picked
if (dest.IsDir()) {
if (!dest.DirExists()) destination = subsname.GetPath() + _T("/");
destination += _T("/") + subsname.GetName() + _T(".zip");
}
// File picked
else {
if (!dest.DirExists()) destination = subsname.GetPath();
else destination = dest.GetPath();
destination += _T("/") + dest.GetName() + _T(".zip");
}
// Clean up name
wxFileName finalDest(destination);
destination = finalDest.GetFullPath();
} }
// Reset log box // Collect font data
wxTextCtrl *LogBox = collector->LogBox; AppendText(_("Collecting font data from system... "));
wxMutexGuiEnter(); CollectFontData();
LogBox->SetValue(_T("")); AppendText(_("done.\n\nScanning file for fonts..."));
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180)));
LogBox->AppendText(_("Searching for fonts in file...\n"));
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0)));
LogBox->Refresh();
LogBox->Update();
wxSafeYield();
wxMutexGuiLeave();
// Scans file // Scan file
bool fileModified = false;
AssStyle *curStyle;
AssDialogue *curDiag; AssDialogue *curDiag;
curLine = 0; curLine = 0;
for (std::list<AssEntry*>::iterator cur=subs->Line.begin();cur!=subs->Line.end();cur++) { for (std::list<AssEntry*>::iterator cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
@ -429,12 +345,6 @@ void FontsCollectorThread::Collect() {
curStyle = AssEntry::GetAsStyle(*cur); curStyle = AssEntry::GetAsStyle(*cur);
if (curStyle) { if (curStyle) {
AddFont(curStyle->font,true); AddFont(curStyle->font,true);
wxMutexGuiEnter();
LogBox->AppendText(wxString(_T("\"")) + curStyle->font + _("\" found on style \"") + curStyle->name + _T("\".\n"));
LogBox->Refresh();
LogBox->Update();
wxSafeYield();
wxMutexGuiLeave();
} }
// Collect from dialogue // Collect from dialogue
@ -449,137 +359,148 @@ void FontsCollectorThread::Collect() {
} }
} }
#ifdef __WINDOWS__ // Copy fonts
// Collect font data AppendText(_("Done.\n\n"));
wxMutexGuiEnter(); switch (oper) {
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180))); case 0: AppendText(_("Checking fonts...\n")); break;
LogBox->AppendText(_("\nReading fonts from registry...\n")); case 1: AppendText(_("Copying fonts to folder...\n")); break;
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0))); case 2: AppendText(_("Copying fonts to archive...\n")); break;
wxSafeYield(); case 3: AppendText(_("Attaching fonts to file...\n")); break;
wxMutexGuiLeave();
CollectFontData();
// Get fonts folder
wxString source;
TCHAR szPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS,NULL,0,szPath))) {
source = wxString(szPath);
} }
else source = wxGetOSDirectory() + _T("\\fonts"); bool ok = true;
source += _T("\\"); for (size_t i=0;i<fonts.Count();i++) {
if (!ProcessFont(fonts[i])) ok = false;
// Open zip stream if saving to compressed archive
wxFFileOutputStream *out = NULL;
wxZipOutputStream *zip = NULL;
if (zipOut) {
out = new wxFFileOutputStream(destination);
zip = new wxZipOutputStream(*out);
} }
// Get font file names // Final result
wxArrayString work; if (ok) {
wxArrayString copied; if (oper == 0) AppendText(_("Done. All fonts found."),1);
for (size_t i=0;i<fonts.GetCount();i++) { else AppendText(_("Done. All fonts copied."),1);
try {
work = GetFontFiles(fonts[i]);
for (size_t j=0;j<work.GetCount();j++) {
// Get path to font file
wxString srcFile,dstFile;
wxFileName srcFileName(work[j]);
if (srcFileName.FileExists() && srcFileName.IsAbsolute()) {
srcFile = work[j];
dstFile = destination + srcFileName.GetFullName();
}
else {
srcFile = source + work[j];
dstFile = destination + work[j];
}
if (copied.Index(work[j]) == wxNOT_FOUND) {
copied.Add(work[j]);
// Check if it exists
if (!attaching && !zipOut && wxFileName::FileExists(dstFile)) {
wxMutexGuiEnter();
LogBox->SetDefaultStyle(wxTextAttr(wxColour(255,128,0)));
LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" already exists on destination.\n"));
LogBox->Refresh();
LogBox->Update();
wxSafeYield();
wxMutexGuiLeave();
}
// Copy
else {
// Attach to file
bool success;
if (attaching) {
try {
subs->InsertAttachment(srcFile);
fileModified = true;
success = true;
}
catch (...) { success = false; }
}
// Copy to zip destination
else if (zipOut) {
// Open file
wxFFileInputStream in(srcFile);
// Write to archive
zip->PutNextEntry(work[j]);
zip->Write(in);
}
// Copy to destination
else {
success = Copy(srcFile,dstFile);
}
// Report
wxMutexGuiEnter();
if (success) {
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,180,0)));
LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" copied.\n"));
}
else {
LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0)));
LogBox->AppendText(wxString(_("Failed copying \"")) + srcFile + _T("\".\n"));
}
LogBox->Refresh();
LogBox->Update();
wxSafeYield();
wxMutexGuiLeave();
}
}
}
}
catch (...) {
wxMutexGuiEnter();
LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0)));
LogBox->AppendText(wxString(_("Could not find font ")) + fonts[i] + _T("\n"));
wxMutexGuiLeave();
}
} }
else {
// Close ZIP archive if (oper == 0) AppendText(_("Done. Some fonts could not be found."),2);
if (zipOut) { else AppendText(_("Done. Some fonts could not be copied."),2);
zip->Close();
delete zip;
delete out;
wxMutexGuiEnter();
LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,180,0)));
LogBox->AppendText(wxString::Format(_("Finished writing to %s.\n"),destination.c_str()));
wxMutexGuiLeave();
}
#endif
// Flag file as modified
if (fileModified) {
subs->FlagAsModified(_("font attachment"));
collector->main->SubsBox->CommitChanges();
} }
} }
////////////////
// Process font
bool FontsCollectorThread::ProcessFont(wxString name) {
// Action
int action = collector->CollectAction->GetSelection();
// Font name
AppendText(wxString::Format(_T("\"%s\"... "),name.c_str()));
// Get font list
wxArrayString files = FontFileLister::GetFilesWithFace(name);
bool result = files.Count() != 0;
// No files found
if (!result) {
AppendText(_("Not found.\n"),2);
return false;
}
// Just checking, found
else if (action == 0) {
AppendText(_("Found.\n"),1);
return true;
}
// Copy font
AppendText(_T("\n"));
for (size_t i=0;i<files.Count();i++) {
int tempResult = 0;
switch (action) {
case 1: tempResult = CopyFont(files[i]); break;
case 2: tempResult = ArchiveFont(files[i]) ? 1 : 0; break;
case 3: tempResult = AttachFont(files[i]) ? 1 : 0; break;
}
if (tempResult == 1) {
AppendText(wxString::Format(_("* Copied %s.\n"),files[i].c_str()),1);
}
else if (tempResult == 2) {
wxFileName fn(files[i]);
AppendText(wxString::Format(_("* %s already exists on destination.\n"),fn.GetFullName().c_str()),3);
}
else {
AppendText(wxString::Format(_("* Failed to copy %s.\n"),files[i].c_str()),2);
result = false;
}
}
// Done
return result;
}
/////////////
// Copy font
int FontsCollectorThread::CopyFont(wxString filename) {
wxFileName fn(filename);
wxString dstName = destFolder + _T("//") + fn.GetFullName();
if (wxFileName::FileExists(dstName)) return 2;
return CopyFile(filename,dstName) ? 1 : 0;
}
////////////////
// Archive font
bool FontsCollectorThread::ArchiveFont(wxString filename) {
return false;
}
///////////////
// Attach font
bool FontsCollectorThread::AttachFont(wxString filename) {
return false;
}
////////////////////////////////
// Get fonts from ass overrides
void FontsCollectorThread::GetFonts (wxString tagName,int par_n,AssOverrideParameter *param,void *usr) {
if (tagName == _T("\\fn")) {
instance->AddFont(param->AsText(),false);
}
}
///////////////
// Adds a font
void FontsCollectorThread::AddFont(wxString fontname,bool isStyle) {
if (fonts.Index(fontname) == wxNOT_FOUND) {
fonts.Add(fontname);
if (isStyle) AppendText(wxString(_T("\"")) + fontname + _("\" found on style \"") + curStyle->name + _T("\".\n"));
if (!isStyle) AppendText(wxString(_T("\"")) + fontname + _("\" found on dialogue line ") + wxString::Format(_T("%i"),curLine) + _T(".\n"));
}
}
///////////////
// Append text
void FontsCollectorThread::AppendText(wxString text,int colour) {
wxStyledTextCtrl *LogBox = collector->LogBox;
wxMutexGuiEnter();
LogBox->SetReadOnly(false);
int pos = LogBox->GetLength();
LogBox->AppendText(text);
if (colour) {
LogBox->StartStyling(pos,31);
LogBox->SetStyling(text.Length(),colour);
}
LogBox->GotoPos(pos);
LogBox->SetReadOnly(true);
wxSafeYield();
wxMutexGuiLeave();
}
///////////////////
// Static instance
FontsCollectorThread *FontsCollectorThread::instance;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro // Copyright (c) 2007, Rodrigo Braz Monteiro
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -40,7 +40,7 @@
//////////// ////////////
// Includes // Includes
#include <wx/wxprec.h> #include <wx/wxprec.h>
#include <map> #include <wx/stc/stc.h>
////////////// //////////////
@ -51,29 +51,30 @@ class DialogFontsCollector;
class FrameMain; class FrameMain;
////////////
// Typedefs
typedef std::map<wxString,wxString> FontMap;
///////////////// /////////////////
// Worker thread // Worker thread
class FontsCollectorThread : public wxThread { class FontsCollectorThread : public wxThread {
private: private:
AssFile *subs; AssFile *subs;
AssStyle *curStyle;
wxString destination; wxString destination;
DialogFontsCollector *collector; DialogFontsCollector *collector;
int curLine; int curLine;
wxString destFolder;
static FontsCollectorThread *instance; static FontsCollectorThread *instance;
std::map<wxString,wxString> regFonts;
wxArrayString fonts; wxArrayString fonts;
bool ProcessFont(wxString fontname);
int CopyFont(wxString filename);
bool ArchiveFont(wxString filename);
bool AttachFont(wxString filename);
void Collect(); void Collect();
wxArrayString GetFontFiles (wxString face);
void AddFont(wxString fontname,bool isStyle); void AddFont(wxString fontname,bool isStyle);
void CollectFontData(); void CollectFontData();
void AppendText(wxString text,int colour=0);
public: public:
FontsCollectorThread(AssFile *subs,wxString destination,DialogFontsCollector *collector); FontsCollectorThread(AssFile *subs,wxString destination,DialogFontsCollector *collector);
@ -90,21 +91,19 @@ class DialogFontsCollector : public wxDialog {
private: private:
wxTextCtrl *DestBox; wxTextCtrl *DestBox;
wxTextCtrl *LogBox; wxStyledTextCtrl *LogBox;
wxButton *BrowseButton; wxButton *BrowseButton;
wxButton *StartButton; wxButton *StartButton;
wxButton *CloseButton; wxButton *CloseButton;
wxCheckBox *AttachmentCheck;
wxCheckBox *ArchiveCheck;
wxStaticText *DestLabel; wxStaticText *DestLabel;
wxRadioBox *CollectAction;
FrameMain *main; FrameMain *main;
void OnStart(wxCommandEvent &event); void OnStart(wxCommandEvent &event);
void OnClose(wxCommandEvent &event); void OnClose(wxCommandEvent &event);
void OnBrowse(wxCommandEvent &event); void OnBrowse(wxCommandEvent &event);
void OnCheckAttach(wxCommandEvent &event); void OnRadio(wxCommandEvent &event);
void OnCheckArchive(wxCommandEvent &event); void Update(int value=-1);
void Update();
public: public:
DialogFontsCollector(wxWindow *parent); DialogFontsCollector(wxWindow *parent);
@ -112,13 +111,3 @@ public:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
///////
// IDs
enum {
BROWSE_BUTTON = 1100,
START_BUTTON,
ATTACHMENT_CHECK,
ARCHIVE_CHECK
};

View file

@ -0,0 +1,177 @@
// Copyright (c) 2007, Niels Martin Hansen, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
////////////
// Includes
#include <wx/dir.h>
#include <ft2build.h>
#ifdef WIN32
#include <shlobj.h>
#endif
#include "font_file_lister.h"
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_SFNT_NAMES_H
////////////////////
// Static instances
FontFileLister *FontFileLister::instance = NULL;
///////////////
// Constructor
FontFileLister::FontFileLister() {
// Initialize freetype2
FT_Init_FreeType(&ft2lib);
}
//////////////
// Destructor
FontFileLister::~FontFileLister() {
}
////////////////////////////////////////
// Get instance and call function there
wxArrayString FontFileLister::GetFilesWithFace(wxString facename) {
if (!instance) instance = new FontFileLister();
return instance->DoGetFilesWithFace(facename);
}
void FontFileLister::GatherData() {
if (!instance) instance = new FontFileLister();
instance->DoGatherData();
}
void FontFileLister::ClearData() {
if (!instance) instance = new FontFileLister();
instance->DoClearData();
}
////////////////////////////////////////////////
// Get list of files that match a specific face
wxArrayString FontFileLister::DoGetFilesWithFace(wxString facename) {
FontMap::iterator iter = fontTable.find(facename);
if (iter != fontTable.end()) return iter->second;
else return wxArrayString();
}
//////////////
// Clear data
void FontFileLister::DoClearData() {
fontFiles.clear();
fontTable.clear();
}
///////////////////////////
// Gather data from system
void FontFileLister::DoGatherData() {
// Get fonts folder
wxString source;
#ifdef WIN32
TCHAR szPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS,NULL,0,szPath))) {
source = wxString(szPath);
}
else source = wxGetOSDirectory() + _T("\\fonts");
source += _T("\\");
#endif
if (source == _T("")) return;
// Get the list of fonts in the fonts folder
wxArrayString fontfiles;
wxDir::GetAllFiles(source, &fontfiles, wxEmptyString, wxDIR_FILES);
// Loop through each file
int fterr;
for (unsigned int i=0;i<fontfiles.Count(); i++) {
// Check if it's cached
if (IsFilenameCached(fontfiles[i])) continue;
// Loop through each face in the file
for (int facenum=0;true;facenum++) {
// Get font face
FT_Face face;
fterr = FT_New_Face(ft2lib, fontfiles[i].mb_str(*wxConvFileName), facenum, &face);
if (fterr) break;
// Add font
AddFont(fontfiles[i],wxString(face->family_name, wxConvLocal));
FT_Done_Face(face);
}
}
}
////////////
// Add font
void FontFileLister::AddFont(wxString filename,wxString facename) {
// Add filename to general list
if (fontFiles.Index(filename) == wxNOT_FOUND) {
fontFiles.Add(filename);
}
// Add filename to mapping of this face
wxArrayString &arr = fontTable[facename];
if (arr.Index(filename) == wxNOT_FOUND) arr.Add(filename);
}
/////////////////////////////////
// Check if a filename is cached
bool FontFileLister::IsFilenameCached(wxString filename) {
return fontFiles.Index(filename) != wxNOT_FOUND;
}
//////////////
// Save cache
void FontFileLister::SaveCache() {
// TODO
}
//////////////
// Load cache
void FontFileLister::LoadCache() {
// TODO
}

View file

@ -0,0 +1,78 @@
// Copyright (c) 2007, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
////////////
// Includes
#include <wx/wxprec.h>
#include <map>
////////////
// Typedefs
typedef struct FT_LibraryRec_ *FT_Library;
typedef std::map<wxString,wxArrayString> FontMap;
////////////////////
// Font file lister
class FontFileLister {
private:
static FontFileLister *instance;
FT_Library ft2lib;
FontMap fontTable;
wxArrayString fontFiles;
virtual void DoGatherData();
FontFileLister();
virtual ~FontFileLister();
wxArrayString DoGetFilesWithFace(wxString facename);
void DoClearData();
bool IsFilenameCached(wxString filename);
void AddFont(wxString filename,wxString facename);
void SaveCache();
void LoadCache();
public:
static wxArrayString GetFilesWithFace(wxString facename);
static void GatherData();
static void ClearData();
};

View file

@ -599,7 +599,7 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) {
// Save // Save
wxString backup = path + origfile.GetName() + _T(".ORIGINAL.") + origfile.GetExt(); wxString backup = path + origfile.GetName() + _T(".ORIGINAL.") + origfile.GetExt();
Backup(filename,backup); CopyFile(filename,backup);
} }
// Sync // Sync

View file

@ -66,19 +66,11 @@ int CountMatches(wxString parent,wxString child) {
/////////////// ///////////////
// Copy a file // Copy a file
#ifdef __WINDOWS__ bool CopyFile(wxString src,wxString dst) {
bool Copy(wxString src,wxString dst) {
BOOL result = CopyFile(src.wc_str(),dst.wc_str(),false);
return (result != 0);
}
#endif
////////////////
// Backup a file
bool Backup(wxString src,wxString dst) {
// Windows // Windows
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
return Copy(src,dst); BOOL result = CopyFile(src.wc_str(),dst.wc_str(),false);
return (result != 0);
// Linux // Linux
#elif defined(__UNIX__) #elif defined(__UNIX__)

View file

@ -54,8 +54,7 @@ typedef std::vector<std::pair<int,int> > IntPairVector;
__int64 abs64(__int64 input); __int64 abs64(__int64 input);
#endif #endif
int CountMatches(wxString parent,wxString child); int CountMatches(wxString parent,wxString child);
bool Copy(wxString src,wxString dst); bool CopyFile(wxString src,wxString dst);
bool Backup(wxString src,wxString dst);
wxString MakeRelativePath(wxString path,wxString reference); wxString MakeRelativePath(wxString path,wxString reference);
wxString DecodeRelativePath(wxString path,wxString reference); wxString DecodeRelativePath(wxString path,wxString reference);
wxString PrettyFloat(wxString src); wxString PrettyFloat(wxString src);