From 80da187cd792b3a48042aa00298b95e9edf93129 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 26 Jan 2023 18:25:37 -0800 Subject: [PATCH] [Part][Draft]fix #8271 temporary files on windows --- src/Mod/Part/App/AppPartPy.cpp | 12 ------- src/Mod/Part/App/FT2FC.cpp | 64 ++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 8bc500d7dd..4f96492aef 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -2062,19 +2062,7 @@ private: try { if (useFontSpec) { -#ifdef FC_OS_WIN32 -// Windows doesn't do Utf8 by default and FreeType doesn't do wchar. -// this is a hacky work around. -// copy fontspec to Ascii temp name - std::string tempFile = Base::FileInfo::getTempFileName(); //utf8/ascii - Base::FileInfo fiIn(fontspec); - fiIn.copyTo(tempFile.c_str()); - CharList = FT2FC(unichars,pysize,tempFile.c_str(),height,track); - Base::FileInfo fiTemp(tempFile); - fiTemp.deleteFile(); -#else CharList = FT2FC(unichars,pysize,fontspec,height,track); -#endif } else { CharList = FT2FC(unichars,pysize,dir,fontfile,height,track); diff --git a/src/Mod/Part/App/FT2FC.cpp b/src/Mod/Part/App/FT2FC.cpp index 9a1692f3cd..97ae5a92c2 100644 --- a/src/Mod/Part/App/FT2FC.cpp +++ b/src/Mod/Part/App/FT2FC.cpp @@ -80,8 +80,8 @@ using namespace Part; using UNICHAR = unsigned long; // ul is FT2's codepoint type <=> Py_UNICODE2/4 // Private function prototypes -PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, double Scale,int charNum, double tracking); -FT_Vector getKerning(FT_Face FTFont, UNICHAR lc, UNICHAR rc); +PyObject* getGlyphContours(FT_Face FTFace, UNICHAR currchar, double PenPos, double Scale,int charNum, double tracking); +FT_Vector getKerning(FT_Face FTFace, UNICHAR lc, UNICHAR rc); TopoDS_Wire edgesToWire(std::vector Edges); int calcClockDir(std::vector points); @@ -107,7 +107,7 @@ PyObject* FT2FC(const Py_UNICODE *PyUString, const double tracking) // fc coords { FT_Library FTLib; - FT_Face FTFont; + FT_Face FTFace; FT_Error error; FT_Long FaceIndex = 0; // some fonts have multiple faces FT_Vector kern; @@ -126,34 +126,38 @@ PyObject* FT2FC(const Py_UNICODE *PyUString, throw std::runtime_error(ErrorMsg.str()); } -#ifdef FC_OS_WIN32 - Base::FileInfo fi(FontSpec); - if (!fi.isReadable()) { - ErrorMsg << "Font file not found (Win): " << FontSpec; + std::ifstream fontfile; + fontfile.open(FontSpec, std::ios::binary|std::ios::in); + if (!fontfile.is_open()) { + //get indignant + ErrorMsg << "Can not open font file: " << FontSpec; throw std::runtime_error(ErrorMsg.str()); } -#else - // FT does not return an error if font file not found? - std::ifstream is; - is.open (FontSpec); - if (!is) { - ErrorMsg << "Font file not found: " << FontSpec; + fontfile.seekg (0, fontfile.end); + int bytesNeeded = fontfile.tellg(); + fontfile.clear(); + fontfile.seekg (0, fontfile.beg); + char* buffer = new char[bytesNeeded]; + fontfile.read(buffer, bytesNeeded); + if (!fontfile) { + //get indignant + ErrorMsg << "Can not read font file: " << FontSpec; throw std::runtime_error(ErrorMsg.str()); } -#endif + fontfile.close(); - - error = FT_New_Face(FTLib,FontSpec,FaceIndex, &FTFont); + const FT_Byte* ftBuffer = reinterpret_cast(buffer); + error = FT_New_Memory_Face(FTLib, ftBuffer, bytesNeeded, FaceIndex, &FTFace); if (error) { ErrorMsg << "FT_New_Face failed: " << error; throw std::runtime_error(ErrorMsg.str()); } - //TODO: check that FTFont is scalable? only relevant for hinting etc? + //TODO: check that FTFace is scalable? only relevant for hinting etc? // FT2 blows up if char size is not set to some non-zero value. // This sets size to 48 point. Magic. - error = FT_Set_Char_Size(FTFont, + error = FT_Set_Char_Size(FTFace, 0, /* char_width in 1/64th of points */ 48*64*10, /* char_height in 1/64th of points */ // increased 10X to preserve very small details 0, /* horizontal device resolution */ @@ -163,10 +167,10 @@ PyObject* FT2FC(const Py_UNICODE *PyUString, throw std::runtime_error(ErrorMsg.str()); } - scalefactor = (stringheight/float(FTFont->height))/10; // divide scale by 10 to offset the 10X increased scale in FT_Set_Char_Size above + scalefactor = (stringheight/float(FTFace->height))/10; // divide scale by 10 to offset the 10X increased scale in FT_Set_Char_Size above for (i=0; iglyph->advance.x; - kern = getKerning(FTFont,prevchar,currchar); + cadv = FTFace->glyph->advance.x; + kern = getKerning(FTFace,prevchar,currchar); PenPos += kern.x; try { - Py::List WireList(getGlyphContours(FTFont, currchar, PenPos, scalefactor, i, tracking), true); + Py::List WireList(getGlyphContours(FTFace, currchar, PenPos, scalefactor, i, tracking), true); CharList.append(WireList); } catch (Py::Exception& e) { @@ -312,7 +316,7 @@ static FT_Outline_Funcs FTcbFuncs = { //********** FT2FC Helpers // get glyph outline in wires -PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, double Scale, int charNum, double tracking) { +PyObject* getGlyphContours(FT_Face FTFace, UNICHAR currchar, double PenPos, double Scale, int charNum, double tracking) { FT_Error error = 0; std::stringstream ErrorMsg; gp_Pnt origin = gp_Pnt(0.0,0.0,0.0); @@ -321,7 +325,7 @@ PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, doub ctx.currchar = currchar; ctx.surf = new Geom_Plane(origin,gp::DZ()); - error = FT_Outline_Decompose(&FTFont->glyph->outline, + error = FT_Outline_Decompose(&FTFace->glyph->outline, &FTcbFuncs, &ctx); if(error) { @@ -339,7 +343,7 @@ PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, doub //an occ outer contour has material on the left, so it must be reversed? - FT_Orientation ftOrient = FT_Outline_Get_Orientation(&FTFont->glyph->outline); + FT_Orientation ftOrient = FT_Outline_Get_Orientation(&FTFace->glyph->outline); bool isTTF = false; if (ftOrient == FT_ORIENTATION_TRUETYPE) { isTTF = true; @@ -384,14 +388,14 @@ PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, doub // get kerning values for this char pair //TODO: should check FT_HASKERNING flag? returns (0,0) if no kerning? -FT_Vector getKerning(FT_Face FTFont, UNICHAR lc, UNICHAR rc) { +FT_Vector getKerning(FT_Face FTFace, UNICHAR lc, UNICHAR rc) { FT_Vector retXY; FT_Error error; std::stringstream ErrorMsg; FT_Vector ftKern; - FT_UInt lcx = FT_Get_Char_Index(FTFont, lc); - FT_UInt rcx = FT_Get_Char_Index(FTFont, rc); - error = FT_Get_Kerning(FTFont,lcx,rcx,FT_KERNING_DEFAULT,&ftKern); + FT_UInt lcx = FT_Get_Char_Index(FTFace, lc); + FT_UInt rcx = FT_Get_Char_Index(FTFace, rc); + error = FT_Get_Kerning(FTFace,lcx,rcx,FT_KERNING_DEFAULT,&ftKern); if(error) { ErrorMsg << "FT_Get_Kerning failed: " << error; throw std::runtime_error(ErrorMsg.str());