Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f127d5f1 authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Reimplement hyphenator with Rust

Bug: 319145324
Bug: 319140825
Bug: 339717607
Bug: 274835275
Bug: 346915432
Test: minikin_tests
Flag: com.android.text.flags.rust_hyphenator
Change-Id: I47a5612a05bd0177043d7533a373e1ad5d2e8f35
parent 2b683b78
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -211,3 +211,12 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "rust_hyphenator"
  namespace: "text"
  description: "Reimplement hyphenator for safe file read"
  # Hyphenator is initialized in Zygote
  is_fixed_read_only: true
  bug: "346915432"
}
+13 −11
Original line number Diff line number Diff line
@@ -36,41 +36,43 @@ static std::string buildFileName(const std::string& locale) {
    return SYSTEM_HYPHENATOR_PREFIX + lowerLocale + SYSTEM_HYPHENATOR_SUFFIX;
}

static const uint8_t* mmapPatternFile(const std::string& locale) {
static std::pair<const uint8_t*, size_t> mmapPatternFile(const std::string& locale) {
    const std::string hyFilePath = buildFileName(locale);
    const int fd = open(hyFilePath.c_str(), O_RDONLY | O_CLOEXEC);
    if (fd == -1) {
        return nullptr;  // Open failed.
        return std::make_pair(nullptr, 0); // Open failed.
    }

    struct stat st = {};
    if (fstat(fd, &st) == -1) {  // Unlikely to happen.
        close(fd);
        return nullptr;
        return std::make_pair(nullptr, 0);
    }

    void* ptr = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0 /* offset */);
    close(fd);
    if (ptr == MAP_FAILED) {
        return nullptr;
        return std::make_pair(nullptr, 0);
    }
    return reinterpret_cast<const uint8_t*>(ptr);
    return std::make_pair(reinterpret_cast<const uint8_t*>(ptr), st.st_size);
}

static void addHyphenatorWithoutPatternFile(const std::string& locale, int minPrefix,
        int minSuffix) {
    minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
            nullptr, minPrefix, minSuffix, locale));
    minikin::addHyphenator(locale,
                           minikin::Hyphenator::loadBinary(nullptr, 0, minPrefix, minSuffix,
                                                           locale));
}

static void addHyphenator(const std::string& locale, int minPrefix, int minSuffix) {
    const uint8_t* ptr = mmapPatternFile(locale);
    if (ptr == nullptr) {
    std::pair<const uint8_t*, size_t> r = mmapPatternFile(locale);
    if (r.first == nullptr) {
        ALOGE("Unable to find pattern file or unable to map it for %s", locale.c_str());
        return;
    }
    minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
            ptr, minPrefix, minSuffix, locale));
    minikin::addHyphenator(locale,
                           minikin::Hyphenator::loadBinary(r.first, r.second, minPrefix, minSuffix,
                                                           locale));
}

static void addHyphenatorAlias(const std::string& from, const std::string& to) {