// 1行辺りのテキストの分割とマッピング情報を取得 private bool CreateLineTextInfo(TextData textData, string lineText, Rect visibleRect, int maxHeigth) { TextLineData lineData = new TextLineData(); float totalHeight = textData.totalHeight; int continuePoint = -1; for (int i = 0; i < lineText.Length; ++i) { if (!font.HasCharacter(lineText[i])) { continue; } CharacterInfo characterInfo; if (font.GetCharacterInfo(lineText[i], out characterInfo, fontSize, style)) { // 行末禁則判定のため次の文字に関しての // チェックをこのタイミングで行う if (IsHyphenationBack(lineText[i]) && i + 1 < lineText.Length) { // Debug.Log("word : " + lineText[i]); CharacterInfo nextCharacterInfo; font.GetCharacterInfo(lineText[i + 1], out nextCharacterInfo, fontSize, style); if (IsNewLine(lineData.totalWidth + characterInfo.advance, nextCharacterInfo.advance, visibleRect.width)) { // Debug.Log("next word : " + lineText[i + 1]); continuePoint = i; lineData.justfit = true; break; } } // warpは自動改行なので // ここで横の長さがrectの大きさを超えてしまうかチェック if (IsNewLine(lineData.totalWidth, characterInfo.advance, visibleRect.width)) { if (!IsHyphenationFront(lineText[i])) { continuePoint = i; break; } else { // 行頭の禁則文字じゃない場合この行に含めて // 均等割り付けにする lineData.justfit = true; } } else if (horizontalLayout == Layout.Horizontal.Warp) { Func <char[], int, bool> serialWords = (words, warpLimitCount) => { if (Exists(words, lineText[i])) { int characterCount = 0; bool inline = IsSerialWordCurrentLine(out characterCount, words, warpLimitCount, lineData.totalWidth + characterInfo.advance, lineText, i, visibleRect.width); // 連続した数値の個数が-1の場合次の行にして表示する if (!inline) { continuePoint = i; lineData.justfit = true; return(false); } for (int j = 0; j < characterCount; ++j) { lineData.totalWidth += characterInfo.advance; lineData.charactersInfo.Add(characterInfo); font.GetCharacterInfo(lineText[i + j + 1], out characterInfo, fontSize, style); } i += characterCount; // 連続した数字がこの行に入り切らない場合均等割付を有効にして収めるようにする if (lineData.totalWidth + characterInfo.advance > visibleRect.width) { lineData.justfit = true; } } return(true); }; // 数字が連続する時に自動改行をしてほしくないので // 連続した数字が存在して、自動改行されるか判定をして // 改行される場合開始地点で開業するように if (!serialWords(Numbers, 0)) { break; } // アルファベットが連続する時に自動改行を変な位置で自動改行しないため if (!serialWords(Alphabet, alphabetWarpLimit)) { break; } } lineData.totalWidth += characterInfo.advance; lineData.charactersInfo.Add(characterInfo); // Debug.Log("glyphWidth : " + characterInfo.glyphWidth); // Debug.Log("glyphHeight : " + characterInfo.glyphHeight ); // Debug.Log("size : " + characterInfo.size); // Debug.Log("maxX : " + characterInfo.maxX); // Debug.Log("maxX : " + characterInfo.minX); // Debug.Log("minY : " + characterInfo.minY); // Debug.Log("maxY : " + characterInfo.maxY); // Debug.Log("advance : " + characterInfo.advance); // Debug.Log("bearing : " + characterInfo.bearing); } } // テキスト全体の最大の高さを保持しておく totalHeight += maxHeigth; // 合計の高さがrectを超える場合表示しない if (verticalLayout == Layout.Vertical.Truncate && visibleRect.height < totalHeight) { return(false); } totalHeight += lineSpaceing; textData.totalHeight = totalHeight; textData.lineData.Add(lineData); if (continuePoint != -1) { string restString = lineText.Substring(continuePoint); return(CreateLineTextInfo(textData, restString, visibleRect, maxHeigth)); } return(true); }
/// <summary> /// Logika dołączania nagłówków. Pierwszy znak + zaczyna tabelę i nagłówek tabeli. Drugi znak + kończy nagłówek. Jeśli po kolejnym znaku + występuje znak | to znaczy, że tabela jest kontynuowana. W przeciwnym razie tabela się kończy. Jeśli są znaki + i zaraz po nim + to poprzednia się kończy i nowa zaczyna. /// </summary> /// <param name="lineData"></param> private void UpdateCurrentPageData(TextLineData lineData, TextLineData nextLineData) { string trimmedLine = lineData.TrimmedText; if (trimmedLine.Length == 0) { this.TryClearTableHeaderCache(); this.currentPageContent.Add(lineData.RawText); return; } char nextLineFirstChar = nextLineData != null && nextLineData.TrimmedText.Length > 0 ? nextLineData.TrimmedText[0] : ' '; switch (trimmedLine[0]) { case '+': { //Początek cachowania nagłówka tabeli if (!this.tableStarted) { this.tableStarted = true; this.currentHeader = new List <string>(); this.currentHeader.Add(lineData.RawText); this.currentHeaderSize = lineData.Size; } //Koniec cachowania nagłówka tabeli else if (!this.tableHeaderEnded) { this.tableHeaderEnded = true; this.currentHeader.Add(lineData.RawText); this.currentHeaderSize += lineData.Size; } //Koniec sekcji tabeli - przerobić bo to niekoniecznie musi być jej koniec!!! else { if (nextLineFirstChar != '|') //koniec tabeli { this.tableStarted = this.tableHeaderEnded = this.currentTableLineEmited = false; //W tym momencie wiadomo, że zmieści się zarowno poprzednia linia jak i koniec tabelki. this.TryEmitHeaderAndLastLineToEmit(); this.currentPageContent.Add(lineData.RawText); this.headerEmited = false; this.currentTableLineEmited = false; } else //kontynuacja tabeli { //Emitujemy poprzednią linię tabelki jeśli mamy pewność, że kolejna linia się mieści if (currentTableLineEmited) { //Emitujemy header jeśli nie był jeszcze wyemitowany this.TryEmitHeaderAndLastLineToEmit(); } //Cachujemy kolejną linię this.lastTableLineToEmit = lineData; this.lastTableLineSize = lineData.Size; this.currentTableLineEmited = true; } } } break; case '|': { if (this.tableStarted) { if (!this.tableHeaderEnded) { //Kontynuacja cachowania nagłówka this.currentHeader.Add(lineData.RawText); this.currentHeaderSize += lineData.Size; } else { //Emitujemy poprzednią linię tabelki jeśli mamy pewność, że kolejna linia się mieści if (currentTableLineEmited) { //Emitujemy header jeśli nie był jeszcze wyemitowany this.TryEmitHeaderAndLastLineToEmit(); } //Cachujemy kolejną linię this.lastTableLineToEmit = lineData; this.lastTableLineSize = lineData.Size; this.currentTableLineEmited = true; } } } break; default: { this.TryClearTableHeaderCache(); //Jeśli linia nie jest powiązana z tabelą po prostu się emituje this.currentPageContent.Add(lineData.RawText); } break; } }