X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fglyphpoints.cpp;h=025f0e1ef3fde7be1c709ee943ada7084d23e7d9;hb=refs%2Fheads%2Fmaster;hp=d0402f6fe041ddc800a29b03db00a24c53d9439f;hpb=c84263bb8b0d16e4c6da49aa0b7d0bc904ae02b1;p=ttedit diff --git a/src/glyphpoints.cpp b/src/glyphpoints.cpp old mode 100755 new mode 100644 index d0402f6..025f0e1 --- a/src/glyphpoints.cpp +++ b/src/glyphpoints.cpp @@ -10,7 +10,7 @@ // JLH = James L. Hammons // // Who When What -// --- ---------- ------------------------------------------------------------ +// --- ---------- ----------------------------------------------------------- // JLH ??/??/200? Created this file // JLH 05/18/2004 Added pure point adding, inserting, better polygon handling // @@ -22,6 +22,8 @@ #ifdef DEBUG #include "debug.h" #endif +#include + /*GlyphPoints::GlyphPoints(void) { @@ -29,16 +31,16 @@ }*/ GlyphPoints::GlyphPoints(int nPts/*=0*/, int nPlys/*=0*/, int * xa/*=null*/, int * ya/*=null*/, - bool * oca/*=null*/, uint16 * pa/*=null*/): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL) + bool * oca/*=null*/, uint16_t * pa/*=null*/): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL) //GlyphPoints::GlyphPoints(int nPts, int nPlys/*=0*/, int * xa/*=null*/, int * ya/*=null*/, -// bool * oca/*=null*/, uint16 * pa/*=null*/): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL) +// bool * oca/*=null*/, uint16_t * pa/*=null*/): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL) { AllocateAndCopy(nPts, nPlys, xa, ya, oca, pa); if (nPlys == 0) { numPolys = 1; - polyEnd = new uint16[numPolys]; + polyEnd = new uint16_t[numPolys]; polyEnd[0] = numPoints - 1; } #ifdef DEBUG @@ -46,6 +48,7 @@ WriteLogMsg("GlyphPoints: Default constructor. %u points, %u polys.\n", numPoint #endif } + GlyphPoints::GlyphPoints(int xx, int yy, bool oc) { //Hmm. What to do with this...? @@ -55,6 +58,7 @@ WriteLogMsg("GlyphPoints: Single point constructor. %u points, %u polys.\n", num #endif } + // Copy constructor (needed for deep copying) //GlyphPoints::GlyphPoints(GlyphPoints &c): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL) @@ -66,22 +70,14 @@ WriteLogMsg("GlyphPoints: Copy constructor. %u points, %u polys.\n", numPoints, #endif } + GlyphPoints::~GlyphPoints() { - if (x) - delete[] x; - - if (y) - delete[] y; - - if (onCurve) - delete[] onCurve; - - if (polyEnd) - delete[] polyEnd; + FreeAllocatedMemory(); } -void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool * oca, uint16 * pa) + +void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool * oca, uint16_t * pa) { numPoints = nPts, numPolys = nPlys; @@ -106,7 +102,7 @@ void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool if (numPolys) { - polyEnd = new uint16[numPolys]; + polyEnd = new uint16_t[numPolys]; if (pa) // Copy poly ends in if they're passed in... for(int i=0; i numPoints) // > because we can insert at end...! throw GP_OUT_OF_RANGE; @@ -230,11 +251,10 @@ void GlyphPoints::InsertPoint(uint16 pt, int xx, int yy, bool oc) totX[pt] = xx, totY[pt] = yy, totOnCurve[pt] = oc; -//A way to fix the kludge in GetPoly() would be to put a check here to see if +//A way to fix the kludge in GetPoly() would be to put a check here to see if //we're adding to the end of the structure: [DONE, below] int polyInsert = (pt == numPoints ? numPolys - 1 : GetPoly(pt)); for(int i=polyInsert; i= numPolys) #ifdef DEBUG { -WriteLogMsg("Exception: GetNumPoints(uint16). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +WriteLogMsg("Exception: GetNumPoints(uint16_t). poly=%u, numPolys=%u\xD\xA", poly, numPolys); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -303,17 +327,19 @@ WriteLogMsg("Exception: GetNumPoints(uint16). poly=%u, numPolys=%u\xD\xA", poly, return polyEnd[poly] - (poly == 0 ? -1 : polyEnd[poly - 1]); } -uint16 GlyphPoints::GetNumPolys(void) + +uint16_t GlyphPoints::GetNumPolys(void) { return numPolys; } -int GlyphPoints::GetX(uint16 pt) + +int GlyphPoints::GetX(uint16_t pt) { if (pt >= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: GetX(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: GetX(uint16_t). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -323,12 +349,13 @@ WriteLogMsg("Exception: GetX(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints) return x[pt]; } -int GlyphPoints::GetY(uint16 pt) + +int GlyphPoints::GetY(uint16_t pt) { if (pt >= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: GetY(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: GetY(uint16_t). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -338,12 +365,29 @@ WriteLogMsg("Exception: GetY(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints) return y[pt]; } -bool GlyphPoints::GetOnCurve(uint16 pt) + +Vector GlyphPoints::GetXY(uint16_t pt) { if (pt >= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: GetOnCurve(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: GetXY(uint16_t). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +#endif + throw GP_OUT_OF_RANGE; +#ifdef DEBUG +} +#endif + + return Vector(x[pt], y[pt]); +} + + +bool GlyphPoints::GetOnCurve(uint16_t pt) +{ + if (pt >= numPoints) +#ifdef DEBUG +{ +WriteLogMsg("Exception: GetOnCurve(uint16_t). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -353,12 +397,13 @@ WriteLogMsg("Exception: GetOnCurve(uint16). pt=%u, numPoints=%u\xD\xA", pt, numP return onCurve[pt]; } -int GlyphPoints::GetX(uint16 poly, uint16 pt) + +int GlyphPoints::GetX(uint16_t poly, uint16_t pt) { if (pt >= GetNumPoints(poly)) #ifdef DEBUG { -WriteLogMsg("Exception: GetX(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); +WriteLogMsg("Exception: GetX(uint16_t, uint16_t). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -368,12 +413,19 @@ WriteLogMsg("Exception: GetX(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\x return x[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)]; } -int GlyphPoints::GetY(uint16 poly, uint16 pt) + +int GlyphPoints::GetNextX(uint16_t poly, uint16_t pt) +{ + return GetX(poly, GetNext(poly, pt)); +} + + +int GlyphPoints::GetY(uint16_t poly, uint16_t pt) { if (pt >= GetNumPoints(poly)) #ifdef DEBUG { -WriteLogMsg("Exception: GetY(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); +WriteLogMsg("Exception: GetY(uint16_t, uint16_t). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -383,12 +435,34 @@ WriteLogMsg("Exception: GetY(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\x return y[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)]; } -bool GlyphPoints::GetOnCurve(uint16 poly, uint16 pt) + +int GlyphPoints::GetNextY(uint16_t poly, uint16_t pt) +{ + return GetY(poly, GetNext(poly, pt)); +} + + +IPoint GlyphPoints::GetPoint(uint16_t poly, uint16_t pt) +{ + return IPoint(GetX(poly, pt), GetY(poly, pt), GetOnCurve(poly, pt)); +} + + +IPoint GlyphPoints::GetPoint(uint16_t pointNumber) +{ + if (pointNumber > numPoints) + throw GP_OUT_OF_RANGE; + + return IPoint(x[pointNumber], y[pointNumber], onCurve[pointNumber]); +} + + +bool GlyphPoints::GetOnCurve(uint16_t poly, uint16_t pt) { if (pt >= GetNumPoints(poly)) #ifdef DEBUG { -WriteLogMsg("Exception: GetOnCurve(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); +WriteLogMsg("Exception: GetOnCurve(uint16_t, uint16_t). poly= %u, pt=%u, numPoints=%u\xD\xA", poly, pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -398,12 +472,42 @@ WriteLogMsg("Exception: GetOnCurve(uint16, uint16). poly= %u, pt=%u, numPoints=% return onCurve[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)]; } -uint16 GlyphPoints::GetPolyEnd(uint16 poly) + +bool GlyphPoints::GetPrevOnCurve(uint16_t poly, uint16_t pt) +{ + return GetOnCurve(poly, GetPrev(poly, pt)); +} + + +bool GlyphPoints::GetNextOnCurve(uint16_t poly, uint16_t pt) +{ + return GetOnCurve(poly, GetNext(poly, pt)); +} + + +uint16_t GlyphPoints::GetPolyStart(uint16_t poly) { if (poly >= numPolys) #ifdef DEBUG { -WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +WriteLogMsg("Exception: GetPolyEnd(uint16_t). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +#endif + throw GP_OUT_OF_RANGE; +#ifdef DEBUG +} +#endif + + // If it's poly 0, return 0. Otherwise, get the previous poly's end & add one to it + return (poly == 0 ? 0 : polyEnd[poly - 1] + 1); +} + + +uint16_t GlyphPoints::GetPolyEnd(uint16_t poly) +{ + if (poly >= numPolys) +#ifdef DEBUG +{ +WriteLogMsg("Exception: GetPolyEnd(uint16_t). poly=%u, numPolys=%u\xD\xA", poly, numPolys); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -413,33 +517,36 @@ WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, n return polyEnd[poly]; } + void GlyphPoints::OffsetPoints(int xOff, int yOff) { for(int i=0; i= numPolys) #ifdef DEBUG { -WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +WriteLogMsg("Exception: GetPolyEnd(uint16_t). poly=%u, numPolys=%u\xD\xA", poly, numPolys); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG } #endif - uint16 polyStart = (poly == 0 ? 0 : polyEnd[poly - 1] + 1); + uint16_t polyStart = (poly == 0 ? 0 : polyEnd[poly - 1] + 1); for(int i=0; i= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: SetXY(uint16, int, int). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: SetXY(uint16_t, int, int). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -462,12 +570,13 @@ WriteLogMsg("Exception: SetXY(uint16, int, int). pt=%u, numPoints=%u\xD\xA", pt, x[pt] = xx, y[pt] = yy; } -void GlyphPoints::SetOnCurve(uint16 pt, bool oc) + +void GlyphPoints::SetOnCurve(uint16_t pt, bool oc) { if (pt >= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: SetOnCurve(uint16, bool). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: SetOnCurve(uint16_t, bool). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -477,10 +586,27 @@ WriteLogMsg("Exception: SetOnCurve(uint16, bool). pt=%u, numPoints=%u\xD\xA", pt onCurve[pt] = oc; } -uint16 GlyphPoints::GetPrev(uint16 pt) + +void GlyphPoints::SetPoint(const uint16_t pointNum, const IPoint point) +{ + if (pointNum >= numPoints) +#ifdef DEBUG +{ +WriteLogMsg("Exception: SetPoint(uint16_t, IPoint). pt=%u, numPoints=%u\xD\xA", pointNum, numPoints); +#endif + throw GP_OUT_OF_RANGE; +#ifdef DEBUG +} +#endif + + x[pointNum] = point.x, y[pointNum] = point.y, onCurve[pointNum] = point.onCurve; +} + + +uint16_t GlyphPoints::GetPrev(uint16_t pt) { // pt = 7, polyEnd = 4, 9, 15 - uint16 min = 0, max = numPoints - 1; + uint16_t min = 0, max = numPoints - 1; for(int i=0; i= numPoints) #ifdef DEBUG { -WriteLogMsg("Exception: GetPoly(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints); +WriteLogMsg("Exception: GetPoly(uint16_t). pt=%u, numPoints=%u\xD\xA", pt, numPoints); #endif throw GP_OUT_OF_RANGE; #ifdef DEBUG @@ -560,17 +691,18 @@ WriteLogMsg("Exception: GetPoly(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoin if (pt <= polyEnd[i]) return i; - return (uint16)-1; + return (uint16_t)-1; } + void GlyphPoints::AddNewPolyAtEnd(void) { if (numPoints == 0) // By default, we already *have* a poly return; - uint16 * newPolyEnd = new uint16[numPolys + 1]; + uint16_t * newPolyEnd = new uint16_t[numPolys + 1]; - for(uint16 i=0; i polyEnd[poly]) + poly++; + + if (IPoint(x[i], y[i]) == point) + return poly; + } + + return 0xFFFF; +} + + +uint16_t GlyphPoints::GetPolyForPointNumber(uint16_t pointNumber) +{ + // If there's only one poly, we know where the point is... + if (numPolys <= 1) + return 0; + + // Otherwise, do a linear search through the polys to find the right one + for(uint16_t i=0; i= GetPolyStart(i) && pointNumber <= polyEnd[i]) + return i; + } + + return 0xFFFF; +} + + +// +// Rotate a point by "angle" around point "center" +// +IPoint GlyphPoints::RotatePoint(const double angle, const IPoint point, const IPoint center) +{ + // Translate the point to the origin + double xt = (double)(point.x - center.x); + double yt = (double)(point.y - center.y); + + // Rotate the point by angle + double xr = (xt * cos(angle)) - (yt * sin(angle)); + double yr = (xt * sin(angle)) + (yt * cos(angle)); + + // Translate it back... + IPoint rotated; + rotated.x = (int)(xr + 0.5) + center.x; + rotated.y = (int)(yr + 0.5) + center.y; + return rotated; +} + + +// +// Rotate all points in the glyph by "angle" around point "pt" +// +void GlyphPoints::RotatePoints(const double angle, const IPoint pt) +{ + for(int i=0; i= numPolys) + throw GP_OUT_OF_RANGE; +// return IPoint(0, 0); + +// if (poly >= numPolys) +//#ifdef DEBUG +//{ +//WriteLogMsg("Exception: GetPolyEnd(uint16_t). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +//#endif +// throw GP_OUT_OF_RANGE; +//#ifdef DEBUG +//} +//#endif + + IPoint centroid; // Initializes to (0, 0) + uint16_t numPointsInPoly = GetNumPoints(poly); + + for(uint16_t i=GetPolyStart(poly); i<=GetPolyEnd(poly); i++) + { + centroid.x += x[i]; + centroid.y += y[i]; + } + + centroid.x /= numPointsInPoly; + centroid.y /= numPointsInPoly; + + return centroid; +} + + +void GlyphPoints::RotatePolyAroundCentroid(const int16_t poly, const double angle) +{ + if (poly >= numPolys) + return; + + IPoint centroid = GetPolyCentroid(poly); + + for(uint16_t i=GetPolyStart(poly); i<=GetPolyEnd(poly); i++) + { + IPoint rotated = RotatePoint(angle, IPoint(x[i], y[i]), centroid); + x[i] = rotated.x; + y[i] = rotated.y; + } +} + + +void GlyphPoints::InvertPolyDrawSequence(const uint16_t poly) +{ + if (poly >= numPolys) + throw GP_OUT_OF_RANGE; + + uint16_t pointNum1 = GetPolyStart(poly); + uint16_t pointNum2 = GetPolyEnd(poly); + + // Algorithm: Step through points in the polygon, swapping 1st and last, then + // 2nd and (last - 1), 3rd and (last - 2), etc. We only do this for half the + // points, as doing it for all would undo the swapping we did in the 1st half. + for(uint16_t i=0; ipts; + fprintf(file, "TTEGLYPH V1.0\n"); + fprintf(file, "POINTS %u\n", numPoints); + + for(int i=0; i