1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024386: Provide high-level API to specify font by user-defined path for AIS (Prs3d) aspects

Add new command vfont to access font manager.
This commit is contained in:
kgv 2013-11-20 13:40:36 +04:00 committed by bugmaster
parent 4889b44e3e
commit 725ef85e1e
3 changed files with 267 additions and 29 deletions

View File

@ -78,6 +78,18 @@ is
--- are not found in the system. --- are not found in the system.
---Level: Public ---Level: Public
CheckFont (me; theFontPath : CString from Standard) returns SystemFont;
---Purpose: Read font file and retrieve information from it.
---Level: Public
RegisterFont (me : mutable;
theFont : SystemFont;
theToOverride : Boolean from Standard) returns Boolean from Standard;
---Purpose: Register new font.
--- If there is existing entity with the same name and properties but different path
--- then font will will be overridden or ignored depending on theToOverride flag.
---Level: Public
--- Private methods --- Private methods
Create returns FontMgr is private; Create returns FontMgr is private;

View File

@ -19,6 +19,7 @@
#include <Font_FontMgr.ixx> #include <Font_FontMgr.ixx>
#include <Font_FTLibrary.hxx>
#include <OSD_Environment.hxx> #include <OSD_Environment.hxx>
#include <NCollection_List.hxx> #include <NCollection_List.hxx>
#include <NCollection_Map.hxx> #include <NCollection_Map.hxx>
@ -170,11 +171,11 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
// function : checkFont // function : checkFont
// purpose : // purpose :
// ======================================================================= // =======================================================================
static Handle(Font_SystemFont) checkFont (FT_Library theFTLib, static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib,
const Standard_CString theFontPath) const Standard_CString theFontPath)
{ {
FT_Face aFontFace; FT_Face aFontFace;
FT_Error aFaceError = FT_New_Face (theFTLib, 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 NULL;
@ -227,6 +228,64 @@ Font_FontMgr::Font_FontMgr()
InitFontDataBase(); InitFontDataBase();
} }
// =======================================================================
// function : CheckFont
// purpose :
// =======================================================================
Handle(Font_SystemFont) Font_FontMgr::CheckFont (Standard_CString theFontPath) const
{
Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
return checkFont (aFtLibrary, theFontPath);
}
// =======================================================================
// function : RegisterFont
// purpose :
// =======================================================================
Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theFont,
const Standard_Boolean theToOverride)
{
if (theFont.IsNull())
{
return Standard_False;
}
for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
aFontIter.More(); aFontIter.Next())
{
if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
{
continue;
}
if (theFont->FontAspect() != Font_FA_Undefined
&& aFontIter.Value()->FontAspect() != theFont->FontAspect())
{
continue;
}
if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
|| theFont->FontHeight() == aFontIter.Value()->FontHeight())
{
if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
{
return Standard_True;
}
else if (theToOverride)
{
myListOfFonts.Remove (aFontIter);
}
else
{
return Standard_False;
}
}
}
myListOfFonts.Append (theFont);
return Standard_True;
}
// ======================================================================= // =======================================================================
// function : InitFontDataBase // function : InitFontDataBase
// purpose : // purpose :
@ -234,9 +293,9 @@ Font_FontMgr::Font_FontMgr()
void Font_FontMgr::InitFontDataBase() void Font_FontMgr::InitFontDataBase()
{ {
myListOfFonts.Clear(); myListOfFonts.Clear();
FT_Library aFtLibrary = NULL; Handle(Font_FTLibrary) aFtLibrary;
#if (defined(_WIN32) || defined(__WIN32__)) #if defined(_WIN32)
// font directory is placed in "C:\Windows\Fonts\" // font directory is placed in "C:\Windows\Fonts\"
UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0); UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0);
@ -266,7 +325,7 @@ void Font_FontMgr::InitFontDataBase()
aSupportedExtensions.Add (TCollection_AsciiString (anExt)); aSupportedExtensions.Add (TCollection_AsciiString (anExt));
} }
FT_Init_FreeType (&aFtLibrary); aFtLibrary = new Font_FTLibrary();
static const DWORD aBufferSize = 256; static const DWORD aBufferSize = 256;
char aNameBuff[aBufferSize]; char aNameBuff[aBufferSize];
char aPathBuff[aBufferSize]; char aPathBuff[aBufferSize];
@ -383,7 +442,7 @@ void Font_FontMgr::InitFontDataBase()
aSupportedExtensions.Add (TCollection_AsciiString (anExt)); aSupportedExtensions.Add (TCollection_AsciiString (anExt));
} }
FT_Init_FreeType (&aFtLibrary); aFtLibrary = new Font_FTLibrary();
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs); for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
anIter.More(); anIter.Next()) anIter.More(); anIter.Next())
{ {
@ -468,7 +527,6 @@ void Font_FontMgr::InitFontDataBase()
aReadFile.Close(); aReadFile.Close();
} }
#endif #endif
FT_Done_FreeType (aFtLibrary);
} }
// ======================================================================= // =======================================================================
@ -506,9 +564,8 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt
return NULL; return NULL;
} }
Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts); for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
aFontsIterator.More(); aFontsIterator.Next())
for (; aFontsIterator.More(); aFontsIterator.Next())
{ {
if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False)) if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
{ {

View File

@ -33,6 +33,7 @@
#include <DBRep.hxx> #include <DBRep.hxx>
#include <Font_BRepFont.hxx> #include <Font_BRepFont.hxx>
#include <Font_FontMgr.hxx>
#include <OSD_Chronometer.hxx> #include <OSD_Chronometer.hxx>
#include <TCollection_AsciiString.hxx> #include <TCollection_AsciiString.hxx>
#include <Visual3d_View.hxx> #include <Visual3d_View.hxx>
@ -76,6 +77,7 @@
#include <Geom_Plane.hxx> #include <Geom_Plane.hxx>
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
#include <TCollection_ExtendedString.hxx> #include <TCollection_ExtendedString.hxx>
#include <TCollection_HAsciiString.hxx>
#include <GC_MakePlane.hxx> #include <GC_MakePlane.hxx>
#include <gp_Circ.hxx> #include <gp_Circ.hxx>
#include <AIS_Axis.hxx> #include <AIS_Axis.hxx>
@ -4671,6 +4673,49 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&,
return 0; return 0;
} }
//! Auxiliary function to parse font aspect style argument
static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
Font_FontAspect& theAspect)
{
if (theArg == "regular"
|| *theArg.ToCString() == 'r')
{
theAspect = Font_FA_Regular;
return Standard_True;
}
else if (theArg == "bolditalic")
{
theAspect = Font_FA_BoldItalic;
return Standard_True;
}
else if (theArg == "bold"
|| *theArg.ToCString() == 'b')
{
theAspect = Font_FA_Bold;
return Standard_True;
}
else if (theArg == "italic"
|| *theArg.ToCString() == 'i')
{
theAspect = Font_FA_Italic;
return Standard_True;
}
return Standard_False;
}
//! Auxiliary function
static TCollection_AsciiString fontStyleString (const Font_FontAspect theAspect)
{
switch (theAspect)
{
case Font_FA_Regular: return "regular";
case Font_FA_BoldItalic: return "bolditalic";
case Font_FA_Bold: return "bold";
case Font_FA_Italic: return "italic";
default: return "undefined";
}
}
//======================================================================= //=======================================================================
//function : TextToBrep //function : TextToBrep
//purpose : Tool for conversion text to occt-shapes //purpose : Tool for conversion text to occt-shapes
@ -4701,37 +4746,27 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
while (anArgIter < theArgNb) while (anArgIter < theArgNb)
{ {
const TCollection_AsciiString anArg (theArgVec[anArgIter++]); const TCollection_AsciiString anArg (theArgVec[anArgIter++]);
if (anArg.Search ("x=") > -1) TCollection_AsciiString anArgCase (anArg);
anArgCase.LowerCase();
if (anArgCase.Search ("x=") > -1)
{ {
aPenLoc.SetX (anArg.Token ("=", 2).RealValue()); aPenLoc.SetX (anArg.Token ("=", 2).RealValue());
} }
else if (anArg.Search ("y=") > -1) else if (anArgCase.Search ("y=") > -1)
{ {
aPenLoc.SetY (anArg.Token ("=", 2).RealValue()); aPenLoc.SetY (anArg.Token ("=", 2).RealValue());
} }
else if (anArg.Search ("z=") > -1) else if (anArgCase.Search ("z=") > -1)
{ {
aPenLoc.SetZ (anArg.Token ("=", 2).RealValue()); aPenLoc.SetZ (anArg.Token ("=", 2).RealValue());
} }
else if (anArg.Search ("composite=") > -1) else if (anArgCase.Search ("composite=") > -1)
{ {
isCompositeCurve = (anArg.Token ("=", 2).IntegerValue() == 1); isCompositeCurve = (anArg.Token ("=", 2).IntegerValue() == 1);
} }
else if (anArg.Search ("regular") > -1) else if (parseFontStyle (anArgCase, aFontAspect))
{ {
aFontAspect = Font_FA_Regular; //
}
else if (anArg.Search ("bolditalic") > -1)
{
aFontAspect = Font_FA_BoldItalic;
}
else if (anArg.Search ("bold") > -1)
{
aFontAspect = Font_FA_Bold;
}
else if (anArg.Search ("italic") > -1)
{
aFontAspect = Font_FA_Italic;
} }
else else
{ {
@ -4751,6 +4786,136 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
return 0; return 0;
} }
//=======================================================================
//function : VFont
//purpose : Font management
//=======================================================================
static int VFont (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
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;
for (Font_NListOfSystemFont::Iterator anIter (aMgr->GetAvailableFonts());
anIter.More(); anIter.Next())
{
const Handle(Font_SystemFont)& aFont = anIter.Value();
if (!isFirst)
{
theDI << "\n";
}
theDI << aFont->FontName()->String()
<< " " << fontStyleString (aFont->FontAspect())
<< " " << aFont->FontPath()->String();
isFirst = Standard_False;
}
return 0;
}
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
const TCollection_AsciiString anArg (theArgVec[anArgIter]);
TCollection_AsciiString anArgCase (anArg);
anArgCase.LowerCase();
if (anArgCase == "find")
{
if (++anArgIter >= theArgNb)
{
std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
return 1;
}
Standard_CString aFontName = theArgVec[anArgIter];
Font_FontAspect aFontAspect = Font_FA_Undefined;
if (++anArgIter < theArgNb)
{
anArgCase = theArgVec[anArgIter];
anArgCase.LowerCase();
if (!parseFontStyle (anArgCase, aFontAspect))
{
--anArgIter;
}
}
Handle(Font_SystemFont) aFont = aMgr->FindFont (new TCollection_HAsciiString (aFontName), aFontAspect, -1);
if (aFont.IsNull())
{
std::cerr << "Error: font '" << aFontName << "' is not found!\n";
continue;
}
theDI << aFont->FontName()->String()
<< " " << fontStyleString (aFont->FontAspect())
<< " " << aFont->FontPath()->String();
}
else if (anArgCase == "add"
|| anArgCase == "register")
{
if (++anArgIter >= theArgNb)
{
std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
return 1;
}
Standard_CString aFontPath = theArgVec[anArgIter];
Standard_CString aFontName = NULL;
Font_FontAspect aFontAspect = Font_FA_Undefined;
if (++anArgIter < theArgNb)
{
if (!parseFontStyle (anArgCase, aFontAspect))
{
aFontName = theArgVec[anArgIter];
}
if (++anArgIter < theArgNb)
{
anArgCase = theArgVec[anArgIter];
anArgCase.LowerCase();
if (!parseFontStyle (anArgCase, aFontAspect))
{
--anArgIter;
}
}
}
Handle(Font_SystemFont) aFont = aMgr->CheckFont (aFontPath);
if (aFont.IsNull())
{
std::cerr << "Error: font '" << aFontPath << "' is not found!\n";
continue;
}
if (aFontAspect != Font_FA_Undefined
|| aFontName != NULL)
{
if (aFontAspect == Font_FA_Undefined)
{
aFontAspect = aFont->FontAspect();
}
Handle(TCollection_HAsciiString) aName = aFont->FontName();
if (aFontName != NULL)
{
aName = new TCollection_HAsciiString (aFontName);
}
aFont = new Font_SystemFont (aName, aFontAspect, new TCollection_HAsciiString (aFontPath));
}
aMgr->RegisterFont (aFont, Standard_True);
theDI << aFont->FontName()->String()
<< " " << fontStyleString (aFont->FontAspect())
<< " " << aFont->FontPath()->String();
}
else
{
std::cerr << "Warning! Unknown argument '" << anArg.ToCString() << "'\n";
}
}
return 0;
}
//======================================================================= //=======================================================================
//function : ObjectsCommands //function : ObjectsCommands
//purpose : //purpose :
@ -4890,4 +5055,8 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
theCommands.Add ("text2brep", theCommands.Add ("text2brep",
"text2brep: res text fontName fontSize [x=0.0 y=0.0 z=0.0 composite=1 {regular,bold,italic,bolditalic=regular}]\n", "text2brep: res text fontName fontSize [x=0.0 y=0.0 z=0.0 composite=1 {regular,bold,italic,bolditalic=regular}]\n",
__FILE__, TextToBRep, group); __FILE__, TextToBRep, group);
theCommands.Add ("vfont",
"vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]"
"\n\t\t: [find fontName [regular,bold,italic,bolditalic=undefined]]",
__FILE__, VFont, group);
} }