| 291 | } |
| 292 | |
| 293 | static int put_codepoint(const char* utf8_codepoint, size_t length, int expectedWidth) { |
| 294 | #if defined(_WIN32) |
| 295 | CONSOLE_SCREEN_BUFFER_INFO bufferInfo; |
| 296 | if (!GetConsoleScreenBufferInfo(hConsole, &bufferInfo)) { |
| 297 | // go with the default |
| 298 | return expectedWidth; |
| 299 | } |
| 300 | COORD initialPosition = bufferInfo.dwCursorPosition; |
| 301 | DWORD nNumberOfChars = length; |
| 302 | WriteConsole(hConsole, utf8_codepoint, nNumberOfChars, &nNumberOfChars, NULL); |
| 303 | |
| 304 | CONSOLE_SCREEN_BUFFER_INFO newBufferInfo; |
| 305 | GetConsoleScreenBufferInfo(hConsole, &newBufferInfo); |
| 306 | |
| 307 | // Figure out our real position if we're in the last column |
| 308 | if (utf8_codepoint[0] != 0x09 && initialPosition.X == newBufferInfo.dwSize.X - 1) { |
| 309 | DWORD nNumberOfChars; |
| 310 | WriteConsole(hConsole, &" \b", 2, &nNumberOfChars, NULL); |
| 311 | GetConsoleScreenBufferInfo(hConsole, &newBufferInfo); |
| 312 | } |
| 313 | |
| 314 | int width = newBufferInfo.dwCursorPosition.X - initialPosition.X; |
| 315 | if (width < 0) { |
| 316 | width += newBufferInfo.dwSize.X; |
| 317 | } |
| 318 | return width; |
| 319 | #else |
| 320 | // We can trust expectedWidth if we've got one |
| 321 | if (expectedWidth >= 0 || tty == nullptr) { |
| 322 | fwrite(utf8_codepoint, length, 1, out); |
| 323 | return expectedWidth; |
| 324 | } |
| 325 | |
| 326 | fputs("\033[6n", tty); // Query cursor position |
| 327 | int x1; |
| 328 | int y1; |
| 329 | int x2; |
| 330 | int y2; |
| 331 | int results = 0; |
| 332 | results = fscanf(tty, "\033[%d;%dR", &y1, &x1); |
| 333 | |
| 334 | fwrite(utf8_codepoint, length, 1, tty); |
| 335 | |
| 336 | fputs("\033[6n", tty); // Query cursor position |
| 337 | results += fscanf(tty, "\033[%d;%dR", &y2, &x2); |
| 338 | |
| 339 | if (results != 4) { |
| 340 | return expectedWidth; |
| 341 | } |
| 342 | |
| 343 | int width = x2 - x1; |
| 344 | if (width < 0) { |
| 345 | // Calculate the width considering text wrapping |
| 346 | struct winsize w; |
| 347 | ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); |
| 348 | width += w.ws_col; |
| 349 | } |
| 350 | return width; |
no outgoing calls
no test coverage detected