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); }
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)); }
private ConsoleButtonString createPlainButton(List <AConsoleDisplayPart> cssList) { AConsoleDisplayPart[] cssArray = new AConsoleDisplayPart[cssList.Count]; cssList.CopyTo(cssArray); cssList.Clear(); return(new ConsoleButtonString(parent, cssArray)); }
/// <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); }
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)); }
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); }
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); } }
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); }
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; }
/// <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); }
/// <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); }
//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); }
//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); }