Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ For detailed installation information, see the [wiki](https://github.com/Automat

OS | Command
----- | -----
OS X | Using [Homebrew](https://brew.sh/):<br/>`brew install pkg-config cairo pango libpng jpeg giflib librsvg`
OS X | Using [Homebrew](https://brew.sh/):<br/>`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`
Expand Down
19 changes: 17 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -140,10 +141,24 @@
'cflags!': ['-fno-exceptions'],
'cflags_cc!': ['-fno-exceptions']
}],
['OS=="linux"', {
'libraries': [
'<!@(pkg-config icu-uc --libs)'
],
'include_dirs': [
'<!@(pkg-config icu-uc --cflags-only-I | sed s/-I//g)'
]
}],
['OS=="mac"', {
'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
}
},
'libraries': [
'-L/usr/local/opt/icu4c/lib -licuuc'
],
'include_dirs': [
'/usr/local/opt/icu4c/include'
]
}],
['with_jpeg=="true"', {
'defines': [
Expand Down
11 changes: 5 additions & 6 deletions src/Canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <cstring>
#include <cctype>
#include <ctime>
#include <glib.h>
#include "PNG.h"
#include "register_font.h"
#include <sstream>
Expand Down Expand Up @@ -706,9 +705,9 @@ NAN_METHOD(Canvas::StreamJPEGSync) {
char *
str_value(Local<Value> 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;
}
Expand Down Expand Up @@ -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) {
Expand Down
78 changes: 24 additions & 54 deletions src/register_font.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
#include <fontconfig/fontconfig.h>
#endif

#if defined(_WIN32)
#include <icu.h>
#else
#include <unicode/ucnv.h>
#endif

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
Expand Down Expand Up @@ -57,72 +63,37 @@ 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 {
free(ret);
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;
}

/*
* Find a family name in the face's name table, preferring the one the
* 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);
Expand All @@ -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
Expand Down