[Igarden-commit] CommonSource/YAAFExtensions RGGLSVGDraw.cpp, 1.26.2.2, 1.26.2.3
Status: Beta
Brought to you by:
jlbedell
|
From: Jeffrey B. <jlb...@us...> - 2006-11-04 23:04:17
|
Update of /cvsroot/igarden/CommonSource/YAAFExtensions In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv5862 Modified Files: Tag: Release_branch_v1 RGGLSVGDraw.cpp Log Message: Improve transforms (still issues with reflecting and rotating groups) Index: RGGLSVGDraw.cpp =================================================================== RCS file: /cvsroot/igarden/CommonSource/YAAFExtensions/RGGLSVGDraw.cpp,v retrieving revision 1.26.2.2 retrieving revision 1.26.2.3 diff -C2 -d -r1.26.2.2 -r1.26.2.3 *** RGGLSVGDraw.cpp 2 Nov 2006 23:43:15 -0000 1.26.2.2 --- RGGLSVGDraw.cpp 4 Nov 2006 23:04:12 -0000 1.26.2.3 *************** *** 47,50 **** --- 47,59 ---- } titleTag_t; + typedef struct + { + double translateX; + double translateY; + double scaleX; + double scaleY; + double angle; + } transform_t; + class SVGCacheEntry { *************** *** 64,72 **** void GetRepeatCounts(double width, double length, long &widthCount, long &lengthCount); const char *GetArcParameters(const char *val, glPoint_t start, bool doTranslate, glSize_t mySize, glPoint_t &end, glPoint_t ¢er, double &rx, double &ry, bool &sweep, bool &large, bool &isClosed); ! void EnumeratePathVertices(const char *val, double xOffset, double yOffset, double zOffset, double xSize, double ySize, double scaleX, double scaleY, double translateX, double translateY); bool IsStrokeStyleVisible(XGXMLData *data); void SetStrokeStyle(XGXMLData *data, double xScale, double yScale); bool IsFillStyleVisible(XGXMLData *data); void SetFillStyle(XGXMLData *data); XGFileSpecifier _spec; --- 73,85 ---- void GetRepeatCounts(double width, double length, long &widthCount, long &lengthCount); const char *GetArcParameters(const char *val, glPoint_t start, bool doTranslate, glSize_t mySize, glPoint_t &end, glPoint_t ¢er, double &rx, double &ry, bool &sweep, bool &large, bool &isClosed); ! void EnumeratePathVertices(const char *val, double xOffset, double yOffset, double zOffset, double xSize, double ySize, double scaleX, double scaleY); bool IsStrokeStyleVisible(XGXMLData *data); void SetStrokeStyle(XGXMLData *data, double xScale, double yScale); bool IsFillStyleVisible(XGXMLData *data); void SetFillStyle(XGXMLData *data); + void StartTransform(XGXMLData *data, double scaleX, double scaleY); + void StopTransform(); + void FindTransform(XGXMLData *data, transform_t &transform); + void TransformPoint(transform_t &transform, double x, double y, double &resultX, double &resultY); XGFileSpecifier _spec; *************** *** 495,498 **** --- 508,512 ---- } + StartTransform(data, scaleX, scaleY); while(sub2 != NULL) { *************** *** 516,519 **** --- 530,534 ---- sub2 = sub2->GetSibling(); } + StopTransform(); } else if(strcmp(data->GetTag(), "polyline") == 0) *************** *** 619,649 **** else if(strcmp(data->GetTag(), "path") == 0) { ! double translateX = 0.0, translateY = 0.0; ! const char *transform, *dval; ! transform = data->GetArgValue("transform"); ! if(transform != NULL) ! { ! if(strncmp(transform, "translate(",10) == 0) ! { ! (void)ParseOnePoint(transform+10, false, 0.0, 0.0, 0.0, 0.0, translateX, translateY); ! } ! else if(strncmp(transform, "matrix(",7) == 0) ! { ! float a, b, c, d, e, f; ! long numValid; ! ! numValid = sscanf(transform, "matrix(%f,%f,%f,%f,%f,%f", &a, &b, &c, &d, &e, &f); ! if(b == 0.0 && c == 0.0) ! { ! // scaleX *= a; ! // scaleY *= d; ! translateX = (-1*e)*a; ! translateY = (-1*f)*d; ! } ! else ! printf("Transform not implemented\n"); ! } ! } dval = data->GetArgValue("d"); --- 634,640 ---- else if(strcmp(data->GetTag(), "path") == 0) { ! const char *dval; ! StartTransform(data, scaleX, scaleY); dval = data->GetArgValue("d"); *************** *** 664,668 **** SetFillStyle(data); glBegin(GL_POLYGON); ! EnumeratePathVertices(dval, xOffset, yOffset, zOffset, xSize, ySize, scaleX, scaleY, translateX, translateY); glEnd(); } --- 655,659 ---- SetFillStyle(data); glBegin(GL_POLYGON); ! EnumeratePathVertices(dval, xOffset, yOffset, zOffset, xSize, ySize, scaleX, scaleY); glEnd(); } *************** *** 677,681 **** glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glBegin(GL_LINE_STRIP); ! EnumeratePathVertices(dval, xOffset, yOffset, 0.0, xSize, ySize, scaleX, scaleY, translateX, translateY); glEnd(); glPopAttrib(); --- 668,672 ---- glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glBegin(GL_LINE_STRIP); ! EnumeratePathVertices(dval, xOffset, yOffset, 0.0, xSize, ySize, scaleX, scaleY); glEnd(); glPopAttrib(); *************** *** 684,691 **** glPopAttrib(); } } ! void SVGCacheEntry::EnumeratePathVertices(const char *val, double xOffset, double yOffset, double zOffset, double xSize, double ySize, double scaleX, double scaleY, double translateX, double translateY) { double xPos, yPos, xPosSVG, yPosSVG, startXPos, startYPos, span; --- 675,733 ---- glPopAttrib(); + StopTransform(); } } ! void SVGCacheEntry::StartTransform(XGXMLData *data, double scaleX, double scaleY) ! { ! const char *transform; ! ! glPushMatrix(); ! transform = data->GetArgValue("transform"); ! if(transform != NULL) ! { ! if(strncmp(transform, "translate(",10) == 0) ! { ! float x, y; ! long numValid; ! // (void)ParseOnePoint(transform+10, false, 0.0, 0.0, 0.0, 0.0, translateX, translateY); ! numValid = sscanf(transform, "translate(%f,%f", &x, &y); ! glTranslatef(x*scaleX,-y*scaleY,0); ! } ! else if(strncmp(transform, "matrix(",7) == 0) ! { ! float a, b, c, d, e, f; ! long numValid; ! GLfloat matrix[16]; ! ! // | a c e | | a c e 0 | ! // | b d f | | b d f 0 | ! // | 0 0 1 | | 0 0 1 0 | ! // | 0 0 0 1 | ! ! numValid = sscanf(transform, "matrix(%f,%f,%f,%f,%f,%f", &a, &b, &c, &d, &e, &f); ! if(b == 0 && c == 0) ! { ! glTranslatef(e*scaleX/a,-f*scaleY/d,0); ! glScalef(a, d, 1.0); ! } ! else ! { ! double angle = acos(a)*360/(2*3.14); ! if(b > 0) ! angle -= 180; ! glRotatef(angle, 0, 0, 1); ! glTranslatef(e*scaleX/a,-f*scaleY/d,0); ! } ! } ! } ! } ! ! void SVGCacheEntry::StopTransform() ! { ! glPopMatrix(); ! } ! ! void SVGCacheEntry::EnumeratePathVertices(const char *val, double xOffset, double yOffset, double zOffset, double xSize, double ySize, double scaleX, double scaleY) { double xPos, yPos, xPosSVG, yPosSVG, startXPos, startYPos, span; *************** *** 725,838 **** glEvalCoord1f(((GLfloat)i)/30.0); } - glEnd(); } ! else { ! if(*val == 'M') ! { val++; ! while(*val == ' ' || *val == '\t') ! val++; ! ParseOnePoint(val, false, xSize, ySize, _bounds.top, _bounds.left, xPosSVG, yPosSVG); ! val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); ! } ! else if(*val == 'L') ! { val++; ! while(*val == ' ' || *val == '\t') ! val++; ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! } ! else { ! if(*val == 'A') { ! glPoint_t start, end, center; ! double rx, ry; ! double startA, endA, delta; ! long count; ! bool sweep, large, isClosed; ! glSize_t mySize; ! ! start.x = xPosSVG; ! start.y = yPosSVG; ! mySize.x = xSize; ! mySize.y = ySize; ! val = GetArcParameters(val, start, false, mySize, end, center, rx, ry, sweep, large, isClosed); ! ! start.x += translateX; ! start.y += translateY; ! end.x += translateX; ! end.y += translateY; ! center.x += translateX; ! center.y += translateY; ! if(start.x != end.x || start.y != end.y) { ! delta = (3.0/360.0)*2*3.14; ! startA = atan2(start.y-center.y,start.x-center.x); //*(360/(2*3.14)); ! endA = atan2(end.y-center.y,end.x-center.x); //*(360/(2*3.14)); ! span = endA-startA; ! if(span < 0) ! span *= -1.0; ! if((span < 3.14) && large) ! span = (2*3.14) - span; ! count = span/delta; ! ! double t, x, y; ! long n; ! ! x = start.x; //- center.x; ! y = start.y; //- center.y; ! if(!sweep) ! delta *= -1.0; ! ! // printf("Count = %ld center = %f,%f, startAnd %f endAng %f\n", count, center.x, center.y, startA, startA+(count*delta)); ! if(startA != NAN && endA != NAN) ! { ! if(!startPosSet) ! { ! startXPos = (cos(startA) * rx*cos(startA) - sin(startA)*ry*sin(startA)); //+ (center.x - (xSize/2)); ! startYPos = (sin(startA) * rx*cos(startA) + cos(startA)*ry*sin(startA)); //+ (center.y - (ySize/2)); ! startPosSet = true; ! } ! ! for(t = startA, n = 0; n < count; n++, t += delta) ! { ! x = (cos(t) * rx*cos(t) - sin(t)*ry*sin(t)); //+ (center.x - (xSize/2)); ! y = (sin(t) * rx*cos(t) + cos(t)*ry*sin(t)); //+ (center.y - (ySize/2)); ! glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! } ! ! x = (cos(endA) * rx*cos(endA) - sin(endA)*ry*sin(endA)); //+ (center.x - (xSize/2)); ! y = (sin(endA) * rx*cos(endA) + cos(endA)*ry*sin(endA)); //+ (center.y - (ySize/2)); ! glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! } ! if(isClosed && startPosSet) ! { ! // glBegin(GL_LINES); ! // glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! // glVertex3f((startXPos * scaleX) + xOffset, (startYPos * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! // glEnd(); ! } ! xPosSVG = end.x; ! yPosSVG = end.y; } } ! else { ! if(*val == 'z') ! val++; ! while(*val == ' ' || *val == '\t') ! val++; ! if(*val != '\0') ! { ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! } } } } --- 767,870 ---- glEvalCoord1f(((GLfloat)i)/30.0); } } ! else if(*val == 'M') { ! val++; ! while(*val == ' ' || *val == '\t') val++; ! ParseOnePoint(val, false, xSize, ySize, _bounds.top, _bounds.left, xPosSVG, yPosSVG); ! val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! } ! else if(*val == 'L') ! { ! val++; ! while(*val == ' ' || *val == '\t') val++; ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); ! glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate ! } ! else if(*val == 'A') ! { ! glPoint_t start, end, center; ! double rx, ry; ! double startA, endA, delta; ! long count; ! bool sweep, large, isClosed; ! glSize_t mySize; ! ! start.x = xPosSVG; ! start.y = yPosSVG; ! mySize.x = xSize; ! mySize.y = ySize; ! val = GetArcParameters(val, start, false, mySize, end, center, rx, ry, sweep, large, isClosed); ! ! if(start.x != end.x || start.y != end.y) { ! delta = (3.0/360.0)*2*3.14; ! startA = atan2(start.y-center.y,start.x-center.x); //*(360/(2*3.14)); ! endA = atan2(end.y-center.y,end.x-center.x); //*(360/(2*3.14)); ! span = endA-startA; ! if(span < 0) ! span *= -1.0; ! if((span < 3.14) && large) ! span = (2*3.14) - span; ! count = span/delta; ! ! double t, x, y; ! long n; ! ! x = start.x; //- center.x; ! y = start.y; //- center.y; ! if(!sweep) ! delta *= -1.0; ! ! // printf("Count = %ld center = %f,%f, startAnd %f endAng %f\n", count, center.x, center.y, startA, startA+(count*delta)); ! if(startA != NAN && endA != NAN) { ! if(!startPosSet) ! { ! startXPos = (cos(startA) * rx*cos(startA) - sin(startA)*ry*sin(startA)); //+ (center.x - (xSize/2)); ! startYPos = (sin(startA) * rx*cos(startA) + cos(startA)*ry*sin(startA)); //+ (center.y - (ySize/2)); ! startPosSet = true; ! } ! for(t = startA, n = 0; n < count; n++, t += delta) { ! x = (cos(t) * rx*cos(t) - sin(t)*ry*sin(t)); //+ (center.x - (xSize/2)); ! y = (sin(t) * rx*cos(t) + cos(t)*ry*sin(t)); //+ (center.y - (ySize/2)); ! glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate } + + x = (cos(endA) * rx*cos(endA) - sin(endA)*ry*sin(endA)); //+ (center.x - (xSize/2)); + y = (sin(endA) * rx*cos(endA) + cos(endA)*ry*sin(endA)); //+ (center.y - (ySize/2)); + glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate } ! if(isClosed && startPosSet) { ! // glBegin(GL_LINES); ! // glVertex3f((x * scaleX) + xOffset, (y * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! // glVertex3f((startXPos * scaleX) + xOffset, (startYPos * scaleY) + yOffset, 0.0); // Z axis taken care of on glTranslate ! // glEnd(); } + xPosSVG = end.x; + yPosSVG = end.y; + } + } + else + { + if(*val == 'z') + { + glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate + val++; + } + while(*val == ' ' || *val == '\t') + val++; + if(*val != '\0') + { + glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate + val = ParseOnePoint(val, true, xSize, ySize, _bounds.top, _bounds.left, xPos, yPos); + glVertex3f((xPos * scaleX) + xOffset, (yPos * scaleY) + yOffset, zOffset); // Z axis taken care of on glTranslate } } *************** *** 927,931 **** XGXMLData *subData; const char *val, *transform; ! double xPos, yPos, localXSize, localYSize; glRectangle_t localBounds; bool forX, forY; --- 959,963 ---- XGXMLData *subData; const char *val, *transform; ! double xPos, yPos, localXSize, localYSize, translateX, translateY; glRectangle_t localBounds; bool forX, forY; *************** *** 942,945 **** --- 974,978 ---- localBounds.bottom = -1*1.0e100; + while(sub2 != NULL) { *************** *** 950,953 **** --- 983,987 ---- } + if(localBounds.left != 1.0e100 && localBounds.right != -1*1.0e100) localXSize = localBounds.right - localBounds.left; *************** *** 958,961 **** --- 992,1002 ---- else localYSize = 0; + + // FindTransformOffsets(data, translateX, translateY); + // localBounds.left += translateX; + //// localBounds.right += translateX; + // localBounds.top -= translateY; + // localBounds.bottom -= translateY; + val = data->GetArgValue("inkscape:label"); tag = GetTitleTag(val, forX, forY, &nextCh); *************** *** 1115,1144 **** else if(strcmp(data->GetTag(), "path") == 0) { ! double translateX = 0.0, translateY = 0.0; ! double scaleX = 1.0, scaleY = 1.0; val = data->GetArgValue("d"); ! transform = data->GetArgValue("transform"); ! if(transform != NULL) ! { ! if(strncmp(transform, "translate(",10) == 0) ! { ! (void)ParseOnePoint(transform+10, false, 0.0, 0.0, 0.0, 0.0, translateX, translateY); ! } ! else if(strncmp(transform, "matrix(",10) == 0) ! { ! double a, b, c, d, e, f; ! ! (void)ParseOnePoint(transform+10, false, 0.0, 0.0, 0.0, 0.0, translateX, translateY); ! sscanf(transform, "matrix(%lf,%lf,%lf,%lf,%lf,%lf", &a, &b, &c, &d, &e, &f); ! if(b == 0.0 && c == 0.0 && e == 0.0 && f == 0.0) ! { ! scaleX = a; ! scaleY = d; ! } ! else ! printf("Transform not implemented\n"); ! } ! } while(*val != '\0') { --- 1156,1164 ---- else if(strcmp(data->GetTag(), "path") == 0) { ! transform_t transform; val = data->GetArgValue("d"); ! ! FindTransform(data, transform); while(*val != '\0') { *************** *** 1195,1200 **** for(t = startA, n = 0; n < count; n++, t += delta) { ! x = cos(t) * rx*cos(t) - sin(t)*ry*sin(t) + center.x + translateX; ! y = sin(t) * rx*cos(t) + cos(t)*ry*sin(t) + center.y + translateY; if(x < bounds.left) bounds.left = x; --- 1215,1221 ---- for(t = startA, n = 0; n < count; n++, t += delta) { ! x = cos(t) * rx*cos(t) - sin(t)*ry*sin(t) + center.x; ! y = sin(t) * rx*cos(t) + cos(t)*ry*sin(t) + center.y; ! TransformPoint(transform, x, y, x, y); if(x < bounds.left) bounds.left = x; *************** *** 1222,1234 **** if(*val != '\0') { val = ParseOnePoint(val, false, 0.0, 0.0, 0.0, 0.0, xPos, yPos); ! if(xPos+translateX < bounds.left) ! bounds.left = xPos+translateX; ! if(xPos+translateX > bounds.right) ! bounds.right = xPos+translateX; ! if(yPos+translateY < bounds.top) ! bounds.top = yPos+translateY; ! if(yPos+translateY > bounds.bottom) ! bounds.bottom = yPos+translateY; } } --- 1243,1258 ---- if(*val != '\0') { + double tx, ty; + val = ParseOnePoint(val, false, 0.0, 0.0, 0.0, 0.0, xPos, yPos); ! TransformPoint(transform, xPos, yPos, tx, ty); ! if(tx < bounds.left) ! bounds.left = tx; ! if(tx > bounds.right) ! bounds.right = tx; ! if(ty < bounds.top) ! bounds.top = ty; ! if(ty > bounds.bottom) ! bounds.bottom = ty; } } *************** *** 1236,1239 **** --- 1260,1308 ---- } + void SVGCacheEntry::FindTransform(XGXMLData *data, transform_t &transform) + { + const char *transformStr; + + transform.translateX = 0.0; + transform.translateY = 0.0; + transform.scaleX = 1.0; + transform.scaleY = 1.0; + transform.angle = 0.0; + transformStr = data->GetArgValue("transform"); + if(transformStr != NULL) + { + if(strncmp(transformStr, "translate(",10) == 0) + { + float x, y; + long numValid; + //(void)ParseOnePoint(transform+10, false, 0.0, 0.0, 0.0, 0.0, translateX, translateY); + numValid = sscanf(transformStr, "translate(%f,%f", &x, &y); + transform.translateX = x; + transform.translateY = y; + } + else if(strncmp(transformStr, "matrix(",7) == 0) + { + float a, b, c, d, e, f; + uint32 numValid; + + // | a c e | | a c e 0 | + // | b d f | | b d f 0 | + // | 0 0 1 | | 0 0 1 0 | + // | 0 0 0 1 | + + numValid = sscanf(transformStr, "matrix(%f,%f,%f,%f,%f,%f", &a, &b, &c, &d, &e, &f); + transform.translateX = e; + transform.translateY = f; + } + } + } + + void SVGCacheEntry::TransformPoint(transform_t &transform, double x, double y, double &resultX, double &resultY) + { + resultX = x + transform.translateX; + resultY = y + transform.translateY; + } + + // --------------------------------------------------------------------------- /// ParseOnePoint PRIVATE *************** *** 1694,1703 **** { char *temp; widthStr += strlen("stroke-width:"); ! glLineWidth((strtod(widthStr, &temp)* xScale)+0.5); } else ! glLineWidth(1.5 * xScale); fill = strstr(val, "stroke:"); --- 1763,1774 ---- { char *temp; + double width; widthStr += strlen("stroke-width:"); ! width = strtod(widthStr, &temp); ! glLineWidth(width+0.5); } else ! glLineWidth(1.5); fill = strstr(val, "stroke:"); |