Skip to content

Commit 6392440

Browse files
authored
♻️ refactor: rustify ass writer write_comment_with_animation (#328)
1 parent 1c06e18 commit 6392440

File tree

7 files changed

+216
-55
lines changed

7 files changed

+216
-55
lines changed

packages/biliass/rust/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,9 @@ fn biliass_pyo3(m: &Bound<'_, PyModule>) -> PyResult<()> {
3333
m.add_function(wrap_pyfunction!(python::py_convert_flash_rotation, m)?)?;
3434
m.add_function(wrap_pyfunction!(python::py_write_head, m)?)?;
3535
m.add_function(wrap_pyfunction!(python::py_write_normal_comment, m)?)?;
36+
m.add_function(wrap_pyfunction!(
37+
python::py_write_comment_with_animation,
38+
m
39+
)?)?;
3640
Ok(())
3741
}

packages/biliass/rust/src/python/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ pub use proto::{PyDanmakuElem, PyDmSegMobileReply};
88
pub use reader::{py_read_comments_from_protobuf, py_read_comments_from_xml};
99
pub use writer::{
1010
py_ass_escape, py_convert_color, py_convert_flash_rotation, py_convert_timestamp,
11-
py_get_zoom_factor, py_write_head, py_write_normal_comment, PyRows,
11+
py_get_zoom_factor, py_write_comment_with_animation, py_write_head, py_write_normal_comment,
12+
PyRows,
1213
};

packages/biliass/rust/src/python/writer.rs

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,49 @@ pub fn py_write_normal_comment(
103103
reduced,
104104
))
105105
}
106-
// pub fn write_normal_comment(
107-
// rows: &mut rows::Rows,
108-
// comment: &Comment,
109-
// width: u32,
110-
// height: u32,
111-
// bottom_reserved: u32,
112-
// fontsize: f32,
113-
// duration_marquee: f64,
114-
// duration_still: f64,
115-
// styleid: &str,
116-
// reduced: bool,
117-
// ) -> String {
106+
107+
#[allow(clippy::too_many_arguments)]
108+
#[pyfunction(name = "write_comment_with_animation")]
109+
pub fn py_write_comment_with_animation(
110+
comment: &crate::python::PyComment,
111+
width: u32,
112+
height: u32,
113+
rotate_y: f64,
114+
rotate_z: f64,
115+
from_x: f64,
116+
from_y: f64,
117+
to_x: f64,
118+
to_y: f64,
119+
from_alpha: u8,
120+
to_alpha: u8,
121+
text: &str,
122+
delay: f64,
123+
lifetime: f64,
124+
duration: f64,
125+
fontface: &str,
126+
is_border: bool,
127+
styleid: &str,
128+
zoom_factor: (f32, f32, f32),
129+
) -> PyResult<String> {
130+
Ok(writer::ass::write_comment_with_animation(
131+
&comment.inner,
132+
width,
133+
height,
134+
rotate_y,
135+
rotate_z,
136+
from_x,
137+
from_y,
138+
to_x,
139+
to_y,
140+
from_alpha,
141+
to_alpha,
142+
text,
143+
delay,
144+
lifetime,
145+
duration,
146+
fontface,
147+
is_border,
148+
styleid,
149+
zoom_factor,
150+
))
151+
}

