JFontID JXFontManager::GetFontID ( const JCharacter* name, const JSize size, const JFontStyle& style ) const { const JSize count = itsFontList->GetElementCount(); for (JIndex i=1; i<=count; i++) { const FontInfo info = itsFontList->GetElement(i); if (*(info.name) == name && info.size == size && info.style.bold == style.bold && info.style.italic == style.italic) { return i; } } // falling through means we need to create a new entry JString xFontName, charSet; ConvertToXFontName(name, &xFontName, &charSet); #ifdef _J_USE_XFT FontInfo info; info.xftfont = GetNewFont(xFontName, charSet, size, style); info.exact = kJTrue; if (info.xftfont == NULL) { info.exact = kJFalse; info.xftfont = ApproximateFont(xFontName, charSet, size, style); } #else FontInfo info; info.xfont = GetNewFont(xFontName, charSet, size, style); info.exact = kJTrue; if (info.xfont == NULL) { info.exact = kJFalse; info.xfont = ApproximateFont(xFontName, charSet, size, style); } #endif info.name = new JString(name); assert( info.name != NULL ); info.size = size; info.style = style; itsFontList->AppendElement(info); return itsFontList->GetElementCount(); }
JFontID JXFontManager::GetFontID ( const JCharacter* name, const JSize size, const JFontStyle& style ) const { const JSize count = itsFontList->GetElementCount(); for (JIndex i=1; i<=count; i++) { const FontInfo info = itsFontList->GetElement(i); if (*(info.name) == name && info.size == size && info.style.bold == style.bold && info.style.italic == style.italic) { return i; } } // falling through means we need to create a new entry const JString xFontName = ConvertToXFontName(name); FontInfo info; if (GetNewFont(xFontName, size, style, &(info.xfont))) { info.exact = kJTrue; } else { info.exact = kJFalse; ApproximateFont(xFontName, size, style, &(info.xfont)); } info.name = new JString(name); assert( info.name != NULL ); info.size = size; info.style = style; info.monoWidth = IsMonospace(info.xfont); itsFontList->AppendElement(info); return itsFontList->GetElementCount(); }
JBoolean JXFontManager::GetFontCharSets ( const JCharacter* name, const JSize size, JPtrArray<JString>* charSetList ) const { charSetList->CleanOut(); charSetList->SetCompareFunction(JCompareStringsCaseInsensitive); charSetList->SetSortOrder(JOrderedSetT::kSortAscending); JString xFontName, charSet; ConvertToXFontName(name, &xFontName, &charSet); // strip charSet const JString regexStr = "-*-" + xFontName + "-*-*-*-*-*-" + JString(10*size, 0, JString::kForceNoExponent) + "-75-75-*-*-*-*"; int nameCount; char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList == NULL) { return kJFalse; } for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name JIgnoreUntil(input, '-'); // font name JIgnoreUntil(input, '-'); // medium/bold JIgnoreUntil(input, '-'); // roman/oblique/italic JIgnoreUntil(input, '-'); // character spacing input.ignore(); // extra dash JIgnoreUntil(input, '-'); // pixel height JIgnoreUntil(input, '-'); // 10*(point size) JIgnoreUntil(input, '-'); // x resolution JIgnoreUntil(input, '-'); // y resolution JIgnoreUntil(input, '-'); // ? JIgnoreUntil(input, '-'); // ? JReadAll(input, &charSet); JBoolean isDuplicate; const JIndex index = charSetList->GetInsertionSortIndex(&charSet, &isDuplicate); if (!isDuplicate) { JString* s = new JString(charSet); assert( s != NULL ); charSetList->InsertElementAtIndex(index, s); } } XFreeFontNames(nameList); return JNegate( charSetList->IsEmpty() ); }
JFontStyle JXFontManager::GetFontStyles ( const JCharacter* name, const JSize size ) const { JFontStyle style(kJFalse, kJFalse, 0, kJTrue); #ifdef _J_USE_XFT double raw_size = size; XftFontSet* fs = XftListFonts(*itsDisplay, DefaultScreen((Display*)*itsDisplay), XFT_FAMILY, XftTypeString, name, XFT_SIZE, XftTypeDouble, raw_size, 0, XFT_SLANT, XFT_WEIGHT, 0); if (fs->nfont == 0) { return style; } for (int i=0; i<fs->nfont; i++) { int raw_slant; if (XftPatternGetInteger(fs->fonts[i], XFT_SLANT, 0, &raw_slant) == XftResultMatch) { if (raw_slant == XFT_SLANT_ITALIC) style.italic = kJTrue; } int raw_weight; if (XftPatternGetInteger(fs->fonts[i], XFT_WEIGHT, 0, &raw_weight) == XftResultMatch) { if (raw_weight == XFT_WEIGHT_BOLD) style.bold = kJTrue; } } XftFontSetDestroy(fs); #else JString xFontName, charSet; if (!ConvertToXFontName(name, &xFontName, &charSet)) { charSet = "*-*"; } const JString regexStr = "-*-" + xFontName + "-*-*-*-*-*-" + JString(10*size, 0, JString::kForceNoExponent) + "-75-75-*-*-" + charSet; int nameCount; char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList == NULL) { return style; } JString weight, slant; for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name JIgnoreUntil(input, '-'); // font name weight = JReadUntil(input, '-'); // medium/bold slant = JReadUntil(input, '-'); // roman/oblique/italic if (weight == "bold") { style.bold = kJTrue; } if (slant == "o" || slant == "i") { style.italic = kJTrue; } } XFreeFontNames(nameList); #endif return style; }
JBoolean JXFontManager::GetFontSizes ( const JCharacter* name, JSize* minSize, JSize* maxSize, JArray<JSize>* sizeList ) const { *minSize = *maxSize = 0; sizeList->RemoveAll(); sizeList->SetCompareFunction(JCompareSizes); sizeList->SetSortOrder(JOrderedSetT::kSortAscending); #ifdef _J_USE_XFT XftFontSet* fs = XftListFonts(*itsDisplay, DefaultScreen((Display*)*itsDisplay), XFT_FAMILY, XftTypeString, name, 0, XFT_SIZE, 0); if (fs->nfont == 0) { *minSize = 8; *maxSize = 24; XftFontSetDestroy(fs); return kJTrue; } for (int i=0; i<fs->nfont; i++) { double raw_size; if (XftPatternGetDouble(fs->fonts[i], XFT_SIZE, 0, &raw_size) == XftResultMatch) { JSize fontSize = static_cast<JSize>(raw_size); if (sizeList->IsEmpty()) { *minSize = *maxSize = fontSize; } JBoolean isDuplicate; const JIndex index = sizeList->GetInsertionSortIndex(fontSize, &isDuplicate); if (!isDuplicate) { sizeList->InsertElementAtIndex(index, fontSize); if (fontSize < *minSize) { *minSize = fontSize; } else if (fontSize > *maxSize) { *maxSize = fontSize; } } } } // Look for scalable if ((*minSize == 0) && (*maxSize == 0)) { *minSize = 8; *maxSize = 24; XftFontSetDestroy(fs); return kJTrue; } XftFontSetDestroy(fs); #else JString xFontName, charSet; if (!ConvertToXFontName(name, &xFontName, &charSet)) { charSet = "*-*"; } // check for rescalable font JString regexStr = "-*-" + xFontName + "-*-*-*-*-*-0-75-75-*-*-" + charSet; int nameCount; char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList != NULL) { *minSize = 8; *maxSize = 24; XFreeFontNames(nameList); return kJTrue; } // get list of available sizes regexStr = "-*-" + xFontName + "-*-*-*-*-*-*-75-75-*-*-" + charSet; nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList == NULL) { return kJFalse; } JSize fontSize; for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name JIgnoreUntil(input, '-'); // font name JIgnoreUntil(input, '-'); // medium/bold JIgnoreUntil(input, '-'); // roman/oblique/italic JIgnoreUntil(input, '-'); // character spacing input.ignore(); // extra dash JIgnoreUntil(input, '-'); // pixel height input >> fontSize; // 10*(point size) if (fontSize < 10) { continue; // we already checked for rescalable version } fontSize /= 10; if (sizeList->IsEmpty()) { *minSize = *maxSize = fontSize; } JBoolean isDuplicate; const JIndex index = sizeList->GetInsertionSortIndex(fontSize, &isDuplicate); if (!isDuplicate) { sizeList->InsertElementAtIndex(index, fontSize); if (fontSize < *minSize) { *minSize = fontSize; } else if (fontSize > *maxSize) { *maxSize = fontSize; } } } XFreeFontNames(nameList); #endif return JNegate( sizeList->IsEmpty() ); }
JBoolean JXFontManager::GetFontSizes ( const JCharacter* name, JSize* minSize, JSize* maxSize, JArray<JSize>* sizeList ) const { sizeList->RemoveAll(); #if ENABLE_TRUE_TYPE *minSize = 8; *maxSize = 24; return kJTrue; #else *minSize = *maxSize = 0; sizeList->SetCompareFunction(JCompareSizes); sizeList->SetSortOrder(JOrderedSetT::kSortAscending); const JString xFontName = ConvertToXFontName(name) // check for rescalable font JString regexStr = "-*-" + xFontName + "-medium-r-normal-*-*-0-75-75-*-*-*"; int nameCount; char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList != NULL) { *minSize = 8; *maxSize = 24; XFreeFontNames(nameList); return kJTrue; } // get list of available sizes regexStr = "-*-" + xFontName + "-medium-r-normal-*-*-*-75-75-*-*-*"; nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList == NULL) { return kJFalse; } JSize fontSize; for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name JIgnoreUntil(input, '-'); // font name JIgnoreUntil(input, '-'); // medium/bold JIgnoreUntil(input, '-'); // roman/oblique/italic JIgnoreUntil(input, '-'); // character spacing JIgnoreUntil(input, '-'); // sans JIgnoreUntil(input, '-'); // pixel height input >> fontSize; // 10*(point size) if (fontSize < 10) { continue; // we already checked for rescalable version } fontSize /= 10; if (sizeList->IsEmpty()) { *minSize = *maxSize = fontSize; } JBoolean isDuplicate; const JIndex index = sizeList->GetInsertionSortIndex(fontSize, &isDuplicate); if (!isDuplicate) { sizeList->InsertElementAtIndex(index, fontSize); if (fontSize < *minSize) { *minSize = fontSize; } else if (fontSize > *maxSize) { *maxSize = fontSize; } } } XFreeFontNames(nameList); #endif return !sizeList->IsEmpty(); }