예제 #1
0
        private static int getDivideIndex(ConsoleButtonString button, StringMeasure sm)
        {
            AConsoleDisplayPart divCss = null;
            int pointX    = button.PointX;
            int strLength = 0;
            int index     = 0;

            foreach (AConsoleDisplayPart css in button.StrArray)
            {
                if (pointX + css.Width > Config.DrawableWidth)
                {
                    if (index == 0 && !css.CanDivide)
                    {
                        continue;
                    }
                    divCss = css;
                    break;
                }
                index++;
                strLength += css.Str.Length;
                pointX    += css.Width;
            }
            if (divCss != null)
            {
                int cssDivIndex = getDivideIndex(divCss, sm);
                if (cssDivIndex > 0)
                {
                    strLength += cssDivIndex;
                }
            }
            return(strLength);
        }
예제 #2
0
 private ConsoleButtonString createButton(List <AConsoleDisplayPart> cssList, string input, ScriptPosition pos)
 {
     AConsoleDisplayPart[] cssArray = new AConsoleDisplayPart[cssList.Count];
     cssList.CopyTo(cssArray);
     cssList.Clear();
     return(new ConsoleButtonString(parent, cssArray, input, pos));
 }
예제 #3
0
 private ConsoleButtonString createPlainButton(List <AConsoleDisplayPart> cssList)
 {
     AConsoleDisplayPart[] cssArray = new AConsoleDisplayPart[cssList.Count];
     cssList.CopyTo(cssArray);
     cssList.Clear();
     return(new ConsoleButtonString(parent, cssArray));
 }
예제 #4
0
        /// <summary>
        /// ここまでのcssをボタン化。発生原因はbrタグ、行末、ボタンタグ
        /// </summary>
        /// <param name="cssList"></param>
        /// <param name="isbutton"></param>
        /// <param name="state"></param>
        /// <param name="console"></param>
        /// <returns></returns>
        private static ConsoleButtonString cssToButton(List <AConsoleDisplayPart> cssList, HtmlAnalzeState state, EmueraConsole console)
        {
            AConsoleDisplayPart[] css = new AConsoleDisplayPart[cssList.Count];
            cssList.CopyTo(css);
            cssList.Clear();
            ConsoleButtonString ret = null;

            if (state.LastButtonTag != null && state.LastButtonTag.IsButton)
            {
                if (state.LastButtonTag.ButtonIsInteger)
                {
                    ret = new ConsoleButtonString(console, css, state.LastButtonTag.ButtonValueInt, state.LastButtonTag.ButtonValueStr);
                }
                else
                {
                    ret = new ConsoleButtonString(console, css, state.LastButtonTag.ButtonValueStr);
                }
            }
            else
            {
                ret       = new ConsoleButtonString(console, css);
                ret.Title = null;
            }
            if (state.LastButtonTag != null)
            {
                ret.Title = state.LastButtonTag.ButtonTitle;
                if (state.LastButtonTag.PointXisLocked)
                {
                    ret.LockPointX(state.LastButtonTag.PointX);
                }
            }
            return(ret);
        }
예제 #5
0
        private ConsoleButtonString createButton(List <AConsoleDisplayPart> cssList, long input)
        {
            var cssArray = new AConsoleDisplayPart[cssList.Count];

            cssList.CopyTo(cssArray);
            cssList.Clear();
            return(new ConsoleButtonString(parent, cssArray, input));
        }
예제 #6
0
 public void Append(AConsoleDisplayPart part)
 {
     if (builder.Length != 0)
     {
         m_stringList.Add(new ConsoleStyledString(builder.ToString(), lastStringStyle));
         builder.Remove(0, builder.Length);
     }
     m_stringList.Add(part);
 }
