예제 #1
0
파일: Nico.cs 프로젝트: harnenim/SmiManager
        private static string CutLineLeftToWidth(string line, double width)
        {
            string last3 = line;

            while (Smi.GetLineWidth(line) > width)
            {
                last3 = line;
                line  = line.Substring(1);
            }
            string last1 = line;

            while (Smi.GetLineWidth(line) < width)
            {
                last1 = line;
                line  = " " + line;
            }
            if (width - Smi.GetLineWidth(last1) < Smi.GetLineWidth(line) - width)
            {
                line = last1;
                if (Smi.GetLineWidth(last3) - width < width - Smi.GetLineWidth(line))
                {
                    line = last3;
                }
            }
            return(line);
        }
예제 #2
0
파일: Nico.cs 프로젝트: harnenim/SmiManager
        // Cut 함수는 SubtitleObject.dll로 빼는 게 나을 듯?
        private static string CutLineRightToWidth(string line, double width)
        {
            string last3 = line;
            float  t     = 0;

            while ((t = Smi.GetLineWidth(line)) > width)
            {
                last3 = line;
                line  = line.Substring(0, line.Length - 1);
            }
            string last1 = line;

            while (Smi.GetLineWidth(line) < width)
            {
                last1 = line;
                line += " ";
            }
            if (width - Smi.GetLineWidth(last1) < Smi.GetLineWidth(line) - width)
            {
                line = last1;
                if (Smi.GetLineWidth(last3) - width < width - Smi.GetLineWidth(line))
                {
                    line = last3;
                }
            }
            return(line);
        }