packages/biliass/rust/src/writer/ass.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,124 @@ pub fn write_normal_comment(
157157
}
158158
"".to_owned()
159159
}
160+
161+
#[allow(clippy::too_many_arguments)]
162+
pub fn write_comment_with_animation(
163+
comment: &Comment,
164+
width: u32,
165+
height: u32,
166+
rotate_y: f64,
167+
rotate_z: f64,
168+
from_x: f64,
169+
from_y: f64,
170+
to_x: f64,
171+
to_y: f64,
172+
from_alpha: u8,
173+
to_alpha: u8,
174+
text: &str,
175+
delay: f64,
176+
lifetime: f64,
177+
duration: f64,
178+
fontface: &str,
179+
is_border: bool,
180+
styleid: &str,
181+
zoom_factor: (f32, f32, f32),
182+
) -> String {
183+
let from_rotarg = utils::convert_flash_rotation(
184+
rotate_y,
185+
rotate_z,
186+
from_x,
187+
from_y,
188+
width as f64,
189+
height as f64,
190+
);
191+
let to_rotarg =
192+
utils::convert_flash_rotation(rotate_y, rotate_z, to_x, to_y, width as f64, height as f64);
193+
if vec![
194+
from_rotarg.0,
195+
from_rotarg.1,
196+
from_rotarg.2,
197+
from_rotarg.3,
198+
from_rotarg.4,
199+
from_rotarg.5,
200+
to_rotarg.0,
201+
to_rotarg.1,
202+
to_rotarg.2,
203+
to_rotarg.3,
204+
to_rotarg.4,
205+
to_rotarg.5,
206+
]
207+
.into_iter()
208+
.any(|x| x.is_nan())
209+
{
210+
// eprintln!(
211+
// "Invalid rotation arguments: {:?}",
212+
// (rotate_y, rotate_z, from_x, from_y)
213+
// );
214+
return "".to_owned();
215+
}
216+
let mut styles = vec![format!("\\org({}, {})", width / 2, height / 2)];
217+
if (from_rotarg.0, from_rotarg.1) == (to_rotarg.0, to_rotarg.1) {
218+
styles.push(format!("\\pos({:.0}, {:.0})", from_rotarg.0, from_rotarg.1));
219+
} else {
220+
styles.push(format!(
221+
"\\move({:.0}, {:.0}, {:.0}, {:.0}, {:.0}, {:.0})",
222+
from_rotarg.0,
223+
from_rotarg.1,
224+
to_rotarg.0,
225+
to_rotarg.1,
226+
delay,
227+
delay + duration
228+
));
229+
}
230+
styles.push(format!(
231+
"\\frx{:.0}\\fry{:.0}\\frz{:.0}\\fscx{:.0}\\fscy{:.0}",
232+
from_rotarg.2, from_rotarg.3, from_rotarg.4, from_rotarg.5, from_rotarg.6
233+
));
234+
if (from_x, from_y) != (to_x, to_y) {
235+
styles.push(format!(
236+
"\\t({}, {}, ",
237+
delay as i32,
238+
(delay + duration) as i32
239+
));
240+
styles.push(format!(
241+
"\\frx{:.0}\\fry{:.0}\\frz{:.0}\\fscx{:.0}\\fscy{:.0}",
242+
to_rotarg.2, to_rotarg.3, to_rotarg.4, to_rotarg.5, to_rotarg.6
243+
));
244+
styles.push(")".to_owned());
245+
}
246+
if !fontface.is_empty() {
247+
styles.push(format!("\\fn{}", utils::ass_escape(fontface)));
248+
}
249+
styles.push(format!("\\fs{:.0}", comment.size * zoom_factor.0));
250+
if comment.color != 0xFFFFFF {
251+
styles.push(format!(
252+
"\\c&H{}&",
253+
utils::convert_color(comment.color, None, None)
254+
));
255+
if comment.color == 0x000000 {
256+
styles.push("\\3c&HFFFFFF&".to_owned());
257+
}
258+
}
259+
if from_alpha == to_alpha {
260+
styles.push(format!("\\alpha&H{from_alpha:02X}"));
261+
} else if (from_alpha, to_alpha) == (255, 0) {
262+
styles.push(format!("\\fad({:.0},0)", lifetime * 1000.))
263+
} else if (from_alpha, to_alpha) == (0, 255) {
264+
styles.push(format!("\\fad(0, {:.0})", lifetime * 1000.));
265+
} else {
266+
let lifetime = lifetime * 1000.;
267+
styles.push(
268+
format!(
269+
"\\fade({from_alpha}, {to_alpha}, {to_alpha}, 0, {lifetime:.0}, {lifetime:.0}, {lifetime:.0})"
270+
)
271+
)
272+
}
273+
if !is_border {
274+
styles.push("\\bord0".to_owned())
275+
}
276+
let start = utils::convert_timestamp(comment.timeline);
277+
let end = utils::convert_timestamp(comment.timeline + lifetime);
278+
let styles = styles.join("");
279+
format!("Dialogue: -1,{start},{end},{styleid},,0,0,0,,{{{styles}}}{text}\n")
280+
}