예제 #7
0
        private void addDisplayLine(ConsoleDisplayLine line, bool force_LEFT)
        {
            if (LastLineIsTemporary)
            {
                deleteLine(1);
            }
            //不適正なFontのチェック
            AConsoleDisplayPart errorStr = null;

            foreach (ConsoleButtonString button in line.Buttons)
            {
                foreach (AConsoleDisplayPart css in button.StrArray)
                {
                    if (css.Error)
                    {
                        errorStr = css;
                        break;
                    }
                }
            }
            if (errorStr != null)
            {
                MessageBox.Show("Emueraの表示処理中に不適正なフォントを検出しました\n描画処理を続行できないため強制終了します", "フォント不適正");
                this.Quit();
                return;
            }
            if (force_LEFT)
            {
                line.SetAlignment(DisplayLineAlignment.LEFT);
            }
            else
            {
                line.SetAlignment(alignment);
            }
            line.LineNo = lineNo;
            displayLineList.Add(line);
            lineNo++;
            if (line.IsLogicalLine)
            {
                logicalLineCount++;
            }
            if (lineNo == int.MaxValue)
            {
                lastDrawnLineNo = -1;
                lineNo          = 0;
            }
            if (logicalLineCount == long.MaxValue)
            {
                logicalLineCount = 0;
            }
            if (displayLineList.Count > Config.MaxLog)
            {
                displayLineList.RemoveAt(0);
            }
        }
예제 #8
0
        private static int getDivideIndex(AConsoleDisplayPart part, StringMeasure sm)
        {
            if (!part.CanDivide)
            {
                return(-1);
            }
            ConsoleStyledString css = part as ConsoleStyledString;

            if (part == null)
            {
                return(-1);
            }
            int    widthLimit = Config.DrawableWidth - css.PointX;
            string str        = css.Str;
            Font   font       = css.Font;
            int    point      = 0;
            int    highLength = str.Length; //widthLimitを超える最低の文字index(文字数-1)。
            int    lowLength  = 0;          //超えない最大の文字index。
            //int i = (int)(widthLimit / fontDisplaySize);//およその文字数を推定
            //if (i > str.Length - 1)//配列の外を参照しないように。
            //	i = str.Length - 1;
            int i = lowLength;            //およその文字数を推定←やめた

            string test = null;

            while ((highLength - lowLength) > 1)            //差が一文字以下になるまで繰り返す。
            {
                test  = str.Substring(0, i);
                point = sm.GetDisplayLength(test, font);
                if (point <= widthLimit)                //サイズ内ならlowLengthを更新。文字数を増やす。
                {
                    lowLength = i;
                    i++;
                }
                else                //サイズ外ならhighLengthを更新。文字数を減らす。
                {
                    highLength = i;
                    i--;
                }
            }
            return(lowLength);
        }
예제 #9
0
 public void CalcWidth(StringMeasure sm, float subpixel)
 {
     Width = -1;
     if ((strArray != null) && (strArray.Length > 0))
     {
         Width = 0;
         for (var i = 0; i < strArray.Length; ++i)
         {
             AConsoleDisplayPart css = strArray[i];
             if (css.Width <= 0)
             {
                 css.SetWidth(sm, subpixel);
             }
             Width   += css.Width;
             subpixel = css.XsubPixel;
         }
         if (Width <= 0)
         {
             Width = -1;
         }
     }
     XsubPixel = subpixel;
 }
