ksplayer word splitting fix

This commit is contained in:
tapframe 2025-11-25 01:15:41 +05:30
parent 0ab85ec870
commit ecaaaa66ed
3 changed files with 289 additions and 291 deletions

View file

@ -2196,33 +2196,28 @@ const KSPlayerCore: React.FC = () => {
// Extract formatted segments from current cue
if (currentCue?.formattedSegments) {
// Split by newlines to get per-line segments
const lines = (currentCue.text || '').split(/\r?\n/);
const segmentsPerLine: SubtitleSegment[][] = [];
let segmentIndex = 0;
let currentLine: SubtitleSegment[] = [];
for (const line of lines) {
const lineSegments: SubtitleSegment[] = [];
const words = line.split(/(\s+)/);
currentCue.formattedSegments.forEach(seg => {
const parts = seg.text.split(/\r?\n/);
parts.forEach((part, index) => {
if (index > 0) {
// New line found
segmentsPerLine.push(currentLine);
currentLine = [];
}
if (part.length > 0) {
currentLine.push({ ...seg, text: part });
}
});
});
for (const word of words) {
if (word.trim()) {
if (segmentIndex < currentCue.formattedSegments.length) {
lineSegments.push(currentCue.formattedSegments[segmentIndex]);
segmentIndex++;
} else {
// Fallback if segment count doesn't match
lineSegments.push({ text: word });
}
}
if (currentLine.length > 0) {
segmentsPerLine.push(currentLine);
}
if (lineSegments.length > 0) {
segmentsPerLine.push(lineSegments);
}
}
setCurrentFormattedSegments(segmentsPerLine.length > 0 ? segmentsPerLine : []);
setCurrentFormattedSegments(segmentsPerLine);
} else {
setCurrentFormattedSegments([]);
}

View file

@ -65,8 +65,17 @@ export const CustomSubtitles: React.FC<CustomSubtitlesProps> = ({
}
effectiveBottom = Math.max(0, effectiveBottom);
// Prepare content lines
const lines = String(currentSubtitle).split(/\r?\n/);
// Detect RTL for each line
const lineRTLStatus = lines.map(line => detectRTL(line));
const hasRTL = lineRTLStatus.some(status => status);
// When using crisp outline, prefer SVG text with real stroke instead of blur shadow
const useCrispSvgOutline = outline === true;
// However, SVG text does not support complex text shaping (required for Arabic/RTL),
// so we must fallback to standard Text component for RTL languages.
const useCrispSvgOutline = outline === true && !hasRTL;
const shadowStyle = (textShadow && !useCrispSvgOutline)
? {
@ -76,12 +85,6 @@ export const CustomSubtitles: React.FC<CustomSubtitlesProps> = ({
}
: {};
// Prepare content lines
const lines = String(currentSubtitle).split(/\r?\n/);
// Detect RTL for each line
const lineRTLStatus = lines.map(line => detectRTL(line));
const displayFontSize = subtitleSize * inverseScale;
const displayLineHeight = subtitleSize * lineHeightMultiplier * inverseScale;
const svgHeight = lines.length * displayLineHeight;

View file

@ -189,7 +189,7 @@ export const detectRTL = (text: string): boolean => {
// Arabic Presentation Forms-B: U+FE70U+FEFF
// Hebrew: U+0590U+05FF
// Persian/Urdu use Arabic script (no separate range)
const rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
const rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/g;
// Remove whitespace and count characters
const nonWhitespace = text.replace(/\s/g, '');