packages/biliass/src/biliass/_core.pyi

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,24 @@ def write_normal_comment(
8181
styleid: str,
8282
reduced: bool,
8383
) -> str: ...
84+
def write_comment_with_animation(
85+
comment: Comment,
86+
width: int,
87+
height: int,
88+
rotate_y: float,
89+
rotate_z: float,
90+
from_x: float,
91+
from_y: float,
92+
to_x: float,
93+
to_y: float,
94+
from_alpha: int,
95+
to_alpha: int,
96+
text: str,
97+
delay: float,
98+
lifetime: float,
99+
duration: float,
100+
fontface: str,
101+
is_border: bool,
102+
styleid: str,
103+
zoom_factor: tuple[float, float, float],
104+
) -> str: ...

packages/biliass/src/biliass/biliass.py

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
get_zoom_factor,
2020
read_comments_from_protobuf,
2121
read_comments_from_xml,
22+
write_comment_with_animation,
2223
write_head,
2324
write_normal_comment,
2425
)
@@ -173,47 +174,26 @@ def write_comment_with_animation(
173174
styleid: str,
174175
zoom_factor: tuple[float, float, float],
175176
) -> None:
176-
from_rotarg = convert_flash_rotation(rotate_y, rotate_z, from_x, from_y, width, height)
177-
to_rotarg = convert_flash_rotation(rotate_y, rotate_z, to_x, to_y, width, height)
178-
styles = ["\\org(%d, %d)" % (width / 2, height / 2)]
179-
if from_rotarg[0:2] == to_rotarg[0:2]:
180-
styles.append("\\pos({:.0f}, {:.0f})".format(*from_rotarg[0:2]))
181-
else:
182-
styles.append(
183-
"\\move({:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f})".format(
184-
*(from_rotarg[0:2] + to_rotarg[0:2] + (delay, delay + duration))
185-
)
186-
)
187-
styles.append("\\frx{:.0f}\\fry{:.0f}\\frz{:.0f}\\fscx{:.0f}\\fscy{:.0f}".format(*from_rotarg[2:7]))
188-
if (from_x, from_y) != (to_x, to_y):
189-
styles.append(f"\\t({delay:d}, {delay + duration:d}, ")
190-
styles.append("\\frx{:.0f}\\fry{:.0f}\\frz{:.0f}\\fscx{:.0f}\\fscy{:.0f}".format(*to_rotarg[2:7]))
191-
styles.append(")")
192-
if fontface:
193-
styles.append(f"\\fn{ass_escape(fontface)}")
194-
styles.append("\\fs%.0f" % (comment.size * zoom_factor[0]))
195-
if comment.color != 0xFFFFFF:
196-
styles.append(f"\\c&H{convert_color(comment.color)}&")
197-
if comment.color == 0x000000:
198-
styles.append("\\3c&HFFFFFF&")
199-
if from_alpha == to_alpha:
200-
styles.append(f"\\alpha&H{from_alpha:02X}")
201-
elif (from_alpha, to_alpha) == (255, 0):
202-
styles.append(f"\\fad({lifetime * 1000:.0f},0)")
203-
elif (from_alpha, to_alpha) == (0, 255):
204-
styles.append(f"\\fad(0, {lifetime * 1000:.0f})")
205-
else:
206-
styles.append(
207-
f"\\fade({from_alpha:d}, {to_alpha:d}, {to_alpha:d}, 0, {lifetime * 1000:.0f}, {lifetime * 1000:.0f}, {lifetime * 1000:.0f})"
208-
)
209-
if not is_border:
210-
styles.append("\\bord0")
211-
self._text += "Dialogue: -1,{start},{end},{styleid},,0,0,0,,{{{styles}}}{text}\n".format(
212-
start=convert_timestamp(comment.timeline),
213-
end=convert_timestamp(comment.timeline + lifetime),
214-
styles="".join(styles),
215-
text=text,
216-
styleid=styleid,
177+
self._text += write_comment_with_animation(
178+
comment,
179+
width,
180+
height,
181+
rotate_y,
182+
rotate_z,
183+
from_x,
184+
from_y,
185+
to_x,
186+
to_y,
187+
from_alpha,
188+
to_alpha,
189+
text,
190+
delay,
191+
lifetime,
192+
duration,
193+
fontface,
194+
is_border,
195+
styleid,
196+
zoom_factor,
217197
)
218198

219199
def to_string(self):

tests/test_biliass/test_corpus

0 commit comments

Comments
 (0)