@@ -66,7 +66,7 @@ Canvas::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
6666 Nan::SetTemplate (proto, " PNG_ALL_FILTERS" , Nan::New<Uint32>(PNG_ALL_FILTERS));
6767
6868 // Class methods
69- Nan::SetMethod (ctor, " registerFont " , RegisterFont);
69+ Nan::SetMethod (ctor, " _registerFont " , RegisterFont);
7070
7171 Nan::Set (target, Nan::New (" Canvas" ).ToLocalChecked (), ctor->GetFunction ());
7272}
@@ -575,72 +575,75 @@ NAN_METHOD(Canvas::StreamJPEGSync) {
575575
576576#endif
577577
578- NAN_METHOD (Canvas::RegisterFont) {
579- FontFace face;
578+ char *
579+ str_value (Local<Value> val, const char *fallback, bool can_be_number) {
580+ if (val->IsString () || (can_be_number && val->IsNumber ())) {
581+ return g_strdup (*String::Utf8Value (val));
582+ } else if (fallback) {
583+ return g_strdup (fallback);
584+ } else {
585+ return NULL ;
586+ }
587+ }
580588
589+ NAN_METHOD (Canvas::RegisterFont) {
581590 if (!info[0 ]->IsString ()) {
582591 return Nan::ThrowError (" Wrong argument type" );
592+ } else if (!info[1 ]->IsObject ()) {
593+ return Nan::ThrowError (GENERIC_FACE_ERROR);
583594 }
584595
585596 String::Utf8Value filePath (info[0 ]);
597+ PangoFontDescription *sys_desc = get_pango_font_description ((unsigned char *) *filePath);
586598
587- if (!register_font ((unsigned char *) *filePath, &face.sys_desc )) {
588- Nan::ThrowError (" Could not load font to the system's font host" );
589- } else {
590- PangoFontDescription *d = pango_font_description_new ();
591-
592- if (!info[1 ]->IsObject ()) {
593- Nan::ThrowError (GENERIC_FACE_ERROR);
594- } else { // now check the attrs, there are many ways to be wrong
595- Local<Object> desc = info[1 ]->ToObject ();
596- Local<String> family_prop = Nan::New<String>(" family" ).ToLocalChecked ();
597- Local<String> weight_prop = Nan::New<String>(" weight" ).ToLocalChecked ();
598- Local<String> style_prop = Nan::New<String>(" style" ).ToLocalChecked ();
599-
600- const char *family;
601- const char *weight = " normal" ;
602- const char *style = " normal" ;
603-
604- Local<Value> family_val = desc->Get (family_prop);
605- if (family_val->IsString ()) {
606- family = strdup (*String::Utf8Value (family_val));
607- } else {
608- Nan::ThrowError (GENERIC_FACE_ERROR);
609- return ;
610- }
599+ if (!sys_desc) return Nan::ThrowError (" Could not parse font file" );
611600
612- if (desc->HasOwnProperty (weight_prop)) {
613- Local<Value> weight_val = desc->Get (weight_prop);
614- if (weight_val->IsString () || weight_val->IsNumber ()) {
615- weight = strdup (*String::Utf8Value (weight_val));
616- } else {
617- Nan::ThrowError (GENERIC_FACE_ERROR);
618- return ;
619- }
620- }
601+ PangoFontDescription *user_desc = pango_font_description_new ();
621602
622- if (desc-> HasOwnProperty (style_prop)) {
623- Local<Value> style_val = desc-> Get (style_prop );
624- if (style_val-> IsString ()) {
625- style = strdup (* String::Utf8Value (style_val) );
626- } else {
627- Nan::ThrowError (GENERIC_FACE_ERROR);
628- return ;
629- }
630- }
603+ // now check the attrs, there are many ways to be wrong
604+ Local<Object> js_user_desc = info[ 1 ]-> ToObject ( );
605+ Local<String> family_prop = Nan::New<String>( " family " ). ToLocalChecked ();
606+ Local<String> weight_prop = Nan::New<String>( " weight " ). ToLocalChecked ( );
607+ Local<String> style_prop = Nan::New<String>( " style " ). ToLocalChecked ();
608+
609+ char *family = str_value (js_user_desc-> Get (family_prop), NULL , false ) ;
610+ char *weight = str_value (js_user_desc-> Get (weight_prop), " normal " , true );
611+ char *style = str_value (js_user_desc-> Get (style_prop), " normal " , false );
631612
632- pango_font_description_set_weight (d, Canvas::GetWeightFromCSSString (weight));
633- pango_font_description_set_style (d, Canvas::GetStyleFromCSSString (style));
634- pango_font_description_set_family (d, family);
613+ if (family && weight && style) {
614+ pango_font_description_set_weight (user_desc, Canvas::GetWeightFromCSSString (weight));
615+ pango_font_description_set_style (user_desc, Canvas::GetStyleFromCSSString (style));
616+ pango_font_description_set_family (user_desc, family);
617+
618+ std::vector<FontFace>::iterator it = _font_face_list.begin ();
619+ FontFace *already_registered = NULL ;
635620
636- free ((char *)family);
637- if (desc->HasOwnProperty (weight_prop)) free ((char *)weight);
638- if (desc->HasOwnProperty (style_prop)) free ((char *)style);
621+ for (; it != _font_face_list.end () && !already_registered; ++it) {
622+ if (pango_font_description_equal (it->sys_desc , sys_desc)) {
623+ already_registered = &(*it);
624+ }
625+ }
639626
640- face.user_desc = d;
627+ if (already_registered) {
628+ pango_font_description_free (already_registered->user_desc );
629+ already_registered->user_desc = user_desc;
630+ } else if (register_font ((unsigned char *) *filePath)) {
631+ FontFace face;
632+ face.user_desc = user_desc;
633+ face.sys_desc = sys_desc;
641634 _font_face_list.push_back (face);
635+ } else {
636+ pango_font_description_free (user_desc);
637+ Nan::ThrowError (" Could not load font to the system's font host" );
642638 }
639+ } else {
640+ pango_font_description_free (user_desc);
641+ Nan::ThrowError (GENERIC_FACE_ERROR);
643642 }
643+
644+ g_free (family);
645+ g_free (weight);
646+ g_free (style);
644647}
645648
646649/*
0 commit comments