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

Commit 091dba2d authored by Raph Levien's avatar Raph Levien
Browse files

Load binary hyphen data files

Support for loading the pre-compiled binary format for hyphenation
patterns.

Bug: 21562869
Bug: 21826930
Change-Id: Iaeaa9c9ac9dac236af6b0d7894c2e2396bc8447d
parent e4de5a0d
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -16,15 +16,17 @@

package android.text;

import com.android.internal.annotations.GuardedBy;

import android.annotation.Nullable;
import android.util.Log;

import libcore.io.IoUtils;
import com.android.internal.annotations.GuardedBy;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Locale;

@@ -45,12 +47,18 @@ public class Hyphenator {
    @GuardedBy("sLock")
    final static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();

    final static Hyphenator sEmptyHyphenator = new Hyphenator(StaticLayout.nLoadHyphenator(""));
    final static Hyphenator sEmptyHyphenator =
            new Hyphenator(StaticLayout.nLoadHyphenator(null, 0), null);

    final private long mNativePtr;

    private Hyphenator(long nativePtr) {
    // We retain a reference to the buffer to keep the memory mapping valid
    @SuppressWarnings("unused")
    final private ByteBuffer mBuffer;

    private Hyphenator(long nativePtr, ByteBuffer b) {
        mNativePtr = nativePtr;
        mBuffer = b;
    }

    public long getNativePtr() {
@@ -94,12 +102,18 @@ public class Hyphenator {
    }

    private static Hyphenator loadHyphenator(String languageTag) {
        String patternFilename = "hyph-"+languageTag.toLowerCase(Locale.US)+".pat.txt";
        String patternFilename = "hyph-" + languageTag.toLowerCase(Locale.US) + ".hyb";
        File patternFile = new File(getSystemHyphenatorLocation(), patternFilename);
        try {
            String patternData = IoUtils.readFileAsString(patternFile.getAbsolutePath());
            long nativePtr = StaticLayout.nLoadHyphenator(patternData);
            return new Hyphenator(nativePtr);
            RandomAccessFile f = new RandomAccessFile(patternFile, "r");
            try {
                FileChannel fc = f.getChannel();
                MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
                long nativePtr = StaticLayout.nLoadHyphenator(buf, 0);
                return new Hyphenator(nativePtr, buf);
            } finally {
                f.close();
            }
        } catch (IOException e) {
            Log.e(TAG, "error loading hyphenation " + patternFile, e);
            return null;
@@ -152,7 +166,7 @@ public class Hyphenator {
        sMap.put(null, null);

        // TODO: replace this with a discovery-based method that looks into /system/usr/hyphen-data
        String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "sa", "und-Ethi"};
        String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "und-Ethi"};
        for (int i = 0; i < availableLanguages.length; i++) {
            String languageTag = availableLanguages[i];
            Hyphenator h = loadHyphenator(languageTag);
+2 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.Pools.SynchronizedPool;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;

@@ -1244,7 +1245,7 @@ public class StaticLayout extends Layout {
    private static native void nFreeBuilder(long nativePtr);
    private static native void nFinishBuilder(long nativePtr);

    /* package */ static native long nLoadHyphenator(String patternData);
    /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset);

    private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);

+12 −4
Original line number Diff line number Diff line
@@ -117,9 +117,17 @@ static void nFinishBuilder(JNIEnv*, jclass, jlong nativePtr) {
    b->finish();
}

static jlong nLoadHyphenator(JNIEnv* env, jclass, jstring patternData) {
    ScopedStringChars str(env, patternData);
    Hyphenator* hyphenator = Hyphenator::load(str.get(), str.size());
static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset) {
    const uint8_t* bytebuf = nullptr;
    if (buffer != nullptr) {
        void* rawbuf = env->GetDirectBufferAddress(buffer);
        if (rawbuf != nullptr) {
            bytebuf = reinterpret_cast<const uint8_t*>(rawbuf) + offset;
        } else {
            ALOGE("failed to get direct buffer address");
        }
    }
    Hyphenator* hyphenator = Hyphenator::loadBinary(bytebuf);
    return reinterpret_cast<jlong>(hyphenator);
}

@@ -177,7 +185,7 @@ static JNINativeMethod gMethods[] = {
    {"nNewBuilder", "()J", (void*) nNewBuilder},
    {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
    {"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
    {"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator},
    {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;I)J", (void*) nLoadHyphenator},
    {"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
    {"nSetupParagraph", "(J[CIFIF[IIII)V", (void*) nSetupParagraph},
    {"nSetIndents", "(J[I)V", (void*) nSetIndents},