@@ -64,7 +64,7 @@ Canvas::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
6464 Nan::SetTemplate (proto, " PNG_ALL_FILTERS" , Nan::New<Uint32>(PNG_ALL_FILTERS));
6565
6666 // Class methods
67- Nan::SetMethod (ctor, " registerFont " , RegisterFont);
67+ Nan::SetMethod (ctor, " _registerFont " , RegisterFont);
6868
6969 Nan::Set (target, Nan::New (" Canvas" ).ToLocalChecked (), ctor->GetFunction ());
7070}
@@ -477,72 +477,75 @@ NAN_METHOD(Canvas::StreamJPEGSync) {
477477
478478#endif
479479
480- NAN_METHOD (Canvas::RegisterFont) {
481- FontFace face;
480+ char *
481+ str_value (Local<Value> val, const char *fallback, bool can_be_number) {
482+ if (val->IsString () || (can_be_number && val->IsNumber ())) {
483+ return g_strdup (*String::Utf8Value (val));
484+ } else if (fallback) {
485+ return g_strdup (fallback);
486+ } else {
487+ return NULL ;
488+ }
489+ }
482490
491+ NAN_METHOD (Canvas::RegisterFont) {
483492 if (!info[0 ]->IsString ()) {
484493 return Nan::ThrowError (" Wrong argument type" );
494+ } else if (!info[1 ]->IsObject ()) {
495+ return Nan::ThrowError (GENERIC_FACE_ERROR);
485496 }
486497
487498 String::Utf8Value filePath (info[0 ]);
499+ PangoFontDescription *sys_desc = get_pango_font_description ((unsigned char *) *filePath);
488500
489- if (!register_font ((unsigned char *) *filePath, &face.sys_desc )) {
490- Nan::ThrowError (" Could not load font to the system's font host" );
491- } else {
492- PangoFontDescription *d = pango_font_description_new ();
493-
494- if (!info[1 ]->IsObject ()) {
495- Nan::ThrowError (GENERIC_FACE_ERROR);
496- } else { // now check the attrs, there are many ways to be wrong
497- Local<Object> desc = info[1 ]->ToObject ();
498- Local<String> family_prop = Nan::New<String>(" family" ).ToLocalChecked ();
499- Local<String> weight_prop = Nan::New<String>(" weight" ).ToLocalChecked ();
500- Local<String> style_prop = Nan::New<String>(" style" ).ToLocalChecked ();
501-
502- const char *family;
503- const char *weight = " normal" ;
504- const char *style = " normal" ;
505-
506- Local<Value> family_val = desc->Get (family_prop);
507- if (family_val->IsString ()) {
508- family = strdup (*String::Utf8Value (family_val));
509- } else {
510- Nan::ThrowError (GENERIC_FACE_ERROR);
511- return ;
512- }
501+ if (!sys_desc) return Nan::ThrowError (" Could not parse font file" );
513502
514- if (desc->HasOwnProperty (weight_prop)) {
515- Local<Value> weight_val = desc->Get (weight_prop);
516- if (weight_val->IsString () || weight_val->IsNumber ()) {
517- weight = strdup (*String::Utf8Value (weight_val));
518- } else {
519- Nan::ThrowError (GENERIC_FACE_ERROR);
520- return ;
521- }
522- }
503+ PangoFontDescription *user_desc = pango_font_description_new ();
523504
524- if (desc-> HasOwnProperty (style_prop)) {
525- Local<Value> style_val = desc-> Get (style_prop );
526- if (style_val-> IsString ()) {
527- style = strdup (* String::Utf8Value (style_val) );
528- } else {
529- Nan::ThrowError (GENERIC_FACE_ERROR);
530- return ;
531- }
532- }
505+ // now check the attrs, there are many ways to be wrong
506+ Local<Object> js_user_desc = info[ 1 ]-> ToObject ( );
507+ Local<String> family_prop = Nan::New<String>( " family " ). ToLocalChecked ();
508+ Local<String> weight_prop = Nan::New<String>( " weight " ). ToLocalChecked ( );
509+ Local<String> style_prop = Nan::New<String>( " style " ). ToLocalChecked ();
510+
511+ char *family = str_value (js_user_desc-> Get (family_prop), NULL , false ) ;
512+ char *weight = str_value (js_user_desc-> Get (weight_prop), " normal " , true );
513+ char *style = str_value (js_user_desc-> Get (style_prop), " normal " , false );
533514
534- pango_font_description_set_weight (d, Canvas::GetWeightFromCSSString (weight));
535- pango_font_description_set_style (d, Canvas::GetStyleFromCSSString (style));
536- pango_font_description_set_family (d, family);
515+ if (family && weight && style) {
516+ pango_font_description_set_weight (user_desc, Canvas::GetWeightFromCSSString (weight));
517+ pango_font_description_set_style (user_desc, Canvas::GetStyleFromCSSString (style));
518+ pango_font_description_set_family (user_desc, family);
519+
520+ std::vector<FontFace>::iterator it = _font_face_list.begin ();
521+ FontFace *already_registered = NULL ;
537522
538- free ((char *)family);
539- if (desc->HasOwnProperty (weight_prop)) free ((char *)weight);
540- if (desc->HasOwnProperty (style_prop)) free ((char *)style);
523+ for (; it != _font_face_list.end () && !already_registered; ++it) {
524+ if (pango_font_description_equal (it->sys_desc , sys_desc)) {
525+ already_registered = &(*it);
526+ }
527+ }
541528
542- face.user_desc = d;
529+ if (already_registered) {
530+ pango_font_description_free (already_registered->user_desc );
531+ already_registered->user_desc = user_desc;
532+ } else if (register_font ((unsigned char *) *filePath)) {
533+ FontFace face;
534+ face.user_desc = user_desc;
535+ face.sys_desc = sys_desc;
543536 _font_face_list.push_back (face);
537+ } else {
538+ pango_font_description_free (user_desc);
539+ Nan::ThrowError (" Could not load font to the system's font host" );
544540 }
541+ } else {
542+ pango_font_description_free (user_desc);
543+ Nan::ThrowError (GENERIC_FACE_ERROR);
545544 }
545+
546+ g_free (family);
547+ g_free (weight);
548+ g_free (style);
546549}
547550
548551/*
0 commit comments