mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-08-25 00:15:27 -07:00
fix(subtitles): preserve opaque text beside ASS texture fragments
- Require structural texture evidence before suppressing same-font fragments
This commit is contained in:
@@ -1265,6 +1265,21 @@ test('parseSubtitleCues drops clipped repeated-glyph texture text', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('parseSubtitleCues preserves opaque same-font text beside texture fragments', () => {
|
||||||
|
const content = [
|
||||||
|
'[Events]',
|
||||||
|
'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text',
|
||||||
|
'Dialogue: 2,0:00:01.00,0:00:04.00,MarySigns,seed,0,0,0,,{\\pos(960,80)\\fnSerangkaian Pattern Regular\\clip(800,20,1120,140)}LLLLLLLLLLLLLLLLLLLLLLLL',
|
||||||
|
'Dialogue: 2,0:00:01.00,0:00:04.00,MarySigns,piece,0,0,0,,{\\pos(960,110)\\fnSerangkaian Pattern Regular\\clip(800,20,1120,140)}LLLL',
|
||||||
|
'Dialogue: 3,0:00:01.00,0:00:04.00,MarySigns,label,0,0,0,,{\\pos(960,150)\\fnSerangkaian Pattern Regular}Keep this label',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
parseSubtitleCues(content, 'test.ass').map((cue) => cue.text),
|
||||||
|
['Keep this label'],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('parseSubtitleCues drops clipped repeated-glyph texture text without a font override', () => {
|
test('parseSubtitleCues drops clipped repeated-glyph texture text without a font override', () => {
|
||||||
const content = [
|
const content = [
|
||||||
'[Events]',
|
'[Events]',
|
||||||
|
|||||||
@@ -1038,6 +1038,14 @@ function isNearlyTransparentPositionedText(cue: AnnotatedSubtitleCue): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasAssTextureCandidateEvidence(cue: AnnotatedSubtitleCue): boolean {
|
||||||
|
return (
|
||||||
|
isClippedRepeatedGlyphFragment(cue) ||
|
||||||
|
isNearlyTransparentPositionedText(cue) ||
|
||||||
|
hasStaticOverride(cue, '2a')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function assFontTextureGroupKey(cue: AnnotatedSubtitleCue): string | null {
|
function assFontTextureGroupKey(cue: AnnotatedSubtitleCue): string | null {
|
||||||
const font = staticFontOverride(cue);
|
const font = staticFontOverride(cue);
|
||||||
return font === null ? null : `${cue.style}\0${cue.startTime}\0${cue.endTime}\0${font}`;
|
return font === null ? null : `${cue.style}\0${cue.startTime}\0${cue.endTime}\0${font}`;
|
||||||
@@ -1050,9 +1058,9 @@ function assTextureTimingGroupKey(cue: AnnotatedSubtitleCue): string {
|
|||||||
function removeAssFontTextureEvents(events: ParsedAssEvents): ParsedAssEvents {
|
function removeAssFontTextureEvents(events: ParsedAssEvents): ParsedAssEvents {
|
||||||
const seeds = events.dialogue.filter(isAssTextureSeed);
|
const seeds = events.dialogue.filter(isAssTextureSeed);
|
||||||
const seedSet = new Set(seeds);
|
const seedSet = new Set(seeds);
|
||||||
// Short pieces can share the seeded font effect under another actor without carrying
|
// Short pieces can share the seeded font effect under another actor. Matching the
|
||||||
// enough tags to identify themselves. The exact style, time, and font group catches
|
// seed's style, timing, and font only narrows the candidates; each piece must still
|
||||||
// those pieces without inspecting their content.
|
// carry structural texture evidence.
|
||||||
const textureGroups = new Set(
|
const textureGroups = new Set(
|
||||||
seeds.map(assFontTextureGroupKey).filter((key): key is string => key !== null),
|
seeds.map(assFontTextureGroupKey).filter((key): key is string => key !== null),
|
||||||
);
|
);
|
||||||
@@ -1090,7 +1098,7 @@ function removeAssFontTextureEvents(events: ParsedAssEvents): ParsedAssEvents {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const key = assFontTextureGroupKey(cue);
|
const key = assFontTextureGroupKey(cue);
|
||||||
if (key !== null && textureGroups.has(key)) {
|
if (key !== null && textureGroups.has(key) && hasAssTextureCandidateEvidence(cue)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!isNearlyTransparentPositionedText(cue)) {
|
if (!isNearlyTransparentPositionedText(cue)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user