예제 #10
0
        /// <summary>
        /// 物理行をボタン単位に分割。引数のcssListの内容は変更される場合がある。
        /// </summary>
        /// <returns></returns>
        private ConsoleButtonString[] createButtons(List <AConsoleDisplayPart> cssList)
        {
            StringBuilder buf = new StringBuilder();

            for (int i = 0; i < cssList.Count; i++)
            {
                buf.Append(cssList[i].Str);
            }
            List <ButtonPrimitive> bpList = ButtonStringCreator.SplitButton(buf.ToString());

            ConsoleButtonString[] ret      = new ConsoleButtonString[bpList.Count];
            AConsoleDisplayPart[] cssArray = null;
            if (ret.Length == 1)
            {
                cssArray = new AConsoleDisplayPart[cssList.Count];
                cssList.CopyTo(cssArray);
                if (bpList[0].CanSelect)
                {
                    ret[0] = new ConsoleButtonString(parent, cssArray, bpList[0].Input);
                }
                else
                {
                    ret[0] = new ConsoleButtonString(parent, cssArray);
                }
                return(ret);
            }
            int cssStartCharIndex  = 0;
            int buttonEndCharIndex = 0;
            int cssIndex           = 0;
            List <AConsoleDisplayPart> buttonCssList = new List <AConsoleDisplayPart>();

            for (int i = 0; i < ret.Length; i++)
            {
                ButtonPrimitive bp = bpList[i];
                buttonEndCharIndex += bp.Str.Length;
                while (true)
                {
                    if (cssIndex >= cssList.Count)
                    {
                        break;
                    }
                    AConsoleDisplayPart css = cssList[cssIndex];
                    if (cssStartCharIndex + css.Str.Length >= buttonEndCharIndex)
                    {                    //ボタンの終端を発見
                        int used = buttonEndCharIndex - cssStartCharIndex;
                        if (used > 0 && css.CanDivide)
                        {                        //cssの区切りの途中でボタンの区切りがある。
                            ConsoleStyledString newCss = ((ConsoleStyledString)css).DivideAt(used);
                            if (newCss != null)
                            {
                                cssList.Insert(cssIndex + 1, newCss);
                                newCss.PointX = css.PointX + css.Width;
                            }
                        }
                        buttonCssList.Add(css);
                        cssStartCharIndex += css.Str.Length;
                        cssIndex++;
                        break;
                    }
                    //ボタンの終端はまだ先。
                    buttonCssList.Add(css);
                    cssStartCharIndex += css.Str.Length;
                    cssIndex++;
                }
                cssArray = new AConsoleDisplayPart[buttonCssList.Count];
                buttonCssList.CopyTo(cssArray);
                if (bp.CanSelect)
                {
                    ret[i] = new ConsoleButtonString(parent, cssArray, bp.Input);
                }
                else
                {
                    ret[i] = new ConsoleButtonString(parent, cssArray);
                }
                buttonCssList.Clear();
            }
            return(ret);
        }