예제 #3
0
        public static List <Smi> Combine(List <Smi> inputUpper, List <Smi> inputLower)
        {
            List <CombinedGroup> groups = new List <CombinedGroup>();
            CombinedGroup        lastGroup = new CombinedGroup();
            Combined             last = new Combined();
            int ui = 0, li = 0;

            while (ui < inputUpper.Count && li < inputLower.Count)
            {
                Smi uLine = inputUpper[ui];
                Smi lLine = inputLower[li];

                int comp = uLine.start - lLine.start;
                if (comp < 0)
                {
                    // 위 바뀜

                    if (last.lower.Length == 0)
                    {
                        // 아래가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹
                        groups.Add((lastGroup = new CombinedGroup()));
                    }

                    lastGroup.combineds.Add((last = new Combined()
                    {
                        start = uLine.start,
                        syncType = uLine.syncType,
                        upper = uLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text),
                        lower = (string[])last.lower.Clone()
                    }));
                    if (last.upper.Length > lastGroup.upperLineCount)
                    {
                        lastGroup.upperLineCount = last.upper.Length;
                    }

                    ui++;
                }
                else if (comp > 0)
                {
                    // 아래 바뀜

                    if (last.upper.Length == 0)
                    {
                        // 위가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹
                        groups.Add((lastGroup = new CombinedGroup()));
                    }

                    lastGroup.combineds.Add((last = new Combined()
                    {
                        start = lLine.start,
                        syncType = lLine.syncType,
                        upper = (string[])last.upper.Clone(),
                        lower = lLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text)
                    }));
                    if (last.lower.Length > lastGroup.lowerLineCount)
                    {
                        lastGroup.lowerLineCount = last.lower.Length;
                    }

                    li++;
                }
                else
                {
                    // 동시

                    // 새 그룹
                    groups.Add((lastGroup = new CombinedGroup()));

                    lastGroup.combineds.Add((last = new Combined()
                    {
                        start = uLine.start,
                        syncType = (uLine.syncType == SyncType.frame || lLine.syncType == SyncType.frame) ? SyncType.frame : SyncType.normal,
                        upper = uLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text),
                        lower = lLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text)
                    }));
                    lastGroup.upperLineCount = last.upper.Length;
                    lastGroup.lowerLineCount = last.lower.Length;

                    ui++; li++;
                }
            }
            for (; ui < inputUpper.Count; ui++)
            {
                Smi uLine = inputUpper[ui];

                if (last.lower.Length == 0)
                {
                    // 아래가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹
                    groups.Add((lastGroup = new CombinedGroup()));
                }

                lastGroup.combineds.Add((last = new Combined()
                {
                    start = uLine.start,
                    syncType = uLine.syncType,
                    upper = uLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text),
                    lower = (string[])last.lower.Clone()
                }));
                if (last.upper.Length > lastGroup.upperLineCount)
                {
                    lastGroup.upperLineCount = last.upper.Length;
                }
            }
            for (; li < inputLower.Count; li++)
            {
                Smi lLine = inputLower[li];

                if (last.upper.Length == 0)
                {
                    // 위가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹
                    groups.Add((lastGroup = new CombinedGroup()));
                }

                lastGroup.combineds.Add((last = new Combined()
                {
                    start = lLine.start,
                    syncType = lLine.syncType,
                    upper = (string[])last.upper.Clone(),
                    lower = lLine.text.Replace("&nbsp;", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text)
                }));
                if (last.lower.Length > lastGroup.lowerLineCount)
                {
                    lastGroup.lowerLineCount = last.lower.Length;
                }
            }

            List <Smi> result = new List <Smi>();

            foreach (CombinedGroup group in groups)
            {
                foreach (Combined combined in group.combineds)
                {
                    int   maxUpperIndex = 0, maxLowerIndex = 0;
                    float maxUpperWidth = 0, maxLowerWidth = 0;
                    for (int i = 0; i < combined.upper.Length; i++)
                    {
                        float width = Smi.GetLineWidth(combined.upper[i]);
                        if (width > maxUpperWidth)
                        {
                            maxUpperIndex = i;
                            maxUpperWidth = width;
                        }
                    }
                    for (int i = 0; i < combined.lower.Length; i++)
                    {
                        float width = Smi.GetLineWidth(combined.lower[i]);
                        if (width > maxLowerWidth)
                        {
                            maxLowerIndex = i;
                            maxLowerWidth = width;
                        }
                    }

                    // 정렬용 글자 수 맞춰주기
                    if (combined.upper.Length > 0 && combined.lower.Length > 0)
                    {
                        if (maxUpperWidth > maxLowerWidth)
                        {
                            //string left = Smi.GetLineAppend(combined.lower[maxLowerIndex], maxUpperWidth, true);
                            string left = Width.GetAppend(Smi.GetLineWidth(combined.lower[maxLowerIndex]), maxUpperWidth, true);
                            if (left.Length > 0)
                            {
                                string right = Width.AppendToRight(left);
                                for (int i = 0; i < combined.lower.Length; i++)
                                {
                                    //combined.lower[i] = "<b></b>" + left + combined.lower[i] + right + "<b></b>";
                                    combined.lower[i] = left + combined.lower[i] + right;
                                }
                            }
                        }
                        else
                        {
                            //string left = Smi.GetLineAppend(combined.upper[maxUpperIndex], maxLowerWidth, true);
                            string left = Width.GetAppend(Smi.GetLineWidth(combined.upper[maxUpperIndex]), maxLowerWidth, true);
                            if (left.Length > 0)
                            {
                                string right = Width.AppendToRight(left);
                                for (int i = 0; i < combined.upper.Length; i++)
                                {
                                    //combined.upper[i] = "<b></b>" + left + combined.upper[i] + right + "<b></b>";
                                    combined.upper[i] = left + combined.upper[i] + right;
                                }
                            }
                        }
                    }

                    Smi smi = new Smi()
                    {
                        start    = combined.start,
                        syncType = combined.syncType,
                        text     = ""
                    };
                    for (int i = 0; i < group.upperLineCount - combined.upper.Length; i++)
                    {
                        smi.text += "<b> </b>" + (i < group.upperLineCount - 1 ? "<br>" : "");
                    }
                    for (int i = 0; i < combined.upper.Length; i++)
                    {
                        smi.text += combined.upper[i] + (i < combined.upper.Length - 1 ? "<br>" : "");
                    }
                    if (group.upperLineCount > 0 && group.lowerLineCount > 0)
                    {
                        smi.text += "<br>";
                    }
                    for (int i = 0; i < group.lowerLineCount - combined.lower.Length; i++)
                    {
                        smi.text += "<b> </b>" + (i < (group.lowerLineCount - 1) ? "<br>" : "");
                    }
                    for (int i = 0; i < combined.lower.Length; i++)
                    {
                        smi.text += combined.lower[i] + (i < (combined.lower.Length - 1) ? "<br>" : "");
                    }

                    if (smi.text.Length == 0)
                    {
                        smi.text = "&nbsp;";
                    }
                    else
                    {
                        if (smi.text.StartsWith(" ") || smi.text.StartsWith(" "))
                        {
                            smi.text = "​" + smi.text;
                        }
                        if (smi.text.EndsWith(" ") || smi.text.EndsWith(" "))
                        {
                            smi.text = smi.text + "​";
                        }
                    }

                    result.Add(smi);
                }
            }
            return(result);
        }
