@@ -971,6 +971,7 @@ static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, bool dump); //
971971static NSVGgradient* nsvg__createGradient (NSVGparser* p, NSVGshape* shape, NSVGgradientLink* link, char * paintType)
972972{
973973 // NSVGattrib* attr = nsvg__getAttr(p);
974+ DBG (" createGradient: START for shape %s\n " , shape->id );
974975 NSVGgradientData* data = NULL ;
975976 NSVGgradientData* ref = NULL ;
976977 NSVGgradientStop* stops = NULL ;
@@ -1084,7 +1085,7 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, NSVGshape* shape, NSVGg
10841085 grad->nstops = nstops;
10851086
10861087 *paintType = data->type ;
1087-
1088+ DBG ( " createGradient: END \n " );
10881089 return grad;
10891090}
10901091
@@ -1144,6 +1145,27 @@ static void nsvg__addShape(NSVGparser* p)
11441145 shape = (NSVGshape*)nsvg__alloczero (sizeof (NSVGshape), S8Printf (" nsvg__addShape %s" , attr->id ));
11451146 if (shape == NULL ) return ;
11461147
1148+ // Проверяем, есть ли реальные ссылки на clipPath
1149+ // if (attr->clipList) {
1150+ // // Проверяем, используется ли этот clipPath
1151+ // NSVGclipNode* node = attr->clipList;
1152+ // XBool hasValidClip = false;
1153+ // while (node) {
1154+ // NSVGclipPath* clipPath = nsvg__findClipPath(p, NULL); // нужна функция поиска по индексу
1155+ // if (clipPath && clipPath->shapes) {
1156+ // hasValidClip = true;
1157+ // break;
1158+ // }
1159+ // node = node->next;
1160+ // }
1161+ //
1162+ // if (hasValidClip) {
1163+ // shape->clipList = attr->clipList;
1164+ // } else {
1165+ // DBG("Skipping unused clipPath for shape %s\n", shape->id);
1166+ // }
1167+ // }
1168+
11471169 memcpy (shape->id , attr->id , sizeof shape->id );
11481170 memcpy (shape->title , attr->title , sizeof shape->title );
11491171// DBG("parse shapeID=%s\n", shape->id);
@@ -2612,11 +2634,10 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args,
26122634 float x, y, tanx, tany, a, px = 0 , py = 0 , ptanx = 0 , ptany = 0 , t[6 ];
26132635 float sinrx, cosrx;
26142636 int fa, fs;
2615- int ndivs;
2616- float hda, kappa;
26172637
26182638 rx = fabsf (args[0 ]); // y radius
26192639 ry = fabsf (args[1 ]); // x radius
2640+
26202641 rotx = args[2 ] * NSVG_PI_DEG ; // x rotation angle
26212642 fa = fabsf (args[3 ]) > 1e-6 ? 1 : 0 ; // Large arc
26222643 fs = fabsf (args[4 ]) > 1e-6 ? 1 : 0 ; // Sweep direction
@@ -2642,6 +2663,11 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args,
26422663 return ;
26432664 }
26442665
2666+ // Если радиусы слишком большие по сравнению с расстоянием, ограничиваем их
2667+ float maxRadius = hypot (x2 - x1, y2 - y1) * 10 .0f ;
2668+ if (rx > maxRadius) rx = maxRadius;
2669+ if (ry > maxRadius) ry = maxRadius;
2670+
26452671 sinrx = sinf (rotx);
26462672 cosrx = cosf (rotx);
26472673
@@ -2666,25 +2692,7 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args,
26662692// Вычисляем радикал более устойчивым способом
26672693 float radicand = (rx2 * ry2 - rx2 * y1p2 - ry2 * x1p2)
26682694 / (rx2 * y1p2 + ry2 * x1p2);
2669-
2670- // Защита от численных ошибок
2671- if (radicand < 0 .0f ) {
2672- // Если радикал отрицательный из-за ошибок округления, корректируем
2673- if (radicand > -1e-6f ) {
2674- radicand = 0 .0f ;
2675- }
2676- else {
2677- // Серьезная ошибка, корректируем радиусы
2678- float scale = sqrtf ((x1p2 / rx2 + y1p2 / ry2));
2679- rx *= scale;
2680- ry *= scale;
2681- rx2 = rx * rx;
2682- ry2 = ry * ry;
2683- radicand = (rx2 * ry2 - rx2 * y1p2 - ry2 * x1p2)
2684- / (rx2 * y1p2 + ry2 * x1p2);
2685- if (radicand < 0 .0f ) radicand = 0 .0f ;
2686- }
2687- }
2695+ if (radicand < 0 .0f ) radicand = 0 .0f ;
26882696
26892697 s = sqrtf (radicand);
26902698
@@ -2726,41 +2734,26 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args,
27262734// Для больших радиусов нужно больше сегментов
27272735 float avgRadius = (rx + ry) * 0 .5f ;
27282736
2729- ndivs = 4 ;
2730-
2731- // Увеличиваем для больших углов
2732- if (fabsf (da) > NSVG_PI * 0 .5f ) {
2733- ndivs = 8 ;
2734- }
2735- if (fabsf (da) > NSVG_PI ) {
2736- ndivs = 16 ;
2737- }
2738-
2739- // Для больших радиусов увеличиваем точность
2740- if (avgRadius > 50 .0f ) {
2741- ndivs = (int ) (ndivs * (avgRadius / 50 .0f ));
2737+ // Если дуга почти прямая (очень большой радиус), просто рисуем линию
2738+ if (avgRadius > 1000 .0f && fabsf (da) < 0 .05f ) {
2739+ nsvg__lineTo (p, x2, y2);
2740+ *cpx = x2;
2741+ *cpy = y2;
2742+ return ;
27422743 }
27432744
2744- // Ограничиваем
2745+ int ndivs = ( int ) floorf ( fabsf (da) / ( NSVG_PI * 0 . 5f ) + 0 . 5f );
27452746 if (ndivs < 4 ) ndivs = 4 ;
2746- if (ndivs > 32 ) ndivs = 32 ;
27472747
2748- // Вычисляем kappa - стандартная формула
2749- hda = (da / (float ) ndivs) * 0 .5f ;
2750- if (fabsf (sinf (hda)) > 1e-10f ) {
2751- kappa = (4 .0f / 3 .0f ) * (1 .0f - cosf (hda)) / sinf (hda);
2752- }
2753- else {
2754- kappa = 0 .0f ;
2755- }
27562748
2757- // ===== ОТЛАДКА ДУГ =====
2758- // Выводим параметры дуги только для проблемных случаев
2759- // (можно закомментировать после отладки)
2760- if (fabsf (da) < 1 .0f && avgRadius > 50 .0f ) {
2761- DBG (" ARC: rx=%f ry=%f rotx=%f fa=%d fs=%d\n " , rx, ry, rotx, fa, fs); DBG (" x1=%f y1=%f x2=%f y2=%f\n " , x1, y1, x2, y2); DBG (" cx=%f cy=%f da=%f ndivs=%d\n " , cx, cy, da, ndivs); DBG (" a1=%f da=%f\n " , a1, da);
2749+ // Вычисляем kappa - стандартная формула
2750+ float hda = (da / (float ) ndivs) * 0 .5f ;
2751+ float kappa = (4 .0f / 3 .0f ) * (1 .0f - cosf (hda)) / sinf (hda);
2752+ if (fabsf (kappa) > 1e-6f ) {
2753+ // используем kappa
2754+ } else {
2755+ kappa = 0 .0f ;
27622756 }
2763- // ===== КОНЕЦ ОТЛАДКИ =====
27642757
27652758 for (int i = 0 ; i <= ndivs; i++) {
27662759 a = a1 + da * ((float ) i / (float ) ndivs);
@@ -2776,18 +2769,14 @@ static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args,
27762769 ptany = tany;
27772770 }
27782771
2779- // ... после вычисления x1p, y1p, cx, cy, da ...
2780-
2781- DBG (" x1p=%f, y1p=%f\n " , x1p, y1p); DBG (" cx=%f, cy=%f\n " , cx, cy); DBG (" a1=%f, da=%f (degrees: %f)\n " , a1, da, da * 180 .0f / NSVG_PI ); DBG (" ndivs=%d, kappa=%f\n " , ndivs, kappa); DBG (" fa=%d, fs=%d\n " , fa, fs);
2782- // ===== КОНЕЦ ОТЛАДКИ =====
2783-
27842772 *cpx = x2;
27852773 *cpy = y2;
27862774}
27872775
27882776
27892777static void nsvg__parsePath (NSVGparser* p, char ** attr, bool addShape)
27902778{
2779+ DBG (" nsvg__parsePath\n " );
27912780 const char * s = NULL ;
27922781 char cmd = ' \0 ' ;
27932782 float args[30 ];
0 commit comments