diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 87e36e634..62df05c39 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -324,9 +324,10 @@ show(PyObject *self, PyObject *args) ////// makeWireString ///////// static PyObject * makeWireString(PyObject *self, PyObject *args) { - char* dir = "dDir"; //something is unhappy if these are uninit. not sure yet. + char* dir = "dDir"; //something is unhappy if these are uninit. not sure why yet. char* fontfile = "dFont"; char* text = "dText"; + const char* ctext = "cText"; float height; int track = 0; std::string sdir,sfontfile,stext; @@ -335,9 +336,10 @@ static PyObject * makeWireString(PyObject *self, PyObject *args) std::vector::iterator iWire; std::vector >:: iterator iChar; - PyObject *WireList, *CharList; -// not right for unicode strings. use format u? or O with check for ascii/ucs2(4)? - if (!PyArg_ParseTuple(args, "sssf|i", &text, + PyObject *WireList, *CharList, *intext; + Py_UNICODE *unichars; +// fixing unicode issues? + if (!PyArg_ParseTuple(args, "Ossf|i", &intext, &dir, &fontfile, &height, @@ -345,32 +347,58 @@ static PyObject * makeWireString(PyObject *self, PyObject *args) Base::Console().Message("** makeWireString bad args.\n"); return NULL; } - - try { - sdir = dir; - sfontfile = fontfile; - stext = text; - // ft2fc seems to work. let's leave it where it is for now while we get Py/FC internals working -// need to tell FT2FC if single byte or multi byte chars. - ret = FT2FC(stext,sdir,sfontfile,height,track); // get vector of wire chars -// int testret = TestSub(); - // if (ret not empty) - CharList = PyList_New(0); - for (iChar = ret.begin(); iChar !=ret.end(); ++iChar) { - WireList = PyList_New(0); - for (iWire = iChar->begin(); iWire != iChar->end(); ++iWire){ - PyObject* newobj = new TopoShapeWirePy(new TopoShape (*iWire)); - PyList_Append(WireList,newobj); - } - // if (list not empty) - PyList_Append(CharList,WireList); +// !@##$$%&^ unicode + if (PyString_Check(intext)) { + Base::Console().Message("** makeWireString obj is pystring.\n"); +// call c-string version + try { + text = PyString_AsString(intext); + int strsize = strlen(text); + Base::Console().Message("** makeWireString pystring len: %d\n", strsize); + sdir = dir; + sfontfile = fontfile; +// stext = text; + ret = FT2FCc(text,sdir,sfontfile,height,track); // get vector of wire chars + } + catch (Standard_DomainError) { + PyErr_SetString(PyExc_Exception, "makeWireString failed 1"); + return NULL; } - return (CharList); } - catch (Standard_DomainError) { - PyErr_SetString(PyExc_Exception, "makeWireString failed"); + else if (PyUnicode_Check(intext)) { + Base::Console().Message("** makeWireString obj is unicode.\n"); +// call ucs-2/4 version (Py_UNICODE object) + try { + Py_ssize_t pysize = PyUnicode_GetSize(intext); + unichars = PyUnicode_AS_UNICODE(intext); +// text = const_cast (PyUnicode_AS_DATA(intext)); //kludge + Base::Console().Message("** makeWireString unicode len: %d\n", pysize); + sdir = dir; + sfontfile = fontfile; + ret = FT2FCpu(unichars,pysize,sdir,sfontfile,height,track); // get vector of wire chars + } + catch (Standard_DomainError) { + PyErr_SetString(PyExc_Exception, "makeWireString failed 2"); + return NULL; + } + } + else { + Base::Console().Message("** makeWireString bad string.\n"); return NULL; + } + + // if (ret not empty) + CharList = PyList_New(0); + for (iChar = ret.begin(); iChar !=ret.end(); ++iChar) { + WireList = PyList_New(0); + for (iWire = iChar->begin(); iWire != iChar->end(); ++iWire){ + PyObject* newobj = new TopoShapeWirePy(new TopoShape (*iWire)); + PyList_Append(WireList,newobj); + } + // if (list not empty) + PyList_Append(CharList,WireList); } + return (CharList); } /////// makeWireString ///////// diff --git a/src/Mod/Part/App/FT2FC.cpp b/src/Mod/Part/App/FT2FC.cpp index f4ac72f81..3f21b5697 100644 --- a/src/Mod/Part/App/FT2FC.cpp +++ b/src/Mod/Part/App/FT2FC.cpp @@ -1,3 +1,5 @@ +#include "Python.h" + #include #include FT_FREETYPE_H #include FT_OUTLINE_H @@ -25,10 +27,13 @@ #include "FT2FC.h" +typedef unsigned long UNICHAR; // should be = Py_UNICODE?? +typedef std::vector > FT2FCRET; + // Private function prototypes -void getFTChar(char c); +void getFTChar(UNICHAR c); std::vector getGlyphContours(); -FT_Vector getKerning(char lc, char rc); +FT_Vector getKerning(UNICHAR lc, UNICHAR rc); TopoDS_Wire edgesToWire(std::vector Edges); bool DEBUG=true; @@ -38,7 +43,7 @@ struct FTDC_Ctx { // FT Decomp Context for 1 char std::vector Edges; int ConCnt; int SegCnt; - char currchar; + UNICHAR currchar; int penpos; float scalefactor; FT_Vector LastVert; @@ -145,7 +150,7 @@ static int cubic_cb(const FT_Vector* pt0, const FT_Vector* pt1, const FT_Vector* Poles.SetValue(2, c1); Poles.SetValue(3, c2); Poles.SetValue(4, v2); - Handle(Geom_BezierCurve) bcseg = new Geom_BezierCurve(Poles); // new? need to free this + Handle(Geom_BezierCurve) bcseg = new Geom_BezierCurve(Poles); // new? need to free this? BRepBuilderAPI_MakeEdge makeEdge(bcseg, v1, v2); TopoDS_Edge edge = makeEdge.Edge(); dc->Edges.push_back(edge); @@ -165,7 +170,7 @@ static FT_Outline_Funcs outline_funcs = { }; // load glyph outline into FTFont. return char's h-adv metric. -void getFTChar(FT_Face FTFont, char c) { +void getFTChar(FT_Face FTFont, UNICHAR c) { FT_Error error; FT_UInt flags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP; std::stringstream ErrorMsg; @@ -182,7 +187,7 @@ void getFTChar(FT_Face FTFont, char c) { // get kerning values for this char pair //TODO: should check FT_HASKERNING flag -FT_Vector getKerning(FT_Face FTFont, char lc, char rc) { +FT_Vector getKerning(FT_Face FTFont, UNICHAR lc, UNICHAR rc) { FT_Vector retXY; FT_Error error; std::stringstream ErrorMsg; @@ -200,7 +205,7 @@ FT_Vector getKerning(FT_Face FTFont, char lc, char rc) { } // get glyph outline for current char -std::vector getGlyphContours(FT_Face FTFont, char currchar, int PenPos, float Scale) { +std::vector getGlyphContours(FT_Face FTFont, UNICHAR currchar, int PenPos, float Scale) { FT_Error error = 0; std::stringstream ErrorMsg; FT_Outline* FTOPointer; @@ -233,7 +238,8 @@ std::vector getGlyphContours(FT_Face FTFont, char currchar, int Pen } // get string's wires (contours) in FC/OCC coords -std::vector > FT2FC(const std::string shapestring, +//std::vector > FT2FC(const std::string shapestring, +FT2FCRET _FT2FC(const std::vector stringvec, const std::string FontPath, const std::string FontName, const float stringheight, // in fc coords @@ -247,11 +253,11 @@ std::vector > FT2FC(const std::string shapestring, std::stringstream ErrorMsg; float scalefactor; - char prevchar,currchar; + UNICHAR prevchar,currchar; int cadv,PenPos; - size_t i; + size_t i, length; std::vector CharWires; - std::vector > RetString; + FT2FCRET RetString; std::cout << "FT2FC started: "<< FontPath << std::endl; @@ -293,15 +299,18 @@ std::vector > FT2FC(const std::string shapestring, prevchar = 0; PenPos = 0; scalefactor = float(stringheight/FTFont->height); - for (i=0;iglyph->advance.x; kern = getKerning(FTFont,prevchar,currchar); PenPos += kern.x; CharWires = getGlyphContours(FTFont,currchar,PenPos, scalefactor); if (CharWires.empty()) // whitespace char - std::cout << "Char " << i << " = " << currchar << " has no wires! " << std::endl; + std::cout << "char " << i << " = " << hex << std::showbase << currchar << " has no wires! " << std::endl; else RetString.push_back(CharWires); // not entirely happy with tracking solution. It's specified in FC units, @@ -320,4 +329,32 @@ std::vector > FT2FC(const std::string shapestring, return(RetString); } + +FT2FCRET FT2FCc(const char *cstring, + const std::string FontPath, + const std::string FontName, + const float stringheight, // in fc coords + const int tracking) { // in fc coords) + size_t i, length; + length = strlen(cstring); + std::vector stringvec(length, 0); + for (i=0;i stringvec(length, 0); + for (i=0;i > FT2FC(const std::string shapestring, +// public functions +std::vector > FT2FCc(const char *cstring, const std::string FontPath, const std::string FontName, const float stringheight, const int tracking); +std::vector > FT2FCpu(const Py_UNICODE *unichars, +//std::vector > FT2FCpu(const char16_t *unichars, + const size_t length, + const std::string FontPath, + const std::string FontName, + const float stringheight, + const int tracking); #endif // FT2FC_H