Skip to content

Commit

Permalink
Merge branch 'layoutres' into feature
Browse files Browse the repository at this point in the history
  • Loading branch information
arch1t3cht committed Dec 2, 2024
2 parents f03bcab + 694a8d6 commit 7db477c
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 26 deletions.
20 changes: 20 additions & 0 deletions src/ass_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
#include "ass_info.h"
#include "ass_style.h"
#include "ass_style_storage.h"
#include "async_video_provider.h"
#include "options.h"
#include "project.h"
#include "include/aegisub/context.h"

#include <algorithm>
#include <boost/algorithm/string/case_conv.hpp>
Expand Down Expand Up @@ -153,6 +156,23 @@ void AssFile::GetResolution(int &sw, int &sh) const {
sh = sw == 1280 ? 1024 : sw * 3 / 4;
}

void AssFile::GetLayoutResolution(int &lw, int &lh) const {
lw = GetScriptInfoAsInt("LayoutResX");
lh = GetScriptInfoAsInt("LayoutResY");
}

void AssFile::GetEffectiveLayoutResolution(agi::Context *c, int &lw, int &lh) const {
GetLayoutResolution(lw, lh);
if (lw == 0 || lh == 0) {
if (c->project->VideoProvider()) {
lw = c->project->VideoProvider()->GetWidth();
lh = c->project->VideoProvider()->GetHeight();
} else {
GetResolution(lw, lh);
}
}
}