예제 #4
0
파일: Nico.cs 프로젝트: harnenim/SmiManager
        public static List <Smi> Nico(List <NicoLine> nicoLines, int width)
        {
            int lineCount  = 0;
            int startOfAll = int.MaxValue;
            int endOfAll   = 0;

            foreach (NicoLine line in nicoLines)
            {
                if (line.line > lineCount)
                {
                    lineCount = line.line;
                }
                if (line.start < startOfAll)
                {
                    startOfAll = line.start;
                }
                if (line.end > endOfAll)
                {
                    endOfAll = line.end;
                }
            }

            int startFrame = (int)Math.Round(startOfAll / FRAME_LENGTH);
            int endFrame   = (int)Math.Round(endOfAll / FRAME_LENGTH);

            List <List <NicoLine> > lines = new List <List <NicoLine> >();

            for (int i = 0; i < lineCount; i++)
            {
                lines.Add(new List <NicoLine>());
            }

            foreach (NicoLine line in nicoLines)
            {
                lines[line.line - 1].Add(line);
            }

            string defaultValue = "";

            for (int i = 0; i < width; i++)
            {
                defaultValue += " ";
            }
            NicoLine.lineWidth = Smi.GetLineWidth(defaultValue);

            List <Smi> output = new List <Smi>();

            for (int frame = startFrame; frame < endFrame; frame++)
            {
                Smi smi = new Smi()
                {
                    start    = (int)(frame * FRAME_LENGTH),
                    syncType = (frame == startFrame ? SyncType.frame : SyncType.inner),
                    text     = "​"
                };
                for (int i = 0; i < lineCount; i++)
                {
                    string result = defaultValue;
                    foreach (NicoLine line in lines[i])
                    {
                        float pos = line.CalcLeft(frame);
                        if (pos < 0)
                        {   // 왼쪽이 잘리기 시작
                            float leftWidth = pos + line.width;
                            if (leftWidth > 0)
                            {     // 화면에 남는 부분이 있음
                                if (leftWidth >= NicoLine.lineWidth)
                                { // 남는 부분이 화면보다 큼
                                    result = CutLineLeftToWidth(line.text, leftWidth);
                                    result = CutLineRightToWidth(line.text, NicoLine.lineWidth);
                                }
                                else
                                {   // 남는 부분이 화면보다 작음
                                    string text = CutLineLeftToWidth(line.text, leftWidth);
                                    result = text + CutLineLeftToWidth(result, NicoLine.lineWidth - leftWidth);
                                }
                            }
                        }
                        else if (pos < NicoLine.lineWidth)
                        {   // 화면 안에서 시작
                            string lastResult = result;
                            result = CutLineRightToWidth(result, pos) + line.text;
                            float thisWidth = Smi.GetLineWidth(result);
                            if (thisWidth > NicoLine.lineWidth)
                            {
                                result = CutLineRightToWidth(result, NicoLine.lineWidth);
                            }
                            else
                            {
                                result += CutLineLeftToWidth(lastResult, NicoLine.lineWidth - thisWidth);
                            }
                        }
                    }
                    smi.text += (i == 0 ? "" : "<br>") + result;
                }
                smi.text += "​";
                output.Add(smi);
            }
            output.Add(new Smi()
            {
                start    = (int)(endFrame * FRAME_LENGTH),
                syncType = SyncType.frame,
                text     = "&nbsp;"
            });

            return(output);
        }