FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
if (aFaceError != FT_Err_Ok)
{
- return NULL;
+ return Handle(Font_SystemFont)();
+ }
+ if (aFontFace->family_name == NULL // skip broken fonts (error in FreeType?)
+ || FT_Select_Charmap (aFontFace, ft_encoding_unicode) != 0) // Font_FTFont supports only UNICODE fonts
+ {
+ FT_Done_Face (aFontFace);
+ return Handle(Font_SystemFont)();
}
+ // FreeType decomposes font definition into Family Name and Style Name,
+ // so that fonts within the same Family and different Styles can be identified.
+ // OCCT Font Manager natively handles 4 basic styles: Regular, Bold, Italic and Bold+Italic.
+ // To include other non-standard Styles, their names can be appended to Family Name; for this, names of normal Styles should be removed.
+ TCollection_AsciiString aFamily (aFontFace->family_name);
+ TCollection_AsciiString aStyle (aFontFace->style_name != NULL ? aFontFace->style_name : "");
Font_FontAspect anAspect = Font_FA_Regular;
if (aFontFace->style_flags == (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD))
{
anAspect = Font_FA_BoldItalic;
+ const Standard_Integer aRemoveItalic = aStyle.Search ("Italic");
+ if (aRemoveItalic != -1)
+ {
+ aStyle.Remove (aRemoveItalic, 6);
+ }
+ else
+ {
+ // synonym
+ const Standard_Integer aRemoveOblique = aStyle.Search ("Oblique");
+ if (aRemoveOblique != -1)
+ {
+ aStyle.Remove (aRemoveOblique, 7);
+ }
+ }
+
+ const Standard_Integer aRemoveBold = aStyle.Search ("Bold");
+ if (aRemoveBold != -1)
+ {
+ aStyle.Remove (aRemoveBold, 4);
+ }
}
else if (aFontFace->style_flags == FT_STYLE_FLAG_ITALIC)
{
anAspect = Font_FA_Italic;
+ const Standard_Integer aRemoveItalic = aStyle.Search ("Italic");
+ if (aRemoveItalic != -1)
+ {
+ aStyle.Remove (aRemoveItalic, 6);
+ }
+ else
+ {
+ // synonym
+ const Standard_Integer aRemoveOblique = aStyle.Search ("Oblique");
+ if (aRemoveOblique != -1)
+ {
+ aStyle.Remove (aRemoveOblique, 7);
+ }
+ }
}
else if (aFontFace->style_flags == FT_STYLE_FLAG_BOLD)
{
anAspect = Font_FA_Bold;
+ const Standard_Integer aRemoveBold = aStyle.Search ("Bold");
+ if (aRemoveBold != -1)
+ {
+ aStyle.Remove (aRemoveBold, 4);
+ }
}
- Handle(Font_SystemFont) aResult;
- if (aFontFace->family_name != NULL // skip broken fonts (error in FreeType?)
- && FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
+ const Standard_Integer aRemoveReg = aStyle.Search ("Regular");
+ if (aRemoveReg != -1)
{
- aResult = new Font_SystemFont (aFontFace->family_name);
- aResult->SetFontPath (anAspect, theFontPath);
- // automatically identify some known single-line fonts
- aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
+ aStyle.Remove (aRemoveReg, 7);
+ }
+ else
+ {
+ // synonym
+ const Standard_Integer aRemoveBook = aStyle.Search ("Book");
+ if (aRemoveBook != -1)
+ {
+ aStyle.Remove (aRemoveBook, 4);
+ }
}
- FT_Done_Face (aFontFace);
+ aStyle.LeftAdjust();
+ aStyle.RightAdjust();
+ for (;;)
+ {
+ // remove double spaces after removal of several keywords in-between, like "Condensed Bold Italic Oblique"
+ const Standard_Integer aRemoveSpace = aStyle.Search (" ");
+ if (aRemoveSpace == -1)
+ {
+ break;
+ }
+ aStyle.Remove (aRemoveSpace, 1);
+ }
+
+ if (!aStyle.IsEmpty())
+ {
+ aFamily = aFamily + " " + aStyle;
+ }
+
+ Handle(Font_SystemFont) aResult = new Font_SystemFont (aFamily);
+ aResult->SetFontPath (anAspect, theFontPath);
+ // automatically identify some known single-line fonts
+ aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
+
+ FT_Done_Face (aFontFace);
return aResult;
}
const char** theArgVec)
{
Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
- if (theArgNb < 2)
- {
- // just print the list of available fonts
- Standard_Boolean isFirst = Standard_True;
- const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
- std::vector<Handle(Font_SystemFont)> aFontsSorted;
- aFontsSorted.reserve (aFonts.Size());
- for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
- {
- aFontsSorted.push_back (aFontIter.Value());
- }
- std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
- for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
- {
- const Handle(Font_SystemFont)& aFont = *aFontIter;
- if (!isFirst)
- {
- theDI << "\n";
- }
-
- theDI << aFont->ToString();
- isFirst = Standard_False;
- }
- return 0;
- }
-
+ bool toPrintList = theArgNb < 2, toPrintNames = false;
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
{
aMgr->InitFontDataBase();
}
+ else if (anArgCase == "-list")
+ {
+ toPrintList = true;
+ }
+ else if (anArgCase == "-names")
+ {
+ toPrintList = true;
+ toPrintNames = true;
+ }
else if (anArgIter + 1 < theArgNb
&& (anArgCase == "-find"
+ || anArgCase == "-findinfo"
+ || anArgCase == "-findall"
|| anArgCase == "find"))
{
- Standard_CString aFontName = theArgVec[++anArgIter];
- Font_FontAspect aFontAspect = Font_FA_Undefined;
+ const TCollection_AsciiString aFontName (theArgVec[++anArgIter]);
+ Font_FontAspect aFontAspect = Font_FA_Undefined;
if (++anArgIter < theArgNb)
{
anArgCase = theArgVec[anArgIter];
}
}
- if (Handle(Font_SystemFont) aFont = aMgr->FindFont (aFontName, aStrictLevel, aFontAspect))
+ const bool toFindAll = (anArgCase == "-findall");
+ const bool toPrintInfo = (anArgCase == "-findinfo");
+ TCollection_AsciiString aResult;
+ if (toFindAll
+ || aFontName.Search ("*") != -1)
{
- theDI << aFont->ToString();
+ const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
+ std::vector<Handle(Font_SystemFont)> aFontsSorted;
+ aFontsSorted.reserve (aFonts.Size());
+ for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
+ {
+ aFontsSorted.push_back (aFontIter.Value());
+ }
+ std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
+ for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
+ {
+ const Handle(Font_SystemFont)& aFont = *aFontIter;
+ const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match -nocase \"") + aFontName + "\" \"" + aFont->FontName() + "\"";
+ if (theDI.Eval (aCheck.ToCString()) == 0
+ && *theDI.Result() != '1')
+ {
+ theDI.Reset();
+ continue;
+ }
+
+ theDI.Reset();
+ if (!aResult.IsEmpty())
+ {
+ aResult += "\n";
+ }
+
+ aResult += toPrintInfo ? aFont->ToString() : aFont->FontName();
+ if (!toFindAll)
+ {
+ break;
+ }
+ }
+ }
+ else if (Handle(Font_SystemFont) aFont = aMgr->FindFont (aFontName, aStrictLevel, aFontAspect))
+ {
+ aResult = toPrintInfo ? aFont->ToString() : aFont->FontName();
+ }
+
+ if (!aResult.IsEmpty())
+ {
+ theDI << aResult;
}
else
{
}
}
+ if (toPrintList)
+ {
+ // just print the list of available fonts
+ Standard_Boolean isFirst = Standard_True;
+ const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
+ std::vector<Handle(Font_SystemFont)> aFontsSorted;
+ aFontsSorted.reserve (aFonts.Size());
+ for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
+ {
+ aFontsSorted.push_back (aFontIter.Value());
+ }
+ std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
+ for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
+ {
+ const Handle(Font_SystemFont)& aFont = *aFontIter;
+
+ if (toPrintNames)
+ {
+ if (!isFirst)
+ {
+ theDI << "\n";
+ }
+ theDI << "\"" << aFont->FontName() << "\"";
+ }
+ else
+ {
+ if (!isFirst)
+ {
+ theDI << "\n";
+ }
+ theDI << aFont->ToString();
+ }
+ isFirst = Standard_False;
+ }
+ return 0;
+ }
+
return 0;
}
theCommands.Add ("vfont",
"vfont [-add pathToFont [fontName] [regular,bold,italic,boldItalic=undefined] [singleStroke]]"
"\n\t\t: [-strict {any|aliases|strict}] [-find fontName [regular,bold,italic,boldItalic=undefined]] [-verbose {on|off}]"
+ "\n\t\t: [-findAll fontNameMask] [-findInfo fontName]"
"\n\t\t: [-unicodeFallback {on|off}]"
- "\n\t\t: [-clear] [-init]",
+ "\n\t\t: [-clear] [-init] [-list] [-names]"
+ "\n\t\t: Work with font registry - register font, list available fonts, find font."
+ "\n\t\t: -findAll is same as -find, but can print more than one font when mask is passed."
+ "\n\t\t: -findInfo is same as -find, but prints complete font information instead of family name.",
__FILE__, VFont, group);
theCommands.Add ("vvertexmode",