Get the coordinates of the cursor after a given letter in an edit field
| 382 | |
| 383 | // Get the coordinates of the cursor after a given letter in an edit field |
| 384 | void TextCanvasTexture::GetLetterPosXY(const char* str, const CanvasTextStyle& style, int letter, int coords[2]) { |
| 385 | std::vector<uint32_t> utf32_string; |
| 386 | try { |
| 387 | utf8::utf8to32(str, str + strlen(str), std::back_inserter(utf32_string)); |
| 388 | } catch (const utf8::not_enough_room& ner) { |
| 389 | LOGE << "Got utf8 exception \"" << ner.what() << "\" this might indicate invalid utf-8 data" << std::endl; |
| 390 | } |
| 391 | |
| 392 | FontRenderer* font_renderer = FontRenderer::Instance(); |
| 393 | FT_Matrix matrix; |
| 394 | FTMatrixFromAngle(&matrix, 0.0f); |
| 395 | int line_height = font_renderer->GetFontInfo(style.font_face_id, FontRenderer::INFO_HEIGHT); |
| 396 | int line_start = 0; |
| 397 | FT_Vector zero_vec = {0}; |
| 398 | TextMetrics metrics; |
| 399 | ClearTextMetrics(&metrics); |
| 400 | for (int i = 0; i <= (int)utf32_string.size(); ++i) { |
| 401 | if (str[i] == '\n' || i == (int)utf32_string.size()) { // Find line endings to draw entire lines at once |
| 402 | TextMetrics line_metrics; |
| 403 | ClearTextMetrics(&line_metrics); |
| 404 | for (int j = line_start; j < i; ++j) { |
| 405 | font_renderer->SetTransform(style.font_face_id, &matrix, &zero_vec); |
| 406 | FT_GlyphSlot slot = font_renderer->RenderCharacterBitmap(style.font_face_id, str[j], FontRenderer::RCB_METRIC); |
| 407 | ApplyGlyphSlotToTextMetrics(&line_metrics, slot); |
| 408 | } |
| 409 | switch (style.alignment) { |
| 410 | case CanvasTextStyle::RIGHT: |
| 411 | metrics.advance[0] = -line_metrics.bounds[1]; |
| 412 | break; |
| 413 | default: |
| 414 | LOGD << "Unhandled style.alignment " << CanvasTextStyle::GetAlignmentString(style.alignment) << std::endl; |
| 415 | ; |
| 416 | break; |
| 417 | } |
| 418 | for (int j = line_start; j < i; ++j) { |
| 419 | font_renderer->SetTransform(style.font_face_id, &matrix, &zero_vec); |
| 420 | FT_GlyphSlot slot = font_renderer->RenderCharacterBitmap(style.font_face_id, str[j], FontRenderer::RCB_METRIC); |
| 421 | if (j == letter) { |
| 422 | coords[0] = metrics.advance[0] / 64; |
| 423 | coords[1] = metrics.advance[1] / 64; |
| 424 | } |
| 425 | ApplyGlyphSlotToTextMetrics(&metrics, slot); |
| 426 | if (j + 1 == letter) { |
| 427 | coords[0] = metrics.advance[0] / 64; |
| 428 | coords[1] = metrics.advance[1] / 64; |
| 429 | } |
| 430 | } |
| 431 | if (str[i] == '\n') { |
| 432 | metrics.advance[1] += line_height; |
| 433 | metrics.advance[0] = 0; |
| 434 | } |
| 435 | line_start = i + 1; |
| 436 | } |
| 437 | } |
| 438 | switch (style.alignment) { |
| 439 | case CanvasTextStyle::RIGHT: |
| 440 | coords[0] -= metrics.bounds[0] / 64; |
| 441 | break; |
nothing calls this directly
no test coverage detected