Get the cursor index given a mouse click position (text canvas space)
| 448 | |
| 449 | // Get the cursor index given a mouse click position (text canvas space) |
| 450 | int TextCanvasTexture::GetCursorPos(const char* str, const CanvasTextStyle& style, const int coords[2], uint32_t char_limit) { |
| 451 | int best_letter = 0; |
| 452 | int best_distance = INT_MAX; |
| 453 | int length = strlen(str); |
| 454 | TextMetrics total_metrics; |
| 455 | RenderText(str, length, style, total_metrics, TMF_METRICS, char_limit); |
| 456 | FontRenderer* font_renderer = FontRenderer::Instance(); |
| 457 | FT_Matrix matrix; |
| 458 | FTMatrixFromAngle(&matrix, 0.0f); |
| 459 | int line_height = font_renderer->GetFontInfo(style.font_face_id, FontRenderer::INFO_HEIGHT); |
| 460 | int click_line = coords[1] / (line_height / 64); |
| 461 | int curr_line = 0; |
| 462 | int line_start = 0; |
| 463 | FT_Vector zero_vec = {0}; |
| 464 | TextMetrics metrics; |
| 465 | ClearTextMetrics(&metrics); |
| 466 | for (int i = 0; i <= length; ++i) { |
| 467 | if (str[i] == '\n' || i == length) { // Find line endings to draw entire lines at once |
| 468 | TextMetrics line_metrics; |
| 469 | ClearTextMetrics(&line_metrics); |
| 470 | for (int j = line_start; j < i; ++j) { |
| 471 | font_renderer->SetTransform(style.font_face_id, &matrix, &zero_vec); |
| 472 | FT_GlyphSlot slot = font_renderer->RenderCharacterBitmap(style.font_face_id, str[j], FontRenderer::RCB_METRIC); |
| 473 | ApplyGlyphSlotToTextMetrics(&line_metrics, slot); |
| 474 | } |
| 475 | switch (style.alignment) { |
| 476 | case CanvasTextStyle::RIGHT: |
| 477 | metrics.advance[0] = -line_metrics.bounds[1]; |
| 478 | break; |
| 479 | default: |
| 480 | LOGD << "Unhandled style.alignment " << CanvasTextStyle::GetAlignmentString(style.alignment) << std::endl; |
| 481 | ; |
| 482 | break; |
| 483 | } |
| 484 | for (int j = line_start; j < i; ++j) { |
| 485 | font_renderer->SetTransform(style.font_face_id, &matrix, &zero_vec); |
| 486 | FT_GlyphSlot slot = font_renderer->RenderCharacterBitmap(style.font_face_id, str[j], FontRenderer::RCB_METRIC); |
| 487 | if (curr_line == click_line) { |
| 488 | int pos_x = metrics.advance[0] / 64; |
| 489 | switch (style.alignment) { |
| 490 | case CanvasTextStyle::RIGHT: |
| 491 | pos_x -= total_metrics.bounds[0] / 64; |
| 492 | break; |
| 493 | default: |
| 494 | LOGD << "Unhandled style.alignment " << CanvasTextStyle::GetAlignmentString(style.alignment) << std::endl; |
| 495 | ; |
| 496 | break; |
| 497 | } |
| 498 | int distance = abs(pos_x - coords[0]); |
| 499 | if (distance < best_distance) { |
| 500 | best_letter = j; |
| 501 | best_distance = distance; |
| 502 | } |
| 503 | } |
| 504 | ApplyGlyphSlotToTextMetrics(&metrics, slot); |
| 505 | if (curr_line == click_line) { |
| 506 | int pos_x = metrics.advance[0] / 64; |
| 507 | switch (style.alignment) { |
nothing calls this directly
no test coverage detected