diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e565aa439..937d9ae18 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -64,7 +64,7 @@ jobs: - name: Install Dependencies run: | brew update - brew install pkg-config cairo pango libpng jpeg giflib librsvg + brew install pkg-config cairo pango libpng jpeg giflib librsvg icu4c - name: Install run: npm install --build-from-source - name: Test diff --git a/Readme.md b/Readme.md index b27549962..448376724 100644 --- a/Readme.md +++ b/Readme.md @@ -23,7 +23,7 @@ For detailed installation information, see the [wiki](https://github.com/Automat OS | Command ----- | ----- -OS X | Using [Homebrew](https://brew.sh/):
`brew install pkg-config cairo pango libpng jpeg giflib librsvg` +OS X | Using [Homebrew](https://brew.sh/):
`brew install pkg-config cairo pango libpng jpeg giflib librsvg icu4c` Ubuntu | `sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev` Fedora | `sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel` Solaris | `pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto` diff --git a/binding.gyp b/binding.gyp index 57f14ab8c..82a8daf48 100644 --- a/binding.gyp +++ b/binding.gyp @@ -85,7 +85,8 @@ '-l<(GTK_Root)/lib/pango-1.0.lib', '-l<(GTK_Root)/lib/freetype.lib', '-l<(GTK_Root)/lib/glib-2.0.lib', - '-l<(GTK_Root)/lib/gobject-2.0.lib' + '-l<(GTK_Root)/lib/gobject-2.0.lib', + '-licu' ], 'include_dirs': [ '<(GTK_Root)/include', @@ -140,10 +141,24 @@ 'cflags!': ['-fno-exceptions'], 'cflags_cc!': ['-fno-exceptions'] }], + ['OS=="linux"', { + 'libraries': [ + ' #include #include -#include #include "PNG.h" #include "register_font.h" #include @@ -706,9 +705,9 @@ NAN_METHOD(Canvas::StreamJPEGSync) { char * str_value(Local val, const char *fallback, bool can_be_number) { if (val->IsString() || (can_be_number && val->IsNumber())) { - return g_strdup(*Nan::Utf8String(val)); + return strdup(*Nan::Utf8String(val)); } else if (fallback) { - return g_strdup(fallback); + return strdup(fallback); } else { return NULL; } @@ -765,9 +764,9 @@ NAN_METHOD(Canvas::RegisterFont) { Nan::ThrowError(GENERIC_FACE_ERROR); } - g_free(family); - g_free(weight); - g_free(style); + free(family); + free(weight); + free(style); } NAN_METHOD(Canvas::DeregisterAllFonts) { diff --git a/src/register_font.cc b/src/register_font.cc index 1b8632dd2..0fb37aaba 100644 --- a/src/register_font.cc +++ b/src/register_font.cc @@ -12,6 +12,12 @@ #include #endif +#if defined(_WIN32) +#include +#else +#include +#endif + #include #include FT_FREETYPE_H #include FT_TRUETYPE_TABLES_H @@ -57,7 +63,7 @@ to_utf8(FT_Byte* buf, FT_UInt len, FT_UShort pid, FT_UShort eid) { char const *fromcode; if (pid == TT_PLATFORM_MACINTOSH && eid == TT_MAC_ID_ROMAN) { - fromcode = "MAC"; + fromcode = "macintosh"; } else if (pid == TT_PLATFORM_MICROSOFT && eid == TT_MS_ID_UNICODE_CS) { fromcode = "UTF-16BE"; } else { @@ -65,28 +71,16 @@ to_utf8(FT_Byte* buf, FT_UInt len, FT_UShort pid, FT_UShort eid) { return NULL; } - GIConv cd = g_iconv_open("UTF-8", fromcode); + UErrorCode err = U_ZERO_ERROR; + int32_t converted_len = ucnv_convert("utf-8", fromcode, ret, ret_len, (const char*) buf, len, &err); - if (cd == (GIConv)-1) { + if (U_FAILURE(err)) { free(ret); return NULL; } - size_t inbytesleft = len; - size_t outbytesleft = ret_len; - - size_t n_converted = g_iconv(cd, (char**)&buf, &inbytesleft, &ret, &outbytesleft); - - ret -= ret_len - outbytesleft; // rewind the pointers to their - buf -= len - inbytesleft; // original starting positions - - if (n_converted == (size_t)-1) { - free(ret); - return NULL; - } else { - ret[ret_len - outbytesleft] = '\0'; - return ret; - } + ret[converted_len] = '\0'; + return ret; } /* @@ -94,35 +88,12 @@ to_utf8(FT_Byte* buf, FT_UInt len, FT_UShort pid, FT_UShort eid) { * system, fall back to the other */ -typedef struct _NameDef { - const char *buf; - int rank; // the higher the more desirable -} NameDef; - -gint -_name_def_compare(gconstpointer a, gconstpointer b) { - return ((NameDef*)a)->rank > ((NameDef*)b)->rank ? -1 : 1; -} - -// Some versions of GTK+ do not have this, particualrly the one we -// currently link to in node-canvas's wiki -void -_free_g_list_item(gpointer data, gpointer user_data) { - NameDef *d = (NameDef *)data; - free((void *)(d->buf)); -} - -void -_g_list_free_full(GList *list) { - g_list_foreach(list, _free_g_list_item, NULL); - g_list_free(list); -} - char * get_family_name(FT_Face face) { FT_SfntName name; - GList *list = NULL; - char *utf8name = NULL; + + int best_rank = -1; + char* best_buf = NULL; for (unsigned i = 0; i < FT_Get_Sfnt_Name_Count(face); ++i) { FT_Get_Sfnt_Name(face, i, &name); @@ -131,20 +102,19 @@ get_family_name(FT_Face face) { char *buf = to_utf8(name.string, name.string_len, name.platform_id, name.encoding_id); if (buf) { - NameDef *d = (NameDef*)malloc(sizeof(NameDef)); - d->buf = (const char*)buf; - d->rank = GET_NAME_RANK(name); - - list = g_list_insert_sorted(list, (gpointer)d, _name_def_compare); + int rank = GET_NAME_RANK(name); + if (rank > best_rank) { + best_rank = rank; + if (best_buf) free(best_buf); + best_buf = buf; + } else { + free(buf); + } } } } - GList *best_def = g_list_first(list); - if (best_def) utf8name = (char*) strdup(((NameDef*)best_def->data)->buf); - if (list) _g_list_free_full(list); - - return utf8name; + return best_buf; } PangoWeight