// Copyright (c) 2005, 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 // /////////// // Headers #include "dialog_resample.h" #include "ass_file.h" #include "ass_dialogue.h" #include "ass_style.h" #include "ass_override.h" #include "subs_grid.h" #include "validators.h" #include "video_display.h" /////////////// // Constructor DialogResample::DialogResample(wxWindow *parent, SubtitlesGrid *_grid) : wxDialog (parent,-1,_("Resample resolution"),wxDefaultPosition) { // Variables AssFile *subs = AssFile::top; grid = _grid; vid = grid->video; // Resolution line wxSizer *ResBoxSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Resolution")); wxSizer *ResSizer = new wxBoxSizer(wxHORIZONTAL); ResXValue = subs->GetScriptInfo(_T("PlayResX")); ResYValue = subs->GetScriptInfo(_T("PlayResY")); ResX = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(50,20),0,NumValidator(&ResXValue)); ResY = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(50,20),0,NumValidator(&ResYValue)); wxStaticText *ResText = new wxStaticText(this,-1,_("x")); wxButton *FromVideo = new wxButton(this,BUTTON_DEST_FROM_VIDEO,_("From video")); if (!vid->loaded) FromVideo->Enable(false); ResSizer->Add(ResX,1,wxRIGHT,5); ResSizer->Add(ResText,0,wxALIGN_CENTER | wxRIGHT,5); ResSizer->Add(ResY,1,wxRIGHT,5); ResSizer->Add(FromVideo,1,0,0); // Resolution box Anamorphic = new wxCheckBox(this,CHECK_ANAMORPHIC,_("Change aspect ratio")); ResBoxSizer->Add(ResSizer,1,wxEXPAND|wxBOTTOM,5); ResBoxSizer->Add(Anamorphic,0,0,0); // Button sizer wxSizer *ButtonSizer = new wxBoxSizer(wxHORIZONTAL); ButtonSizer->AddStretchSpacer(1); ButtonSizer->Add(new wxButton(this,BUTTON_RESAMPLE,_("Resample")),0,wxRIGHT,5); ButtonSizer->Add(new wxButton(this,wxID_CANCEL),0,wxRIGHT,0); // Main sizer wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL); MainSizer->Add(ResBoxSizer,1,wxEXPAND|wxALL,5); MainSizer->Add(ButtonSizer,0,wxEXPAND|wxRIGHT|wxLEFT|wxBOTTOM,5); MainSizer->SetSizeHints(this); SetSizer(MainSizer); CenterOnParent(); } /////////////// // Event table BEGIN_EVENT_TABLE(DialogResample,wxDialog) EVT_BUTTON(BUTTON_RESAMPLE,DialogResample::OnResample) EVT_BUTTON(BUTTON_DEST_FROM_VIDEO,DialogResample::OnGetDestRes) END_EVENT_TABLE() ///////////////// // Resample tags void DialogResample::ResampleTags (wxString name,int n,AssOverrideParameter *curParam,void *_curDiag) { double resizer = 1.0; switch (curParam->classification) { case PARCLASS_ABSOLUTE_SIZE: resizer = r; break; case PARCLASS_ABSOLUTE_POS_X: resizer = rx; break; case PARCLASS_ABSOLUTE_POS_Y: resizer = ry; break; case PARCLASS_RELATIVE_SIZE_X: resizer = ar; break; case PARCLASS_RELATIVE_SIZE_Y: //resizer = ry; default: return; } VariableDataType curType = curParam->GetType(); if (curType == VARDATA_FLOAT) { curParam->SetFloat(curParam->AsFloat() * resizer); } if (curType == VARDATA_INT) { curParam->SetInt(double(curParam->AsInt()) * resizer + 0.5); } } //////////// // Resample void DialogResample::OnResample (wxCommandEvent &event) { // Resolutions AssFile *subs = AssFile::top; long x1 = subs->GetScriptInfoAsInt(_T("PlayResX")); long y1 = subs->GetScriptInfoAsInt(_T("PlayResY")); long x2 = 0; long y2 = 0; ResX->GetValue().ToLong(&x2); ResY->GetValue().ToLong(&y2); // Check for validity if (x1 == 0 || x2 == 0 || y1 == 0 || y2 == 0) { EndModal(0); return; } // Calculate resamples rx = double(x2)/double(x1); ry = double(y2)/double(y1); r = ry; if (Anamorphic->IsChecked()) ar = rx/ry; else ar = 1.0; // Iterate through subs AssStyle *curStyle; AssDialogue *curDiag; for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) { // Apply to dialogues curDiag = AssEntry::GetAsDialogue(*cur); if (curDiag) { try { // Override tags curDiag->ParseASSTags(); curDiag->ProcessParameters(ResampleTags,curDiag); // Drawing tags size_t nblocks = curDiag->Blocks.size(); AssDialogueBlockDrawing *curBlock; for (size_t i=0;iBlocks.at(i)); if (curBlock) { curBlock->MultiplyCoords(rx,ry); } } // Margins curDiag->MarginL = int(curDiag->MarginL * rx + 0.5); curDiag->MarginR = int(curDiag->MarginR * rx + 0.5); curDiag->MarginV = int(curDiag->MarginV * ry + 0.5); // Update curDiag->UpdateText(); curDiag->UpdateData(); continue; } catch (wchar_t *err) { wxLogMessage(err); } catch (wxString err) { wxLogMessage(err); } } // Apply to styles curStyle = AssEntry::GetAsStyle(*cur); if (curStyle) { curStyle->fontsize = int(curStyle->fontsize * r + 0.5); //curStyle->outline_w *= r; //curStyle->shadow_w *= r; curStyle->spacing *= rx; curStyle->scalex *= ar; curStyle->MarginL = int(curStyle->MarginL * rx + 0.5); curStyle->MarginR = int(curStyle->MarginR * rx + 0.5); curStyle->MarginV = int(curStyle->MarginV * ry + 0.5); curStyle->UpdateData(); } } // Change script resolution subs->SetScriptInfo(_T("PlayResX"),wxString::Format(_T("%i"),x2)); subs->SetScriptInfo(_T("PlayResY"),wxString::Format(_T("%i"),y2)); // Flag as modified grid->LoadFromAss(); EndModal(0); } ///////////////////////////////////////// // Get destination resolution from video void DialogResample::OnGetDestRes (wxCommandEvent &event) { ResX->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceWidth())); ResY->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceHeight())); } //////////////////// // Static variables double DialogResample::r; double DialogResample::rx; double DialogResample::ry; double DialogResample::ar;