From 725ef85e1ed1cf3002a604fbb254839e725d4545 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 20 Nov 2013 13:40:36 +0400 Subject: [PATCH] 0024386: Provide high-level API to specify font by user-defined path for AIS (Prs3d) aspects Add new command vfont to access font manager. --- src/Font/Font_FontMgr.cdl | 12 ++ src/Font/Font_FontMgr.cxx | 79 ++++++- src/ViewerTest/ViewerTest_ObjectCommands.cxx | 205 +++++++++++++++++-- 3 files changed, 267 insertions(+), 29 deletions(-) diff --git a/src/Font/Font_FontMgr.cdl b/src/Font/Font_FontMgr.cdl index 616f095a16..33f807d7ff 100644 --- a/src/Font/Font_FontMgr.cdl +++ b/src/Font/Font_FontMgr.cdl @@ -78,6 +78,18 @@ is --- are not found in the system. ---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 Create returns FontMgr is private; diff --git a/src/Font/Font_FontMgr.cxx b/src/Font/Font_FontMgr.cxx index 9f71400d60..4f64e23561 100644 --- a/src/Font/Font_FontMgr.cxx +++ b/src/Font/Font_FontMgr.cxx @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -170,11 +171,11 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] = // function : checkFont // purpose : // ======================================================================= -static Handle(Font_SystemFont) checkFont (FT_Library theFTLib, - const Standard_CString theFontPath) +static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib, + const Standard_CString theFontPath) { 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) { return NULL; @@ -227,6 +228,64 @@ Font_FontMgr::Font_FontMgr() 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 // purpose : @@ -234,9 +293,9 @@ Font_FontMgr::Font_FontMgr() void Font_FontMgr::InitFontDataBase() { 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\" UINT aStrLength = GetSystemWindowsDirectoryA (NULL, 0); @@ -266,7 +325,7 @@ void Font_FontMgr::InitFontDataBase() aSupportedExtensions.Add (TCollection_AsciiString (anExt)); } - FT_Init_FreeType (&aFtLibrary); + aFtLibrary = new Font_FTLibrary(); static const DWORD aBufferSize = 256; char aNameBuff[aBufferSize]; char aPathBuff[aBufferSize]; @@ -383,7 +442,7 @@ void Font_FontMgr::InitFontDataBase() aSupportedExtensions.Add (TCollection_AsciiString (anExt)); } - FT_Init_FreeType (&aFtLibrary); + aFtLibrary = new Font_FTLibrary(); for (NCollection_Map::Iterator anIter (aMapOfFontsDirs); anIter.More(); anIter.Next()) { @@ -468,7 +527,6 @@ void Font_FontMgr::InitFontDataBase() aReadFile.Close(); } #endif - FT_Done_FreeType (aFtLibrary); } // ======================================================================= @@ -506,9 +564,8 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt return NULL; } - Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts); - - for (; aFontsIterator.More(); aFontsIterator.Next()) + for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts); + aFontsIterator.More(); aFontsIterator.Next()) { if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False)) { diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index fe6aa739ef..2dab66760d 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -76,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -4671,6 +4673,49 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&, 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 //purpose : Tool for conversion text to occt-shapes @@ -4701,37 +4746,27 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/, while (anArgIter < theArgNb) { 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()); } - else if (anArg.Search ("y=") > -1) + else if (anArgCase.Search ("y=") > -1) { aPenLoc.SetY (anArg.Token ("=", 2).RealValue()); } - else if (anArg.Search ("z=") > -1) + else if (anArgCase.Search ("z=") > -1) { aPenLoc.SetZ (anArg.Token ("=", 2).RealValue()); } - else if (anArg.Search ("composite=") > -1) + else if (anArgCase.Search ("composite=") > -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 { @@ -4751,6 +4786,136 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/, 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 //purpose : @@ -4890,4 +5055,8 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) 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", __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); }