/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* utf8xfe.cpp UTF8 to XmString conversion and XmFontList monitor stuff we need for RDF related UI Created: Frank Tang tftang@netscape.com>, 30-Sep-98 */ #include "utf8xfe.h" #include "csid.h" #include "xupfonts.h" #include "felocale.h" //--------------------------------------------------------------- class UTF8TextAndFontListTracer : public UTF8ToXmStringConverter { public: UTF8TextAndFontListTracer( FontListNotifier *inNotifier, fe_Font inUFont); virtual ~UTF8TextAndFontListTracer(); virtual XmString convertToXmString(const char* utf8text); protected: int numberOfFonts(fe_Font f); void notifyFontListChanges(XmFontList fontlist); private: fe_Font fUFont; FontListNotifier* fNotifier; int fLastNumberOfFonts; }; //--------------------------------------------------------------- class UnicodePseudoFontFactory { public: static fe_Font makeByFontList(Display* dpy, XmFontList defFontList); static fe_Font makeByFontStruct(Display* dpy, XFontStruct *xfstruc); static fe_Font makeByFontSet(Display* dpy, XFontSet xfset); static fe_Font makeByNameSize(Display* dpy, const char* fam, int pt); }; //--------------------------------------------------------------- fe_Font UnicodePseudoFontFactory::makeByFontList( Display *dpy, XmFontList defFontList) { fe_Font ret = NULL; XmFontContext context; XmFontListEntry entry; XmFontListInitFontContext(&context, defFontList); while(NULL != (entry = XmFontListNextEntry(context))) { XtPointer font; XmFontType type; char* tag; tag = XmFontListEntryGetTag(entry); if((NULL == ret) || (0 == strcmp(XmFONTLIST_DEFAULT_TAG, tag))) { font = XmFontListEntryGetFont(entry, &type); if(XmFONT_IS_FONT == type) ret = UnicodePseudoFontFactory::makeByFontStruct(dpy, (XFontStruct*) font); else ret = UnicodePseudoFontFactory::makeByFontSet(dpy, (XFontSet) font); } free(tag); } XmFontListFreeFontContext(context); return ret; } //--------------------------------------------------------------- fe_Font UnicodePseudoFontFactory::makeByFontSet( Display *dpy, XFontSet xfset) { char **fnl; XFontStruct ** fsl; if(XFontsOfFontSet(xfset, &fsl, &fnl)>0) return UnicodePseudoFontFactory::makeByFontStruct(dpy, fsl[0]); else return UnicodePseudoFontFactory::makeByNameSize(dpy, "helvetica", 120); } //--------------------------------------------------------------- fe_Font UnicodePseudoFontFactory::makeByFontStruct( Display *dpy, XFontStruct* xfstruct) { Atom fmlAtom; char fam[32]; int ptSize = 0; if(XGetFontProperty( xfstruct, XA_FAMILY_NAME, (unsigned long* )&fmlAtom)) { char * famName = XGetAtomName(dpy, fmlAtom); PR_snprintf(fam, 31, famName); fam[31] = '\0'; XFree((void*)famName); } else { PR_snprintf(fam, 31, "helvetica"); } if(! XGetFontProperty( xfstruct, XA_POINT_SIZE, (unsigned long*)&ptSize)) ptSize = 120; return UnicodePseudoFontFactory::makeByNameSize(dpy, fam, ptSize); } extern "C" { extern int fe_UnicodePointToPixelSize(Display *, int) ; }; //--------------------------------------------------------------- fe_Font UnicodePseudoFontFactory::makeByNameSize( Display *dpy, const char* family, int ptSize) { int pixelSize = fe_UnicodePointToPixelSize(dpy, ptSize) ; return (fe_Font) fe_LoadUnicodeFontByPixelSize( NULL, (char*)family, pixelSize, 0, CS_UTF8, 0, 0, dpy ); } //--------------------------------------------------------------- // To Do: we should make a array to return different font depend on // passed in parameter. fe_Font UnicodeFontSingleton::gUFont = NULL; fe_Font UnicodeFontSingleton::Instance(Display *dpy, char* family, int pt) { if(NULL == UnicodeFontSingleton::gUFont) { gUFont = UnicodePseudoFontFactory::makeByNameSize(dpy, family, pt); } return gUFont; } //--------------------------------------------------------------- UTF8ToXmStringConverter* UTF8ToXmStringConverterFactory::make( FontListNotifier* inNotifier, fe_Font inFont ) { return new UTF8TextAndFontListTracer(inNotifier, inFont); } //--------------------------------------------------------------- UTF8TextAndFontListTracer::UTF8TextAndFontListTracer( FontListNotifier *inNotifier, fe_Font inUFont ) { fNotifier = inNotifier; fLastNumberOfFonts = 0; fUFont = inUFont; } UTF8TextAndFontListTracer::~UTF8TextAndFontListTracer() { // fe_freeUnicodePseudoFont(fUFont); } int UTF8TextAndFontListTracer::numberOfFonts(fe_Font f) { fe_UnicodePseudoFont *ufont = (fe_UnicodePseudoFont*) f; int i,num; for(i=num=0; i < INTL_CHAR_SET_MAX; i++) if(TRUE == ufont->xfont_inited[i]) num++; return num; } XmString UTF8TextAndFontListTracer::convertToXmString(const char* utf8text) { XmFontList fontlist; XmFontType type = XmFONT_IS_FONT; XmString xmstr = fe_ConvertToXmString((unsigned char*)utf8text, CS_UTF8, fUFont, type , &fontlist); int newNumberOfFonts = numberOfFonts(fUFont); if(fLastNumberOfFonts != newNumberOfFonts) { fNotifier->notifyFontListChanged(fontlist); fLastNumberOfFonts = newNumberOfFonts; } return xmstr; } /* some debugger function here */ void DebugXmString(XmString inString) { XmStringContext context; char *text; XmStringCharSet tag; XmStringDirection dir; Boolean sep; if(! XmStringInitContext(&context, inString) ) { fprintf(stderr, "cannot exam this XmString\n"); return; } fprintf(stderr, "dump XmString:"); while(XmStringGetNextSegment(context, &text,&tag, &dir,&sep)) { fprintf(stderr,"[%s:%s:%s:%s:%s]", (sep ? "Sep" : ""), ((dir == XmSTRING_DIRECTION_L_TO_R) ? "L2R" : ((dir == XmSTRING_DIRECTION_R_TO_L) ? "R2L" : "Def")), tag, text, (sep ? "Sep" : "")); XtFree(text); } fprintf(stderr,"\n"); fflush(stderr); XmStringFreeContext(context); } void DebugFontList(XmFontList inFontList) { XmFontContext context; XmFontListEntry entry; XmFontListInitFontContext(&context, inFontList); fprintf(stderr, "dump XmFontList:"); while(NULL != (entry = XmFontListNextEntry(context))) { XtPointer font; XmFontType type; char* tag; font = XmFontListEntryGetFont(entry, &type); tag = XmFontListEntryGetTag(entry); fprintf(stderr, "[%s:%s:%xl]", ((type == XmFONT_IS_FONT) ? "F" : "L"), tag, (int)font ); free(tag); } fprintf(stderr,"\n"); XmFontListFreeFontContext(context); }