X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fglyphpoints.cpp;h=2e80e387e4987871dbf6c261ea608ea18b91046d;hb=3ef71393f70213eb53db552605ae3c93f1303ee9;hp=d7ce0d5b19d082d629c28aa9f8458142830402e2;hpb=a4763354603a2f8fbaff27a17edab7710ead6c2b;p=ttedit diff --git a/src/glyphpoints.cpp b/src/glyphpoints.cpp index d7ce0d5..2e80e38 100755 --- a/src/glyphpoints.cpp +++ b/src/glyphpoints.cpp @@ -22,6 +22,8 @@ #ifdef DEBUG #include "debug.h" #endif +#include + /*GlyphPoints::GlyphPoints(void) { @@ -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,8 +70,11 @@ WriteLogMsg("GlyphPoints: Copy constructor. %u points, %u polys.\n", numPoints, #endif } + GlyphPoints::~GlyphPoints() { + FreeAllocatedMemory(); +#if 0 if (x) delete[] x; @@ -79,8 +86,10 @@ GlyphPoints::~GlyphPoints() if (polyEnd) delete[] polyEnd; +#endif } + void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool * oca, uint16 * pa) { numPoints = nPts, numPolys = nPlys; @@ -114,11 +123,9 @@ void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool } } -GlyphPoints& GlyphPoints::operator=(const GlyphPoints &c) -{ - if (this == &c) - return *this; // Take care of self-assignment +void GlyphPoints::FreeAllocatedMemory(void) +{ if (x) delete[] x; @@ -130,12 +137,21 @@ GlyphPoints& GlyphPoints::operator=(const GlyphPoints &c) if (polyEnd) delete[] polyEnd; +} + +GlyphPoints& GlyphPoints::operator=(const GlyphPoints &c) +{ + if (this == &c) + return *this; // Take care of self-assignment + + FreeAllocatedMemory(); AllocateAndCopy(c.numPoints, c.numPolys, c.x, c.y, c.onCurve, c.polyEnd); return *this; } + // Add another GlyphPoints' points to this one... GlyphPoints GlyphPoints::operator+(const GlyphPoints &c) @@ -177,6 +193,7 @@ GlyphPoints GlyphPoints::operator+(const GlyphPoints &c) return retVal; } + // Add a point to this GlyphPoints... GlyphPoints GlyphPoints::operator+(const IPoint &c) @@ -205,6 +222,7 @@ GlyphPoints GlyphPoints::operator+(const IPoint &c) return retVal; } + GlyphPoints& GlyphPoints::operator+=(const IPoint &p) { InsertPoint(numPoints, p.x, p.y, p.onCurve); @@ -212,6 +230,21 @@ GlyphPoints& GlyphPoints::operator+=(const IPoint &p) return *this; } + +void GlyphPoints::Clear(void) +{ + FreeAllocatedMemory(); + x = y = NULL; + onCurve = NULL; + polyEnd = NULL; + numPoints = numPolys = pointsAllocated = polysAllocated = 0; + + numPolys = 1; + polyEnd = new uint16[numPolys]; + polyEnd[0] = numPoints - 1; +} + + void GlyphPoints::InsertPoint(uint16 pt, int xx, int yy, bool oc) { if (pt > numPoints) // > because we can insert at end...! @@ -246,11 +279,13 @@ void GlyphPoints::InsertPoint(uint16 pt, int xx, int yy, bool oc) x = totX, y = totY, onCurve = totOnCurve; } + void GlyphPoints::InsertPoint(uint16 pt, const IPoint &p) { InsertPoint(pt, p.x, p.y, p.onCurve); } + // // Delete a point from the glyph // Note that we don't bother to reallocate anything here, just bump the @@ -283,11 +318,13 @@ void GlyphPoints::DeletePoint(uint16 pt) x[i] = x[i + 1], y[i] = y[i + 1], onCurve[i] = onCurve[i + 1]; } + uint16 GlyphPoints::GetNumPoints(void) { return numPoints; } + uint16 GlyphPoints::GetNumPoints(uint16 poly) { if (poly >= numPolys) @@ -303,11 +340,13 @@ WriteLogMsg("Exception: GetNumPoints(uint16). poly=%u, numPolys=%u\xD\xA", poly, return polyEnd[poly] - (poly == 0 ? -1 : polyEnd[poly - 1]); } + uint16 GlyphPoints::GetNumPolys(void) { return numPolys; } + int GlyphPoints::GetX(uint16 pt) { if (pt >= numPoints) @@ -323,6 +362,7 @@ WriteLogMsg("Exception: GetX(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints) return x[pt]; } + int GlyphPoints::GetY(uint16 pt) { if (pt >= numPoints) @@ -338,6 +378,7 @@ WriteLogMsg("Exception: GetY(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints) return y[pt]; } + bool GlyphPoints::GetOnCurve(uint16 pt) { if (pt >= numPoints) @@ -353,6 +394,7 @@ WriteLogMsg("Exception: GetOnCurve(uint16). pt=%u, numPoints=%u\xD\xA", pt, numP return onCurve[pt]; } + int GlyphPoints::GetX(uint16 poly, uint16 pt) { if (pt >= GetNumPoints(poly)) @@ -368,6 +410,13 @@ 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::GetNextX(uint16 poly, uint16 pt) +{ + return GetX(poly, GetNext(poly, pt)); +} + + int GlyphPoints::GetY(uint16 poly, uint16 pt) { if (pt >= GetNumPoints(poly)) @@ -383,6 +432,28 @@ WriteLogMsg("Exception: GetY(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\x return y[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)]; } + +int GlyphPoints::GetNextY(uint16 poly, uint16 pt) +{ + return GetY(poly, GetNext(poly, pt)); +} + + +IPoint GlyphPoints::GetPoint(uint16 poly, uint16 pt) +{ + return IPoint(GetX(poly, pt), GetY(poly, pt), GetOnCurve(poly, pt)); +} + + +IPoint GlyphPoints::GetPoint(uint16 pointNumber) +{ + if (pointNumber > numPoints) + throw GP_OUT_OF_RANGE; + + return IPoint(x[pointNumber], y[pointNumber], onCurve[pointNumber]); +} + + bool GlyphPoints::GetOnCurve(uint16 poly, uint16 pt) { if (pt >= GetNumPoints(poly)) @@ -398,6 +469,36 @@ WriteLogMsg("Exception: GetOnCurve(uint16, uint16). poly= %u, pt=%u, numPoints=% return onCurve[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)]; } + +bool GlyphPoints::GetPrevOnCurve(uint16 poly, uint16 pt) +{ + return GetOnCurve(poly, GetPrev(poly, pt)); +} + + +bool GlyphPoints::GetNextOnCurve(uint16 poly, uint16 pt) +{ + return GetOnCurve(poly, GetNext(poly, pt)); +} + + +uint16 GlyphPoints::GetPolyStart(uint16 poly) +{ + if (poly >= numPolys) +#ifdef DEBUG +{ +WriteLogMsg("Exception: GetPolyEnd(uint16). 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 GlyphPoints::GetPolyEnd(uint16 poly) { if (poly >= numPolys) @@ -413,12 +514,14 @@ 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= numPoints) @@ -462,6 +567,7 @@ 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) { if (pt >= numPoints) @@ -477,6 +583,23 @@ WriteLogMsg("Exception: SetOnCurve(uint16, bool). pt=%u, numPoints=%u\xD\xA", pt onCurve[pt] = oc; } + +void GlyphPoints::SetPoint(const uint16 pointNum, const IPoint point) +{ + if (pointNum >= numPoints) +#ifdef DEBUG +{ +WriteLogMsg("Exception: SetPoint(uint16, 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 GlyphPoints::GetPrev(uint16 pt) { // pt = 7, polyEnd = 4, 9, 15 @@ -502,6 +625,7 @@ uint16 GlyphPoints::GetPrev(uint16 pt) return retVal; } + uint16 GlyphPoints::GetNext(uint16 pt) { uint16 min = 0, max = numPoints - 1; @@ -526,6 +650,7 @@ uint16 GlyphPoints::GetNext(uint16 pt) return retVal; } + // // Get previous point for this polygon using wraparound. // Note that pt is a zero-based index! @@ -535,6 +660,7 @@ uint16 GlyphPoints::GetPrev(uint16 poly, uint16 pt) return (pt == 0 ? GetNumPoints(poly) - 1 : pt - 1); } + // // Get next point for this polygon using wraparound. // Note that pt is a zero-based index! @@ -544,6 +670,8 @@ uint16 GlyphPoints::GetNext(uint16 poly, uint16 pt) return (pt == GetNumPoints(poly) - 1 ? 0 : pt + 1); } + +#warning "!!! This function returns incorrect results !!!" uint16 GlyphPoints::GetPoly(uint16 pt) { if (pt >= numPoints) @@ -563,6 +691,7 @@ WriteLogMsg("Exception: GetPoly(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoin return (uint16)-1; } + void GlyphPoints::AddNewPolyAtEnd(void) { if (numPoints == 0) // By default, we already *have* a poly @@ -579,6 +708,7 @@ void GlyphPoints::AddNewPolyAtEnd(void) polyEnd = newPolyEnd; } + IPoint GlyphPoints::GetMidpointToPrev(uint16 poly, uint16 pt) { uint16 prev = GetPrev(poly, pt); @@ -589,6 +719,7 @@ IPoint GlyphPoints::GetMidpointToPrev(uint16 poly, uint16 pt) return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f); } + IPoint GlyphPoints::GetMidpointToNext(uint16 poly, uint16 pt) { uint16 next = GetNext(poly, pt); @@ -599,6 +730,7 @@ IPoint GlyphPoints::GetMidpointToNext(uint16 poly, uint16 pt) return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f); } + IPoint GlyphPoints::GetPrevPoint(uint16 poly, uint16 pt) { uint16 prevPt = GetPrev(poly, pt); @@ -606,9 +738,214 @@ IPoint GlyphPoints::GetPrevPoint(uint16 poly, uint16 pt) return IPoint(GetX(poly, prevPt), GetY(poly, prevPt)); } + IPoint GlyphPoints::GetNextPoint(uint16 poly, uint16 pt) { uint16 nextPt = GetNext(poly, pt); return IPoint(GetX(poly, nextPt), GetY(poly, nextPt)); } + + +uint16 GlyphPoints::GetPolyForPoint(IPoint point) +{ + uint16 poly = 0; + + for(uint16 i=0; i polyEnd[poly]) + poly++; + + if (IPoint(x[i], y[i]) == point) + return poly; + } + + return 0xFFFF; +} + + +uint16 GlyphPoints::GetPolyForPointNumber(uint16 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 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). poly=%u, numPolys=%u\xD\xA", poly, numPolys); +//#endif +// throw GP_OUT_OF_RANGE; +//#ifdef DEBUG +//} +//#endif + + IPoint centroid; // Initializes to (0, 0) + uint16 numPointsInPoly = GetNumPoints(poly); + + for(uint16 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 poly, const double angle) +{ + if (poly >= numPolys) + return; + + IPoint centroid = GetPolyCentroid(poly); + + for(uint16 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 poly) +{ + if (poly >= numPolys) + throw GP_OUT_OF_RANGE; + + uint16 pointNum1 = GetPolyStart(poly); + uint16 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 i=0; ipts; + fprintf(file, "TTEGLYPH V1.0\n"); + fprintf(file, "POINTS %u\n", numPoints); + + for(int i=0; i