platform/cc/TextLine.cc (149 lines of code) (raw):

#include <cstring> #include <iostream> #include <jni.h> #include "interop.hh" #include "SkShaper.h" #include "TextLine.hh" static void unrefTextLine(TextLine* ptr) { ptr->unref(); } extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_TextLine__1nGetFinalizer (JNIEnv* env, jclass jclass) { return static_cast<jlong>(reinterpret_cast<uintptr_t>(&unrefTextLine)); } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetAscent (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fAscent; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetCapHeight (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fCapHeight; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetXHeight (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fXHeight; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetDescent (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fDescent; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetLeading (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fLeading; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetWidth (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return instance->fWidth; } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetHeight (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); return -instance->fAscent + instance->fDescent + instance->fLeading; } extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skija_TextLine__1nGetTextBlob (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); if (instance->fBlob == nullptr) return 0; instance->fBlob->ref(); return reinterpret_cast<jlong>(instance->fBlob.get()); } extern "C" JNIEXPORT jshortArray JNICALL Java_org_jetbrains_skija_TextLine__1nGetGlyphs (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); std::vector<jshort> glyphs(instance->fGlyphCount); size_t idx = 0; for (auto& run: instance->fRuns) { memcpy(glyphs.data() + idx, run.fGlyphs, run.fGlyphCount * sizeof(uint16_t)); idx += run.fGlyphCount; } SkASSERTF(idx == instance->fGlyphCount, "TextLine.cc: idx = %d != instance->fGlyphCount = %d", idx, instance->fGlyphCount); return javaShortArray(env, glyphs); } extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skija_TextLine__1nGetPositions (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); std::vector<jfloat> positions(2 * instance->fGlyphCount); size_t idx = 0; for (auto& run: instance->fRuns) { memcpy(positions.data() + idx, run.fPos, run.fGlyphCount * sizeof(SkPoint)); idx += 2 * run.fGlyphCount; } SkASSERTF(idx == 2 * instance->fGlyphCount, "TextLine.cc: idx = %d != 2 * instance->fGlyphCount = %d", idx, 2 * instance->fGlyphCount); return javaFloatArray(env, positions); } extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skija_TextLine__1nGetRunPositions (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); std::vector<jfloat> positions(instance->fRuns.size()); for (size_t idx = 0; idx < positions.size(); ++idx) positions[idx] = instance->fRuns[idx].fPosition; return javaFloatArray(env, positions); } extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skija_TextLine__1nGetBreakPositions (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); std::vector<jfloat> positions; for (auto& run: instance->fRuns) positions.insert(positions.end(), run.fBreakPositions.begin(), run.fBreakPositions.end()); return javaFloatArray(env, positions); } extern "C" JNIEXPORT jintArray JNICALL Java_org_jetbrains_skija_TextLine__1nGetBreakOffsets (JNIEnv* env, jclass jclass, jlong ptr) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); std::vector<jint> offsets; for (auto& run: instance->fRuns) offsets.insert(offsets.end(), run.fBreakOffsets.begin(), run.fBreakOffsets.end()); return javaIntArray(env, offsets); } extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skija_TextLine__1nGetOffsetAtCoord (JNIEnv* env, jclass jclass, jlong ptr, jfloat x) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); if (instance->fRuns.empty()) return 0; for (auto& run: instance->fRuns) { SkScalar breakLeft = run.fBreakPositions[0]; for (uint32_t idx = 0; idx < run.fBreakPositions.size() - 1; ++idx) { SkScalar breakRight = run.fBreakPositions[idx + 1]; if (x < (breakLeft + breakRight) / 2) return run.fBreakOffsets[idx]; breakLeft = breakRight; } } return (jint) instance->fRuns.back().fBreakOffsets.back(); } extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skija_TextLine__1nGetLeftOffsetAtCoord (JNIEnv* env, jclass jclass, jlong ptr, jfloat x) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); if (instance->fRuns.empty()) return 0; for (auto& run: instance->fRuns) { for (uint32_t idx = 0; idx < run.fBreakPositions.size() - 1; ++idx) { SkScalar breakRight = run.fBreakPositions[idx + 1]; if (x < breakRight) return run.fBreakOffsets[idx]; } } return (jint) instance->fRuns.back().fBreakOffsets.back(); } extern "C" JNIEXPORT jfloat JNICALL Java_org_jetbrains_skija_TextLine__1nGetCoordAtOffset (JNIEnv* env, jclass jclass, jlong ptr, jint offset16) { TextLine* instance = reinterpret_cast<TextLine*>(static_cast<uintptr_t>(ptr)); for (auto& run: instance->fRuns) { if (offset16 > run.fBreakOffsets.back()) continue; for (uint32_t idx = 0; idx < run.fBreakPositions.size() - 1; ++idx) { if (offset16 < run.fBreakOffsets[idx] && idx > 0) return run.fBreakPositions[idx - 1]; if (offset16 <= run.fBreakOffsets[idx]) return run.fBreakPositions[idx]; } } return instance->fWidth; }