#include "./TextMeasurerEmbed.h" #include "./../../fontengine/TextShaper.h" #define RAW_POINTER(value) ((CPointerEmbedObject*)value->toObject()->getNative())->Data #define POINTER_OBJECT(value) ((CPointerEmbedObject*)value->toObject()->getNative()) class CExternalPointerJS : public NSShaper::CExternalPointer { public: CExternalPointerJS() : NSShaper::CExternalPointer() {} virtual ~CExternalPointerJS() {} public: virtual void Alloc(const unsigned int& len) { Len = len; Data = NSAllocator::Alloc((size_t)Len); } virtual void Free() { if (Data) NSAllocator::Free(Data, (size_t)Len); } }; JSSmart CTextMeasurerEmbed::FT_Malloc(JSSmart typed_array_or_len) { void* pData = NULL; size_t len = 0; if (typed_array_or_len->isNumber()) { len = (size_t)typed_array_or_len->toInt32(); if (0 != len) pData = malloc((size_t)len); } else { CJSDataBuffer pBuffer = typed_array_or_len->toTypedArray()->getData(); pData = malloc(pBuffer.Len); memcpy(pData, pBuffer.Data, pBuffer.Len); if (pBuffer.IsExternalize) pBuffer.Free(); } CPointerEmbedObject* pObject = new CPointerEmbedObject(pData, NSPointerObjectDeleters::FreeDeleter); return pObject->createObject(); } JSSmart CTextMeasurerEmbed::FT_Free(JSSmart pointer) { CPointerEmbedObject* pEmbed = (CPointerEmbedObject*)pointer->toObject()->getNative(); pEmbed->Free(); return CJSContext::createUndefined(); } JSSmart CTextMeasurerEmbed::FT_Init() { CPointerEmbedObject* pointer = new CPointerEmbedObject(NSShaper::FT_Library_Init(), [](void* data) { NSShaper::FT_Library_Destroy(data); }); return pointer->createObject(); } JSSmart CTextMeasurerEmbed::FT_Set_TrueType_HintProp(JSSmart library, JSSmart tt_interpreter) { return CJSContext::createInt(NSShaper::FT_Set_TrueType_HintProp(RAW_POINTER(library), tt_interpreter->toUInt32())); } JSSmart CTextMeasurerEmbed::FT_Open_Face(JSSmart library, JSSmart memory, JSSmart size, JSSmart face_index) { void* face = NSShaper::FT_Open_Face(RAW_POINTER(library), (unsigned char*)RAW_POINTER(memory), size->toUInt32(), face_index->toInt32()); CPointerEmbedObject* pointer = new CPointerEmbedObject(face, [](void* data) { NSShaper::FT_Done_Face(data); }); return pointer->createObject(); } JSSmart CTextMeasurerEmbed::FT_Open_Face2(JSSmart library, JSSmart array, JSSmart face_index) { CJSDataBuffer buffer = array->toTypedArray()->getData(); void* face = NSShaper::FT_Open_Face(RAW_POINTER(library), (unsigned char*)buffer.Data, (unsigned int)buffer.Len, face_index->toInt32()); CPointerEmbedObject* pointer = new CPointerEmbedObject(face, NSPointerObjectDeleters::EmptyDeleter); return pointer->createObject(); } JSSmart CTextMeasurerEmbed::FT_GetFaceInfo(JSSmart face) { CExternalPointerJS result; if (!NSShaper::FT_GetFaceInfo(RAW_POINTER(face), &result)) return CJSContext::createNull(); return CJSContext::createUint8Array(result.Data, result.Len, false); } JSSmart CTextMeasurerEmbed::FT_Load_Glyph(JSSmart face, JSSmart gid, JSSmart mode) { return CJSContext::createInt(NSShaper::FT_Load_Glyph(RAW_POINTER(face), gid->toUInt32(), mode->toInt32())); } JSSmart CTextMeasurerEmbed::FT_Get_Glyph_Measure_Params(JSSmart face, JSSmart is_vector) { CExternalPointerJS result; if (!NSShaper::FT_Get_Glyph_Measure_Params(RAW_POINTER(face), is_vector->toBool(), &result)) return CJSContext::createNull(); return CJSContext::createUint8Array(result.Data, result.Len, false); } JSSmart CTextMeasurerEmbed::FT_Get_Glyph_Render_Params(JSSmart face, JSSmart render_mode) { CExternalPointerJS result; if (!NSShaper::FT_Get_Glyph_Render_Params(RAW_POINTER(face), render_mode->toInt32(), &result)) return CJSContext::createNull(); return CJSContext::createUint8Array(result.Data, result.Len, false); } JSSmart CTextMeasurerEmbed::FT_Get_Glyph_Render_Buffer(JSSmart face, JSSmart size) { void* Data = NSShaper::FT_Get_Glyph_Render_Buffer(RAW_POINTER(face)); return CJSContext::createUint8Array((unsigned char*)Data, size->toInt32(), true); } JSSmart CTextMeasurerEmbed::FT_Set_Transform(JSSmart face, JSSmart xx, JSSmart yx, JSSmart xy, JSSmart yy) { NSShaper::FT_Set_Transform(RAW_POINTER(face), xx->toInt32(), yx->toInt32(), xy->toInt32(), yy->toInt32()); return CJSContext::createUndefined(); } JSSmart CTextMeasurerEmbed::FT_Set_Char_Size(JSSmart face, JSSmart char_width, JSSmart char_height, JSSmart hres, JSSmart vres) { return CJSContext::createInt(NSShaper::FT_Set_Char_Size(RAW_POINTER(face), char_width->toInt32(), char_height->toInt32(), hres->toUInt32(), vres->toUInt32())); } JSSmart CTextMeasurerEmbed::FT_SetCMapForCharCode(JSSmart face, JSSmart unicode) { return CJSContext::createUInt(NSShaper::FT_SetCMapForCharCode(RAW_POINTER(face), unicode->toUInt32())); } JSSmart CTextMeasurerEmbed::FT_GetKerningX(JSSmart face, JSSmart gid1, JSSmart gid2) { return CJSContext::createInt(NSShaper::FT_GetKerningX(RAW_POINTER(face), gid1->toUInt32(), gid2->toUInt32())); } JSSmart CTextMeasurerEmbed::FT_GetFaceMaxAdvanceX(JSSmart face) { return CJSContext::createInt(NSShaper::FT_GetFaceMaxAdvanceX(RAW_POINTER(face))); } #ifdef SUPPORT_HARFBUZZ_SHAPER JSSmart CTextMeasurerEmbed::HB_LanguageFromString(JSSmart language_bcp_47) { void* Data = NSShaper::HB_LanguageFromString(language_bcp_47->toStringA()); CPointerEmbedObject* pObject = new CPointerEmbedObject(Data, [](void* data) { NSShaper::HB_free(data); }); return pObject->createObject(); } JSSmart CTextMeasurerEmbed::HB_ShapeText(JSSmart face, JSSmart font, JSSmart text, JSSmart nFeatures, JSSmart nScript, JSSmart nDirection, JSSmart nLanguage) { CPointerEmbedObject* pFont = POINTER_OBJECT(font); CExternalPointerJS result; NSShaper::HB_ShapeText(RAW_POINTER(face), pFont->Data, text->toStringA(), nFeatures->toUInt32(), nScript->toUInt32(), nDirection->toUInt32(), RAW_POINTER(nLanguage), &result); if (NULL == result.Data) return CJSContext::createNull(); return CJSContext::createUint8Array(result.Data, result.Len, false); } JSSmart CTextMeasurerEmbed::HB_FontFree(JSSmart font) { NSShaper::HB_FontFree(RAW_POINTER(font)); return CJSContext::createUndefined(); } #endif