[Part][Draft]fix #8271 temporary files on windows

This commit is contained in:
wandererfan
2023-01-26 18:25:37 -08:00
committed by WandererFan
parent 633a6e825c
commit c318bc08cb
2 changed files with 34 additions and 42 deletions

View File

@@ -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);

View File

@@ -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<TopoDS_Edge> Edges);
int calcClockDir(std::vector<Base::Vector3d> 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<FT_Byte*>(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; i<length; i++) {
currchar = PyUString[i];
error = FT_Load_Char(FTFont,
error = FT_Load_Char(FTFace,
currchar,
FTLoadFlags);
if (error) {
@@ -174,11 +178,11 @@ PyObject* FT2FC(const Py_UNICODE *PyUString,
throw std::runtime_error(ErrorMsg.str());
}
cadv = FTFont->glyph->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());