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(); }
JSize JXFontManager::GetStringWidth16 ( const JFontID fontID, const JSize size, const JFontStyle& style, const JCharacter16* str, const JSize charCount ) const { #ifdef _J_USE_XFT XftFont* xftfont = GetXftFont(fontID); XGlyphInfo extents; unsigned short test = 0x00FF; bool bigE = ((const char*)&test)[0] == 0x00; XftTextExtentsUtf16(*itsDisplay, xftfont, (XftChar8*)str, bigE ? FcEndianBig : FcEndianLittle, charCount * sizeof(JCharacter16), &extents); return extents.xOff; #else XFontStruct* xfont = GetXFontInfo(fontID); if (IsMonospace(*xfont)) { return charCount * xfont->min_bounds.width; } else { JString16 utf16(str, charCount); JString str_ascii = utf16.ToASCII(); const JCharacter* _str = str_ascii.GetCString(); JSize actualCount = str_ascii.GetLength(); const JSize maxStringLength = itsDisplay->GetMaxStringLength(); JSize width = 0; JSize offset = 0; while (offset < actualCount) { const JSize count = JMin(actualCount - offset, maxStringLength); width += XTextWidth(xfont, _str + offset, count); offset += count; } return width; } #endif }
JSize JXFontManager::GetStringWidth ( const JFontID fontID, const JSize size, const JFontStyle& style, const JCharacter* str, const JSize charCount ) const { #ifdef _J_USE_XFT XftFont* xftfont = GetXftFont(fontID); XGlyphInfo extents; //XftTextExtents8(*itsDisplay, xftfont, (XftChar8*)str, charCount, &extents); XftTextExtentsUtf8(*itsDisplay, xftfont, (XftChar8*)str, charCount, &extents); return extents.xOff; #else XFontStruct* xfont = GetXFontInfo(fontID); if (IsMonospace(*xfont)) { return charCount * xfont->min_bounds.width; } else { const JSize maxStringLength = itsDisplay->GetMaxStringLength(); JSize width = 0; JSize offset = 0; while (offset < charCount) { const JSize count = JMin(charCount - offset, maxStringLength); width += XTextWidth(xfont, str + offset, count); offset += count; } return width; } #endif }
void JXFontManager::GetMonospaceFontNames ( JPtrArray<JString>* fontNames ) const { if (itsMonoFontNames != NULL) { fontNames->CopyObjects(*itsMonoFontNames, fontNames->GetCleanUpAction(), kJFalse); } else { (JXGetApplication())->DisplayBusyCursor(); fontNames->CleanOut(); fontNames->SetCompareFunction(JCompareStringsCaseInsensitive); fontNames->SetSortOrder(JOrderedSetT::kSortAscending); #ifdef _J_USE_XFT FcBool scalable = 1; XftFontSet* fs = XftListFonts(*itsDisplay, DefaultScreen((Display*)*itsDisplay), XFT_SPACING, XftTypeInteger, XFT_MONO, XFT_SCALABLE, XftTypeBool, scalable, 0, XFT_FAMILY, 0); for (int i=0; i<fs->nfont; i++) { char* raw_name; if (XftPatternGetString(fs->fonts[i], XFT_FAMILY, 0, &raw_name) == XftResultMatch) { JString name(raw_name); JBoolean isDuplicate; const JIndex index = fontNames->GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { fontNames->InsertAtIndex(index, name); } } } XftFontSetDestroy(fs); #else JPtrArray<JString> allFontNames(JPtrArrayT::kDeleteAll); allFontNames.SetCompareFunction(JCompareStringsCaseInsensitive); allFontNames.SetSortOrder(JOrderedSetT::kSortAscending); for (int j=0; j<kMonospaceFontPatternCount; j++) { int nameCount; char** nameList = XListFonts(*itsDisplay, kMonospaceFontPattern[j], INT_MAX, &nameCount); if (nameList == NULL) { return; } JString name, charSet; 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 name = JReadUntil(input, '-'); // font name JIgnoreUntil(input, "-iso"); // ignore specs JReadAll(input, &charSet); // char set if (name.IsEmpty() || name == "nil") { continue; } ConvertToPSFontName(&name); #if ! QUERY_FOR_MONOSPACE if (name == "Clean" || name == "Courier" || name == "Fixed" || name == "Terminal" || name == "Lucidatypewriter" || name == "Profontwindows") { #endif // charSet.Prepend("iso"); // name = CombineNameAndCharacterSet(name, charSet); JBoolean isDuplicate; const JIndex index = allFontNames.GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { allFontNames.InsertAtIndex(index, name); // cout << nameList[i] << endl; XFontStruct* xfont = XLoadQueryFont(*itsDisplay, nameList[i]); if (xfont != NULL) { if (IsMonospace(*xfont)) { JString* n = new JString(name); assert( n != NULL ); const JBoolean ok = fontNames->InsertSorted(n, kJFalse); assert( ok ); } XFreeFont(*itsDisplay, xfont); } } #if ! QUERY_FOR_MONOSPACE } #endif } XFreeFontNames(nameList); } #endif // save names for next time JXFontManager* me = const_cast<JXFontManager*>(this); me->itsMonoFontNames = new JPtrArray<JString>(*fontNames, JPtrArrayT::kDeleteAll, kJTrue); assert( me->itsMonoFontNames != NULL ); } }
JBoolean JXFontManager::GetFontID ( const JCharacter* xFontStr, JFontID* fontID ) const { const JSize count = itsFontList->GetElementCount(); for (JIndex i=1; i<=count; i++) { const FontInfo info = itsFontList->GetElement(i); if (*(info.name) == xFontStr && info.size == 0) { *fontID = i; return kJTrue; } } // falling through means we need to create a new entry FontInfo info; #if ENABLE_TRUE_TYPE XftFont* xft = XftFontOpenXlfd(*itsDisplay, itsDisplay->GetScreen(), xFontStr); if (xft != NULL) { info.xfont.type = kTrueType; info.xfont.xftrue = xft; } else #endif { XFontStruct* xfs = XLoadQueryFont(*itsDisplay, xFontStr); if (xfs != NULL) { info.xfont.type = kStdType; info.xfont.xfstd = xfs; } else { *fontID = 0; return kJFalse; } } info.name = new JString(xFontStr); assert( info.name != NULL ); info.size = 0; info.exact = kJTrue; info.monoWidth = IsMonospace(info.xfont); itsFontList->AppendElement(info); *fontID = itsFontList->GetElementCount(); return kJTrue; }