예제 #11
0
        /// <summary>
        /// htmlから表示行の作成
        /// </summary>
        /// <param name="str">htmlテキスト</param>
        /// <param name="sm"></param>
        /// <param name="console">実際の表示に使わないならnullにする</param>
        /// <returns></returns>
        public static ConsoleDisplayLine[] Html2DisplayLine(string str, StringMeasure sm, EmueraConsole console)
        {
            List <AConsoleDisplayPart> cssList    = new List <AConsoleDisplayPart>();
            List <ConsoleButtonString> buttonList = new List <ConsoleButtonString>();
            StringStream    st = new StringStream(str);
            int             found;
            bool            hasComment = str.IndexOf("<!--") >= 0;
            bool            hasReturn  = str.IndexOf('\n') >= 0;
            HtmlAnalzeState state      = new HtmlAnalzeState();

            while (!st.EOS)
            {
                found = st.Find('<');
                if (hasReturn)
                {
                    int rFound = st.Find('\n');
                    if (rFound >= 0 && (found > rFound || found < 0))
                    {
                        found = rFound;
                    }
                }
                if (found < 0)
                {
                    string txt = Unescape(st.Substring());
                    cssList.Add(new ConsoleStyledString(txt, state.GetSS()));
                    if (state.FlagPClosed)
                    {
                        throw new CodeEE("</p>の後にテキストがあります");
                    }
                    if (state.FlagNobrClosed)
                    {
                        throw new CodeEE("</nobr>の後にテキストがあります");
                    }
                    break;
                }
                else if (found > 0)
                {
                    string txt = Unescape(st.Substring(st.CurrentPosition, found));
                    cssList.Add(new ConsoleStyledString(txt, state.GetSS()));
                    state.LineHead      = false;
                    st.CurrentPosition += found;
                }
                //コメントタグのみ特別扱い
                if (hasComment && st.CurrentEqualTo("<!--"))
                {
                    st.CurrentPosition += 4;
                    found = st.Find("-->");
                    if (found < 0)
                    {
                        throw new CodeEE("コメンdト終了タグ\"-->\"がみつかりません");
                    }
                    st.CurrentPosition += found + 3;
                    continue;
                }
                if (hasReturn && st.Current == '\n')                //テキスト中の\nは<br>として扱う
                {
                    state.FlagBr = true;
                    st.ShiftNext();
                }
                else                //タグ解析
                {
                    st.ShiftNext();
                    AConsoleDisplayPart part = tagAnalyze(state, st);
                    if (st.Current != '>')
                    {
                        throw new CodeEE("タグ終端'>'が見つかりません");
                    }
                    if (part != null)
                    {
                        cssList.Add(part);
                    }
                    st.ShiftNext();
                }

                if (state.FlagBr)
                {
                    state.LastButtonTag = state.CurrentButtonTag;
                    if (cssList.Count > 0)
                    {
                        buttonList.Add(cssToButton(cssList, state, console));
                    }
                    buttonList.Add(null);
                }
                if (state.FlagButton && cssList.Count > 0)
                {
                    buttonList.Add(cssToButton(cssList, state, console));
                }
                state.FlagBr        = false;
                state.FlagButton    = false;
                state.LastButtonTag = state.CurrentButtonTag;
            }
            //</nobr></p>は省略許可
            if (state.CurrentButtonTag != null || state.FontStyle != FontStyle.Regular || state.FonttagList.Count > 0)
            {
                throw new CodeEE("閉じられていないタグがあります");
            }
            if (cssList.Count > 0)
            {
                buttonList.Add(cssToButton(cssList, state, console));
            }

            foreach (ConsoleButtonString button in buttonList)
            {
                if (button != null && button.PointXisLocked)
                {
                    if (!state.FlagNobr)
                    {
                        throw new CodeEE("<nobr>が設定されていない行ではpos属性は使用できません");
                    }
                    if (state.Alignment != DisplayLineAlignment.LEFT)
                    {
                        throw new CodeEE("alignがleftでない行ではpos属性は使用できません");
                    }
                    break;
                }
            }
            ConsoleDisplayLine[] ret = PrintStringBuffer.ButtonsToDisplayLines(buttonList, sm, state.FlagNobr, false);

            foreach (ConsoleDisplayLine dl in ret)
            {
                dl.SetAlignment(state.Alignment);
            }
            return(ret);
        }
