//--------------------------------------------------------------------------- // This Program is made by Maxleo21c(Park Sang Hoon). // It works in C++ Builder 6. // 2006. 06. 17. // // Reference : Scalable Vector Graphics(SVG) 1.2 // W3C Working Draft 17 June 2006 // for processing SVG format file //--------------------------------------------------------------------------- #pragma hdrstop #include "SVG2VectorByTinyXML.h" #include "define.h" #include //--------------------------------------------------------------------------- #define MAX_DATA_NCOUNT 1024 //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- using namespace TTinyXML; using namespace std; //--------------------------------------------------------------------------- //todo: SVGElement Class --------------------------------------------------// bool __fastcall SVGElement::AddData(TiXmlNode* XmlNode, TVecData *data) { return true; } //--------------------------------------------------------------------------- bool __fastcall SVGElement::MakePoint(TVecData *data) { return true; } //--------------------------------------------------------------------------- void __fastcall SVGElement::GetRectSize(TVecData *data) { data->First.x = MaxInt; data->First.y = MaxInt; data->Second.x = 0; data->Second.y = 0; for (int i = 0; i < data->nCount*3+1; i++) { if (data->pList == NULL) continue; if (data->First.x > data->pList[i].x) data->First.x = data->pList[i].x; if (data->First.y > data->pList[i].y) data->First.y = data->pList[i].y; if (data->Second.x < data->pList[i].x) data->Second.x = data->pList[i].x; if (data->Second.y < data->pList[i].y) data->Second.y = data->pList[i].y; } } //--------------------------------------------------------------------------- double __fastcall SVGElement::GetUnits() { // "1pt" equals "1.25px" (and therefore 1.25 user units) // "1pc" equals "15px" (and therefore 15 user units) // "1mm" would be "3.543307px" (3.543307 user units) // "1cm" equals "35.43307px" (and therefore 35.43307 user units) // "1in" equals "90px" (and therefore 90 user units) String tUnits = Units.SubString(Units.Length()-1, 2); String Number = Units.SubString(1, Units.Length()-2); Units = tUnits; if (tUnits.Compare("pt") == true) return 1.25*Number.ToDouble(); else if (tUnits == "pc") return 15*Number.ToDouble(); else if (tUnits == "mm") return 3.543307*Number.ToDouble(); else if (tUnits == "cm") return 35.43307*Number.ToDouble(); else if (tUnits == "in") return 90*Number.ToDouble(); else return Number.ToDouble(); } //--------------------------------------------------------------------------- // 16Áø¼ö°ªÀ¸·Î Ç¥½ÃµÈ String data·Î °¡Áö¸¦ Int·Î º¯°æÇÏ´Â ÇÔ¼ö int __fastcall SVGElement::HEX_StringToInt(String sData) { int length = sData.Length(); int result=0, power=length-1; String tNum; for (int i=0; i TColor(BGR) TColor __fastcall SVGElement::SVGColor2TColor(String &svgColor) { Byte c_red, c_green, c_blue; c_blue = static_cast(HEX_StringToInt(svgColor.SubString(5,2))); c_green = static_cast(HEX_StringToInt(svgColor.SubString(3,2))); c_red = static_cast(HEX_StringToInt(svgColor.SubString(1,2))); return static_cast(c_blue<<16 | c_green<<8 | c_red); } //--------------------------------------------------------------------------- void __fastcall SVGElement::GetTransformData(String AttrData, TVecData *data) { double num_data[6]={0}; int kind = GetTransformAttr(AttrData, num_data); if (kind == 0) { // matrix if (num_data[0]==1 && num_data[1]==0 && num_data[2]==0 && num_data[3]==1) { // [1 0 0 1 tx ty] Translation kind = 1; } else if (num_data[1]==0 && num_data[2]==0 && num_data[4]==0 && num_data[5]==0) { // [sx 0 0 sy 0 0] Scale kind = 2; } else if ((num_data[1]!=0 || num_data[2]!=0) && num_data[4]==0 && num_data[5]==0) { // [cos(a) sin(a) -sin(a) cos(a) 0 0] Rotation kind = 3; num_data[0] = ArcCos(num_data[0]); } } switch(kind) { case -1: // error return; case 1: // translate { double tx=0, ty=0; tx = num_data[4]; ty = num_data[5]; for (int i = 0; i < data->nCount*3+1; i++) { data->pList[i].x = data->pList[i].x + tx; data->pList[i].y = data->pList[i].y + ty; } break; } case 2: // rotate { double cx=0, cy=0; double angle=num_data[0]; cx = abs(data->First.x - data->Second.x) / 2; cy = abs(data->First.y - data->Second.y) / 2; for (int i = 0; i < data->nCount*3+1; i++) { int tx = data->pList[i].x - cx; int ty = cy - data->pList[i].y; data->pList[i].x = tx*cos(-angle) + ty*sin(-angle) + cx; data->pList[i].y = cy - (-tx*sin(-angle) + ty*cos(-angle)); } break; } case 3: // scale { double sx=0, sy=0; sx = num_data[0]; sy = num_data[3]; for (int i = 0; i < data->nCount*3+1; i++) { data->pList[i].x = data->pList[i].x * sx; data->pList[i].y = data->pList[i].y * sy; } break; } case 4: // skewX, skewY return; } } //--------------------------------------------------------------------------- //3Á¾·ùÀÇ TransformÀ» È®ÀÎÇϰí data¸¦ ó¸®ÇÏ¿© ¸®ÅÏÇÏ´Â ÇÔ¼ö //return -1: error, 0: matrix, 1:translate, 2:rotate, 3:scale, 4:skewX, skewY int __fastcall SVGElement::GetTransformAttr(String AttrData, double *data) { int count=0; bool bMinus=false; String tNum; switch(AttrData.c_str()[0]) { case L'm': // matrix(0.45 0 0 0.45 0 0) { AttrData = AttrData.SubString(8, AttrData.Length()-7); for (int i=7; iKind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor)0; //stroke data->PenThick = 1; // data->nCount = pointCount; int length = 0; String attr_name, tString, temp; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "d") { d = pAttrib->Value(); //path "d" attribute data¾È¿¡ ¿©·Á°³ÀÇ path°¡ Á¸ÀçÇÒ ¼ö ÀÖ´Ù. MÀÇ °³¼ö¸¦ È®ÀÎÇϰí //m°ú MÀ» ±¸ºÐÇØ¾ß ÇÑ´Ù. mÀÏ °æ¿ì¿¡´Â ¸¶Áö¸· Á¡µµ È®ÀÎÇØ¾ß Çϱ⠶§¹®ÀÌ´Ù. //¿ì¼± MÀÇ °³¼ö¸¦ È®ÀÎÇÏ´Â ÇÔ¼ö°¡ ÇÊ¿äÇÏ´Ù. Check_M_counter(); } else if (attr_name == "fill") { // data->Color tString = pAttrib->Value(); length = tString.Length(); if (tString != "none" && tString.c_str()[0]==L'#') { tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); data->bFill = true; } else if (tString.SubString(1, 3)=="url") { fill_url = tString.SubString(6, length-6); } } else if (attr_name == "fill-rule") { tString = pAttrib->Value(); if (tString == "evenodd") data->bWinding = false; else data->bWinding = true; } else if (attr_name == "stroke") { // data->Brush tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "stroke-linecap") { tString = pAttrib->Value(); if (tString == "round") data->bRound = true; } else if (attr_name == "stroke-linejoin") { tString = pAttrib->Value(); if (tString == "round") data->bRound = true; } else if (attr_name == "stroke-dasharray") { // 06.09.20 by maxleo21c tString = pAttrib->Value(); float no1=0, no2=0; for (int i=0; iPenStyle = P_DASH; else if (abs((long)(no2-no1))!=1 && no1 != 1) { data->PenStyle = P_USERSTYLE; data->DashValues[0] = 2; data->DashValues[1] = no1; data->DashValues[2] = no2; } else data->PenStyle = P_DOT; } pAttrib = pAttrib->Next(); } return true; } //--------------------------------------------------------------------------- // modified by maxleo21c(06.06.23) -> exist Ãß°¡ bool __fastcall SVGPath::AddPatternData(TVecData *data, TList *patternList) { bool exist = false; SVGPattern *svgPattern = NULL; for (int i=0; iCount; i++) { svgPattern = (SVGPattern*)patternList->Items[i]; if (svgPattern->id == fill_url) { exist = true; break; } } if (exist && svgPattern) { data->PatternAngle = svgPattern->PatternAngle; data->PatternAdjustX = svgPattern->PatternAdjustX; data->PatternAdjustY = svgPattern->PatternAdjustY; data->RatioX = svgPattern->RatioX; data->RatioY = svgPattern->RatioY; data->TBitmapSource = new TTexpiaBitmap; data->TBitmapSource->Create(svgPattern->PatternWidth, svgPattern->PatternHeight, 24); data->TBitmapSource->Copy(svgPattern->patternBitmap, SRCCOPY); data->bPatternFill = true; return true; } return false; } //--------------------------------------------------------------------------- void __fastcall SVGPath::Check_M_counter(String *d_data) { if (!d_data) { for (int i=0; ikind = last_kind; pathData->point = 0; dataList->Add(pathData); } i--; continue; } if (d_data.c_str()[i] == L'C' || d_data.c_str()[i] == L'c' || d_data.c_str()[i] == L'S' || d_data.c_str()[i] == L's' || d_data.c_str()[i] == L'H' || d_data.c_str()[i] == L'h' || d_data.c_str()[i] == L'V' || d_data.c_str()[i] == L'v' || d_data.c_str()[i] == L'L' || d_data.c_str()[i] == L'l') { bAddKindData = true; check = true; last_kind = d_data.c_str()[i]; if(d_data.c_str()[i-1] == L' ') numcount = 0; else numcount = -1; } else if (d_data.c_str()[i] == L' ' || d_data.c_str()[i] == L',' || d_data.c_str()[i] == L'-') { check = true; } else if (d_data.c_str()[i] == L'\n' || d_data.c_str()[i] == L'\t') { check = true; } if (check && tPoint.Length()==0) { check = false; if (bAddKindData) { pathData = new TPathData; pathData->kind = d_data.c_str()[i]; pathData->point = 0; dataList->Add(pathData); bAddKindData = false; } if (d_data.c_str()[i] == L'-') { //À½¼ö°¡ µé¾î°¡ ÀÖ´Â °ÍÀ» ó¸®Çϱâ À§Çؼ­ bMinusNum = true; //À½¼öÀÏ °æ¿ì ó¸®ÇÏ´Â ¿©ºÎ } } else if (check) { pathData = new TPathData; pathData->kind = L'P'; pathData->point = tPoint.ToDouble(); numcount++; if (bMinusNum) { pathData->point *= (-1); bMinusNum = false; } if (d_data.c_str()[i] == L'-') { //À½¼ö°¡ µé¾î°¡ ÀÖ´Â °ÍÀ» ó¸®Çϱâ À§Çؼ­ bMinusNum = true; //À½¼öÀÏ °æ¿ì ó¸®ÇÏ´Â ¿©ºÎ } tPoint = ""; dataList->Add(pathData); check = false; if (bAddKindData) { pathData = new TPathData; pathData->kind = d_data.c_str()[i]; pathData->point = 0; dataList->Add(pathData); bAddKindData = false; } } else { tPoint+=d_data.c_str()[i]; } } if (tPoint.Length()) { pathData = new TPathData; pathData->kind = L'P'; pathData->point = tPoint.ToDouble(); if (bMinusNum) pathData->point *= (-1); dataList->Add(pathData); } } //--------------------------------------------------------------------------- void __fastcall SVGPath::ClearDataList() { TPathData *pathData; for (int i = 0; i < dataList->Count; i++) { pathData=(TPathData*)dataList->Items[i]; delete pathData; pathData=NULL; } dataList->Clear(); } //--------------------------------------------------------------------------- bool __fastcall SVGPath::MakePoint(TVecData *data, String d_data) { bool bMinusNum=false; TPathData *pathData; dataList = new TList; //'d' data¸¦ ÀúÀåÇÏ´Â List int length = d_data.Length(); Char isZ = d_data.c_str()[length-1]; if (d_data.c_str()[length-1]==L'Z' || d_data.c_str()[length-1]==L'z') { data->bClosed = true; GetPoint(d_data.Length()-1, d_data); } else { GetPoint(d_data.Length(), d_data); } if (data->nCount < 1) { if (dataList) delete dataList; return false; } data->nCount = pointCount; // 1024 Á¦ÇÑ Ç®·ÈÀ½ - by monkman (2011.04.20) //if (data->nCount*3+1 > MAX_DATA_NCOUNT) return false; //-- Á¡µéÀÇ °³¼ö¸¦ ÀÌ¿ëÇÏ¿© pList¸¦ »ý¼ºÇÏ´Â ºÎºÐ --// if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); //-- °¢ Á¡ µ¥ÀÌÅ͸¦ data¿¡ Ãß°¡ÇÏ´Â ºÎºÐ --// int count = 0; bool relative = false, addPoint = false; double ReferencePointX=0, ReferencePointY=0; //relative value󸮸¦ À§ÇÑ ±âÁذª Char last_kind = 0; if (data->pList == NULL) goto fail; for (int i=0; iCount; i++) { pathData = (TPathData*)dataList->Items[i]; switch(pathData->kind) { case L'P': { if (count%2) { data->pList[count/2].y = pathData->point; if (relative) data->pList[count/2].y += ReferencePointY; if (last_kind == L'L' || last_kind == L'l') { data->pList[count/2+1].x = data->pList[count/2].x; data->pList[count/2+1].y = data->pList[count/2].y; if (i != dataList->Count-1) { data->pList[count/2+2].x = data->pList[count/2].x; data->pList[count/2+2].y = data->pList[count/2].y; count+=4; //¹Ø¿¡¼­ Çѹø ´õ ´õÇØÁö±â ¶§¹®¿¡ 3À» ´õÇß´Ù. } else { count+=2;; } } } else { if (last_kind == L'H' || last_kind == L'h') {//ÇöÀç°ªÀÌ º¯°æµÇ´Â y°ªÀ» ³ªÅ¸³½´Ù. // (x, cpy) x°¡ ÇöÀç °ªÀ» ³ªÅ¸³½´Ù. data->pList[count/2].x = pathData->point; if (relative) data->pList[count/2].x += ReferencePointX; data->pList[count/2].y = data->pList[count/2-1].y; data->pList[count/2+1].x = data->pList[count/2].x; data->pList[count/2+1].y = data->pList[count/2].y; if (i != dataList->Count-1) { data->pList[count/2+2].x = data->pList[count/2].x; data->pList[count/2+2].y = data->pList[count/2].y; count+=5; } else { count+=3; } } else if (last_kind == L'V' || last_kind == L'v') {//ÇöÀç°ªÀÌ º¯°æµÇ´Â x°ªÀ» ³ªÅ¸³½´Ù. // (cpx, y) y°¡ ÇöÀç °ªÀ» ³ªÅ¸³½´Ù. data->pList[count/2].x = data->pList[count/2-1].x; data->pList[count/2].y = pathData->point; if (relative) data->pList[count/2].y += ReferencePointY; data->pList[count/2+1].x = data->pList[count/2].x; data->pList[count/2+1].y = data->pList[count/2].y; if (i != dataList->Count-1) { data->pList[count/2+2].x = data->pList[count/2].x; data->pList[count/2+2].y = data->pList[count/2].y; count+=5; } else { count+=3; } } else { // ÀϹÝÀûÀÏ ¶§ data->pList[count/2].x = pathData->point; if (relative) data->pList[count/2].x += ReferencePointX; } } count++; break; } case L'C': //Á÷¼±À» ó¸®ÇÏ´ø Áß°£¿¡ Ä¿ºê¸¦ ´Ù½Ã ±×¸®°Ô µÇ¸é Á÷¼±À» ó¸®ÇÒ ¶§ 3°³ÀÇ Á¡ÀÌ °°°í ÀÌ¹Ì //3°³ÀÇ Á¡ÀÌ ÀԷµǾ Ä¿ºêÀÇ Ã¹¹øÂ° ÄÁÆ®·Ñ¸¦ ÀÔ·ÂÇÏ¸é ¾ÈµÈ´Ù. ÀÔ·ÂÇÏ¸é °³¼ö°¡ Çϳª //Â÷À̰¡ ³ª°Ô µÈ´Ù. ±×·¡¼­ i+=2·Î ÄÁÆ®·Ñ Æ÷ÀÎÆ® ºÎºÐÀ» °Ç³Ê ¶Ù°Ô Çß´Ù. //dataList¿¡´Â ¸ðµç ¼ýÀÚ, knid°ªÀÌ µé¾î Àֱ⠶§¹®¿¡ ±×³É °Ç³Ê ¶Ú´Ù. if (last_kind == L'L' || last_kind == L'V' || last_kind == L'H' || last_kind == L'l' || last_kind == L'v' || last_kind == L'h') i+=2; relative = false; last_kind = L'C'; break; case L'c': //Á÷¼±À» ó¸®ÇÏ´ø Áß°£¿¡ Ä¿ºê¸¦ ´Ù½Ã ±×¸®°Ô µÇ¸é Á÷¼±À» ó¸®ÇÒ ¶§ 3°³ÀÇ Á¡ÀÌ °°°í ÀÌ¹Ì //3°³ÀÇ Á¡ÀÌ ÀԷµǾ Ä¿ºêÀÇ Ã¹¹øÂ° ÄÁÆ®·Ñ¸¦ ÀÔ·ÂÇÏ¸é ¾ÈµÈ´Ù. ÀÔ·ÂÇÏ¸é °³¼ö°¡ Çϳª //Â÷À̰¡ ³ª°Ô µÈ´Ù. ±×·¡¼­ i+=2·Î ÄÁÆ®·Ñ Æ÷ÀÎÆ® ºÎºÐÀ» °Ç³Ê ¶Ù°Ô Çß´Ù. if (last_kind == L'L' || last_kind == L'V' || last_kind == L'H' || last_kind == L'l' || last_kind == L'v' || last_kind == L'h') i+=2; ReferencePointX = data->pList[count/2-1].x; ReferencePointY = data->pList[count/2-1].y; relative = true; last_kind = L'C'; break; case L'S': case L's': { // 'S'´Â ÄÁÆ®·Î Æ÷ÀÌÆ®¸¦ ÀÚµ¿À¸·Î ó¸®ÇÑ ºÎºÐÀ̱⠶§¹®¿¡ 'S'ÀÌÀüÀÇ µÎÁ¡À» ºñ±³ÇÏ¿© // ÄÁÆ®·Î Æ÷ÀÎÆ®¸¦ °è»êÇØ Áà¾ßÇÑ´Ù. È®ÀÎµÈ ¸ðµç Á¡Àº ÀÌ¹Ì Real PointÀ̱⠶§¹®¿¡ relative¶ó°í // Ưº°È÷ ó¸®ÇÒ ÇÊ¿ä´Â ¾ø´Ù. data->pList[count/2].x = data->pList[count/2-1].x + (data->pList[count/2-1].x - data->pList[count/2-2].x); data->pList[count/2].y = data->pList[count/2-1].y + (data->pList[count/2-1].y - data->pList[count/2-2].y); if (pathData->kind == L's') { ReferencePointX = data->pList[count/2-1].x; ReferencePointY = data->pList[count/2-1].y; relative = true; } else { relative = false; } count+=2; last_kind = L'S'; break; } case L'L': case L'V': case L'H': { relative = false; if (last_kind == 0 || last_kind == L'C' || last_kind == L'S') { data->pList[count/2].x = data->pList[count/2-1].x; data->pList[count/2].y = data->pList[count/2-1].y; count+=2; } last_kind = pathData->kind; break; } case L'l': case L'v': case L'h': { if (last_kind == 0 || last_kind == L'C' || last_kind == L'S') { data->pList[count/2].x = data->pList[count/2-1].x; data->pList[count/2].y = data->pList[count/2-1].y; count+=2; } ReferencePointX = data->pList[count/2-1].x; ReferencePointY = data->pList[count/2-1].y; relative = true; last_kind = pathData->kind; break; } } //¿©±â±îÁö switch¹®~ } ClearDataList(); //-- vector objectÀÇ Å©±â¸¦ ÃøÁ¤ÇÏ´Â ºÎºÐ --// GetRectSize(data); return true; fail: ClearDataList(); //-- vector objectÀÇ Å©±â¸¦ ÃøÁ¤ÇÏ´Â ºÎºÐ --// GetRectSize(data); return false; } //--------------------------------------------------------------------------- int __fastcall SVGPath::GetPointCount() { int count=0; TPathData *pathData; bool last=false, bLine=false; Char last_kind=0; // 'M'À» Æ÷ÇÔÇÏÁö ¾Ê°í 'P'ºÎÅÍ ½ÃÀÛÇÑ´Ù. µû¶ó¼­ '0'ºÎÅÍ~ for (int i=0; iCount; i++) { pathData = (TPathData*)dataList->Items[i]; switch(pathData->kind) { case L'P': if (bLine) count+=3; //L´ÙÀ½ Á¡À» Æ÷ÇÔÇÏ¿© µÎ°³°¡ ´õ Ãß°¡(3°³ÀÇ Á¡ÀÌ ÇÊ¿äÇϱâ Çϱ⠶§¹®) else count++; break; case L'C': case L'c': //Á÷¼±À» ó¸®ÇÏ´ø Áß°£¿¡ Ä¿ºê¸¦ ´Ù½Ã ±×¸®°Ô µÇ¸é Á÷¼±À» ó¸®ÇÒ ¶§ 3°³ÀÇ Á¡ÀÌ °°°í ÀÌ¹Ì //3°³ÀÇ Á¡ÀÌ ÀԷµǾ Ä¿ºêÀÇ Ã¹¹øÂ° ÄÁÆ®·Ñ¸¦ ÀÔ·ÂÇÏ¸é ¾ÈµÈ´Ù. ÀÔ·ÂÇÏ¸é °³¼ö°¡ Çϳª //Â÷À̰¡ ³ª°Ô µÈ´Ù. ±×·¡¼­ i+=2·Î ÄÁÆ®·Ñ Æ÷ÀÎÆ® ºÎºÐÀ» °Ç³Ê ¶Ù°Ô Çß´Ù. if (last_kind == L'L' || last_kind == L'V' || last_kind == L'H') i+=2; last = false; bLine = false; last_kind = L'C'; break; case L'S': case L's': last = false; bLine = false; count+=2; last_kind = L'S'; break; case L'L': case L'l': last = true; bLine = true; if (last_kind == 0 || last_kind == L'C' || last_kind == L'S') //ÇϳªÀÇ ÁÂÇ¥°¡ 2°³ÀÇ Á¡À¸·Î ±¸¼ºµÇ¾î¼­ 2¸¦ ´õÇÑ´Ù. count+=2; //¸¶Áö¸· ÁÂÇ¥¸¦ µÎ¹ø ½á¾ß ÇÑ´Ù. Control point¸¦ ¸¶Áö¸· ÁÂÇ¥¿Í °°°ÔÇϱâ À§Çؼ­ last_kind = L'L'; break; case L'V': case L'v': count+=5; //V´ÙÀ½ Á¡À» Æ÷ÇÔÇÏ¿© µÎ°³°¡ ´õ Ãß°¡(3°³ÀÇ Á¡ÀÌ ÇÊ¿äÇϱâ Çϱ⠶§¹®) last = true; bLine = false; if (last_kind == 0 || last_kind == L'C' || last_kind == L'S') count+=2; //¸¶Áö¸· ÁÂÇ¥¸¦ µÎ¹ø ½á¾ß ÇÑ´Ù. Control point¸¦ ¸¶Áö¸· ÁÂÇ¥¿Í °°°ÔÇϱâ À§Çؼ­ last_kind = L'V'; break; case L'H': case L'h': count+=5; //V´ÙÀ½ Á¡À» Æ÷ÇÔÇÏ¿© µÎ°³°¡ ´õ Ãß°¡(3°³ÀÇ Á¡ÀÌ ÇÊ¿äÇϱâ Çϱ⠶§¹®) last = true; bLine = false; if (last_kind == 0 || last_kind == L'C' || last_kind == L'S') count+=2; //¸¶Áö¸· ÁÂÇ¥¸¦ µÎ¹ø ½á¾ß ÇÑ´Ù. Control point¸¦ ¸¶Áö¸· ÁÂÇ¥¿Í °°°ÔÇϱâ À§Çؼ­ last_kind = L'H'; break; } //¿©±â±îÁö switch¹®~ } if (last) count-=2; //'L', 'V', 'H'·Î ³¡ÀÌ ³ª¸é Á¡ÀÌ µÎ°³¸é µÇ±â ¶§¹®¿¡ count /=2; return count/3; } //--------------------------------------------------------------------------- bool __fastcall SVGPath::ProcessMotiveCDATA(String cData, TVecData *data) { int start=0, sVersion=0; String returnData; float sFloat; //File Version°ü¸®°¡ ÇÊ¿äÇÒ °Í °°¾Æ¼­ Ãß°¡Çß´Ù. start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, sVersion)) return false; ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->mode)) return false; start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->gap = sFloat; start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->motivecount)) return false; ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->proportion = sFloat; start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->childwidth = sFloat; start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->childheight = sFloat; ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->centerX = sFloat; start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->centerY = sFloat; start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->ChildCount)) return false; if (data->ChildList) data->DeleteChildList(); data->bMotive = true; data->ChildList = new TList; return true; } //--------------------------------------------------------------------------- bool __fastcall SVGPath::AddMotiveChildData(TVecData *data, int parentID, TList *MotiveIDList) { TMotiveParent* item = NULL; for (int i = 0; i < MotiveIDList->Count; i++) { item = (TMotiveParent*)MotiveIDList->Items[i]; if (item->id == parentID && item->data && item->data->ChildList) { item->data->ChildList->Add(data); break; } } } //--------------------------------------------------------------------------- //-- Pattern Prcess --// //--------------------------------------------------------------------------- //todo: SVGPattern Class --------------------------------------------------// __fastcall SVGPattern::SVGPattern() { PatternAngle=0, PatternAdjustX=0, PatternAdjustY=0, RatioX=0, RatioY=0; PatternWidth=0, PatternHeight=0; patternBitmap = NULL; } //--------------------------------------------------------------------------- __fastcall SVGPattern::~SVGPattern() { if (patternBitmap) delete patternBitmap; patternBitmap = NULL; } //--------------------------------------------------------------------------- bool __fastcall SVGPattern::AddData(TiXmlNode* XmlNode) { int length = 0; String attr_name, tString; TiXmlNode *AttributeNode, *childNode, *nextSibling; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "id") { id = pAttrib->Value(); break; } pAttrib = pAttrib->Next(); } //Pattern¿¡ child node°¡ image Çϳª»ÓÀÌ ¾ø´Ù. childNode = XmlNode->FirstChild(); if (childNode == NULL) return false; //child°¡ ¾ø°Å³ª nextSibling = childNode->NextSibling(); if (nextSibling != NULL) return false; //child°¡ 2°³ ÀÌ»óÀÌ¸é ¹®Á¦ attr_name = childNode->Value(); pElement = childNode->ToElement(); pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "width") { tString = pAttrib->Value(); if (TryStrToFloat(tString, width)) { } else { width = (tString.SubString(1, tString.Length()-2)).ToDouble(); } } else if (attr_name == "height") { tString = pAttrib->Value(); if (TryStrToFloat(tString, height)) { } else { height = (tString.SubString(1, tString.Length()-2)).ToDouble(); } } else if (attr_name == "xlink:href") { xlink_uri = pAttrib->Value(); } else if (attr_name == "xlink:sourcehref") { xlink_srcuri = pAttrib->Value(); } pAttrib = pAttrib->Next(); } return true; } //--------------------------------------------------------------------------- ///xlink_uri¿¡ ¸í½ÃµÈ ºñÆ®¸ÊÀ» ·ÎµåÇÑ´Ù. //2007.08.14.diekun. bool __fastcall SVGPattern::LoadBitmap(TiXmlNode* XmlNode, String dn) { String fullname, fn, t_fn; t_fn = xlink_uri.SubString(1, xlink_uri.Length()-4); //t_fn += "_s.jpg"; t_fn += "_s"; t_fn += ".jpg"; for (int i=0; iCreate(width, height, 24); if (!patternBitmap->LoadFromFile(fullname.c_str())) { delete patternBitmap; //(06.06.23) Ãß°¡ patternBitmap = NULL; return false; } return true; } //--------------------------------------------------------------------------- ///xlink_uri¿¡ ¸í½ÃµÈ ºñÆ®¸ÊÀ» B64¹æ½ÄÀ¸·Î ·ÎµåÇÑ´Ù. //2007.08.14.diekun. bool __fastcall SVGPattern::LoadBitmapB64(TiXmlNode* XmlNode, String dn) { const String strB64Start = "data:image/jpeg;base64,"; if( strB64Start!=xlink_srcuri.SubString(1, strB64Start.Length()) ) { //return false; return LoadBitmap(XmlNode, dn); } String strB64RawCode, strB64Code; strB64RawCode = xlink_srcuri.SubString(1 + strB64Start.Length(), xlink_srcuri.Length() - strB64Start.Length() ); strB64Code = strB64RawCode; while( strB64RawCode.Pos("\n") ) { int partLength = strB64RawCode.Pos("\n") - 1; strB64Code += strB64RawCode.SubString(1, partLength); strB64RawCode.Delete(1, partLength); } //////// //Base64¹æ½Ä¿¡¸¸ »ç¿ëµÇ´Â imgBuffer¿Í imgB64BufferÀÇ ÇÒ´ç //todo:2007.07.31.diekun. ¹öÆÛÀÇ »çÀÌÁî°¡ ÇöÀç 1¸Þ°¡·Î °íÁ¤µÇ¾î ÀÖÀ¸¹Ç·Î ÃßÈÄ ¿ë·®¹®Á¦°¡ »ý±æ ¼ö ÀÖ´Ù. //À̶§´Â LeadToolsÀÇ L_SaveBitmapBufferÀÇ callbackÇÔ¼ö »ç¿ë¹ýÀ» Âü°íÇÏ¿© ¼öÁ¤ÇØ¾ß ÇÑ´Ù. char* imgBuffer; imgBuffer = (char*)malloc(pow(2,20) * sizeof(char)); if(imgBuffer==NULL) { if(imgBuffer) free(imgBuffer); ShowMessage(IDS_MESSAGE_MEMORYLACK); return false; //<¸Þ¸ð¸® ÇÒ´ç ½ÇÆÐ } //////// unsigned int fileSize; AnsiString buff = strB64Code; fileSize = Base64Decode(buff.c_str(), strB64Code.Length(), imgBuffer); if(fileSize==-1) { free(imgBuffer); return false; } HANDLE hFile; DWORD dwWrote; hFile = CreateFile(L"temp.tmp", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS ,FILE_ATTRIBUTE_NORMAL, NULL); if( hFile == INVALID_HANDLE_VALUE ) { free(imgBuffer); return false; } WriteFile(hFile, imgBuffer, fileSize, &dwWrote, NULL); if( fileSize != dwWrote ) { free(imgBuffer); CloseHandle(hFile); DeleteFile("temp.tmp"); return false; } CloseHandle(hFile); patternBitmap = new TTexpiaBitmap; patternBitmap->Create(width, height, 24); if (!patternBitmap->LoadFromFile("temp.tmp")) { delete patternBitmap; //(06.06.23) Ãß°¡ patternBitmap = NULL; free(imgBuffer);//< À̹ÌÁö ¹öÆÛ¿¡ ÇÒ´çµÈ ¸Þ¸ð¸®¸¦ »èÁ¦ÇØÁØ´Ù. return false; } // free(imgBuffer);//< À̹ÌÁö ¹öÆÛ¿¡ ÇÒ´çµÈ ¸Þ¸ð¸®¸¦ »èÁ¦ÇØÁØ´Ù. //////// DeleteFile("temp.tmp"); return true; } //--------------------------------------------------------------------------- void __fastcall SVGPattern::ProcessPatternCDATA(String cData) { int start=0, sVersion=0; String returnData; //File Version°ü¸®°¡ ÇÊ¿äÇÒ °Í °°¾Æ¼­ Ãß°¡Çß´Ù. start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, sVersion)) return; // sVersion = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, PatternAngle)) return; // PatternAngle = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, PatternAdjustX)) return; // PatternAdjustX = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, PatternAdjustY)) return; // PatternAdjustY = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, RatioX)) return; // RatioX = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, RatioY)) return; // RatioY = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, PatternWidth)) return; // PatternWidth = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, PatternHeight)) return; // PatternHeight = returnData.ToInt(); } //--------------------------------------------------------------------------- //-- RECT Prcess --// //--------------------------------------------------------------------------- //todo: SVGRect Class -----------------------------------------------------// __fastcall SVGRect::SVGRect(int instance) { dataList = NULL; Instance = instance; x=0, y=0, width=0, height=0, rx=0, ry=0; } //--------------------------------------------------------------------------- bool __fastcall SVGRect::AddData(TiXmlNode* XmlNode, TVecData *data) { data->Kind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor) 0; //stroke data->PenThick = 1; int length = 0; String attr_name, tString; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "fill") { // data->Brush tString = pAttrib->Value(); if (tString != "none" && tString.c_str()[0]==L'#') { length = tString.Length(); tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); data->bFill = true; } } else if (attr_name == "stroke") { // data->Color tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "x") { tString = pAttrib->Value(); x = tString.ToDouble(); } else if (attr_name == "y") { tString = pAttrib->Value(); y = tString.ToDouble(); } else if (attr_name == "rx") { tString = pAttrib->Value(); rx = tString.ToDouble(); } else if (attr_name == "ry") { tString = pAttrib->Value(); ry = tString.ToDouble(); } else if (attr_name == "width") { tString = pAttrib->Value(); width = tString.ToDouble(); } else if (attr_name == "height") { tString = pAttrib->Value(); height = tString.ToDouble(); } pAttrib = pAttrib->Next(); } if (MakePoint(data)) return true; else return false; } //--------------------------------------------------------------------------- bool __fastcall SVGRect::MakePoint(TVecData *data) { data->bClosed = true; data->nCount = 4; //½ÃÀÛÁ¡ 2°³, µÎ¹øÂ°, 3°³, ¼¼¹øÂ° 3°³, ³×¹øÂ° 3°³, ½ÃÀÛÁ¡ 2°³ => 13°³Á¡ // 4 x 3 + 1 = 13 if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); if (rx || ry) data->bRound = true; else data->bRound = false; //½ÃÀÛÁ¡ 2°³ data->pList[0].x = x; data->pList[0].y = y; data->pList[1].x = x; data->pList[1].y = y; //µÎ¹øÂ°, 3°³ data->pList[2].x = x+width; data->pList[2].y = y; data->pList[3].x = x+width; data->pList[3].y = y; data->pList[4].x = x+width; data->pList[4].y = y; //¼¼¹øÂ°, 3°³ data->pList[5].x = x+width; data->pList[5].y = y+height; data->pList[6].x = x+width; data->pList[6].y = y+height; data->pList[7].x = x+width; data->pList[7].y = y+height; //³×¹øÂ°, 3°³ data->pList[8].x = x; data->pList[8].y = y+height; data->pList[9].x = x; data->pList[9].y = y+height; data->pList[10].x = x; data->pList[10].y = y+height; //½ÃÀÛÁ¡ 2°³ data->pList[11].x = x; data->pList[11].y = y; data->pList[12].x = x; data->pList[12].y = y; //-- vector objectÀÇ Å©±â¸¦ ÃøÁ¤ÇÏ´Â ºÎºÐ --// GetRectSize(data); return true; } //--------------------------------------------------------------------------- //-- Circle Prcess --// //--------------------------------------------------------------------------- //todo: SVGCircle Class ---------------------------------------------------// __fastcall SVGCircle::SVGCircle(int instance) { dataList = NULL; Instance = instance; cx = 0, cy = 0, r = 0; } //--------------------------------------------------------------------------- bool __fastcall SVGCircle::AddData(TiXmlNode* XmlNode, TVecData *data) { data->Kind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor) 0; //stroke data->PenThick = 1; int length = 0; String attr_name, tString; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "fill") { // data->Brush tString = pAttrib->Value(); if (tString != "none" && tString.c_str()[0]==L'#') { length = tString.Length(); tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); data->bFill = true; } } else if (attr_name == "stroke") { // data->Color tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "cx") { tString = pAttrib->Value(); cx = tString.ToDouble(); } else if (attr_name == "cy") { tString = pAttrib->Value(); cy = tString.ToDouble(); } else if (attr_name == "r") { tString = pAttrib->Value(); r = tString.ToDouble(); } pAttrib = pAttrib->Next(); } if (MakePoint(data)) return true; else return false; } //--------------------------------------------------------------------------- bool __fastcall SVGCircle::MakePoint(TVecData *data) { data->nCount = 4; if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); double pFstX = cx - r , pFstY = cy - r, pScdX = cx + r, pScdY = cy + r; double M = 0.55228474983; double dx = abs(long(pFstX-pScdX))/2.0, dy = abs(long(pFstY-pScdY))/2.0; double ddx = dx * M, ddy = dy * M; data->First.x = pFstX, data->First.y = pFstY; data->Second.x = pScdX, data->Second.y = pScdY; data->bAntialiasing = true; // ½Ã°è ¹æÇâÀ¸·Î ±×¸°´Ù (ÆÐ½º¸¦ µû¶ó°¡´Â ¹®ÀÚ ¶§¹®¿¡ º¯°æ) - by monkman (2005.05.06) data->pList[12].DPoint((pFstX+pScdX)/2.0, pFstY); data->pList[11].DPoint((pFstX+pScdX)/2.0-ddx, pFstY); data->pList[10].DPoint(pFstX, (pFstY+pScdY)/2.0-ddy); data->pList[9].DPoint(pFstX, (pFstY+pScdY)/2.0); data->pList[8].DPoint(pFstX, (pFstY+pScdY)/2+ddy); data->pList[7].DPoint((pFstX+pScdX)/2.0-ddx, pScdY); data->pList[6].DPoint((pFstX+pScdX)/2.0, pScdY); data->pList[5].DPoint((pFstX+pScdX)/2.0+ddx, pScdY); data->pList[4].DPoint(pScdX, (pFstY+pScdY)/2.0+ddy); data->pList[3].DPoint(pScdX, (pFstY+pScdY)/2.0); data->pList[2].DPoint(pScdX, (pFstY+pScdY)/2.0-ddy); data->pList[1].DPoint((pFstX+pScdX)/2.0+ddx, pFstY); data->pList[0].DPoint((pFstX+pScdX)/2.0, pFstY); data->bClosed = true; return true; } //--------------------------------------------------------------------------- //-- Ellipse Prcess --// //--------------------------------------------------------------------------- //todo: SVGEllipse Class --------------------------------------------------// __fastcall SVGEllipse::SVGEllipse(int instance) { dataList = NULL; Instance = instance; cx = 0, cy = 0, rx = 0, ry = 0; } //--------------------------------------------------------------------------- bool __fastcall SVGEllipse::AddData(TiXmlNode* XmlNode, TVecData *data) { data->Kind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor) 0; //stroke data->PenThick = 1; int length = 0; String attr_name, tString; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "fill") { // data->Brush tString = pAttrib->Value(); if (tString != "none" && tString.c_str()[0]=='#') { length = tString.Length(); tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); data->bFill = true; } } else if (attr_name == "stroke") { // data->Color tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "cx") { tString = pAttrib->Value(); cx = tString.ToDouble(); } else if (attr_name == "cy") { tString = pAttrib->Value(); cy = tString.ToDouble(); } else if (attr_name == "rx") { tString = pAttrib->Value(); rx = tString.ToDouble(); } else if (attr_name == "ry") { tString = pAttrib->Value(); ry = tString.ToDouble(); } pAttrib = pAttrib->Next(); } if (MakePoint(data)) return true; else return false; } //--------------------------------------------------------------------------- bool __fastcall SVGEllipse::MakePoint(TVecData *data) { data->nCount = 4; if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); double pFstX = cx - rx, pFstY = cy - ry, pScdX = cx + rx, pScdY = cy + ry; double M = 0.55228474983; double dx = abs(long(pFstX-pScdX))/2.0, dy = abs(long(pFstY-pScdY))/2.0; double ddx = dx * M, ddy = dy * M; data->First.x = pFstX, data->First.y = pFstY; data->Second.x = pScdX, data->Second.y = pScdY; data->bAntialiasing = true; // ½Ã°è ¹æÇâÀ¸·Î ±×¸°´Ù (ÆÐ½º¸¦ µû¶ó°¡´Â ¹®ÀÚ ¶§¹®¿¡ º¯°æ) - by monkman (2005.05.06) data->pList[12].DPoint((pFstX+pScdX)/2.0, pFstY); data->pList[11].DPoint((pFstX+pScdX)/2.0-ddx, pFstY); data->pList[10].DPoint(pFstX, (pFstY+pScdY)/2.0-ddy); data->pList[9].DPoint(pFstX, (pFstY+pScdY)/2.0); data->pList[8].DPoint(pFstX, (pFstY+pScdY)/2+ddy); data->pList[7].DPoint((pFstX+pScdX)/2.0-ddx, pScdY); data->pList[6].DPoint((pFstX+pScdX)/2.0, pScdY); data->pList[5].DPoint((pFstX+pScdX)/2.0+ddx, pScdY); data->pList[4].DPoint(pScdX, (pFstY+pScdY)/2.0+ddy); data->pList[3].DPoint(pScdX, (pFstY+pScdY)/2.0); data->pList[2].DPoint(pScdX, (pFstY+pScdY)/2.0-ddy); data->pList[1].DPoint((pFstX+pScdX)/2.0+ddx, pFstY); data->pList[0].DPoint((pFstX+pScdX)/2.0, pFstY); data->bClosed = true; return true; } //--------------------------------------------------------------------------- //-- Line Prcess --// //--------------------------------------------------------------------------- //todo: SVGLine Class -----------------------------------------------------// __fastcall SVGLine::SVGLine(int instance) { dataList = NULL; Instance = instance; } //--------------------------------------------------------------------------- __fastcall SVGLine::~SVGLine() { } //--------------------------------------------------------------------------- bool __fastcall SVGLine::AddData(TiXmlNode* XmlNode, TVecData *data) { data->Kind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor) 0; //stroke data->PenThick = 1; String attr_name, tString, temp; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "stroke") { // data->Brush tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "stroke-linecap") { tString = pAttrib->Value(); if (tString == "round") data->bRound = true; } else if (attr_name == "stroke-linejoin") { tString = pAttrib->Value(); if (tString == "round") data->bRound = true; } else if (attr_name == "stroke-dasharray") { // 06.09.20 by maxleo21c tString = pAttrib->Value(); float no1=0, no2=0; for (int i=0; iPenStyle = P_DASH; else if (abs(long(no2-no1))!=1 && no1 != 1) { data->PenStyle = P_USERSTYLE; data->DashValues[0] = 2; data->DashValues[1] = no1; data->DashValues[2] = no2; } else data->PenStyle = P_DOT; } else if (attr_name == "x1") { tString = pAttrib->Value(); x1 = tString.ToDouble(); } else if (attr_name == "y1") { tString = pAttrib->Value(); y1 = tString.ToDouble(); } else if (attr_name == "x2") { tString = pAttrib->Value(); x2 = tString.ToDouble(); } else if (attr_name == "y2") { tString = pAttrib->Value(); y2 = tString.ToDouble(); } pAttrib = pAttrib->Next(); } if (MakePoint(data)) return true; else return false; } //--------------------------------------------------------------------------- bool __fastcall SVGLine::MakePoint(TVecData *data) { data->bClosed = false; data->nCount = 1; //½ÃÀÛÁ¡ 2°³, ¸¶Áö¸·Á¡ 2°³ // 1 x 3 + 1= 4 if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); //½ÃÀÛÁ¡ 2°³ data->pList[0].x = x1; data->pList[0].y = y1; data->pList[1].x = x1; data->pList[1].y = y1; //¸¶Áö¸·Á¡ 2°³ data->pList[2].x = x2; data->pList[2].y = y2; data->pList[3].x = x2; data->pList[3].y = y2; //-- vector objectÀÇ Å©±â¸¦ ÃøÁ¤ÇÏ´Â ºÎºÐ --// GetRectSize(data); return true; } //--------------------------------------------------------------------------- //-- Poly Prcess --// //--------------------------------------------------------------------------- //todo: SVGPoly Class -----------------------------------------------------// __fastcall SVGPoly::SVGPoly(int instance, bool _polygon) { polygon = _polygon; dataList = NULL; Instance = instance; pointList = new TList; } //--------------------------------------------------------------------------- __fastcall SVGPoly::~SVGPoly() { double *t_num; for (int i = 0; i < pointList->Count; i++) { t_num=(double*)pointList->Items[i]; delete t_num; t_num=NULL; } pointList->Clear(); delete pointList; pointList = NULL; } //--------------------------------------------------------------------------- bool __fastcall SVGPoly::AddData(TiXmlNode* XmlNode, TVecData *data) { data->Kind = V_CURVE; data->bRound = false; data->PenStyle = P_SOLID; data->Color = (TColor) 0; //stroke data->PenThick = 1; int length = 0; String attr_name, tString, temp; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "points") { points = pAttrib->Value(); if (!MakePoint(data)) return false; } else if (attr_name == "fill") { // data->Color tString = pAttrib->Value(); if (tString != "none" && tString.c_str()[0]==L'#') { length = tString.Length(); tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); data->bFill = true; } } else if (attr_name == "stroke") { // data->Brush tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "fill-rule") { tString = pAttrib->Value(); if (tString == "evenodd") data->bWinding = false; else data->bWinding = true; } else if (attr_name == "stroke-dasharray") { // 06.09.20 by maxleo21c tString = pAttrib->Value(); float no1=0, no2=0; for (int i=0; iPenStyle = P_DASH; else if (abs(long(no2-no1))!=1 && no1 != 1) { data->PenStyle = P_USERSTYLE; data->DashValues[0] = 2; data->DashValues[1] = no1; data->DashValues[2] = no2; } else data->PenStyle = P_DOT; } pAttrib = pAttrib->Next(); } return true; } //--------------------------------------------------------------------------- bool __fastcall SVGPoly::MakePoint(TVecData *data) { int count=0, check; double *t_num; data->nCount = GetPoint()/3; if (data->nCount < 1) return false; // 1024 Á¦ÇÑ Ç®·ÈÀ½ - by monkman (2011.04.20) //if (data->nCount*3+1 > MAX_DATA_NCOUNT) return false; if (data->pList != NULL) { HeapFree(GetProcessHeap(), 0, data->pList); data->pList = NULL; } data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (data->nCount * 3 + 1) % 8 == 0 ? (data->nCount * 3 + 1) / 8 : (data->nCount * 3 + 1) / 8 + 1); for (int i=0; iCount; i++) { t_num = (double*)pointList->Items[i]; check = count/2; if (count%2) { //y °ªÀÌ µé¾î°¡´Â ºÎºÐ À̰÷¿¡¼­ pList¿¡ À§Ä¡°ªÀ» ´ëÀÔÇÑ´Ù. if (i==1 || (i==pointList->Count-1 && !polygon)) { //ù¹øÂ° point´Â µÎ°³ÀÇ Á¡À¸·Î µÇ°í ³ª¸ÓÁö´Â 3°³ÀÇ Á¡À¸·Î ±¸¼ºµÈ´Ù. data->pList[check].y = *t_num; data->pList[check+1].x = data->pList[check].x; data->pList[check+1].y = data->pList[check].y; count+=2; //2°³ÀÇ Á¡ÀÌ Ãß°¡µÇ¾ú±â ¶§¹®¿¡ } else { //ÀÏ¹Ý ¼¼°³ÀÇ Á¡À¸·Î ±¸¼º data->pList[check].y = *t_num; data->pList[check+1].x = data->pList[check].x; data->pList[check+1].y = data->pList[check].y; data->pList[check+2].x = data->pList[check].x; data->pList[check+2].y = data->pList[check].y; count+=4; //4°³ÀÇ Á¡ÀÌ Ãß°¡µÇ¾ú±â ¶§¹®¿¡ } } else { //x °ªÀÌ µé¾î°¡´Â ºÎºÐÀÌ´Ù. data->pList[check].x = *t_num; } count++; } if (polygon) { check = count/2; data->pList[check].x = data->pList[0].x; data->pList[check].y = data->pList[0].y; data->pList[check+1].x = data->pList[0].x; data->pList[check+1].y = data->pList[0].y; } //-- vector objectÀÇ Å©±â¸¦ ÃøÁ¤ÇÏ´Â ºÎºÐ --// GetRectSize(data); return true; } //--------------------------------------------------------------------------- int __fastcall SVGPoly::GetPoint() { String tPoint=""; bool check=false; bool bMinusNum=false; int check_count = 0; double temp, *t_num; bool isFirst = true; int minus = 1; for (int i=0; iAdd(t_num); if (points.c_str()[i] == L'-') { //À½¼ö°¡ µé¾î°¡ ÀÖ´Â °ÍÀ» ó¸®Çϱâ À§Çؼ­ bMinusNum = true; //À½¼öÀÏ °æ¿ì ó¸®ÇÏ´Â ¿©ºÎ } check = false; tPoint = ""; } else { tPoint+=points.c_str()[i]; } } if (tPoint.Length()) { temp = tPoint.ToDouble(); if (bMinusNum) { temp *= -1; bMinusNum = false; } t_num = new double; *t_num = temp; pointList->Add(t_num); } if (polygon) //ù¹øÂ° 2°³ÀÇ Á¡, ³ª¸ÓÁö´Â 3°³ÀÇ Á¡ = (count-1)*3, ´Ù½Ã ùÁ¡À¸·Î ¿¬°áÇÏ´Â ¸¶Áö¸·Á¡ 2°³ return 4+(pointList->Count/2-1)*3; else //ù¹øÂ°, ¸¶Áö¸·¹øÂ°´Â 2°³ÀÇ Á¡ = 2*2, ³ª¸ÓÁö´Â 3°³ÀÇ Á¡ = (count-2)*3À¸·Î ±¸¼º µÊ return 4+((pointList->Count/2)-2)*3; } //--------------------------------------------------------------------------- //-- Text Prcess --// //--------------------------------------------------------------------------- //todo: SVGText Class -----------------------------------------------------// __fastcall SVGText::SVGText(int instance) { dataList = NULL; // _dataList => MainImageForm->dataList¸¦ ÀǹÌÇÑ´Ù. Instance = instance; LineCount=0, RealWordCount=0; Version = 100; // ÃÖÃÊ: 100ºÎÅÍ ½ÃÀÛ } //--------------------------------------------------------------------------- __fastcall SVGText::~SVGText() { } //--------------------------------------------------------------------------- void __fastcall SVGText::SearchSVGNode(TiXmlNode* XmlNode, TVecData *data) { if (XmlNode == NULL) return; /////////////////////////////////// String NodeText, NodeName; TiXmlNode *childNode, *nextSibling;; int xml_type; NodeName = XmlNode->Value(); childNode = XmlNode->FirstChild(); xml_type = childNode->Type(); if (NodeName == "tspan" && childNode && xml_type == TiXmlNode::TINYXML_TEXT) { ProcessTspan(XmlNode, data); return; } if (childNode) { NodeName = childNode->Value(); while(childNode) { NodeName = childNode->Value(); SearchSVGNode(childNode, data); childNode = childNode->NextSibling(); } } } //--------------------------------------------------------------------------- bool __fastcall SVGText::AddData(TiXmlNode* XmlNode, TVecData *data) { String NodeText, NodeName; TiXmlNode* pChild; NodeName = XmlNode->Value(); for ( pChild = XmlNode->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { NodeName = pChild->Value(); if (NodeName == "textPath") { ProcessTextPath(pChild, data); return true; } } SearchSVGNode(XmlNode,data); return true; } //--------------------------------------------------------------------------- bool __fastcall SVGText::MakePoint(TVecData *data) { return true; } //--------------------------------------------------------------------------- // ¹®Á¦°¡ À־ ¼öÁ¤ ±×³É returnÀ» ÇÏ¸é ¾ÈµÈ´Ù. ¤Ð¤Ð // by maxleo21c 07.03.10 bool __fastcall SVGText::ProcessTextCDATA(String cData, TVecData *data) { int start=0, sVersion=0, check=0; String returnData, temp; float sFloat; data->Kind = V_TEXTBOX; data->Color = (TColor) 0; data->nCount = 0; data->ListOfAllLine = new TWordList; //File Version°ü¸®°¡ ÇÊ¿äÇÒ °Í °°¾Æ¼­ Ãß°¡Çß´Ù. start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, sVersion)) return false; Version = sVersion; // sVersion = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->First.x = sFloat; // data->First.x = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->First.y = sFloat; // data->First.y = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->Second.x = sFloat; // data->Second.x = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->Second.y = sFloat; // data->Second.y = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->CharH)) return false; // data->CharH = returnData.ToInt(); start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->CharW)) return false; // data->CharW = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, data->TextAngle)) return false; // data->TextAngle = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->StartPoint.x = sFloat; // data->StartPoint.x = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->StartPoint.y = sFloat; // data->StartPoint.y = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->CenterPoint.x = sFloat; // data->CenterPoint.x = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; data->CenterPoint.y = sFloat; // data->CenterPoint.y = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, data->nCount)) return false; // data->nCount = returnData.ToInt(); ///////////////////////////////////////////////// int lineheight, wordcount, linecount, bPathText; //LineCount start = CDATAElement(cData, returnData, start); linecount = returnData.ToInt(); ///////////////////////////////////////////////// TSWordData *srcWordData = {0}; TLineTextBox *lineTextBox; for (int i=0; iLFont.lfFaceName, returnData.c_str()); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->PPoint.x = sFloat; // srcWordData->PPoint.x = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->PPoint.y = sFloat; // srcWordData->PPoint.y = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, srcWordData->UsedByte)) return false; srcWordData->UsedByte = 1; // srcWordData->UsedByte = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, srcWordData->Interval)) return false; // srcWordData->Interval = returnData.ToInt(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->HeightGap = sFloat; // srcWordData->HeightGap = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->WidthGap = sFloat; // srcWordData->WidthGap = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); // bPathText = returnData.ToInt(); if (!TryStrToInt(returnData, bPathText)) return false; ///////////////////////////////////////////////// // if (xLink_data.Length()){ if (bPathText){ start = CDATAElement(cData, returnData, start); if (!TryStrToInt(returnData, check)) return false; // if (returnData.ToInt()) if (check) srcWordData->bNameChanged = true; else srcWordData->bNameChanged = false; ///////////////////////////////////////////////// //-->by linuxjun for CurvedVectorText start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->px = sFloat; // srcWordData->px = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->py = sFloat; // srcWordData->py = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->tx = sFloat; // srcWordData->tx = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->ty = sFloat; // srcWordData->ty = returnData.ToDouble(); ///////////////////////////////////////////////// start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->nx = sFloat; // srcWordData->nx = returnData.ToDouble(); start = CDATAElement(cData, returnData, start); if (!TryStrToFloat(returnData, sFloat)) return false; srcWordData->ny = sFloat; // srcWordData->ny = returnData.ToDouble(); ///////////////////////////////////////////////// //<--by linuxjun for CurvedVectorText } else { srcWordData->bNameChanged = false; } //by linuxjun for CurvedVectorText(Save) if (Version > 100) { // by maxleo21c 070628 for (int k=start, l=0; kUsedByte; k++, l++) { srcWordData->Word[l] = cData.c_str()[k]; } srcWordData->Word[srcWordData->UsedByte] = L'\0'; start += (srcWordData->UsedByte+1); } lineTextBox->LineDataList->Add(srcWordData); } start = CDATAElement(cData, returnData, start); // if (!TryStrToInt(returnData, sFloat)) return; if (!TryStrToInt(returnData, lineTextBox->lineHeight)) return false; // lineTextBox->lineHeight = sFloat; // lineHeight ///////////////////////////////////////////////// data->ListOfAllLine->Add(lineTextBox); } //»ç½Ç pathText¿¡¼­´Â Çʿ䰡 ¾ø´Ù. Å×½ºÆ® ÇÒ¶§ ¿¡·¯°¡ ¹ß»ýÇØ¼­ ³Ö¾ú´Ù. data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*5); if (data->pMask != NULL) HeapFree(GetProcessHeap(), 0, data->pMask); data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, 1); return true; } //--------------------------------------------------------------------------- // textPath´Â ¶óÀÎÀÌ Çϳª»ÓÀÌ ¾ø´Ù. ±ÛÀÚÀÇ Á¾·ù, Å©±â¿¡ µû¸¥ tspanÀÌ ¿©·¯°³°¡ // Á¸ÀçÇÒ ¼ö ÀÖ´Ù. tspan¾Æ·¡¿¡ text°¡ Á¸ÀçÇÑ´Ù. void __fastcall SVGText::ProcessTextPath(TiXmlNode* XmlNode, TVecData *data) { String NodeText, NodeName; TiXmlNode* pChild; TFont *font = MainImageForm->iMainImage->Canvas->Font; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { NodeName = pAttrib->Name(); if (NodeName == "xlink:href") { xLink_data = pAttrib->Value(); //ù¹øÂ° #ÀÌ ºÙ¾î Àֱ⠶§¹®¿¡.... xLink_data = xLink_data.SubString(2, xLink_data.Length()); } pAttrib = pAttrib->Next(); } int wordCount, linecount, start=0, m=0, realWordCount=0; TSWordData *tsWordData; TLineTextBox *lineTextBox; for ( pChild = XmlNode->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { NodeName = pChild->Value(); if (NodeName == "tspan") { wordCount = CheckAttrData(pChild, data); //NodeText = pChild->Value(); linecount = data->ListOfAllLine->GetLineCount(); start=0; for (int j=0; jListOfAllLine->GetLineTextBox(j)->LineDataList->Items[k]; tsWordData->LFont.lfHeight = data->Font.lfHeight; tsWordData->LFont.lfWidth = 0; tsWordData->LFont.lfEscapement = data->TextAngle*10; if (data->Font.lfItalic) tsWordData->LFont.lfItalic = data->Font.lfItalic; else tsWordData->LFont.lfItalic = false; if (data->Font.lfWeight == FW_BOLD) tsWordData->LFont.lfWeight = FW_BOLD; else tsWordData->LFont.lfWeight = FW_NORMAL; tsWordData->LFont.lfUnderline = false; tsWordData->LFont.lfStrikeOut = false; tsWordData->LFont.lfCharSet = font->Charset; tsWordData->LFont.lfOrientation = 0; tsWordData->LFont.lfPitchAndFamily = font->Pitch | FF_DONTCARE; tsWordData->LFont.lfOutPrecision = OUT_DEFAULT_PRECIS; tsWordData->LFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; tsWordData->LFont.lfQuality = DEFAULT_QUALITY; tsWordData->Color = data->Brush; if (Version == 100) { m = 0; for (int l=start; lUsedByte; l++) { tsWordData->Word[m] = NodeText.c_str()[l]; m++; } tsWordData->Word[m] = L'\0'; start += tsWordData->UsedByte; } } realWordCount+=wordCount; } } } } //--------------------------------------------------------------------------- void __fastcall SVGText::ProcessTspan(TiXmlNode* XmlNode, TVecData *data) { String NodeText, NodeName; TFont *font = MainImageForm->iMainImage->Canvas->Font; int wordCount, start=0, m=0; TSWordData *tsWordData; TLineTextBox *lineTextBox; lineTextBox = static_cast(data->ListOfAllLine->GetLineTextBox(LineCount)); wordCount = CheckAttrData(XmlNode, data); NodeText = XmlNode->Value(); start=0; int dataWordcount; dataWordcount = static_cast(lineTextBox->LineDataList)->Count; /* //¿¡·¯°¡ ³ª¼­ svg input Ãʱ⠰³¹ß¶§ ÀÌ ºÎºÐÀ» ¸¸µé¾î ³õ¾Ò´Ù. //ÇÏÁö¸¸ ¹®Á¦°¡ À־ 070807 ÁÖ¼®À¸·Î ó¸® //ÀÌÀ¯: fontÀÇ Á¾·ù°¡ ´Ù¸¦ °æ¿ì tspanÀÌ ³ª´µ¾î Áö´Âµ¥ ±×·² °æ¿ì texstylist¿¡¼­´Â Çѹ®Àå //ÀÌÁö¸¸ svg¿¡¼­´Â ¿©·¯°³ÀÇ tspanÀ¸·Î ³ª´µ¾î Áø´Ù. À̶§ RealWordCount·Î texstylist¿¡¼­ //data À§Ä¡¸¦ È®ÀÎÇØ¾ß ÇÑ´Ù. µû¶ó¼­ ±×³É Áö¿ö ¹ö¸®¸é ¾ÈµÇ±â ¶§¹®¿¡ ÁÖ¼®À¸·Î ó¸®Çß°í // if (dataWordcount > wordCount) { for (int i=wordCount; i(lineTextBox->LineDataList->Items[i]); static_cast(lineTextBox->LineDataList)->Remove(tsWordData); delete tsWordData; tsWordData=NULL; } } */ for (int k=RealWordCount; k(data->ListOfAllLine->GetLineTextBox(LineCount)->LineDataList->Items[k]); tsWordData->LFont.lfHeight = data->Font.lfHeight; tsWordData->LFont.lfWidth = 0; tsWordData->LFont.lfEscapement = data->TextAngle*10; if (data->Font.lfItalic) tsWordData->LFont.lfItalic = data->Font.lfItalic; else tsWordData->LFont.lfItalic = false; if (data->Font.lfWeight == FW_BOLD) tsWordData->LFont.lfWeight = FW_BOLD; else tsWordData->LFont.lfWeight = FW_NORMAL; tsWordData->LFont.lfUnderline = false; tsWordData->LFont.lfStrikeOut = false; tsWordData->LFont.lfCharSet = font->Charset; tsWordData->LFont.lfOrientation = 0; tsWordData->LFont.lfPitchAndFamily = font->Pitch | FF_DONTCARE; tsWordData->LFont.lfOutPrecision = OUT_DEFAULT_PRECIS; tsWordData->LFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; tsWordData->LFont.lfQuality = DEFAULT_QUALITY; tsWordData->Color = data->Brush; if (Version == 100) { // by maxleo21c 070627 m = 0; for (int l=start; lUsedByte; l++) { tsWordData->Word[m] = NodeText.c_str()[l]; m++; } tsWordData->Word[m] = L'\0'; start += tsWordData->UsedByte; } if (tsWordData->Word[0] == L'\n') { tsWordData->Word[0] = L'\r'; LineCount++; RealWordCount=0; wordCount=0; } } RealWordCount+=wordCount; if (dataWordcount == RealWordCount) { //070807 RealWordCount = 0; } } //--------------------------------------------------------------------------- void __fastcall SVGText::ProcessTref(TiXmlNode* XmlSubNode) { } //--------------------------------------------------------------------------- // attributeÀ» È®ÀÎÇϱâ À§Çؼ­ int __fastcall SVGText::CheckAttrData(TiXmlNode* XmlSubNode, TVecData *data) { int length=0, sameFontcount=0; String attr_name, tString; TiXmlNode* AttributeNode; data->Font.lfItalic = 0; data->Font.lfWeight = FW_NORMAL; data->Brush = clBlack; data->Color = clBlack; // 06.09.26 by maxleo21c TiXmlElement* pElement = XmlSubNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); const char *buff; while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "fill") { // data->Brush tString = pAttrib->Value(); if (tString != "none" && tString.c_str()[0]==L'#') { length = tString.Length(); tString = tString.SubString(2, length-1); data->Brush = SVGColor2TColor(tString); // data->bFill = true; } } else if (attr_name == "stroke") { // data->Color tString = pAttrib->Value(); if (tString.c_str()[0]!=L'#') continue; tString = tString.SubString(2, tString.Length()-1); data->Color = SVGColor2TColor(tString); } else if (attr_name == "stroke-width") { tString = pAttrib->Value(); data->PenThick = tString.ToDouble(); } else if (attr_name == "font-family") { buff = pAttrib->Value(); tString = Utf8ToAnsi(buff); _tcscpy(data->Font.lfFaceName, tString.c_str()); } else if (attr_name == "font-size") { tString = pAttrib->Value(); data->Font.lfHeight = tString.ToDouble(); } else if (attr_name == "font-style") { tString = pAttrib->Value(); if (tString == "italic") data->Font.lfItalic = true; } else if (attr_name == "font-weight") { tString = pAttrib->Value(); if (tString == "bold") data->Font.lfWeight = FW_BOLD; } else if (attr_name == "length") { tString = pAttrib->Value(); sameFontcount = tString.ToInt(); } pAttrib = pAttrib->Next(); } return sameFontcount; } //--------------------------------------------------------------------------- void __fastcall SVGText::AddWordData(String nodeText, TVecData *data) { } //--------------------------------------------------------------------------- // 07.03.09 by maxleo21c void __fastcall SVGText::ModifyData(TVecData *data) { TWordList *ListOfAllLine; ListOfAllLine = static_cast(data->ListOfAllLine); int linecount = ListOfAllLine->GetLineCount(); ///< ÀüÁ¦ ¶óÀμö ±¸ÇÏ´Â ÇÔ¼ö LineCount++; ///< XML¿¡¼­ °è»êµÈ ¶óÀÎÀÇ °³¼ö, +1Àº ÃʱⰪÀÌ 0À̱⠶§¹® if (LineCount < linecount) { for (int i=LineCount; iDeleteLine(i); } } int allwordcount = ListOfAllLine->GetCount(); ///< ÀüÁ¦ ¿öµå°³¼ö¸¦ ±¸ÇÏ´Â ÇÔ¼ö if (data->nCount != allwordcount) data->nCount = allwordcount; } //--------------------------------------------------------------------------- //todo: TSVG2Vector Class -------------------------------------------------// //--------------------------------------------------------------------------- __fastcall TSVG2Vector::TSVG2Vector() { // ÀÌ ¹öÀüÀº ÆÄÀÏ Æ¯È÷ CDATA¿¡ ³»¿ëÀ» ±¸ºÐÇϱâ À§Çؼ­ »ç¿ëµÈ´Ù. Version = 100; //by maxleo21c(ÆÄÀÏ In/Out ÃÖÃÊ ¹öÀü) - (06.06.22) ListforPathText = NULL; } //--------------------------------------------------------------------------- __fastcall TSVG2Vector::TSVG2Vector(TList *sDataList, int instance) { // ÀÌ ¹öÀüÀº ÆÄÀÏ Æ¯È÷ CDATA¿¡ ³»¿ëÀ» ±¸ºÐÇϱâ À§Çؼ­ »ç¿ëµÈ´Ù. Version = 100; //by maxleo21c(ÆÄÀÏ In/Out ÃÖÃÊ ¹öÀü) - (06.06.22) Instance = instance; dataList = sDataList; isOwnText = false; ListforPathText = new TList; PatternList = new TList; MotiveIDList = new TList; } //--------------------------------------------------------------------------- __fastcall TSVG2Vector::~TSVG2Vector() { TCurveForTextPath *items = NULL; SVGPattern *patternItems = NULL; TMotiveParent *motiveItems = NULL; if (ListforPathText) { for (int i = 0; i < ListforPathText->Count; i++) { items = (TCurveForTextPath*)ListforPathText->Items[i]; delete items; items=NULL; } ListforPathText->Clear(); delete ListforPathText; } if (PatternList) { for (int i = 0; i < PatternList->Count; i++) { patternItems = (SVGPattern*)PatternList->Items[i]; delete patternItems; patternItems=NULL; } PatternList->Clear(); delete PatternList; } if (MotiveIDList) { for (int i = 0; i < MotiveIDList->Count; i++) { motiveItems = (TMotiveParent*)MotiveIDList->Items[i]; delete motiveItems; motiveItems=NULL; } MotiveIDList->Clear(); delete MotiveIDList; } } //--------------------------------------------------------------------------- bool __fastcall TSVG2Vector::LoadFromFile(String dn, String fname, TUnit mainUnit) { TStringList *FileList = NULL; String strFileName; TiXmlDocument *doc = NULL; HANDLE hFile = INVALID_HANDLE_VALUE; try { int xmlType; String NodeName; DWORD dwWrite, dwRead; char *buff, *buff2; int DocTypePoz, SvgPoz, XmlPoz; String tempBuff, resualt; AnsiString filename; DWORD dwFileSize; UTF8String resualtUTF8; ///////////////////////////////////////////////////////////////////////// // SVG ·Îµå Áß ºÎºÐÀ» // Á¦°ÅÇϰí Àӽà ÀúÀåÇϸç, Àӽà ÀúÀåµÈ ÆÄÀÏÀ» XML·ÎµåÇÒ ¼ö ÀÖµµ·Ï ¼öÁ¤ // XMLDocument->LoadFromFile¿¡¼­ ¿¡·¯¹ß»ýÇÔ. hFile = CreateFile(fname.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (!hFile) throw EC_FILE_NOT_READ; dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize == 0) throw EC_FILE_NOT_READ; buff = new char[dwFileSize]; buff2 = new char[dwFileSize]; memset(buff, 0, dwFileSize); memset(buff2, 0, dwFileSize); ReadFile(hFile, buff, dwFileSize, &dwRead, NULL); if (hFile) CloseHandle(hFile); hFile = NULL; //6.0¿¡¼­´Â ÇÒ Çʿ䰡 ¾ø¾ú´Âµ¥ 2010ºÎÅÍ´Â ÀúÀåÇÒ ¶§ utf-8·Î ÀúÀåÇ߱⠶§¹®¿¡ //Àо ó¸® ÇÒ ¶§ µðÄÚµùÀ» ÇÑ ÈÄ¿¡ ó¸®ÇÑ´Ù. tempBuff = Utf8ToAnsi(buff); XmlPoz = tempBuff.Pos("LoadFile()) throw EC_FILE_NOT_READ; // Àӽà ÆÄÀÏ »èÁ¦ DeleteFile(strFileName.c_str()); TiXmlNode* XmlNode; XmlNode = SearchSVGRoot(doc); if (!XmlNode) throw EC_FILE_NOT_READ; xmlType = XmlNode->Type(); if (xmlType == 0) throw EC_FILE_NOT_READ; NodeName = XmlNode->Value(); if (NodeName != "svg") throw EC_FILE_NOT_READ; else { CheckUnits(XmlNode, mainUnit); } SearchSVGNode(XmlNode); if (doc) delete doc; doc = NULL; return true; } catch(...) { // Àӽà ÆÄÀÏ »èÁ¦ if (hFile) CloseHandle(hFile); hFile = NULL; if (FileExists(strFileName)) DeleteFile(strFileName.c_str()); if (doc) delete doc; doc = NULL; return false; } } //--------------------------------------------------------------------------- TiXmlNode* __fastcall TSVG2Vector::SearchSVGRoot(TiXmlNode* pParent) { if (!pParent ) return NULL; AnsiString temp, r_temp; if (pParent) { r_temp = pParent->Value(); if (r_temp == "svg") return pParent; } TiXmlNode* pChild, *returnNode; TiXmlText* pText; int t = pParent->Type(); int num; switch ( t ) { case TiXmlNode::TINYXML_DOCUMENT: temp = "Document"; break; case TiXmlNode::TINYXML_ELEMENT: temp = "Element:"; r_temp = pParent->Value(); break; case TiXmlNode::TINYXML_COMMENT: temp = "Comment: "; r_temp = pParent->Value(); break; case TiXmlNode::TINYXML_UNKNOWN: temp = "Unknown"; break; case TiXmlNode::TINYXML_TEXT: pText = pParent->ToText(); temp = "Text:"; r_temp = pText->Value(); break; case TiXmlNode::TINYXML_DECLARATION: temp = "Declaration"; break; default: break; } if (r_temp == "svg") return pParent; for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { returnNode = SearchSVGRoot(pChild); if (returnNode) { r_temp = returnNode->Value(); if (r_temp == "svg") return returnNode; } } } //--------------------------------------------------------------------------- void __fastcall TSVG2Vector::CheckUnits(TiXmlNode* XmlNode, TUnit mainUnit) { TiXmlNode* AttributeNode; String attr_name, s_width, s_height, viewBox; String temp; int j; double viewBox_x, viewBox_y, width, height; Width = 0; Height = 0; TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { attr_name = pAttrib->Name(); if (attr_name == "width") { s_width = pAttrib->Value(); if (TryStrToFloat(s_width, Width)) { } else { Width = (s_width.SubString(1, s_width.Length()-2)).ToDouble(); } } else if (attr_name == "height") { s_height = pAttrib->Value(); if (TryStrToFloat(s_height, Height)) { } else { Height = (s_height.SubString(1, s_height.Length()-2)).ToDouble(); } } else if (attr_name == "viewBox") { viewBox = pAttrib->Value(); j = 0; temp=""; while (viewBox.c_str()[j] != L' ' && viewBox.c_str()[j] != L',') { if (j > viewBox.Length()) break; temp += viewBox.c_str()[j]; j++; } viewBox_x = temp.ToDouble(); temp=""; j++; while (viewBox.c_str()[j] != L' ' && viewBox.c_str()[j] != L',') { if (j > viewBox.Length()) break; temp += viewBox.c_str()[j]; j++; } viewBox_y = temp.ToDouble(); temp=""; j++; if( !(Width * Height) ) { while (viewBox.c_str()[j] != L' ' && viewBox.c_str()[j] != L',') { if (j > viewBox.Length()) break; temp += viewBox.c_str()[j]; j++; } Width = temp.ToDouble(); s_width = temp + "px"; temp=""; j++; while (viewBox.c_str()[j] != L' ' && viewBox.c_str()[j] != L',') { if (j > viewBox.Length()) break; temp += viewBox.c_str()[j]; j++; } Height = temp.ToDouble(); s_height = temp + "px"; temp=""; } } pAttrib = pAttrib->Next(); } if (s_width.IsEmpty() == false){ SVGElement *svgElement; svgElement = new SVGElement(); svgElement->Units = s_width; width = svgElement->GetUnits(); delete svgElement; svgElement = NULL; } } //--------------------------------------------------------------------------- void __fastcall TSVG2Vector::SearchSVGNode(TiXmlNode* XmlNode) { String NodeText, NodeName, cDATA; TiXmlNode *AttrNode, *ChildNode; TiXmlNode* parentNode; TVecData *data = NULL; // by maxleo21c 06.09.26 bool isRight = false; NodeName = XmlNode->Value(); if (NodeName == "text") { //textBox¿Í pathText¸¦ ó¸®Çϱâ À§ÇÑ ºÎºÐÀÌ´Ù. //texts´Â CDATA¿¡ ÀúÀåµÈ ³»¿ëÀ» ºÐ¼®Çؼ­ ó¸®ÇÏ°Ô Çß´Ù. SVGText *svgText = NULL; try { GetCDATAOwnNode(XmlNode, cDATA); if (isOwnText) { svgText = new SVGText(Instance); data = new TVecData(Instance); if (!svgText->ProcessTextCDATA(cDATA, data)) { SAVE_EXCEPTION(EC_FILE_NOT_READ); throw EC_FILE_NOT_READ; } svgText->AddData(XmlNode, data); svgText->ModifyData(data); if (svgText->xLink_data.Length()) { TCurveForTextPath *items; TVecData *pathdata; for (int i=0; iCount; i++) { items = (TCurveForTextPath*)ListforPathText->Items[i]; if (items->id == svgText->xLink_data) { pathdata = (TVecData *)dataList->Items[items->vecdata_num]; data->ListOfAllLine->CurveData = pathdata; pathdata->ParentTextBox = data; } } } else { } dataList->Add(data); delete svgText; svgText = NULL; VecDraw->MakeTextBoxPointList(data); } } catch (...) { if (data) delete data; data=NULL; if (svgText) delete svgText; svgText=NULL; isOwnText = false; return; } isOwnText = false; return; } else if(!XmlNode->FirstChild()) { NodeName = XmlNode->Value(); if (NodeName == "path") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. parentNode = XmlNode->Parent(); IsPatternChild(parentNode, isRight); if (isRight) return; //patternID: -1 => parent int motiveID = -2, patternID = -2; patternID = IsMotiveParent(XmlNode, cDATA); if (patternID < -2) return; //-3: ¿ÜºÎ¿¡¼­ º¸ÀÏ ¶§ »ç¿ëÇÏ´Â data //-2: child data //-1: ÀÏ¹Ý path·Î addó¸® //0ÀÌ»ó: TexPro pattern id if (patternID == -2) { //motive child dataÀ̸é //XmlNode->GetParentNode()´Â "texpro_pattern"ÀÌ´Ù. motiveID =IsMotiveChild(XmlNode->Parent()); //0ÀÌ»ó: motive id if (motiveID == -1) return; //-2: patternÀÌ º¸À϶§ »ç¿ëÇÏ´Â path·Î ¸®ÅÏ } SVGPath *svgPath; TCurveForTextPath *pathItems = {0}; svgPath = new SVGPath(Instance); data = new TVecData(Instance); if (!svgPath->AddData(XmlNode, data)) { delete data; data = NULL; delete svgPath; svgPath = NULL; return; } String *t_data; t_data = new String[svgPath->m_count]; svgPath->Check_M_counter(t_data); if (svgPath->m_count > 1) { TVecData *tdata; for(int i=0; im_count-1; i++) { if (i==0) { svgPath->MakePoint(data, t_data[0]); dataList->Add(data); } tdata = new TVecData(Instance); tdata->Copy(data); svgPath->MakePoint(tdata, t_data[i+1]); if (patternID != -2) dataList->Add(tdata); } } else { if (!svgPath->MakePoint(data, t_data[0])) { if (t_data) delete[] t_data; t_data= NULL; if (svgPath) delete svgPath; svgPath = NULL; if (data) delete data; data = NULL; return; } if (svgPath->fill_url.Length() && svgPath->AddPatternData(data, PatternList)) { VecDraw->MakePatternBitmap(data); } if (patternID != -2) dataList->Add(data); } if (patternID >= 0) { svgPath->ProcessMotiveCDATA(cDATA, data); TMotiveParent* item = new TMotiveParent(patternID, data); MotiveIDList->Add(item); } else if (patternID == -2) { svgPath->AddMotiveChildData(data, motiveID, MotiveIDList); } delete[] t_data; delete svgPath; svgPath = NULL; //pathText¿Í id¸¦ ºñ±³ÇØ º¸±â À§Çؼ­ Tlist¿¡ ÀúÀåÇÑ´Ù. TiXmlElement* pElement = XmlNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { NodeName = pAttrib->Name(); if (NodeName == "id") { pathItems = new TCurveForTextPath; pathItems->id = pAttrib->Value(); pathItems->vecdata_num = (dataList->Count - 1); //ÀÌ¹Ì dataList¿¡ addµÈ ÈÄÀ̱⠶§¹®¿¡ -1À» Çß´Ù. ListforPathText->Add(pathItems); } pAttrib = pAttrib->Next(); } return; } else if (NodeName == "rect") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. parentNode = XmlNode->Parent(); IsPatternChild(parentNode, isRight); if (isRight) return; SVGRect *svgRect; svgRect = new SVGRect(Instance); data = new TVecData(Instance); svgRect->AddData(XmlNode, data); dataList->Add(data); delete svgRect; svgRect = NULL; return; } else if (NodeName == "ellipse") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. IsPatternChild(XmlNode->Parent(), isRight); if (isRight) return; SVGEllipse *svgEllipse; svgEllipse = new SVGEllipse(Instance); data = new TVecData(Instance); svgEllipse->AddData(XmlNode, data); dataList->Add(data); delete svgEllipse; svgEllipse = NULL; return; } else if (NodeName == "circle") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. IsPatternChild(XmlNode->Parent(), isRight); if (isRight) return; SVGCircle *svgCircle; svgCircle = new SVGCircle(Instance); data = new TVecData(Instance); svgCircle->AddData(XmlNode, data); dataList->Add(data); delete svgCircle; svgCircle = NULL; return; } else if (NodeName == "polyline") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. IsPatternChild(XmlNode->Parent(), isRight); if (isRight) return; SVGPoly *svgPoly; svgPoly = new SVGPoly(Instance); data = new TVecData(Instance); if (svgPoly->AddData(XmlNode, data)) { data->bClosed = false; dataList->Add(data); } else { delete data; data = NULL; } delete svgPoly; svgPoly = NULL; return; } else if (NodeName == "polygon") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. IsPatternChild(XmlNode->Parent(), isRight); if (isRight) return; SVGPoly *svgPoly; svgPoly = new SVGPoly(Instance, true); data = new TVecData(Instance); svgPoly->AddData(XmlNode, data); // 1024 Á¦ÇÑ Ç®·ÈÀ½ - by monkman (2011.04.20) //if (data->nCount*3+1 > MAX_DATA_NCOUNT) { TVecData *_data = NULL; int nCount = data->nCount; // 1024 Á¦ÇÑ Ç®·ÈÀ½ - by monkman (2011.04.20) //int MAX = 341; //MAX: 341 => 341 * 3 + 1 = 1024 int index = 0; while(true) { _data = new TVecData(Instance); _data->Copy(data); HeapFree(GetProcessHeap(), 0, _data->pList); if (_data->pMask != NULL) HeapFree(GetProcessHeap(), 0, _data->pMask); _data->pMask = NULL; // 1024 Á¦ÇÑ Ç®·ÈÀ½ - by monkman (2011.04.20) /*if (nCount > MAX) { _data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(MAX*3+1)); if (index == 0) { memcpy(_data->pList, data->pList, sizeof(DPOINT)*(MAX*3+1)); _data->bClosed = false; _data->nCount = MAX; dataList->Add(_data); index += (MAX*3+1); } else { _data->pList[0].x = data->pList[index].x; _data->pList[0].y = data->pList[index].y; for (int i = 0; i < MAX*3; i++) { _data->pList[i+1].x = data->pList[index+i].x; _data->pList[i+1].y = data->pList[index+i].y; } _data->bClosed = false; _data->nCount = MAX; dataList->Add(_data); index += (MAX*3); } } else { */ _data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(nCount*3+1)); _data->pMask = (BYTE*)HeapAlloc(GetProcessHeap(), 0, (_data->nCount * 3 + 1) % 8 == 0 ? (_data->nCount * 3 + 1) / 8 : (_data->nCount * 3 + 1) / 8 + 1); _data->pList[0].x = data->pList[index].x; _data->pList[0].y = data->pList[index].y; for (int i = 0; i < nCount*3; i++) { _data->pList[i+1].x = data->pList[index+i].x; _data->pList[i+1].y = data->pList[index+i].y; } _data->bClosed = false; _data->nCount = nCount; dataList->Add(_data); break; //} //nCount -= MAX; } delete data; data = NULL; /*} else { data->bClosed = true; dataList->Add(data); } */ /* if (svgPoly->AddData(XmlNode, data)) { data->bClosed = true; dataList->Add(data); } else { delete data; data = NULL; }*/ delete svgPoly; svgPoly = NULL; return; } else if (NodeName == "line") { //ÀÏ·¯ÀÇ PatternÀÏ °æ¿ì Çʿ䰡 ¾ø±â ¶§¹®¿¡ ReturnÇÑ´Ù. IsPatternChild(XmlNode->Parent(), isRight); if (isRight) return; SVGLine *svgLine; svgLine = new SVGLine(Instance); data = new TVecData(Instance); if (svgLine->AddData(XmlNode, data)) { dataList->Add(data); } else { delete data; data = NULL; } delete svgLine; svgLine = NULL; return; } else if (NodeName == "image") { TiXmlNode* _parentNode = XmlNode->Parent(); NodeName = _parentNode->Value(); if (NodeName == "pattern") { SVGPattern *svgPattern; svgPattern = new SVGPattern(); GetCDATAOwnNode(_parentNode, cDATA); svgPattern->ProcessPatternCDATA(cDATA); if (!svgPattern->AddData(_parentNode)) { delete svgPattern; svgPattern=NULL; return; } //if (!svgPattern->LoadBitmap(_parentNode, directory)) { //B64¹æ½ÄÀ» »ç¿ëÇϵµ·Ï º¯°æ. if (!svgPattern->LoadBitmapB64(_parentNode, directory)) { delete svgPattern; svgPattern=NULL; return; } PatternList->Add(svgPattern); } return; } return; } for ( ChildNode = XmlNode->FirstChild(); ChildNode != 0; ChildNode = ChildNode->NextSibling()) { NodeName = ChildNode->Value(); SearchSVGNode(ChildNode); } } //--------------------------------------------------------------------------- void __fastcall TSVG2Vector::GetCDATAOwnNode(TiXmlNode* XmlNode, String &cDATA) { TiXmlNode *attrNode, *parentNode, *childNode; parentNode = XmlNode->Parent(); String text, attrName, nodeName, cNodeName; nodeName = parentNode->Value(); int xml_type; const char *buff; if (nodeName == "g") { TiXmlElement* pElement = parentNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); TiXmlText* pText = NULL; while (pAttrib) { attrName = pAttrib->Name(); text = pAttrib->Value(); if (attrName == "kind" && text == "text") { isOwnText = true; for ( childNode = parentNode->FirstChild(); childNode != 0; childNode = childNode->NextSibling()) { xml_type = childNode->Type(); cNodeName = childNode->Value(); if (xml_type == TiXmlNode::TINYXML_TEXT) { //if (cNodeName == "#cdata-section") { // pElement = childNode->ToElement(); // pText = pElement->ToText(); // cDATA = pText->Value(); //} //cDATA = cNodeName; buff = childNode->Value(); cDATA = Utf8ToAnsi(buff); } } return; } else if (attrName == "kind" && text == "pattern") { for ( childNode = parentNode->FirstChild(); childNode != 0; childNode = childNode->NextSibling()) { xml_type = childNode->Type(); cNodeName = childNode->Value(); if (xml_type == TiXmlNode::TINYXML_TEXT) { //if (cNodeName == "#cdata-section") { // pElement = childNode->ToElement(); // pText = pElement->ToText(); // cDATA = pText->Value(); //} cDATA = cNodeName; } } return; } pAttrib = pAttrib->Next(); } GetCDATAOwnNode(parentNode, cDATA); } } //--------------------------------------------------------------------------- void __fastcall TSVG2Vector::IsPatternChild(TiXmlNode* XmlNode, bool &isRight) { TiXmlNode* parentNode; String nodeName; nodeName = XmlNode->Value(); if (nodeName == "svg" || nodeName == "switch") isRight=false; else if (nodeName == "pattern") isRight=true; else if (parentNode = XmlNode->Parent()) IsPatternChild(parentNode, isRight); } //--------------------------------------------------------------------------- // id: -3=> TexPro Àü¿ëÀÌ ¾Æ´Ï¾î¼­ ó¸®ÇÏÁö ¾Ê°í Return // id: -2=> Child data // id: -1=> ÀÏ¹Ý Path·Î Add ó¸® // id > 0 => PatternÀÇ motive id int __fastcall TSVG2Vector::IsMotiveParent(TiXmlNode* XmlNode, String &cDATA) { TiXmlNode *parentNode, *childNode; String nodeName, attrName, text; int id = -1; parentNode = XmlNode->Parent(); nodeName = parentNode->Value(); //XmlNode: ÇöÀçÀÇ parent node //nodeName: ÇöÀçÀÇ parent node name TiXmlElement* pElement = parentNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); //0¹øÂ° TiXmlText* pText = NULL; if (pAttrib) { attrName = pAttrib->Name(); text = pAttrib->Value(); } if (nodeName == "svg" || nodeName == "switch") { id = -1; } else if (nodeName == "g" && attrName == "kind" && text == "motive") { childNode = parentNode->FirstChild(); if (XmlNode == childNode) { pAttrib = pAttrib->Next(); //1¹øÂ° attrName = pAttrib->Name(); text = pAttrib->Value(); id = text.ToInt(); while(childNode) { childNode = childNode->NextSibling(); nodeName = childNode->Value(); if (nodeName == "#cdata-section") { pElement = childNode->ToElement(); pText = pElement->ToText(); cDATA = pText->Value(); } } } else { id = -3; } } else if (nodeName == "g" && attrName == "kind" && text == "pattern") { return IsMotiveParent(parentNode, cDATA); } else if (nodeName == "texpro_pattern") { id = -2; } return id; } //--------------------------------------------------------------------------- int __fastcall TSVG2Vector::IsMotiveChild(TiXmlNode* XmlNode) { int rData = -1; TiXmlNode* parentNode = XmlNode->Parent(); //pathÀÇ parent node TiXmlNode* childNode; String nodeName, text, attrName, cNodeName; nodeName = parentNode->Value(); //nodeName: ÇöÀçÀÇ parent node name TiXmlElement* pElement = parentNode->ToElement(); TiXmlAttribute* pAttrib = pElement->FirstAttribute(); //0¹øÂ° if (pAttrib) { attrName = pAttrib->Name(); text = pAttrib->Value(); } if (nodeName == "g" && attrName == "kind" && text == "motive") { pAttrib = pAttrib->Next(); //1¹øÂ° attrName = pAttrib->Name(); text = pAttrib->Value(); rData = text.ToInt(); } else if (nodeName == "g" && attrName == "kind" && text == "pattern") { return IsMotiveChild(parentNode); } else if (nodeName == "texpro_pattern") { return IsMotiveChild(parentNode); } return rData; } //---------------------------------------------------------------------------