Skip to content

Commit

Permalink
[Part][Draft]fix #8271 temporary files on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan committed Jan 28, 2023
1 parent 633a6e8 commit c318bc0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 42 deletions.
12 changes: 0 additions & 12 deletions src/Mod/Part/App/AppPartPy.cpp
Expand Up @@ -2062,19 +2062,7 @@ class Module : public Py::ExtensionModule<Module>

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);
Expand Down
64 changes: 34 additions & 30 deletions src/Mod/Part/App/FT2FC.cpp
Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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 */
Expand All @@ -163,22 +167,22 @@ 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) {
ErrorMsg << "FT_Load_Char failed: " << error;
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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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());
Expand Down

0 comments on commit c318bc0

Please sign in to comment.