diff --git a/DesktopEditor/doctrenderer/doctrenderer.pro b/DesktopEditor/doctrenderer/doctrenderer.pro index e7471eac8e..002af235cd 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.pro +++ b/DesktopEditor/doctrenderer/doctrenderer.pro @@ -85,7 +85,8 @@ include($$PWD/js_internal/js_base.pri) embed/v8/v8_NativeBuilder.cpp \ embed/v8/v8_Graphics.cpp \ embed/v8/v8_Zip.cpp \ - embed/v8/v8_Pointer.cpp + embed/v8/v8_Pointer.cpp \ + embed/v8/v8_TextMeasurer.cpp build_xp:DESTDIR=$$DESTDIR/xp } else { @@ -96,12 +97,15 @@ include($$PWD/js_internal/js_base.pri) embed/jsc/jsc_NativeControl.mm \ embed/jsc/jsc_NativeBuilder.mm \ embed/jsc/jsc_Zip.mm \ - embed/jsc/jsc_Pointer.mm + embed/jsc/jsc_Pointer.mm \ + embed/jsc/jsc_TextMeasurer.mm LIBS += -framework Foundation } } +include(../graphics/pro/textshaper.pri) + # downloader DEFINES += BUIDLER_OPEN_DOWNLOAD_ENABLED DEFINES += BUIDLER_OPEN_BASE64_ENABLED diff --git a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp index bac9f57d90..9d46120571 100644 --- a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp @@ -2,6 +2,7 @@ #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 { @@ -26,10 +27,12 @@ JSSmart CTextMeasurerEmbed::FT_Malloc(JSSmart typed_array_or { void* pData = NULL; size_t len = 0; + if (typed_array_or_len->isNumber()) { len = (size_t)typed_array_or_len->toInt32(); - pData = malloc((size_t)len); + if (0 != len) + pData = malloc((size_t)len); } else { @@ -66,6 +69,13 @@ JSSmart CTextMeasurerEmbed::FT_Open_Face(JSSmart library, JS 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; @@ -123,3 +133,32 @@ JSSmart CTextMeasurerEmbed::FT_GetFaceMaxAdvanceX(JSSmart fa { 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 diff --git a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.h b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.h index e97cf45818..584b58f9ce 100644 --- a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.h +++ b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.h @@ -23,6 +23,7 @@ public: JSSmart FT_Set_TrueType_HintProp(JSSmart library, JSSmart tt_interpreter); JSSmart FT_Open_Face(JSSmart library, JSSmart memory, JSSmart size, JSSmart face_index); + JSSmart FT_Open_Face2(JSSmart library, JSSmart array, JSSmart face_index); JSSmart FT_GetFaceInfo(JSSmart face); JSSmart FT_Load_Glyph(JSSmart face, JSSmart gid, JSSmart mode); @@ -36,6 +37,15 @@ public: JSSmart FT_GetKerningX(JSSmart face, JSSmart gid1, JSSmart gid2); JSSmart FT_GetFaceMaxAdvanceX(JSSmart face); +#ifdef SUPPORT_HARFBUZZ_SHAPER + JSSmart HB_LanguageFromString(JSSmart language_bcp_47); + + JSSmart HB_ShapeText(JSSmart face, JSSmart font, JSSmart text, + JSSmart nFeatures, JSSmart nScript, JSSmart nDirection, JSSmart nLanguage); + + JSSmart HB_FontFree(JSSmart font); +#endif + static void CreateObjectInContext(const std::string& name, JSSmart context); }; diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index b021a3b101..fca9b815c0 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -636,7 +636,7 @@ namespace NSShaper HB_free(data); } - void HB_ShapeText(void* face, void* font, char* text, + void HB_ShapeText(void* face, void*& font, const std::string& text, unsigned int nFeatures, unsigned int nScript, unsigned int nDirection, void* nLanguage, CExternalPointer* result) { // init features @@ -665,6 +665,7 @@ namespace NSShaper { pFont = hb_ft_font_create((FT_Face)face, NULL); hb_ft_font_set_funcs(pFont); + font = (void*)pFont; } else pFont = (hb_font_t*)font; @@ -679,8 +680,8 @@ namespace NSShaper hb_buffer_set_script(hbBuffer, (hb_script_t)nScript); hb_buffer_set_language(hbBuffer, (hb_language_t)nLanguage); hb_buffer_set_cluster_level(hbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES); - int text_len = (int)strlen(text); - hb_buffer_add_utf8(hbBuffer, text, text_len, 0, text_len); + int text_len = (int)text.length(); + hb_buffer_add_utf8(hbBuffer, text.c_str(), text_len, 0, text_len); hb_buffer_guess_segment_properties(hbBuffer); // shape diff --git a/DesktopEditor/fontengine/TextShaper.h b/DesktopEditor/fontengine/TextShaper.h index e0212bc388..ef52b86cd0 100644 --- a/DesktopEditor/fontengine/TextShaper.h +++ b/DesktopEditor/fontengine/TextShaper.h @@ -82,7 +82,7 @@ namespace NSShaper GRAPHICS_DECL void* HB_LanguageFromString(const std::string language_bcp_47); GRAPHICS_DECL void HB_free(void* data); - GRAPHICS_DECL void HB_ShapeText(void* face, void* font, char* text, + GRAPHICS_DECL void HB_ShapeText(void* face, void*& font, const std::string& text, unsigned int nFeatures, unsigned int nScript, unsigned int nDirection, void* nLanguage, CExternalPointer* result); GRAPHICS_DECL void HB_FontFree(void* font); diff --git a/DesktopEditor/graphics/pro/graphics.pro b/DesktopEditor/graphics/pro/graphics.pro index c66859d141..2a55c1ccff 100644 --- a/DesktopEditor/graphics/pro/graphics.pro +++ b/DesktopEditor/graphics/pro/graphics.pro @@ -494,6 +494,10 @@ HEADERS += ./../../fontengine/TextShaper.h SOURCES += ./../../fontengine/TextShaper.cpp include($$PWD/textshaper.pri) + +enable_support_shaper { + include($$CORE_ROOT_DIR/Common/3dParty/harfbuzz/harfbuzz.pri) +} # ------------------------------------------------- core_ios { diff --git a/DesktopEditor/graphics/pro/textshaper.pri b/DesktopEditor/graphics/pro/textshaper.pri index 276ce4d2fb..e57644ef40 100644 --- a/DesktopEditor/graphics/pro/textshaper.pri +++ b/DesktopEditor/graphics/pro/textshaper.pri @@ -14,5 +14,4 @@ core_linux { enable_support_shaper { DEFINES += SUPPORT_HARFBUZZ_SHAPER - include($$CORE_ROOT_DIR/Common/3dParty/harfbuzz/harfbuzz.pri) }