mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0031118: Visualization - Font_FontMgr skips fonts with unknown styles like Narrow or Black
Extended Style name is now appended to Family name for unique identification of the font. vfont -find now accepts mask to search the font and returns family name.
This commit is contained in:
parent
6b467e52bb
commit
15e4e6a23e
@ -150,35 +150,114 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib
|
|||||||
FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
|
FT_Error aFaceError = FT_New_Face (theFTLib->Instance(), theFontPath, 0, &aFontFace);
|
||||||
if (aFaceError != FT_Err_Ok)
|
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;
|
Font_FontAspect anAspect = Font_FA_Regular;
|
||||||
if (aFontFace->style_flags == (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD))
|
if (aFontFace->style_flags == (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD))
|
||||||
{
|
{
|
||||||
anAspect = Font_FA_BoldItalic;
|
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)
|
else if (aFontFace->style_flags == FT_STYLE_FLAG_ITALIC)
|
||||||
{
|
{
|
||||||
anAspect = Font_FA_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)
|
else if (aFontFace->style_flags == FT_STYLE_FLAG_BOLD)
|
||||||
{
|
{
|
||||||
anAspect = Font_FA_Bold;
|
anAspect = Font_FA_Bold;
|
||||||
|
const Standard_Integer aRemoveBold = aStyle.Search ("Bold");
|
||||||
|
if (aRemoveBold != -1)
|
||||||
|
{
|
||||||
|
aStyle.Remove (aRemoveBold, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Font_SystemFont) aResult;
|
const Standard_Integer aRemoveReg = aStyle.Search ("Regular");
|
||||||
if (aFontFace->family_name != NULL // skip broken fonts (error in FreeType?)
|
if (aRemoveReg != -1)
|
||||||
&& FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
|
|
||||||
{
|
{
|
||||||
aResult = new Font_SystemFont (aFontFace->family_name);
|
aStyle.Remove (aRemoveReg, 7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// synonym
|
||||||
|
const Standard_Integer aRemoveBook = aStyle.Search ("Book");
|
||||||
|
if (aRemoveBook != -1)
|
||||||
|
{
|
||||||
|
aStyle.Remove (aRemoveBook, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
aResult->SetFontPath (anAspect, theFontPath);
|
||||||
// automatically identify some known single-line fonts
|
// automatically identify some known single-line fonts
|
||||||
aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
|
aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
|
||||||
}
|
|
||||||
|
|
||||||
FT_Done_Face (aFontFace);
|
FT_Done_Face (aFontFace);
|
||||||
|
|
||||||
return aResult;
|
return aResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5490,32 +5490,7 @@ static int VFont (Draw_Interpretor& theDI,
|
|||||||
const char** theArgVec)
|
const char** theArgVec)
|
||||||
{
|
{
|
||||||
Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
|
Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
|
||||||
if (theArgNb < 2)
|
bool toPrintList = theArgNb < 2, toPrintNames = false;
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
|
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
|
||||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
||||||
{
|
{
|
||||||
@ -5536,11 +5511,22 @@ static int VFont (Draw_Interpretor& theDI,
|
|||||||
{
|
{
|
||||||
aMgr->InitFontDataBase();
|
aMgr->InitFontDataBase();
|
||||||
}
|
}
|
||||||
|
else if (anArgCase == "-list")
|
||||||
|
{
|
||||||
|
toPrintList = true;
|
||||||
|
}
|
||||||
|
else if (anArgCase == "-names")
|
||||||
|
{
|
||||||
|
toPrintList = true;
|
||||||
|
toPrintNames = true;
|
||||||
|
}
|
||||||
else if (anArgIter + 1 < theArgNb
|
else if (anArgIter + 1 < theArgNb
|
||||||
&& (anArgCase == "-find"
|
&& (anArgCase == "-find"
|
||||||
|
|| anArgCase == "-findinfo"
|
||||||
|
|| anArgCase == "-findall"
|
||||||
|| anArgCase == "find"))
|
|| anArgCase == "find"))
|
||||||
{
|
{
|
||||||
Standard_CString aFontName = theArgVec[++anArgIter];
|
const TCollection_AsciiString aFontName (theArgVec[++anArgIter]);
|
||||||
Font_FontAspect aFontAspect = Font_FA_Undefined;
|
Font_FontAspect aFontAspect = Font_FA_Undefined;
|
||||||
if (++anArgIter < theArgNb)
|
if (++anArgIter < theArgNb)
|
||||||
{
|
{
|
||||||
@ -5552,9 +5538,52 @@ static int VFont (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
@ -5664,6 +5693,43 @@ static int VFont (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6608,8 +6674,12 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
|
|||||||
theCommands.Add ("vfont",
|
theCommands.Add ("vfont",
|
||||||
"vfont [-add pathToFont [fontName] [regular,bold,italic,boldItalic=undefined] [singleStroke]]"
|
"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: [-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: [-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);
|
__FILE__, VFont, group);
|
||||||
|
|
||||||
theCommands.Add ("vvertexmode",
|
theCommands.Add ("vvertexmode",
|
||||||
|
26
tests/3rdparty/fonts/C4
vendored
Normal file
26
tests/3rdparty/fonts/C4
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
puts "================"
|
||||||
|
puts "0031118: Visualization - Font_FontMgr skips fonts with unknown styles like Narrow or Black"
|
||||||
|
puts "================"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
dtracelevel trace
|
||||||
|
pload VISUALIZATION
|
||||||
|
|
||||||
|
# Do the trick - find any pair of fonts with and without "Narrow" style suffix.
|
||||||
|
# On Windows it might be "Arial" and "Arial Narrow", on Linux "Liberation Sans" and "Liberation Sans Narrow".
|
||||||
|
vfont -verbose 1
|
||||||
|
set aFontN [vfont -strict -find "* Narrow"]
|
||||||
|
set aFontR [string map {" Narrow" ""} $aFontN]
|
||||||
|
vfont -strict -findInfo "$aFontN"
|
||||||
|
vfont -strict -findInfo "$aFontR"
|
||||||
|
|
||||||
|
vclear
|
||||||
|
vinit View1
|
||||||
|
vpoint p0 0 0 0
|
||||||
|
vpoint p1 0 10 0
|
||||||
|
vdrawtext t1 "My Text \[$aFontR\]" -font "$aFontR" -pos 0 5 0
|
||||||
|
vdrawtext t2 "My Text \[$aFontN\]" -font "$aFontN" -pos 0 6 0
|
||||||
|
vtop
|
||||||
|
vfit
|
||||||
|
|
||||||
|
vdump $imagedir/${casename}.png
|
Loading…
x
Reference in New Issue
Block a user