std::vector<std::string> AssFile::GetStyles() const {
std::vector<std::string> styles;
for (auto& style : Styles)
Expand Down
9 changes: 9 additions & 0 deletions src/ass_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AssDialogue;
class AssInfo;
class AssStyle;
class wxString;
namespace agi { struct Context; }

template<typename T>
using EntryList = typename boost::intrusive::make_list<T, boost::intrusive::constant_time_size<false>, boost::intrusive::base_hook<AssEntryListHook>>::type;
Expand Down Expand Up @@ -125,6 +126,14 @@ class AssFile {
/// @param[out] w Width
/// @param[in] h Height
void GetResolution(int &w,int &h) const;
/// @brief Get the specified layout resolution, if present, or 0 if it is not present
/// @param[out] w Width
/// @param[in] h Height
void GetLayoutResolution(int &w,int &h) const;
/// @brief Get the effective layout resolution (i.e. falling back to the video resolution, if present)
/// @param[out] w Width
/// @param[in] h Height
void GetEffectiveLayoutResolution(agi::Context *c, int &w,int &h) const;
/// Get the value in a [Script Info] key as int, or 0 if it is not present
int GetScriptInfoAsInt(std::string const& key) const;
/// Get the value in a [Script Info] key as string.
Expand Down
56 changes: 50 additions & 6 deletions src/dialog_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "project.h"
#include "resolution_resampler.h"
#include "validators.h"
#include "video_controller.h"

#include <boost/algorithm/string/predicate.hpp>
#include <vector>
Expand All @@ -59,13 +60,17 @@ class DialogProperties {
wxComboBox *WrapStyle; ///< Wrapping style for long lines
wxTextCtrl *ResX; ///< Script x resolution
wxTextCtrl *ResY; ///< Script y resolution
wxTextCtrl *LayoutResX; ///< Layout x resolution
wxTextCtrl *LayoutResY; ///< Layout y resolution
wxCheckBox *ScaleBorder; ///< If script resolution != video resolution how should borders be handled
wxComboBox *YCbCrMatrix;

/// OK button handler
void OnOK(wxCommandEvent &event);
/// Set script resolution to video resolution button
void OnSetFromVideo(wxCommandEvent &event);
/// Set layout resolution to video resolution button
void OnSetLayoutResFromVideo(wxCommandEvent &event);
/// Set a script info field
/// @param key Name of field
/// @param value New value
Expand Down Expand Up @@ -119,18 +124,36 @@ DialogProperties::DialogProperties(agi::Context *c)
ResX = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResX")));
ResY = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResY")));

LayoutResX = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("LayoutResX")));
LayoutResY = new wxTextCtrl(&d,-1,"",wxDefaultPosition,wxDefaultSize,0,IntValidator(c->ass->GetScriptInfoAsInt("LayoutResY")));

wxButton *FromVideo = new wxButton(&d,-1,_("From &video"));
if (!c->project->VideoProvider())
FromVideo->Enable(false);
else
FromVideo->Bind(wxEVT_BUTTON, &DialogProperties::OnSetFromVideo, this);

auto res_sizer = new wxBoxSizer(wxHORIZONTAL);
res_sizer->Add(ResX, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
res_sizer->Add(new wxStaticText(&d, -1, "x"), 0, wxALIGN_CENTER | wxRIGHT, 5);
res_sizer->Add(ResY, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
auto res_sizer = new wxFlexGridSizer(5, 5, 5);
res_sizer->AddGrowableCol(1, 1);
res_sizer->AddGrowableCol(3, 1);
res_sizer->Add(new wxStaticText(&d, -1, _("Script: ")), wxSizerFlags().Center().Left());
res_sizer->Add(ResX, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
res_sizer->Add(new wxStaticText(&d, -1, "x"), 0, wxALIGN_CENTER | wxRIGHT, 2);
res_sizer->Add(ResY, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
res_sizer->Add(FromVideo, 1, 0, 0);

wxButton *LayoutResFromVideo = new wxButton(&d,-1,_("From video"));
if (!c->project->VideoProvider())
LayoutResFromVideo->Enable(false);
else
LayoutResFromVideo->Bind(wxEVT_BUTTON, &DialogProperties::OnSetLayoutResFromVideo, this);

res_sizer->Add(new wxStaticText(&d, -1, _("Layout: ")), wxSizerFlags().Center().Left());
res_sizer->Add(LayoutResX, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
res_sizer->Add(new wxStaticText(&d, -1, "x"), 0, wxALIGN_CENTER | wxRIGHT, 2);
res_sizer->Add(LayoutResY, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
res_sizer->Add(LayoutResFromVideo, 1, 0, 0);

YCbCrMatrix = new wxComboBox(&d, -1, to_wx(c->ass->GetScriptInfo("YCbCr Matrix")),
wxDefaultPosition, wxDefaultSize, to_wx(MatrixNames()), wxCB_READONLY);

Expand Down Expand Up @@ -189,6 +212,8 @@ void DialogProperties::OnOK(wxCommandEvent &) {

count += SetInfoIfDifferent("PlayResX", from_wx(ResX->GetValue()));
count += SetInfoIfDifferent("PlayResY", from_wx(ResY->GetValue()));
count += SetInfoIfDifferent("LayoutResX", from_wx(LayoutResX->GetValue()));
count += SetInfoIfDifferent("LayoutResY", from_wx(LayoutResY->GetValue()));
count += SetInfoIfDifferent("WrapStyle", std::to_string(WrapStyle->GetSelection()));
count += SetInfoIfDifferent("ScaledBorderAndShadow", ScaleBorder->GetValue() ? "yes" : "no");
count += SetInfoIfDifferent("YCbCr Matrix", from_wx(YCbCrMatrix->GetValue()));
Expand All @@ -206,9 +231,28 @@ int DialogProperties::SetInfoIfDifferent(std::string const& key, std::string con
return 0;
}

std::pair<int, int> GetVideoDisplayResolution(agi::Context *c) {
double dar = c->videoController->GetAspectRatioValue();
int width = c->project->VideoProvider()->GetWidth();
int height = c->project->VideoProvider()->GetHeight();
double sar = double(width) / double(height);

return std::make_pair(
width * std::max(1., dar / sar),
height * std::max(1., sar / dar)
);
}

void DialogProperties::OnSetFromVideo(wxCommandEvent &) {
ResX->SetValue(std::to_wstring(c->project->VideoProvider()->GetWidth()));
ResY->SetValue(std::to_wstring(c->project->VideoProvider()->GetHeight()));
auto [width, height] = GetVideoDisplayResolution(c);
ResX->SetValue(std::to_wstring(width));
ResY->SetValue(std::to_wstring(height));
}

void DialogProperties::OnSetLayoutResFromVideo(wxCommandEvent &) {
auto [width, height] = GetVideoDisplayResolution(c);
LayoutResX->SetValue(std::to_wstring(width));
LayoutResY->SetValue(std::to_wstring(height));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/gl_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,11 @@ void OpenGLWrapper::SetScale(Vector2D scale) {
glScalef(scale.X() / 100.f, scale.Y() / 100.f, 1.f);
}

void OpenGLWrapper::SetRotation(float x, float y, float z) {
void OpenGLWrapper::SetRotation(float x, float y, float z, float zScale) {
PrepareTransform();
float matrix[16] = { 2500, 0, 0, 0, 0, 2500, 0, 0, 0, 0, 1, 1, 0, 0, 2500, 2500 };
glMultMatrixf(matrix);
glScalef(1.f, 1.f, 8.f);
glScalef(1.f, 1.f, 8.f / zScale);
glRotatef(y, 0.f, -1.f, 0.f);
glRotatef(x, -1.f, 0.f, 0.f);
glRotatef(z, 0.f, 0.f, -1.f);
Expand Down
2 changes: 1 addition & 1 deletion src/gl_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OpenGLWrapper {

void SetScale(Vector2D scale);
void SetOrigin(Vector2D origin);
void SetRotation(float x, float y, float z);
void SetRotation(float x, float y, float z, float zScale = 1);
void SetShear(float x, float y);
void ResetTransform();

Expand Down
16 changes: 10 additions & 6 deletions src/visual_tool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,27 @@ VisualToolBase::VisualToolBase(VideoDisplay *parent, agi::Context *context)
, shaded_area_alpha_opt(OPT_GET("Colour/Visual Tools/Shaded Area Alpha"))
, file_changed_connection(c->ass->AddCommitListener(&VisualToolBase::OnCommit, this))
{
int script_w, script_h;
c->ass->GetResolution(script_w, script_h);
script_res = Vector2D(script_w, script_h);
SetResolutions();
active_line = GetActiveDialogueLine();
connections.push_back(c->selectionController->AddActiveLineListener(&VisualToolBase::OnActiveLineChanged, this));
connections.push_back(c->videoController->AddSeekListener(&VisualToolBase::OnSeek, this));
parent->Bind(wxEVT_MOUSE_CAPTURE_LOST, &VisualToolBase::OnMouseCaptureLost, this);
}

void VisualToolBase::SetResolutions() {
int script_w, script_h, layout_w, layout_h;
c->ass->GetResolution(script_w, script_h);
c->ass->GetEffectiveLayoutResolution(c, layout_w, layout_h);
script_res = Vector2D(script_w, script_h);
layout_res = Vector2D(layout_w, layout_h);
}

void VisualToolBase::OnCommit(int type) {
holding = false;
dragging = false;

if (type == AssFile::COMMIT_NEW || type & AssFile::COMMIT_SCRIPTINFO) {
int script_w, script_h;
c->ass->GetResolution(script_w, script_h);
script_res = Vector2D(script_w, script_h);
SetResolutions();
OnCoordinateSystemsChanged();
}

Expand Down
2 changes: 2 additions & 0 deletions src/visual_tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace agi {
/// functionality as possible is implemented here to avoid having four copies
/// of each method for no good reason (and four times as many error messages)
class VisualToolBase {
void SetResolutions();
void OnCommit(int type);
void OnSeek(int new_frame);

Expand Down Expand Up @@ -102,6 +103,7 @@ class VisualToolBase {
Vector2D mouse_pos; ///< Last seen mouse position
Vector2D drag_start; ///< Mouse position at the beginning of the last drag
Vector2D script_res; ///< Script resolution
Vector2D layout_res; ///< Layout resolution
Vector2D video_pos; ///< Top-left corner of the video in the display area
Vector2D video_res; ///< Video resolution
Vector2D client_size; ///< The size of the display area
Expand Down
24 changes: 14 additions & 10 deletions src/visual_tool_perspective.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
static const float pi = 3.1415926536f;
static const float deg2rad = pi / 180.f;
static const float rad2deg = 180.f / pi;
static const float screen_z = 312.5;
static const float default_screen_z = 312.5;
static const char *ambient_plane_key = "_aegi_perspective_ambient_plane";

static const int BUTTON_ID_BASE = 1400;
Expand Down Expand Up @@ -127,6 +127,10 @@ std::vector<Vector2D> MakeRect(Vector2D a, Vector2D b) {
});
}

inline float VisualToolPerspective::screenZ() const {
return default_screen_z * script_res.Y() / layout_res.Y();
}

void VisualToolPerspective::AddTool(std::string command_name, VisualToolPerspectiveSetting setting) {
cmd::Command *command = cmd::get(command_name);
int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt();
Expand Down Expand Up @@ -331,7 +335,7 @@ void VisualToolPerspective::Draw() {
// Transform grid
gl.SetOrigin(FromScriptCoords(org));
gl.SetScale(100 * video_res / script_res);
gl.SetRotation(angle_x, angle_y, angle_z);
gl.SetRotation(angle_x, angle_y, angle_z, script_res.Y() / layout_res.Y());
gl.SetScale(fsc);
gl.SetShear(fax, fay);
Vector2D glScale = (bbox.second.Y() - bbox.first.Y()) * Vector2D(1, 1) / spacing / 4;
Expand Down Expand Up @@ -591,7 +595,7 @@ bool VisualToolPerspective::InnerToText() {
// with the following coefficients.
float a = (1 - z1) * (1 - z3);
Vector2D b = z1 * v1 + z3 * v3 - z1 * z3 * (v1 + v3);
float c = z1 * z3 * v1.Dot(v3) + (z1 - 1) * (z3 - 1) * screen_z * screen_z;
float c = z1 * z3 * v1.Dot(v3) + (z1 - 1) * (z3 - 1) * screenZ() * screenZ();

// Our default value for t, which would put \org at the center of the quad.
// We'll try to find a value for \org that's as close as possible to it.
Expand Down Expand Up @@ -635,10 +639,10 @@ bool VisualToolPerspective::InnerToText() {
q2 = q2 - org;
q3 = q3 - org;

Vector3D r0 = Vector3D(q0, screen_z);
Vector3D r1 = z1 * Vector3D(q1, screen_z);
Vector3D r2 = (z1 + z3 - 1) * Vector3D(q2, screen_z);
Vector3D r3 = z3 * Vector3D(q3, screen_z);
Vector3D r0 = Vector3D(q0, screenZ());
Vector3D r1 = z1 * Vector3D(q1, screenZ());
Vector3D r2 = (z1 + z3 - 1) * Vector3D(q2, screenZ());
Vector3D r3 = z3 * Vector3D(q3, screenZ());
std::vector<Vector3D> r({r0, r1, r2, r3});

// Find the z coordinate of the point projecting to the origin
Expand All @@ -648,9 +652,9 @@ bool VisualToolPerspective::InnerToText() {
Solve2x2(side0.X(), side1.X(), side0.Y(), side1.Y(), -r0.X(), -r0.Y(), orgla0, orgla1);
float orgz = (r0 + orgla0 * side0 + orgla1 * side1).Z();

// Normalize so the origin has z=screen_z, and move the screen plane to z=0
// Normalize so the origin has z=screenZ, and move the screen plane to z=0
for (int i = 0; i < 4; i++)
r[i] = r[i] * screen_z / orgz - Vector3D(0, 0, screen_z);
r[i] = r[i] * screenZ() / orgz - Vector3D(0, 0, screenZ());

// Find the rotations
Vector3D n = (r[1] - r[0]).Cross(r[3] - r[0]);
Expand Down Expand Up @@ -825,7 +829,7 @@ void VisualToolPerspective::TextToPersp() {
q = q.RotateX(-angle_x * deg2rad);
q = q.RotateY(angle_y * deg2rad);
// Project
q = (screen_z / (q.Z() + screen_z)) * q;
q = (screenZ() / (q.Z() + screenZ())) * q;
// Move to origin
Vector2D r = q.XY() + org;
inner_corners[i]->pos = FromScriptCoords(r);
Expand Down
2 changes: 2 additions & 0 deletions src/visual_tool_perspective.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class VisualToolPerspective final : public VisualTool<VisualToolPerspectiveDragg
std::vector<Feature *> inner_corners;
std::vector<Feature *> outer_corners;

inline float screenZ() const;

std::vector<Vector2D> FeaturePositions(std::vector<Feature *> features) const;
void UpdateInner();
void UpdateOuter();
Expand Down
2 changes: 1 addition & 1 deletion src/visual_tool_rotatexy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void VisualToolRotateXY::Draw() {
// Transform grid
gl.SetOrigin(org->pos);
gl.SetScale(100 * video_res / script_res);
gl.SetRotation(angle_x, angle_y, angle_z);
gl.SetRotation(angle_x, angle_y, angle_z, script_res.Y() / layout_res.Y());
gl.SetScale(fsc);
gl.SetShear(fax, fay);

Expand Down

0 comments on commit 7db477c

Please sign in to comment.