-\r
- for (PrevCurrIndex = 0, CurrIndex = 0, LineCount = 0, LastSpaceIndex = 0,\r
- IndexArray[0] = 0, GlyphWidth = 1, GlyphOffset = 0, LastSpaceGlyphWidth = 1, LineStartGlyphWidth = 1;\r
- (StringPtr[CurrIndex] != CHAR_NULL);\r
- CurrIndex ++) {\r
-\r
- if (LineCount == AllocateSize) {\r
- AllocateSize += 0x10;\r
- OldIndexArray = IndexArray;\r
- IndexArray = AllocatePool (AllocateSize * sizeof (UINTN) * 3);\r
- ASSERT (IndexArray != NULL);\r
-\r
- CopyMem (IndexArray, OldIndexArray, LineCount * sizeof (UINTN) * 3);\r
- FreePool (OldIndexArray);\r
- }\r
- switch (StringPtr[CurrIndex]) {\r
-\r
- case NARROW_CHAR:\r
- case WIDE_CHAR:\r
- GlyphWidth = ((StringPtr[CurrIndex] == WIDE_CHAR) ? 2 : 1);\r
- if (CurrIndex == 0) {\r
- LineStartGlyphWidth = GlyphWidth;\r
- }\r
- break;\r
-\r
- //\r
- // char is '\n'\r
- // "\r\n" isn't handled here, handled by case CHAR_CARRIAGE_RETURN\r
- //\r
- case CHAR_LINEFEED:\r
- //\r
- // Store a range of string as a line\r
- //\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineCount ++;\r
- //\r
- // Reset offset and save begin position of line\r
- //\r
- GlyphOffset = 0;\r
- LineStartGlyphWidth = GlyphWidth;\r
- PrevCurrIndex = CurrIndex + 1;\r
- break;\r
-\r
- //\r
- // char is '\r'\r
- // "\r\n" and "\r" both are handled here\r
- //\r
- case CHAR_CARRIAGE_RETURN:\r
- if (StringPtr[CurrIndex + 1] == CHAR_LINEFEED) {\r
- //\r
- // next char is '\n'\r
- //\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineCount ++;\r
- CurrIndex ++;\r
- }\r
- GlyphOffset = 0;\r
- LineStartGlyphWidth = GlyphWidth;\r
- PrevCurrIndex = CurrIndex + 1;\r
- break;\r
-\r
- //\r
- // char is space or other char\r
- //\r
- default:\r
- GlyphOffset += GlyphWidth;\r
- if (GlyphOffset >= BlockWidth) {\r
- if (LastSpaceIndex > PrevCurrIndex) {\r
- //\r
- // LastSpaceIndex points to space inside current screen-line,\r
- // restore to LastSpaceIndex\r
- // (Otherwise the word is too long to fit one screen-line, just cut it)\r
- //\r
- CurrIndex = LastSpaceIndex;\r
- GlyphWidth = LastSpaceGlyphWidth;\r
- } else if (GlyphOffset > BlockWidth) {\r
- //\r
- // the word is too long to fit one screen-line and we don't get the chance\r
- // of GlyphOffset == BlockWidth because GlyphWidth = 2\r
- //\r
- CurrIndex --;\r
- }\r
-\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex + 1;\r
- IndexArray[LineCount*3+2] = LineStartGlyphWidth;\r
- LineStartGlyphWidth = GlyphWidth;\r
- LineCount ++;\r
- //\r
- // Reset offset and save begin position of line\r
- //\r
- GlyphOffset = 0;\r
- PrevCurrIndex = CurrIndex + 1;\r
- }\r
-\r
- //\r
- // LastSpaceIndex: remember position of last space\r
- //\r
- if (StringPtr[CurrIndex] == CHAR_SPACE) {\r
- LastSpaceIndex = CurrIndex;\r
- LastSpaceGlyphWidth = GlyphWidth;\r
- }\r
- break;\r
- }\r
- }\r
-\r
- if (GlyphOffset > 0) {\r
- IndexArray[LineCount*3] = PrevCurrIndex;\r
- IndexArray[LineCount*3+1] = CurrIndex;\r
- IndexArray[LineCount*3+2] = GlyphWidth;\r
- LineCount ++;\r
- }\r
-\r
- if (LineCount == 0) {\r
- //\r
- // in case we meet null string\r
- //\r
- IndexArray[0] = 0;\r
- IndexArray[1] = 1;\r
- //\r
- // we assume null string's glyph width is 1\r
- //\r
- IndexArray[1] = 1;\r
- LineCount ++;\r
- }\r
-\r
- VirtualLineCount = RowCount * (LineCount / RowCount + (LineCount % RowCount > 0));\r
- *FormattedString = AllocateZeroPool (VirtualLineCount * (BlockWidth + 1) * sizeof (CHAR16) * 2);\r