예제 #12
0
        //indexの文字数の前方文字列とindex以降の後方文字列に分割
        public ConsoleButtonString DivideAt(int divIndex, StringMeasure sm)
        {
            if (divIndex <= 0)
            {
                return(null);
            }
            List <AConsoleDisplayPart> cssListA = new List <AConsoleDisplayPart>();
            List <AConsoleDisplayPart> cssListB = new List <AConsoleDisplayPart>();
            int  index    = 0;
            int  cssIndex = 0;
            bool b        = false;

            for (cssIndex = 0; cssIndex < strArray.Length; cssIndex++)
            {
                if (b)
                {
                    cssListB.Add(strArray[cssIndex]);
                    continue;
                }
                int length = strArray[cssIndex].Str.Length;
                if (divIndex < index + length)
                {
                    ConsoleStyledString oldcss = strArray[cssIndex] as ConsoleStyledString;
                    if (oldcss == null || !oldcss.CanDivide)
                    {
                        throw new ExeEE("文字列分割異常");
                    }
                    ConsoleStyledString newCss = oldcss.DivideAt(divIndex - index, sm);
                    cssListA.Add(oldcss);
                    if (newCss != null)
                    {
                        cssListB.Add(newCss);
                    }
                    b = true;
                    continue;
                }
                else if (divIndex == index + length)
                {
                    cssListA.Add(strArray[cssIndex]);
                    b = true;
                    continue;
                }
                index += length;
                cssListA.Add(strArray[cssIndex]);
            }
            if ((cssIndex >= strArray.Length) && (cssListB.Count == 0))
            {
                return(null);
            }
            AConsoleDisplayPart[] cssArrayA = new AConsoleDisplayPart[cssListA.Count];
            AConsoleDisplayPart[] cssArrayB = new AConsoleDisplayPart[cssListB.Count];
            cssListA.CopyTo(cssArrayA);
            cssListB.CopyTo(cssArrayB);
            this.strArray = cssArrayA;
            ConsoleButtonString ret = new ConsoleButtonString(null, cssArrayB);

            this.CalcWidth(sm, XsubPixel);
            ret.CalcWidth(sm, 0);
            this.CalcPointX(this.PointX);
            ret.CalcPointX(this.PointX + this.Width);
            ret.parent     = this.parent;
            ret.ParentLine = this.ParentLine;
            ret.IsButton   = this.IsButton;
            ret.IsInteger  = this.IsInteger;
            ret.Input      = this.Input;
            ret.Inputs     = this.Inputs;
            ret.Generation = this.Generation;
            ret.ErrPos     = this.ErrPos;
            ret.Title      = this.Title;
            return(ret);
        }
예제 #13
0
        //indexの文字数の前方文字列とindex以降の後方文字列に分割
        public ConsoleButtonString DivideAt(int divIndex, StringMeasure sm)
        {
            if (divIndex <= 0)
            {
                return(null);
            }
            var cssListA = new List <AConsoleDisplayPart>();
            var cssListB = new List <AConsoleDisplayPart>();
            var index    = 0;
            var cssIndex = 0;
            var b        = false;

            for (cssIndex = 0; cssIndex < StrArray.Length; cssIndex++)
            {
                if (b)
                {
                    cssListB.Add(StrArray[cssIndex]);
                    continue;
                }
                var length = StrArray[cssIndex].Str.Length;
                if (divIndex < index + length)
                {
                    var oldcss = StrArray[cssIndex] as ConsoleStyledString;
                    if (oldcss == null || !oldcss.CanDivide)
                    {
                        throw new ExeEE("文字列分割異常");
                    }
                    var newCss = oldcss.DivideAt(divIndex - index, sm);
                    cssListA.Add(oldcss);
                    if (newCss != null)
                    {
                        cssListB.Add(newCss);
                    }
                    b = true;
                    continue;
                }
                if (divIndex == index + length)
                {
                    cssListA.Add(StrArray[cssIndex]);
                    b = true;
                    continue;
                }
                index += length;
                cssListA.Add(StrArray[cssIndex]);
            }
            if (cssIndex >= StrArray.Length && cssListB.Count == 0)
            {
                return(null);
            }
            var cssArrayA = new AConsoleDisplayPart[cssListA.Count];
            var cssArrayB = new AConsoleDisplayPart[cssListB.Count];

            cssListA.CopyTo(cssArrayA);
            cssListB.CopyTo(cssArrayB);
            StrArray = cssArrayA;
            var ret = new ConsoleButtonString(null, cssArrayB);

            CalcWidth(sm, XsubPixel);
            ret.CalcWidth(sm, 0);
            CalcPointX(PointX);
            ret.CalcPointX(PointX + Width);
            ret.parent     = parent;
            ret.ParentLine = ParentLine;
            ret.IsButton   = IsButton;
            ret.IsInteger  = IsInteger;
            ret.Input      = Input;
            ret.Inputs     = Inputs;
            ret.Generation = Generation;
            ret.ErrPos     = ErrPos;
            ret.Title      = Title;
            return(ret);
        }