21 #include <tqvaluevector.h>
22 #include <tqstringlist.h>
23 #include <tqwmatrix.h>
34 #include <libart_lgpl/art_rgba.h>
35 #include <libart_lgpl/art_bpath.h>
36 #include <libart_lgpl/art_vpath.h>
37 #include <libart_lgpl/art_vpath_dash.h>
38 #include <libart_lgpl/art_affine.h>
39 #include <libart_lgpl/art_render_svp.h>
40 #include <libart_lgpl/art_svp.h>
41 #include <libart_lgpl/art_svp_vpath.h>
42 #include <libart_lgpl/art_svp_intersect.h>
43 #include <libart_lgpl/art_svp_vpath_stroke.h>
45 #include "ksvgiconpainter.h"
49 const double deg2rad = 0.017453292519943295769;
51 class KSVGIconPainterHelper
54 KSVGIconPainterHelper(
int width,
int height, KSVGIconPainter *painter)
60 m_fillColor = Qt::black;
65 m_useFillGradient =
false;
66 m_useStrokeGradient =
false;
68 m_worldMatrix =
new TQWMatrix();
71 m_image =
new TQImage(width, height, 32);
72 m_image->setAlphaBuffer(
true);
75 m_strokeMiterLimit = 4;
81 m_strokeOpacity = 0xff;
83 m_fillRule =
"nonzero";
88 m_rowstride = m_width * 4;
91 m_buffer = art_new(art_u8, m_rowstride * m_height);
92 memset(m_buffer, 0, m_rowstride * m_height);
97 ~KSVGIconPainterHelper()
100 art_svp_free(m_clipSVP);
105 delete m_worldMatrix;
107 for(TQMap<TQString, ArtGradientLinear *>::Iterator it = m_linearGradientMap.begin(); it != m_linearGradientMap.end(); ++it)
111 delete [] it.data()->stops;
114 for(TQMap<TQString, ArtGradientRadial *>::Iterator it = m_radialGradientMap.begin(); it != m_radialGradientMap.end(); ++it)
118 delete [] it.data()->stops;
123 ArtVpath *allocVPath(
int number)
125 return art_new(ArtVpath, number);
128 ArtBpath *allocBPath(
int number)
130 return art_new(ArtBpath, number);
133 void ensureSpace(TQMemArray<ArtBpath> &vec,
int index)
135 if(vec.size() == (
unsigned int) index)
136 vec.resize(index + 1);
141 m_tempBuffer = art_new(art_u8, m_rowstride * m_height);
142 memset(m_tempBuffer, 0, m_rowstride * m_height);
145 art_u8 *temp = m_buffer;
146 m_buffer = m_tempBuffer;
150 void mixBuffer(
int opacity)
152 art_u8 *srcPixel = m_buffer;
153 art_u8 *dstPixel = m_tempBuffer;
155 for(
int y = 0; y < m_height; y++)
157 for(
int x = 0; x < m_width; x++)
161 a = srcPixel[4 * x + 3];
166 g = srcPixel[4 * x + 1];
167 b = srcPixel[4 * x + 2];
169 int temp = a * opacity + 0x80;
170 a = (temp + (temp >> 8)) >> 8;
171 art_rgba_run_alpha(dstPixel + 4 * x, r, g, b, a, 1);
175 srcPixel += m_rowstride;
176 dstPixel += m_rowstride;
180 art_u8 *temp = m_buffer;
181 m_buffer = m_tempBuffer;
184 art_free(m_tempBuffer);
188 TQ_UINT32 toArtColor(
const TQColor &color)
191 TQString tempName = color.name();
192 const char *str = tempName.latin1();
196 for(
int i = 1; str[i]; i++)
199 if(str[i] >=
'0' && str[i] <=
'9')
200 hexval = str[i] -
'0';
201 else if (str[i] >=
'A' && str[i] <=
'F')
202 hexval = str[i] -
'A' + 10;
203 else if (str[i] >=
'a' && str[i] <=
'f')
204 hexval = str[i] -
'a' + 10;
208 result = (result << 4) + hexval;
214 void drawSVP(ArtSVP *svp, TQ_UINT32 rgb,
int opacity)
219 ArtRender *render = art_render_new(0, 0, m_width, m_height, m_buffer, m_rowstride, 3, 8, ART_ALPHA_SEPARATE, 0);
220 art_render_svp(render, svp);
222 art_render_mask_solid(render, (opacity << 8) + opacity + (opacity >> 7));
224 ArtPixMaxDepth color[3];
225 color[0] = ART_PIX_MAX_FROM_8(rgb >> 16);
226 color[1] = ART_PIX_MAX_FROM_8((rgb >> 8) & 0xff);
227 color[2] = ART_PIX_MAX_FROM_8(rgb & 0xff);
229 art_render_image_solid(render, color);
230 art_render_invoke(render);
233 void drawBPath(ArtBpath *bpath)
236 affine[0] = m_worldMatrix->m11();
237 affine[1] = m_worldMatrix->m12();
238 affine[2] = m_worldMatrix->m21();
239 affine[3] = m_worldMatrix->m22();
240 affine[4] = m_worldMatrix->dx();
241 affine[5] = m_worldMatrix->dy();
243 ArtBpath *temp = art_bpath_affine_transform(bpath, affine);
244 ArtVpath *vec = art_bez_path_to_vec(temp, 0.25);
246 drawPathInternal(vec, affine);
249 void drawVPath(ArtVpath *vec)
252 affine[0] = m_worldMatrix->m11();
253 affine[1] = m_worldMatrix->m12();
254 affine[2] = m_worldMatrix->m21();
255 affine[3] = m_worldMatrix->m22();
256 affine[4] = m_worldMatrix->dx();
257 affine[5] = m_worldMatrix->dy();
259 ArtVpath *temp = art_vpath_affine_transform(vec, affine);
262 drawPathInternal(vec, affine);
265 void drawPathInternal(ArtVpath *vec,
double *affine)
268 ArtSVP *fillSVP = 0, *strokeSVP = 0;
270 TQ_UINT32 fillColor = 0, strokeColor = 0;
275 TQValueVector<int> toCorrect;
276 while(vec[++index].code != ART_END)
278 if(vec[index].code == ART_END2)
280 vec[index].code = ART_LINETO;
281 toCorrect.push_back(index);
285 fillColor = toArtColor(m_fillColor);
289 temp = art_svp_from_vpath(vec);
291 if(m_fillRule ==
"evenodd")
292 swr = art_svp_writer_rewind_new(ART_WIND_RULE_ODDEVEN);
294 swr = art_svp_writer_rewind_new(ART_WIND_RULE_NONZERO);
296 art_svp_intersector(temp, swr);
297 svp = art_svp_writer_rewind_reap(swr);
303 TQValueVector<int>::iterator it;
304 for(it = toCorrect.begin(); it != toCorrect.end(); ++it)
305 vec[(*it)].code = (ArtPathcode)ART_END2;
310 if(m_strokeWidth <= 0)
311 m_useStroke = m_useStrokeGradient =
false;
314 if(m_useStroke || m_useStrokeGradient)
316 strokeColor = toArtColor(m_strokeColor);
318 double ratio = art_affine_expansion(affine);
319 double strokeWidth = m_strokeWidth * ratio;
321 ArtPathStrokeJoinType joinStyle = ART_PATH_STROKE_JOIN_MITER;
322 ArtPathStrokeCapType capStyle = ART_PATH_STROKE_CAP_BUTT;
324 if(m_joinStyle ==
"miter")
325 joinStyle = ART_PATH_STROKE_JOIN_MITER;
326 else if(m_joinStyle ==
"round")
327 joinStyle = ART_PATH_STROKE_JOIN_ROUND;
328 else if(m_joinStyle ==
"bevel")
329 joinStyle = ART_PATH_STROKE_JOIN_BEVEL;
331 if(m_capStyle ==
"butt")
332 capStyle = ART_PATH_STROKE_CAP_BUTT;
333 else if(m_capStyle ==
"round")
334 capStyle = ART_PATH_STROKE_CAP_ROUND;
335 else if(m_capStyle ==
"square")
336 capStyle = ART_PATH_STROKE_CAP_SQUARE;
338 if(m_dashes.length() > 0)
340 TQRegExp reg(
"[, ]");
341 TQStringList dashList = TQStringList::split(reg, m_dashes);
343 double *dashes =
new double[dashList.count()];
344 for(
unsigned int i = 0; i < dashList.count(); i++)
345 dashes[i] = m_painter->toPixel(dashList[i],
true);
348 dash.offset = m_dashOffset;
349 dash.n_dash = dashList.count();
353 ArtVpath *vec2 = art_vpath_dash(vec, &dash);
361 svp = art_svp_vpath_stroke(vec, joinStyle, capStyle, strokeWidth, m_strokeMiterLimit, 0.25);
367 int fillOpacity =
static_cast<int>(m_fillOpacity);
368 int strokeOpacity =
static_cast<int>(m_strokeOpacity);
369 int opacity =
static_cast<int>(m_opacity);
373 if(fillOpacity == strokeOpacity && fillOpacity == opacity && !m_useFillGradient && !m_useStrokeGradient)
376 if(fillOpacity != 255)
378 int temp = fillOpacity * opacity + 0x80;
379 fillOpacity = (temp + (temp >> 8)) >> 8;
382 if(strokeOpacity != 255)
384 int temp = strokeOpacity * opacity + 0x80;
385 strokeOpacity = (temp + (temp >> 8)) >> 8;
389 bool tempDone =
false;
390 if(m_opacity != 0xff)
397 if(m_useFillGradient)
398 applyGradient(fillSVP,
true);
400 drawSVP(fillSVP, fillColor, fillOpacity);
402 if(m_useStrokeGradient)
403 applyGradient(strokeSVP,
false);
405 drawSVP(strokeSVP, strokeColor, strokeOpacity);
413 art_svp_free(m_clipSVP);
418 art_svp_free(fillSVP);
421 art_svp_free(strokeSVP);
425 m_fillOpacity = 255.0;
426 m_strokeOpacity = 255.0;
431 void applyLinearGradient(ArtSVP *svp,
const TQString &ref)
433 ArtGradientLinear *linear = m_linearGradientMap[ref];
436 TQDomElement element = m_linearGradientElementMap[linear];
438 double x1, y1, x2, y2;
439 if(element.hasAttribute(
"x1"))
440 x1 = m_painter->toPixel(element.attribute(
"x1"),
true);
444 if(element.hasAttribute(
"y1"))
445 y1 = m_painter->toPixel(element.attribute(
"y1"),
false);
449 if(element.hasAttribute(
"x2"))
450 x2 = m_painter->toPixel(element.attribute(
"x2"),
true);
454 if(element.hasAttribute(
"y2"))
455 y2 = m_painter->toPixel(element.attribute(
"y2"),
false);
460 TQWMatrix m = m_painter->parseTransform(element.attribute(
"gradientTransform"));
461 m.map(x1, y1, &x1, &y1);
462 m.map(x2, y2, &x2, &y2);
464 double x1n = x1 * m_worldMatrix->m11() + y1 * m_worldMatrix->m21() + m_worldMatrix->dx();
465 double y1n = x1 * m_worldMatrix->m12() + y1 * m_worldMatrix->m22() + m_worldMatrix->dy();
466 double x2n = x2 * m_worldMatrix->m11() + y2 * m_worldMatrix->m21() + m_worldMatrix->dx();
467 double y2n = x2 * m_worldMatrix->m12() + y2 * m_worldMatrix->m22() + m_worldMatrix->dy();
469 double dx = x2n - x1n;
470 double dy = y2n - y1n;
471 double scale = 1.0 / (dx * dx + dy * dy);
473 linear->a = dx * scale;
474 linear->b = dy * scale;
475 linear->c = -(x1n * linear->a + y1n * linear->b);
477 ArtRender *render = art_render_new(0, 0, m_width, m_height, m_buffer, m_rowstride, 3, 8, ART_ALPHA_SEPARATE, 0);
478 art_render_svp(render, svp);
480 art_render_gradient_linear(render, linear, ART_FILTER_HYPER);
481 art_render_invoke(render);
485 void applyRadialGradient(ArtSVP *svp,
const TQString &ref)
487 ArtGradientRadial *radial = m_radialGradientMap[ref];
490 TQDomElement element = m_radialGradientElementMap[radial];
492 double cx, cy, r, fx, fy;
493 if(element.hasAttribute(
"cx"))
494 cx = m_painter->toPixel(element.attribute(
"cx"),
true);
498 if(element.hasAttribute(
"cy"))
499 cy = m_painter->toPixel(element.attribute(
"cy"),
false);
503 if(element.hasAttribute(
"r"))
504 r = m_painter->toPixel(element.attribute(
"r"),
true);
508 if(element.hasAttribute(
"fx"))
509 fx = m_painter->toPixel(element.attribute(
"fx"),
false);
513 if(element.hasAttribute(
"fy"))
514 fy = m_painter->toPixel(element.attribute(
"fy"),
false);
518 radial->affine[0] = m_worldMatrix->m11();
519 radial->affine[1] = m_worldMatrix->m12();
520 radial->affine[2] = m_worldMatrix->m21();
521 radial->affine[3] = m_worldMatrix->m22();
522 radial->affine[4] = m_worldMatrix->dx();
523 radial->affine[5] = m_worldMatrix->dy();
525 radial->fx = (fx - cx) / r;
526 radial->fy = (fy - cy) / r;
528 double aff1[6], aff2[6], gradTransform[6];
531 TQWMatrix m = m_painter->parseTransform(element.attribute(
"gradientTransform"));
533 gradTransform[0] = m.m11();
534 gradTransform[1] = m.m12();
535 gradTransform[2] = m.m21();
536 gradTransform[3] = m.m22();
537 gradTransform[4] = m.dx();
538 gradTransform[5] = m.dy();
540 art_affine_scale(aff1, r, r);
541 art_affine_translate(aff2, cx, cy);
543 art_affine_multiply(aff1, aff1, aff2);
544 art_affine_multiply(aff1, aff1, gradTransform);
545 art_affine_multiply(aff1, aff1, radial->affine);
546 art_affine_invert(radial->affine, aff1);
548 ArtRender *render = art_render_new(0, 0, m_width, m_height, m_buffer, m_rowstride, 3, 8, ART_ALPHA_SEPARATE, 0);
549 art_render_svp(render, svp);
551 art_render_gradient_radial(render, radial, ART_FILTER_HYPER);
552 art_render_invoke(render);
556 void applyGradient(ArtSVP *svp,
const TQString &ref)
558 ArtGradientLinear *linear = m_linearGradientMap[ref];
561 TQDomElement element = m_linearGradientElementMap[linear];
563 if(!element.hasAttribute(
"xlink:href"))
565 applyLinearGradient(svp, ref);
570 ArtGradientLinear *linear = m_linearGradientMap[element.attribute(
"xlink:href").mid(1)];
571 TQDomElement newElement = m_linearGradientElementMap[linear];
574 TQDict<TQString> refattrs;
575 refattrs.setAutoDelete(
true);
577 for(
unsigned int i = 0; i < newElement.attributes().length(); ++i)
578 refattrs.insert(newElement.attributes().item(i).nodeName(),
new TQString(newElement.attributes().item(i).nodeValue()));
581 if(!newElement.isNull())
583 TQDomNamedNodeMap attr = element.attributes();
585 for(
unsigned int i = 0; i < attr.length(); i++)
587 TQString
name = attr.item(i).nodeName();
588 if(name !=
"xlink:href" && name !=
"id")
589 newElement.setAttribute(name, attr.item(i).nodeValue());
593 applyGradient(svp, element.attribute(
"xlink:href").mid(1));
596 TQDictIterator<TQString> itr(refattrs);
597 for(; itr.current(); ++itr)
598 newElement.setAttribute(itr.currentKey(), *(itr.current()));
604 ArtGradientRadial *radial = m_radialGradientMap[ref];
607 TQDomElement element = m_radialGradientElementMap[radial];
609 if(!element.hasAttribute(
"xlink:href"))
611 applyRadialGradient(svp, ref);
616 ArtGradientRadial *radial = m_radialGradientMap[element.attribute(
"xlink:href").mid(1)];
617 TQDomElement newElement = m_radialGradientElementMap[radial];
620 TQDict<TQString> refattrs;
621 refattrs.setAutoDelete(
true);
623 for(
unsigned int i = 0; i < newElement.attributes().length(); ++i)
624 refattrs.insert(newElement.attributes().item(i).nodeName(),
new TQString(newElement.attributes().item(i).nodeValue()));
627 if(!newElement.isNull())
629 TQDomNamedNodeMap attr = element.attributes();
631 for(
unsigned int i = 0; i < attr.length(); i++)
633 TQString name = attr.item(i).nodeName();
634 if(name !=
"xlink:href" && name !=
"id")
635 newElement.setAttribute(name, attr.item(i).nodeValue());
639 applyGradient(svp, element.attribute(
"xlink:href").mid(1));
642 TQDictIterator<TQString> itr(refattrs);
643 for(; itr.current(); ++itr)
644 newElement.setAttribute(itr.currentKey(), *(itr.current()));
651 void applyGradient(ArtSVP *svp,
bool fill)
657 m_useFillGradient =
false;
658 ref = m_fillGradientReference;
662 m_useStrokeGradient =
false;
663 ref = m_strokeGradientReference;
666 applyGradient(svp, ref);
671 unsigned char *line = m_buffer;
673 for(
int y = 0; y < m_height; y++)
675 QRgb *sl =
reinterpret_cast<QRgb *
>(m_image->scanLine(y));
676 for(
int x = 0; x < m_width; x++)
677 sl[x] = tqRgba(line[x * 4], line[x * 4 + 1], line[x * 4 + 2], line[x * 4 + 3]);
683 void calculateArc(
bool relative, TQMemArray<ArtBpath> &vec,
int &index,
double &curx,
double &cury,
double angle,
double x,
double y,
double r1,
double r2,
bool largeArcFlag,
bool sweepFlag)
685 double sin_th, cos_th;
686 double a00, a01, a10, a11;
687 double x0, y0, x1, y1, xc, yc;
688 double d, sfactor, sfactor_sq;
689 double th0, th1, th_arc;
692 sin_th = sin(angle * (M_PI / 180.0));
693 cos_th = cos(angle * (M_PI / 180.0));
698 dx = (curx - x) / 2.0;
705 dy = (cury - y) / 2.0;
709 double _x1 = cos_th * dx + sin_th * dy;
710 double _y1 = -sin_th * dx + cos_th * dy;
711 double Pr1 = r1 * r1;
712 double Pr2 = r2 * r2;
713 double Px = _x1 * _x1;
714 double Py = _y1 * _y1;
717 double check = Px / Pr1 + Py / Pr2;
720 r1 = r1 * sqrt(check);
721 r2 = r2 * sqrt(check);
729 x0 = a00 * curx + a01 * cury;
730 y0 = a10 * curx + a11 * cury;
733 x1 = a00 * x + a01 * y;
735 x1 = a00 * (curx + x) + a01 * (cury + y);
738 y1 = a10 * x + a11 * y;
740 y1 = a10 * (curx + x) + a11 * (cury + y);
748 d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
750 sfactor_sq = 1.0 / d - 0.25;
755 sfactor = sqrt(sfactor_sq);
757 if(sweepFlag == largeArcFlag)
760 xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
761 yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
764 th0 = atan2(y0 - yc, x0 - xc);
765 th1 = atan2(y1 - yc, x1 - xc);
768 if(th_arc < 0 && sweepFlag)
770 else if(th_arc > 0 && !sweepFlag)
773 n_segs = (int) (
int) ceil(fabs(th_arc / (M_PI * 0.5 + 0.001)));
775 for(i = 0; i < n_segs; i++)
779 ensureSpace(vec, index);
782 double sin_th, cos_th;
783 double a00, a01, a10, a11;
784 double x1, y1, x2, y2, x3, y3;
788 double _th0 = th0 + i * th_arc / n_segs;
789 double _th1 = th0 + (i + 1) * th_arc / n_segs;
791 sin_th = sin(angle * (M_PI / 180.0));
792 cos_th = cos(angle * (M_PI / 180.0));
800 th_half = 0.5 * (_th1 - _th0);
801 t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
802 x1 = xc + cos(_th0) - t * sin(_th0);
803 y1 = yc + sin(_th0) + t * cos(_th0);
806 x2 = x3 + t * sin(_th1);
807 y2 = y3 - t * cos(_th1);
809 ensureSpace(vec, index);
811 vec[index].code = ART_CURVETO;
812 vec[index].x1 = a00 * x1 + a01 * y1;
813 vec[index].y1 = a10 * x1 + a11 * y1;
814 vec[index].x2 = a00 * x2 + a01 * y2;
815 vec[index].y2 = a10 * x2 + a11 * y2;
816 vec[index].x3 = a00 * x3 + a01 * y3;
817 vec[index].y3 = a10 * x3 + a11 * y3;
833 static void art_vpath_render_bez(ArtVpath **p_vpath,
int *pn,
int *pn_max,
834 double x0,
double y0,
835 double x1,
double y1,
836 double x2,
double y2,
837 double x3,
double y3,
840 double x3_0, y3_0, z3_0_dot, z1_dot, z2_dot;
841 double z1_perp, z2_perp, max_perp_sq;
843 double x_m, y_m, xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2;
848 z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
850 if (z3_0_dot < 0.001)
853 max_perp_sq = flatness * flatness * z3_0_dot;
855 z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
856 if (z1_perp * z1_perp > max_perp_sq)
859 z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
860 if (z2_perp * z2_perp > max_perp_sq)
863 z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
864 if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq)
867 z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
868 if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq)
871 if (z1_dot + z1_dot > z3_0_dot)
874 if (z2_dot + z2_dot > z3_0_dot)
878 art_vpath_add_point (p_vpath, pn, pn_max, ART_LINETO, x3, y3);
882 xa1 = (x0 + x1) * 0.5;
883 ya1 = (y0 + y1) * 0.5;
884 xa2 = (x0 + 2 * x1 + x2) * 0.25;
885 ya2 = (y0 + 2 * y1 + y2) * 0.25;
886 xb1 = (x1 + 2 * x2 + x3) * 0.25;
887 yb1 = (y1 + 2 * y2 + y3) * 0.25;
888 xb2 = (x2 + x3) * 0.5;
889 yb2 = (y2 + y3) * 0.5;
890 x_m = (xa2 + xb1) * 0.5;
891 y_m = (ya2 + yb1) * 0.5;
892 art_vpath_render_bez (p_vpath, pn, pn_max, x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, flatness);
893 art_vpath_render_bez (p_vpath, pn, pn_max, x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness);
896 ArtVpath *art_bez_path_to_vec(
const ArtBpath *bez,
double flatness)
899 int vec_n, vec_n_max;
904 vec_n_max = (1 << 4);
905 vec = art_new (ArtVpath, vec_n_max);
913 if(vec_n >= vec_n_max)
914 art_expand (vec, ArtVpath, vec_n_max);
916 switch (bez[bez_index].code)
918 case ART_MOVETO_OPEN:
921 x = bez[bez_index].x3;
922 y = bez[bez_index].y3;
923 vec[vec_n].code = bez[bez_index].code;
929 vec[vec_n].code = ART_END;
935 vec[vec_n].code = (ArtPathcode)ART_END2;
936 vec[vec_n].x = bez[bez_index].x3;
937 vec[vec_n].y = bez[bez_index].y3;
941 art_vpath_render_bez (&vec, &vec_n, &vec_n_max,
943 bez[bez_index].x1, bez[bez_index].y1,
944 bez[bez_index].x2, bez[bez_index].y2,
945 bez[bez_index].x3, bez[bez_index].y3,
947 x = bez[bez_index].x3;
948 y = bez[bez_index].y3;
953 while (bez[bez_index++].code != ART_END);
957 static void art_rgb_affine_run(
int *p_x0,
int *p_x1,
int y,
958 int src_width,
int src_height,
959 const double affine[6])
969 if (affine[0] > 1e-6)
971 z = affine[2] * (y + 0.5) + affine[4];
972 x_intercept = -z / affine[0];
973 xi = (int) (
int) ceil (x_intercept + 1e-6 - 0.5);
976 x_intercept = (-z + src_width) / affine[0];
977 xi = (int) ceil (x_intercept - 1e-6 - 0.5);
981 else if (affine[0] < -1e-6)
983 z = affine[2] * (y + 0.5) + affine[4];
984 x_intercept = (-z + src_width) / affine[0];
985 xi = (int) ceil (x_intercept + 1e-6 - 0.5);
988 x_intercept = -z / affine[0];
989 xi = (int) ceil (x_intercept - 1e-6 - 0.5);
995 z = affine[2] * (y + 0.5) + affine[4];
996 if (z < 0 || z >= src_width)
1002 if (affine[1] > 1e-6)
1004 z = affine[3] * (y + 0.5) + affine[5];
1005 x_intercept = -z / affine[1];
1006 xi = (int) ceil (x_intercept + 1e-6 - 0.5);
1009 x_intercept = (-z + src_height) / affine[1];
1010 xi = (int) ceil (x_intercept - 1e-6 - 0.5);
1014 else if (affine[1] < -1e-6)
1016 z = affine[3] * (y + 0.5) + affine[5];
1017 x_intercept = (-z + src_height) / affine[1];
1018 xi = (int) ceil (x_intercept + 1e-6 - 0.5);
1021 x_intercept = -z / affine[1];
1022 xi = (int) ceil (x_intercept - 1e-6 - 0.5);
1028 z = affine[3] * (y + 0.5) + affine[5];
1029 if (z < 0 || z >= src_height)
1041 static void art_rgba_rgba_affine(art_u8 *dst,
1042 int x0,
int y0,
int x1,
int y1,
int dst_rowstride,
1044 int src_width,
int src_height,
int src_rowstride,
1045 const double affine[6])
1049 art_u8 *dst_p, *dst_linestart;
1050 const art_u8 *src_p;
1051 ArtPoint pt, src_pt;
1054 art_u8 bg_r, bg_g, bg_b, bg_a, cr, cg, cb;
1055 art_u8 fg_r, fg_g, fg_b;
1059 dst_linestart = dst;
1060 art_affine_invert (inv, affine);
1061 for (y = y0; y < y1; y++)
1066 art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
1068 dst_p = dst_linestart + (run_x0 - x0) * 4;
1069 for (x = run_x0; x < run_x1; x++)
1072 art_affine_point (&src_pt, &pt, inv);
1073 src_x = (int) floor (src_pt.x);
1074 src_y = (int) floor (src_pt.y);
1075 src_p = src + (src_y * src_rowstride) + src_x * 4;
1076 if (src_x >= 0 && src_x < src_width &&
1077 src_y >= 0 && src_y < src_height)
1085 dst_p[0] = src_p[0];
1086 dst_p[1] = src_p[1];
1087 dst_p[2] = src_p[2];
1097 cr = (bg_r * bg_a + 0x80) >> 8;
1098 cg = (bg_g * bg_g + 0x80) >> 8;
1099 cb = (bg_b * bg_b + 0x80) >> 8;
1101 tmp = (src_p[0] - bg_r) * alpha;
1102 fg_r = bg_r + ((tmp + (tmp >> 8) + 0x80) >> 8);
1103 tmp = (src_p[1] - bg_g) * alpha;
1104 fg_g = bg_g + ((tmp + (tmp >> 8) + 0x80) >> 8);
1105 tmp = (src_p[2] - bg_b) * alpha;
1106 fg_b = bg_b + ((tmp + (tmp >> 8) + 0x80) >> 8);
1111 dst_p[3] = bg_a + (((255 - bg_a) * alpha + 0x80) >> 8);
1114 }
else { dst_p[0] = 255; dst_p[1] = 0; dst_p[2] = 0; dst_p[3] = 255;}
1117 dst_linestart += dst_rowstride;
1122 friend class KSVGIconPainter;
1126 TQWMatrix *m_worldMatrix;
1128 TQString m_fillRule;
1129 TQString m_joinStyle;
1130 TQString m_capStyle;
1132 int m_strokeMiterLimit;
1135 unsigned short m_dashOffset;
1137 TQColor m_fillColor;
1138 TQColor m_strokeColor;
1141 art_u8 *m_tempBuffer;
1149 double m_fillOpacity;
1150 double m_strokeOpacity;
1155 bool m_useFillGradient;
1156 bool m_useStrokeGradient;
1158 TQString m_fillGradientReference;
1159 TQString m_strokeGradientReference;
1161 TQMap<TQString, ArtGradientLinear *> m_linearGradientMap;
1162 TQMap<ArtGradientLinear *, TQDomElement> m_linearGradientElementMap;
1164 TQMap<TQString, ArtGradientRadial *> m_radialGradientMap;
1165 TQMap<ArtGradientRadial *, TQDomElement> m_radialGradientElementMap;
1167 KSVGIconPainter *m_painter;
1169 double m_strokeWidth;
1172 struct KSVGIconPainter::Private
1174 KSVGIconPainterHelper *helper;
1180 KSVGIconPainter::KSVGIconPainter(
int width,
int height) : d(new Private())
1182 d->helper =
new KSVGIconPainterHelper(width, height,
this);
1184 d->drawWidth = width;
1185 d->drawHeight = height;
1188 KSVGIconPainter::~KSVGIconPainter()
1194 void KSVGIconPainter::setDrawWidth(
int dwidth)
1196 d->drawWidth = dwidth;
1199 void KSVGIconPainter::setDrawHeight(
int dheight)
1201 d->drawHeight = dheight;
1204 void KSVGIconPainter::finish()
1209 TQImage *KSVGIconPainter::image()
1211 return new TQImage(*d->helper->m_image);
1214 TQWMatrix *KSVGIconPainter::worldMatrix()
1216 return d->helper->m_worldMatrix;
1219 void KSVGIconPainter::setWorldMatrix(TQWMatrix *matrix)
1221 if(d->helper->m_worldMatrix)
1222 delete d->helper->m_worldMatrix;
1224 d->helper->m_worldMatrix = matrix;
1227 void KSVGIconPainter::setStrokeWidth(
double width)
1229 d->helper->m_strokeWidth = width;
1232 void KSVGIconPainter::setStrokeMiterLimit(
const TQString &miter)
1234 d->helper->m_strokeMiterLimit = miter.toInt();
1237 void KSVGIconPainter::setStrokeDashOffset(
const TQString &dashOffset)
1239 d->helper->m_dashOffset = dashOffset.toUInt();
1242 void KSVGIconPainter::setStrokeDashArray(
const TQString &dashes)
1244 d->helper->m_dashes = dashes;
1247 void KSVGIconPainter::setCapStyle(
const TQString &cap)
1249 d->helper->m_capStyle = cap;
1252 void KSVGIconPainter::setJoinStyle(
const TQString &join)
1254 d->helper->m_joinStyle = join;
1257 void KSVGIconPainter::setStrokeColor(
const TQString &stroke)
1259 if(stroke.startsWith(
"url"))
1261 d->helper->m_useStroke =
false;
1262 d->helper->m_useStrokeGradient =
true;
1264 TQString url = stroke;
1266 unsigned int start = url.find(
"#") + 1;
1267 unsigned int end = url.findRev(
")");
1269 d->helper->m_strokeGradientReference = url.mid(start, end - start);
1273 d->helper->m_strokeColor = parseColor(stroke);
1275 d->helper->m_useStrokeGradient =
false;
1276 d->helper->m_strokeGradientReference = TQString::null;
1278 if(stroke.stripWhiteSpace().lower() !=
"none")
1281 setUseStroke(
false);
1285 void KSVGIconPainter::setFillColor(
const TQString &fill)
1287 if(fill.startsWith(
"url"))
1289 d->helper->m_useFill =
false;
1290 d->helper->m_useFillGradient =
true;
1292 TQString url = fill;
1294 unsigned int start = url.find(
"#") + 1;
1295 unsigned int end = url.findRev(
")");
1297 d->helper->m_fillGradientReference = url.mid(start, end - start);
1301 d->helper->m_fillColor = parseColor(fill);
1303 d->helper->m_useFillGradient =
false;
1304 d->helper->m_fillGradientReference = TQString::null;
1306 if(fill.stripWhiteSpace().lower() !=
"none")
1313 void KSVGIconPainter::setFillRule(
const TQString &fillRule)
1315 d->helper->m_fillRule = fillRule;
1318 TQ_UINT32 KSVGIconPainter::parseOpacity(
const TQString &data)
1326 if(data.contains(
"%"))
1328 TQString tempString = data.left(data.length() - 1);
1329 temp = double(255 * tempString.toDouble()) / 100.0;
1332 temp = data.toDouble();
1334 opacity = (int) floor(temp * 255 + 0.5);
1340 void KSVGIconPainter::setFillOpacity(
const TQString &fillOpacity)
1342 d->helper->m_fillOpacity = parseOpacity(fillOpacity);
1345 void KSVGIconPainter::setStrokeOpacity(
const TQString &strokeOpacity)
1347 d->helper->m_strokeOpacity = parseOpacity(strokeOpacity);
1350 void KSVGIconPainter::setOpacity(
const TQString &opacity)
1352 d->helper->m_opacity = parseOpacity(opacity);
1355 void KSVGIconPainter::setUseFill(
bool fill)
1357 d->helper->m_useFill = fill;
1360 void KSVGIconPainter::setUseStroke(
bool stroke)
1362 d->helper->m_useStroke = stroke;
1365 void KSVGIconPainter::setClippingRect(
int x,
int y,
int w,
int h)
1367 ArtVpath *vec = d->helper->allocVPath(6);
1369 vec[0].code = ART_MOVETO;
1373 vec[1].code = ART_LINETO;
1377 vec[2].code = ART_LINETO;
1381 vec[3].code = ART_LINETO;
1385 vec[4].code = ART_LINETO;
1389 vec[5].code = ART_END;
1391 if(d->helper->m_clipSVP)
1392 art_svp_free(d->helper->m_clipSVP);
1394 d->helper->m_clipSVP = art_svp_from_vpath(vec);
1399 void KSVGIconPainter::drawRectangle(
double x,
double y,
double w,
double h,
double rx,
double ry)
1401 if((
int) rx != 0 && (
int) ry != 0)
1404 ArtBpath *vec = d->helper->allocBPath(10);
1414 vec[i].code = ART_MOVETO_OPEN;
1420 vec[i].code = ART_CURVETO;
1421 vec[i].x1 = x + rx * (1 - 0.552);
1424 vec[i].y2 = y + ry * (1 - 0.552);
1432 vec[i].code = ART_LINETO;
1434 vec[i].y3 = y + h - ry;
1439 vec[i].code = ART_CURVETO;
1441 vec[i].y1 = y + h - ry * (1 - 0.552);
1442 vec[i].x2 = x + rx * (1 - 0.552);
1451 vec[i].code = ART_LINETO;
1452 vec[i].x3 = x + w - rx;
1458 vec[i].code = ART_CURVETO;
1459 vec[i].x1 = x + w - rx * (1 - 0.552);
1462 vec[i].y2 = y + h - ry * (1 - 0.552);
1465 vec[i].y3 = y + h - ry;
1471 vec[i].code = ART_LINETO;
1478 vec[i].code = ART_CURVETO;
1480 vec[i].y1 = y + ry * (1 - 0.552);
1481 vec[i].x2 = x + w - rx * (1 - 0.552);
1483 vec[i].x3 = x + w - rx;
1490 vec[i].code = ART_LINETO;
1497 vec[i].code = ART_END;
1499 res = d->helper->art_bez_path_to_vec(vec, 0.25);
1501 d->helper->drawVPath(res);
1505 ArtVpath *vec = d->helper->allocVPath(6);
1507 vec[0].code = ART_MOVETO;
1511 vec[1].code = ART_LINETO;
1515 vec[2].code = ART_LINETO;
1519 vec[3].code = ART_LINETO;
1523 vec[4].code = ART_LINETO;
1527 vec[5].code = ART_END;
1529 d->helper->drawVPath(vec);
1533 void KSVGIconPainter::drawEllipse(
double cx,
double cy,
double rx,
double ry)
1537 temp = d->helper->allocBPath(6);
1539 double x1, y1, x2, y2, x3, y3;
1540 double len = 0.55228474983079356;
1541 double cos4[] = {1.0, 0.0, -1.0, 0.0, 1.0};
1542 double sin4[] = {0.0, 1.0, 0.0, -1.0, 0.0};
1545 temp[i].code = ART_MOVETO;
1546 temp[i].x3 = cx + rx;
1553 x1 = cos4[i-1] + len * cos4[i];
1554 y1 = sin4[i-1] + len * sin4[i];
1555 x2 = cos4[i] + len * cos4[i-1];
1556 y2 = sin4[i] + len * sin4[i-1];
1560 temp[i].code = ART_CURVETO;
1561 temp[i].x1 = cx + x1 * rx;
1562 temp[i].y1 = cy + y1 * ry;
1563 temp[i].x2 = cx + x2 * rx;
1564 temp[i].y2 = cy + y2 * ry;
1565 temp[i].x3 = cx + x3 * rx;
1566 temp[i].y3 = cy + y3 * ry;
1571 temp[i].code = ART_END;
1573 d->helper->drawBPath(temp);
1578 void KSVGIconPainter::drawLine(
double x1,
double y1,
double x2,
double y2)
1582 vec = d->helper->allocVPath(3);
1584 vec[0].code = ART_MOVETO_OPEN;
1588 vec[1].code = ART_LINETO;
1592 vec[2].code = ART_END;
1594 d->helper->drawVPath(vec);
1597 void KSVGIconPainter::drawPolyline(TQPointArray polyArray,
int points)
1599 if(polyArray.point(0).x() == -1 || polyArray.point(0).y() == -1)
1605 points = polyArray.count();
1607 polyline = d->helper->allocVPath(3 + points);
1608 polyline[0].code = ART_MOVETO;
1609 polyline[0].x = polyArray.point(0).x();
1610 polyline[0].y = polyArray.point(0).y();
1613 for(index = 1; index < points; index++)
1615 TQPoint point = polyArray.point(index);
1616 polyline[index].code = ART_LINETO;
1617 polyline[index].x = point.x();
1618 polyline[index].y = point.y();
1621 if(d->helper->m_useFill)
1623 polyline[index].code = (ArtPathcode)ART_END2;
1624 polyline[index].x = polyArray.point(0).x();
1625 polyline[index++].y = polyArray.point(0).y();
1628 polyline[index].code = ART_END;
1630 d->helper->drawVPath(polyline);
1633 void KSVGIconPainter::drawPolygon(TQPointArray polyArray)
1637 polygon = d->helper->allocVPath(3 + polyArray.count());
1638 polygon[0].code = ART_MOVETO;
1639 polygon[0].x = polyArray.point(0).x();
1640 polygon[0].y = polyArray.point(0).y();
1643 for(index = 1; index < polyArray.count(); index++)
1645 TQPoint point = polyArray.point(index);
1646 polygon[index].code = ART_LINETO;
1647 polygon[index].x = point.x();
1648 polygon[index].y = point.y();
1651 polygon[index].code = ART_LINETO;
1652 polygon[index].x = polyArray.point(0).x();
1653 polygon[index].y = polyArray.point(0).y();
1656 polygon[index].code = ART_END;
1658 d->helper->drawVPath(polygon);
1663 static const char *getCoord(
const char *ptr,
double &number)
1665 int integer, exponent;
1666 double decimal, frac;
1679 else if(*ptr ==
'-')
1685 while(*ptr !=
'\0' && *ptr >=
'0' && *ptr <=
'9')
1686 integer = (integer * 10) + *(ptr++) -
'0';
1691 while(*ptr !=
'\0' && *ptr >=
'0' && *ptr <=
'9')
1692 decimal += (*(ptr++) -
'0') * (frac *= 0.1);
1695 if(*ptr ==
'e' || *ptr ==
'E')
1702 else if(*ptr ==
'-')
1709 while(*ptr !=
'\0' && *ptr >=
'0' && *ptr <=
'9')
1712 exponent += *ptr -
'0';
1717 number = integer + decimal;
1718 number *= sign * pow(10.0, expsign * exponent);
1727 void KSVGIconPainter::drawPath(
const TQString &data,
bool filled)
1729 if (!data.isEmpty())
1731 TQString value = data;
1733 TQMemArray<ArtBpath> vec;
1736 double curx = 0.0, cury = 0.0, contrlx = 0.0, contrly = 0.0, xc, yc;
1737 unsigned int lastCommand = 0;
1739 TQString _d = value.replace(
",",
" ");
1740 _d = _d.simplifyWhiteSpace();
1741 const char *ptr = _d.latin1();
1742 const char *end = _d.latin1() + _d.length() + 1;
1744 double tox, toy, x1, y1, x2, y2, rx, ry, angle;
1745 bool largeArc, sweep;
1746 char command = *(ptr++);
1756 ptr = getCoord(ptr, tox);
1757 ptr = getCoord(ptr, toy);
1759 if(index != -1 && lastCommand !=
'z')
1763 for(
int i = index; i >= 0; i--)
1765 if(vec[i].code == ART_MOVETO_OPEN || vec[i].code == ART_MOVETO)
1774 if(vec.size() == (
unsigned int) index)
1775 vec.resize(index + 1);
1777 vec[index].code = (ArtPathcode)ART_END2;
1778 vec[index].x3 = vec[find].x3;
1779 vec[index].y3 = vec[find].y3;
1787 d->helper->ensureSpace(vec, index);
1789 vec[index].code = (index == 0) ? ART_MOVETO : ART_MOVETO_OPEN;
1790 vec[index].x3 = curx;
1791 vec[index].y3 = cury;
1796 ptr = getCoord(ptr, tox);
1797 ptr = getCoord(ptr, toy);
1798 if(index != -1 && lastCommand !=
'z')
1802 for(
int i = index; i >= 0; i--)
1804 if(vec[i].code == ART_MOVETO_OPEN || vec[i].code == ART_MOVETO)
1813 if(vec.size() == (
unsigned int) index)
1814 vec.resize(index + 1);
1816 vec[index].code = (ArtPathcode)ART_END2;
1817 vec[index].x3 = vec[find].x3;
1818 vec[index].y3 = vec[find].y3;
1826 d->helper->ensureSpace(vec, index);
1828 vec[index].code = (index == 0) ? ART_MOVETO : ART_MOVETO_OPEN;
1829 vec[index].x3 = curx;
1830 vec[index].y3 = cury;
1835 ptr = getCoord(ptr, tox);
1836 ptr = getCoord(ptr, toy);
1840 d->helper->ensureSpace(vec, index);
1842 vec[index].code = ART_LINETO;
1843 vec[index].x3 = curx + tox;
1844 vec[index].y3 = cury + toy;
1852 ptr = getCoord(ptr, tox);
1853 ptr = getCoord(ptr, toy);
1857 d->helper->ensureSpace(vec, index);
1859 vec[index].code = ART_LINETO;
1860 vec[index].x3 = tox;
1861 vec[index].y3 = toy;
1869 ptr = getCoord(ptr, tox);
1875 d->helper->ensureSpace(vec, index);
1877 vec[index].code = ART_LINETO;
1878 vec[index].x3 = curx;
1879 vec[index].y3 = cury;
1884 ptr = getCoord(ptr, tox);
1890 d->helper->ensureSpace(vec, index);
1892 vec[index].code = ART_LINETO;
1893 vec[index].x3 = curx;
1894 vec[index].y3 = cury;
1899 ptr = getCoord(ptr, toy);
1905 d->helper->ensureSpace(vec, index);
1907 vec[index].code = ART_LINETO;
1908 vec[index].x3 = curx;
1909 vec[index].y3 = cury;
1914 ptr = getCoord(ptr, toy);
1920 d->helper->ensureSpace(vec, index);
1922 vec[index].code = ART_LINETO;
1923 vec[index].x3 = curx;
1924 vec[index].y3 = cury;
1929 ptr = getCoord(ptr, x1);
1930 ptr = getCoord(ptr, y1);
1931 ptr = getCoord(ptr, x2);
1932 ptr = getCoord(ptr, y2);
1933 ptr = getCoord(ptr, tox);
1934 ptr = getCoord(ptr, toy);
1938 d->helper->ensureSpace(vec, index);
1940 vec[index].code = ART_CURVETO;
1941 vec[index].x1 = curx + x1;
1942 vec[index].y1 = cury + y1;
1943 vec[index].x2 = curx + x2;
1944 vec[index].y2 = cury + y2;
1945 vec[index].x3 = curx + tox;
1946 vec[index].y3 = cury + toy;
1951 contrlx = vec[index].x2;
1952 contrly = vec[index].y2;
1957 ptr = getCoord(ptr, x1);
1958 ptr = getCoord(ptr, y1);
1959 ptr = getCoord(ptr, x2);
1960 ptr = getCoord(ptr, y2);
1961 ptr = getCoord(ptr, tox);
1962 ptr = getCoord(ptr, toy);
1966 d->helper->ensureSpace(vec, index);
1968 vec[index].code = ART_CURVETO;
1973 vec[index].x3 = tox;
1974 vec[index].y3 = toy;
1976 curx = vec[index].x3;
1977 cury = vec[index].y3;
1978 contrlx = vec[index].x2;
1979 contrly = vec[index].y2;
1984 ptr = getCoord(ptr, x2);
1985 ptr = getCoord(ptr, y2);
1986 ptr = getCoord(ptr, tox);
1987 ptr = getCoord(ptr, toy);
1991 d->helper->ensureSpace(vec, index);
1993 vec[index].code = ART_CURVETO;
1994 vec[index].x1 = 2 * curx - contrlx;
1995 vec[index].y1 = 2 * cury - contrly;
1996 vec[index].x2 = curx + x2;
1997 vec[index].y2 = cury + y2;
1998 vec[index].x3 = curx + tox;
1999 vec[index].y3 = cury + toy;
2004 contrlx = vec[index].x2;
2005 contrly = vec[index].y2;
2010 ptr = getCoord(ptr, x2);
2011 ptr = getCoord(ptr, y2);
2012 ptr = getCoord(ptr, tox);
2013 ptr = getCoord(ptr, toy);
2017 d->helper->ensureSpace(vec, index);
2019 vec[index].code = ART_CURVETO;
2020 vec[index].x1 = 2 * curx - contrlx;
2021 vec[index].y1 = 2 * cury - contrly;
2024 vec[index].x3 = tox;
2025 vec[index].y3 = toy;
2027 curx = vec[index].x3;
2028 cury = vec[index].y3;
2029 contrlx = vec[index].x2;
2030 contrly = vec[index].y2;
2035 ptr = getCoord(ptr, x1);
2036 ptr = getCoord(ptr, y1);
2037 ptr = getCoord(ptr, tox);
2038 ptr = getCoord(ptr, toy);
2042 d->helper->ensureSpace(vec, index);
2044 vec[index].code = ART_CURVETO;
2045 vec[index].x1 = (curx + 2 * (x1 + curx)) * (1.0 / 3.0);
2046 vec[index].y1 = (cury + 2 * (y1 + cury)) * (1.0 / 3.0);
2047 vec[index].x2 = ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0);
2048 vec[index].y2 = ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0);
2049 vec[index].x3 = curx + tox;
2050 vec[index].y3 = cury + toy;
2052 contrlx = curx + x1;
2053 contrly = cury + y1;
2060 ptr = getCoord(ptr, x1);
2061 ptr = getCoord(ptr, y1);
2062 ptr = getCoord(ptr, tox);
2063 ptr = getCoord(ptr, toy);
2067 d->helper->ensureSpace(vec, index);
2070 vec[index].code = ART_CURVETO;
2071 vec[index].x1 = (curx + 2 * x1) * (1.0 / 3.0);
2072 vec[index].y1 = (cury + 2 * y1) * (1.0 / 3.0);
2073 vec[index].x2 = (tox + 2 * x1) * (1.0 / 3.0);
2074 vec[index].y2 = (toy + 2 * y1) * (1.0 / 3.0);
2075 vec[index].x3 = tox;
2076 vec[index].y3 = toy;
2078 curx = vec[index].x3;
2079 cury = vec[index].y3;
2080 contrlx = vec[index].x2;
2081 contrly = vec[index].y2;
2086 ptr = getCoord(ptr, tox);
2087 ptr = getCoord(ptr, toy);
2089 xc = 2 * curx - contrlx;
2090 yc = 2 * cury - contrly;
2094 d->helper->ensureSpace(vec, index);
2096 vec[index].code = ART_CURVETO;
2097 vec[index].x1 = (curx + 2 * xc) * (1.0 / 3.0);
2098 vec[index].y1 = (cury + 2 * yc) * (1.0 / 3.0);
2099 vec[index].x2 = ((curx + tox) + 2 * xc) * (1.0 / 3.0);
2100 vec[index].y2 = ((cury + toy) + 2 * yc) * (1.0 / 3.0);
2102 vec[index].x3 = curx + tox;
2103 vec[index].y3 = cury + toy;
2113 ptr = getCoord(ptr, tox);
2114 ptr = getCoord(ptr, toy);
2116 xc = 2 * curx - contrlx;
2117 yc = 2 * cury - contrly;
2121 d->helper->ensureSpace(vec, index);
2123 vec[index].code = ART_CURVETO;
2124 vec[index].x1 = (curx + 2 * xc) * (1.0 / 3.0);
2125 vec[index].y1 = (cury + 2 * yc) * (1.0 / 3.0);
2126 vec[index].x2 = (tox + 2 * xc) * (1.0 / 3.0);
2127 vec[index].y2 = (toy + 2 * yc) * (1.0 / 3.0);
2128 vec[index].x3 = tox;
2129 vec[index].y3 = toy;
2142 for(
int i = index; i >= 0; i--)
2144 if(vec[i].code == ART_MOVETO_OPEN || vec[i].code == ART_MOVETO)
2153 if(vec[find].x3 != curx || vec[find].y3 != cury)
2157 d->helper->ensureSpace(vec, index);
2159 vec[index].code = ART_LINETO;
2160 vec[index].x3 = vec[find].x3;
2161 vec[index].y3 = vec[find].y3;
2166 curx = vec[find].x3;
2167 cury = vec[find].y3;
2172 ptr = getCoord(ptr, rx);
2173 ptr = getCoord(ptr, ry);
2174 ptr = getCoord(ptr, angle);
2175 ptr = getCoord(ptr, tox);
2176 largeArc = tox == 1;
2177 ptr = getCoord(ptr, tox);
2179 ptr = getCoord(ptr, tox);
2180 ptr = getCoord(ptr, toy);
2186 d->helper->calculateArc(
true, vec, index, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep);
2191 ptr = getCoord(ptr, rx);
2192 ptr = getCoord(ptr, ry);
2193 ptr = getCoord(ptr, angle);
2194 ptr = getCoord(ptr, tox);
2195 largeArc = tox == 1;
2196 ptr = getCoord(ptr, tox);
2198 ptr = getCoord(ptr, tox);
2199 ptr = getCoord(ptr, toy);
2205 d->helper->calculateArc(
false, vec, index, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep);
2211 if(*ptr ==
'+' || *ptr ==
'-' || *ptr ==
'.' || (*ptr >=
'0' && *ptr <=
'9'))
2218 else if(command ==
'm')
2229 if(lastCommand !=
'C' && lastCommand !=
'c' &&
2230 lastCommand !=
'S' && lastCommand !=
's' &&
2231 lastCommand !=
'Q' && lastCommand !=
'q' &&
2232 lastCommand !=
'T' && lastCommand !=
't')
2241 for(
int i = index; i >= 0; i--)
2243 if(vec[i].code == ART_MOVETO_OPEN || vec[i].code == ART_MOVETO)
2251 if(curx != vec[find].x3 && cury != vec[find].y3)
2253 if((
int) curx == (int) vec[find].x3 && (
int) cury == (int) vec[find].y3)
2257 if(vec.size() == (
unsigned int) index)
2258 vec.resize(index + 1);
2260 vec[index].code = ART_LINETO;
2261 vec[index].x3 = vec[find].x3;
2262 vec[index].y3 = vec[find].y3;
2264 curx = vec[find].x3;
2265 cury = vec[find].y3;
2272 if((
int) curx != (
int) vec[find].x3 || (
int) cury != (
int) vec[find].y3)
2276 if(vec.size() == (
unsigned int) index)
2277 vec.resize(index + 1);
2279 vec[index].code = (ArtPathcode)ART_END2;
2280 vec[index].x3 = vec[find].x3;
2281 vec[index].y3 = vec[find].y3;
2283 curx = vec[find].x3;
2284 cury = vec[find].y3;
2291 if(vec.size() == (
unsigned int) index)
2292 vec.resize(index + 1);
2294 vec[index].code = ART_END;
2298 bool render =
false;
2299 for(
int i = index; i >= 0; i--)
2301 if(vec[i].code != ART_MOVETO_OPEN && vec[i].code != ART_MOVETO && !(vec[i].code >= ART_END))
2309 d->helper->drawBPath(vec.data());
2313 void KSVGIconPainter::drawImage(
double x,
double y, TQImage &image)
2315 if(image.depth() != 32)
2316 image = image.convertDepth(32);
2319 affine[0] = d->helper->m_worldMatrix->m11();
2320 affine[1] = d->helper->m_worldMatrix->m12();
2321 affine[2] = d->helper->m_worldMatrix->m21();
2322 affine[3] = d->helper->m_worldMatrix->m22();
2324 d->helper->m_worldMatrix->map(x, y, &affine[4], &affine[5]);
2326 d->helper->art_rgba_rgba_affine(d->helper->m_buffer, 0, 0, d->helper->m_width, d->helper->m_height,
2327 d->helper->m_rowstride, image.bits(), image.width(), image.height(),
2328 image.width() * 4, affine);
2331 TQColor KSVGIconPainter::parseColor(
const TQString ¶m)
2333 if(param.stripWhiteSpace().startsWith(
"#"))
2336 color.setNamedColor(param.stripWhiteSpace());
2339 else if(param.stripWhiteSpace().startsWith(
"rgb("))
2341 TQString parse = param.stripWhiteSpace();
2342 TQStringList colors = TQStringList::split(
',', parse);
2343 TQString r = colors[0].right((colors[0].length() - 4));
2344 TQString g = colors[1];
2345 TQString b = colors[2].left((colors[2].length() - 1));
2349 r = r.left(r.length() - 1);
2350 r = TQString::number(
int((
double(255 * r.toDouble()) / 100.0)));
2355 g = g.left(g.length() - 1);
2356 g = TQString::number(
int((
double(255 * g.toDouble()) / 100.0)));
2361 b = b.left(b.length() - 1);
2362 b = TQString::number(
int((
double(255 * b.toDouble()) / 100.0)));
2365 return TQColor(r.toInt(), g.toInt(), b.toInt());
2369 TQString rgbColor = param.stripWhiteSpace();
2371 if(rgbColor ==
"aliceblue")
2372 return TQColor(240, 248, 255);
2373 else if(rgbColor ==
"antiquewhite")
2374 return TQColor(250, 235, 215);
2375 else if(rgbColor ==
"aqua")
2376 return TQColor(0, 255, 255);
2377 else if(rgbColor ==
"aquamarine")
2378 return TQColor(127, 255, 212);
2379 else if(rgbColor ==
"azure")
2380 return TQColor(240, 255, 255);
2381 else if(rgbColor ==
"beige")
2382 return TQColor(245, 245, 220);
2383 else if(rgbColor ==
"bisque")
2384 return TQColor(255, 228, 196);
2385 else if(rgbColor ==
"black")
2386 return TQColor(0, 0, 0);
2387 else if(rgbColor ==
"blanchedalmond")
2388 return TQColor(255, 235, 205);
2389 else if(rgbColor ==
"blue")
2390 return TQColor(0, 0, 255);
2391 else if(rgbColor ==
"blueviolet")
2392 return TQColor(138, 43, 226);
2393 else if(rgbColor ==
"brown")
2394 return TQColor(165, 42, 42);
2395 else if(rgbColor ==
"burlywood")
2396 return TQColor(222, 184, 135);
2397 else if(rgbColor ==
"cadetblue")
2398 return TQColor(95, 158, 160);
2399 else if(rgbColor ==
"chartreuse")
2400 return TQColor(127, 255, 0);
2401 else if(rgbColor ==
"chocolate")
2402 return TQColor(210, 105, 30);
2403 else if(rgbColor ==
"coral")
2404 return TQColor(255, 127, 80);
2405 else if(rgbColor ==
"cornflowerblue")
2406 return TQColor(100, 149, 237);
2407 else if(rgbColor ==
"cornsilk")
2408 return TQColor(255, 248, 220);
2409 else if(rgbColor ==
"crimson")
2410 return TQColor(220, 20, 60);
2411 else if(rgbColor ==
"cyan")
2412 return TQColor(0, 255, 255);
2413 else if(rgbColor ==
"darkblue")
2414 return TQColor(0, 0, 139);
2415 else if(rgbColor ==
"darkcyan")
2416 return TQColor(0, 139, 139);
2417 else if(rgbColor ==
"darkgoldenrod")
2418 return TQColor(184, 134, 11);
2419 else if(rgbColor ==
"darkgray")
2420 return TQColor(169, 169, 169);
2421 else if(rgbColor ==
"darkgrey")
2422 return TQColor(169, 169, 169);
2423 else if(rgbColor ==
"darkgreen")
2424 return TQColor(0, 100, 0);
2425 else if(rgbColor ==
"darkkhaki")
2426 return TQColor(189, 183, 107);
2427 else if(rgbColor ==
"darkmagenta")
2428 return TQColor(139, 0, 139);
2429 else if(rgbColor ==
"darkolivegreen")
2430 return TQColor(85, 107, 47);
2431 else if(rgbColor ==
"darkorange")
2432 return TQColor(255, 140, 0);
2433 else if(rgbColor ==
"darkorchid")
2434 return TQColor(153, 50, 204);
2435 else if(rgbColor ==
"darkred")
2436 return TQColor(139, 0, 0);
2437 else if(rgbColor ==
"darksalmon")
2438 return TQColor(233, 150, 122);
2439 else if(rgbColor ==
"darkseagreen")
2440 return TQColor(143, 188, 143);
2441 else if(rgbColor ==
"darkslateblue")
2442 return TQColor(72, 61, 139);
2443 else if(rgbColor ==
"darkslategray")
2444 return TQColor(47, 79, 79);
2445 else if(rgbColor ==
"darkslategrey")
2446 return TQColor(47, 79, 79);
2447 else if(rgbColor ==
"darkturquoise")
2448 return TQColor(0, 206, 209);
2449 else if(rgbColor ==
"darkviolet")
2450 return TQColor(148, 0, 211);
2451 else if(rgbColor ==
"deeppink")
2452 return TQColor(255, 20, 147);
2453 else if(rgbColor ==
"deepskyblue")
2454 return TQColor(0, 191, 255);
2455 else if(rgbColor ==
"dimgray")
2456 return TQColor(105, 105, 105);
2457 else if(rgbColor ==
"dimgrey")
2458 return TQColor(105, 105, 105);
2459 else if(rgbColor ==
"dodgerblue")
2460 return TQColor(30, 144, 255);
2461 else if(rgbColor ==
"firebrick")
2462 return TQColor(178, 34, 34);
2463 else if(rgbColor ==
"floralwhite")
2464 return TQColor(255, 250, 240);
2465 else if(rgbColor ==
"forestgreen")
2466 return TQColor(34, 139, 34);
2467 else if(rgbColor ==
"fuchsia")
2468 return TQColor(255, 0, 255);
2469 else if(rgbColor ==
"gainsboro")
2470 return TQColor(220, 220, 220);
2471 else if(rgbColor ==
"ghostwhite")
2472 return TQColor(248, 248, 255);
2473 else if(rgbColor ==
"gold")
2474 return TQColor(255, 215, 0);
2475 else if(rgbColor ==
"goldenrod")
2476 return TQColor(218, 165, 32);
2477 else if(rgbColor ==
"gray")
2478 return TQColor(128, 128, 128);
2479 else if(rgbColor ==
"grey")
2480 return TQColor(128, 128, 128);
2481 else if(rgbColor ==
"green")
2482 return TQColor(0, 128, 0);
2483 else if(rgbColor ==
"greenyellow")
2484 return TQColor(173, 255, 47);
2485 else if(rgbColor ==
"honeydew")
2486 return TQColor(240, 255, 240);
2487 else if(rgbColor ==
"hotpink")
2488 return TQColor(255, 105, 180);
2489 else if(rgbColor ==
"indianred")
2490 return TQColor(205, 92, 92);
2491 else if(rgbColor ==
"indigo")
2492 return TQColor(75, 0, 130);
2493 else if(rgbColor ==
"ivory")
2494 return TQColor(255, 255, 240);
2495 else if(rgbColor ==
"khaki")
2496 return TQColor(240, 230, 140);
2497 else if(rgbColor ==
"lavender")
2498 return TQColor(230, 230, 250);
2499 else if(rgbColor ==
"lavenderblush")
2500 return TQColor(255, 240, 245);
2501 else if(rgbColor ==
"lawngreen")
2502 return TQColor(124, 252, 0);
2503 else if(rgbColor ==
"lemonchiffon")
2504 return TQColor(255, 250, 205);
2505 else if(rgbColor ==
"lightblue")
2506 return TQColor(173, 216, 230);
2507 else if(rgbColor ==
"lightcoral")
2508 return TQColor(240, 128, 128);
2509 else if(rgbColor ==
"lightcyan")
2510 return TQColor(224, 255, 255);
2511 else if(rgbColor ==
"lightgoldenrodyellow")
2512 return TQColor(250, 250, 210);
2513 else if(rgbColor ==
"lightgray")
2514 return TQColor(211, 211, 211);
2515 else if(rgbColor ==
"lightgrey")
2516 return TQColor(211, 211, 211);
2517 else if(rgbColor ==
"lightgreen")
2518 return TQColor(144, 238, 144);
2519 else if(rgbColor ==
"lightpink")
2520 return TQColor(255, 182, 193);
2521 else if(rgbColor ==
"lightsalmon")
2522 return TQColor(255, 160, 122);
2523 else if(rgbColor ==
"lightseagreen")
2524 return TQColor(32, 178, 170);
2525 else if(rgbColor ==
"lightskyblue")
2526 return TQColor(135, 206, 250);
2527 else if(rgbColor ==
"lightslategray")
2528 return TQColor(119, 136, 153);
2529 else if(rgbColor ==
"lightslategrey")
2530 return TQColor(119, 136, 153);
2531 else if(rgbColor ==
"lightsteelblue")
2532 return TQColor(176, 196, 222);
2533 else if(rgbColor ==
"lightyellow")
2534 return TQColor(255, 255, 224);
2535 else if(rgbColor ==
"lime")
2536 return TQColor(0, 255, 0);
2537 else if(rgbColor ==
"limegreen")
2538 return TQColor(50, 205, 50);
2539 else if(rgbColor ==
"linen")
2540 return TQColor(250, 240, 230);
2541 else if(rgbColor ==
"magenta")
2542 return TQColor(255, 0, 255);
2543 else if(rgbColor ==
"maroon")
2544 return TQColor(128, 0, 0);
2545 else if(rgbColor ==
"mediumaquamarine")
2546 return TQColor(102, 205, 170);
2547 else if(rgbColor ==
"mediumblue")
2548 return TQColor(0, 0, 205);
2549 else if(rgbColor ==
"mediumorchid")
2550 return TQColor(186, 85, 211);
2551 else if(rgbColor ==
"mediumpurple")
2552 return TQColor(147, 112, 219);
2553 else if(rgbColor ==
"mediumseagreen")
2554 return TQColor(60, 179, 113);
2555 else if(rgbColor ==
"mediumslateblue")
2556 return TQColor(123, 104, 238);
2557 else if(rgbColor ==
"mediumspringgreen")
2558 return TQColor(0, 250, 154);
2559 else if(rgbColor ==
"mediumturquoise")
2560 return TQColor(72, 209, 204);
2561 else if(rgbColor ==
"mediumvioletred")
2562 return TQColor(199, 21, 133);
2563 else if(rgbColor ==
"midnightblue")
2564 return TQColor(25, 25, 112);
2565 else if(rgbColor ==
"mintcream")
2566 return TQColor(245, 255, 250);
2567 else if(rgbColor ==
"mistyrose")
2568 return TQColor(255, 228, 225);
2569 else if(rgbColor ==
"moccasin")
2570 return TQColor(255, 228, 181);
2571 else if(rgbColor ==
"navajowhite")
2572 return TQColor(255, 222, 173);
2573 else if(rgbColor ==
"navy")
2574 return TQColor(0, 0, 128);
2575 else if(rgbColor ==
"oldlace")
2576 return TQColor(253, 245, 230);
2577 else if(rgbColor ==
"olive")
2578 return TQColor(128, 128, 0);
2579 else if(rgbColor ==
"olivedrab")
2580 return TQColor(107, 142, 35);
2581 else if(rgbColor ==
"orange")
2582 return TQColor(255, 165, 0);
2583 else if(rgbColor ==
"orangered")
2584 return TQColor(255, 69, 0);
2585 else if(rgbColor ==
"orchid")
2586 return TQColor(218, 112, 214);
2587 else if(rgbColor ==
"palegoldenrod")
2588 return TQColor(238, 232, 170);
2589 else if(rgbColor ==
"palegreen")
2590 return TQColor(152, 251, 152);
2591 else if(rgbColor ==
"paleturquoise")
2592 return TQColor(175, 238, 238);
2593 else if(rgbColor ==
"palevioletred")
2594 return TQColor(219, 112, 147);
2595 else if(rgbColor ==
"papayawhip")
2596 return TQColor(255, 239, 213);
2597 else if(rgbColor ==
"peachpuff")
2598 return TQColor(255, 218, 185);
2599 else if(rgbColor ==
"peru")
2600 return TQColor(205, 133, 63);
2601 else if(rgbColor ==
"pink")
2602 return TQColor(255, 192, 203);
2603 else if(rgbColor ==
"plum")
2604 return TQColor(221, 160, 221);
2605 else if(rgbColor ==
"powderblue")
2606 return TQColor(176, 224, 230);
2607 else if(rgbColor ==
"purple")
2608 return TQColor(128, 0, 128);
2609 else if(rgbColor ==
"red")
2610 return TQColor(255, 0, 0);
2611 else if(rgbColor ==
"rosybrown")
2612 return TQColor(188, 143, 143);
2613 else if(rgbColor ==
"royalblue")
2614 return TQColor(65, 105, 225);
2615 else if(rgbColor ==
"saddlebrown")
2616 return TQColor(139, 69, 19);
2617 else if(rgbColor ==
"salmon")
2618 return TQColor(250, 128, 114);
2619 else if(rgbColor ==
"sandybrown")
2620 return TQColor(244, 164, 96);
2621 else if(rgbColor ==
"seagreen")
2622 return TQColor(46, 139, 87);
2623 else if(rgbColor ==
"seashell")
2624 return TQColor(255, 245, 238);
2625 else if(rgbColor ==
"sienna")
2626 return TQColor(160, 82, 45);
2627 else if(rgbColor ==
"silver")
2628 return TQColor(192, 192, 192);
2629 else if(rgbColor ==
"skyblue")
2630 return TQColor(135, 206, 235);
2631 else if(rgbColor ==
"slateblue")
2632 return TQColor(106, 90, 205);
2633 else if(rgbColor ==
"slategray")
2634 return TQColor(112, 128, 144);
2635 else if(rgbColor ==
"slategrey")
2636 return TQColor(112, 128, 144);
2637 else if(rgbColor ==
"snow")
2638 return TQColor(255, 250, 250);
2639 else if(rgbColor ==
"springgreen")
2640 return TQColor(0, 255, 127);
2641 else if(rgbColor ==
"steelblue")
2642 return TQColor(70, 130, 180);
2643 else if(rgbColor ==
"tan")
2644 return TQColor(210, 180, 140);
2645 else if(rgbColor ==
"teal")
2646 return TQColor(0, 128, 128);
2647 else if(rgbColor ==
"thistle")
2648 return TQColor(216, 191, 216);
2649 else if(rgbColor ==
"tomato")
2650 return TQColor(255, 99, 71);
2651 else if(rgbColor ==
"turquoise")
2652 return TQColor(64, 224, 208);
2653 else if(rgbColor ==
"violet")
2654 return TQColor(238, 130, 238);
2655 else if(rgbColor ==
"wheat")
2656 return TQColor(245, 222, 179);
2657 else if(rgbColor ==
"white")
2658 return TQColor(255, 255, 255);
2659 else if(rgbColor ==
"whitesmoke")
2660 return TQColor(245, 245, 245);
2661 else if(rgbColor ==
"yellow")
2662 return TQColor(255, 255, 0);
2663 else if(rgbColor ==
"yellowgreen")
2664 return TQColor(154, 205, 50);
2670 double KSVGIconPainter::dpi()
2675 double KSVGIconPainter::toPixel(
const TQString &s,
bool hmode)
2685 const char *start = check.latin1();
2686 const char *end = getCoord(start, value);
2688 if(uint(end - start) < check.length())
2690 if(check.endsWith(
"px"))
2692 else if(check.endsWith(
"cm"))
2693 ret = (value / 2.54) * dpi();
2694 else if(check.endsWith(
"pc"))
2695 ret = (value / 6.0) * dpi();
2696 else if(check.endsWith(
"mm"))
2697 ret = (value / 25.4) * dpi();
2698 else if(check.endsWith(
"in"))
2699 ret = value * dpi();
2700 else if(check.endsWith(
"pt"))
2701 ret = (value / 72.0) * dpi();
2702 else if(check.endsWith(
"%"))
2704 ret = value / 100.0;
2707 ret *= d->drawWidth;
2709 ret *= d->drawHeight;
2711 else if(check.endsWith(
"em"))
2722 ArtGradientLinear *KSVGIconPainter::linearGradient(
const TQString &
id)
2724 return d->helper->m_linearGradientMap[id];
2727 void KSVGIconPainter::addLinearGradient(
const TQString &
id, ArtGradientLinear *gradient)
2729 d->helper->m_linearGradientMap.insert(
id, gradient);
2732 TQDomElement KSVGIconPainter::linearGradientElement(ArtGradientLinear *linear)
2734 return d->helper->m_linearGradientElementMap[linear];
2737 void KSVGIconPainter::addLinearGradientElement(ArtGradientLinear *gradient, TQDomElement element)
2739 d->helper->m_linearGradientElementMap.insert(gradient, element);
2742 ArtGradientRadial *KSVGIconPainter::radialGradient(
const TQString &
id)
2744 return d->helper->m_radialGradientMap[id];
2747 void KSVGIconPainter::addRadialGradient(
const TQString &
id, ArtGradientRadial *gradient)
2749 d->helper->m_radialGradientMap.insert(
id, gradient);
2752 TQDomElement KSVGIconPainter::radialGradientElement(ArtGradientRadial *radial)
2754 return d->helper->m_radialGradientElementMap[radial];
2757 void KSVGIconPainter::addRadialGradientElement(ArtGradientRadial *gradient, TQDomElement element)
2759 d->helper->m_radialGradientElementMap.insert(gradient, element);
2762 TQ_UINT32 KSVGIconPainter::toArtColor(
const TQColor &color)
2764 return d->helper->toArtColor(color);
2767 TQWMatrix KSVGIconPainter::parseTransform(
const TQString &transform)
2772 TQStringList subtransforms = TQStringList::split(
')', transform);
2773 TQStringList::ConstIterator it = subtransforms.begin();
2774 TQStringList::ConstIterator end = subtransforms.end();
2775 for(; it != end; ++it)
2777 TQStringList subtransform = TQStringList::split(
'(', (*it));
2779 subtransform[0] = subtransform[0].stripWhiteSpace().lower();
2780 subtransform[1] = subtransform[1].simplifyWhiteSpace();
2781 TQRegExp reg(
"([-]?\\d*\\.?\\d+(?:e[-]?\\d+)?)");
2784 TQStringList params;
2788 pos = reg.search(subtransform[1], pos);
2791 params += reg.cap(1);
2792 pos += reg.matchedLength();
2796 if(subtransform[0].startsWith(
";") || subtransform[0].startsWith(
","))
2797 subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
2799 if(subtransform[0] ==
"rotate")
2801 if(params.count() == 3)
2803 double x = params[1].toDouble();
2804 double y = params[2].toDouble();
2806 result.translate(x, y);
2807 result.rotate(params[0].toDouble());
2808 result.translate(-x, -y);
2811 result.rotate(params[0].toDouble());
2813 else if(subtransform[0] ==
"translate")
2815 if(params.count() == 2)
2816 result.translate(params[0].toDouble(), params[1].toDouble());
2818 result.translate(params[0].toDouble() , 0);
2820 else if(subtransform[0] ==
"scale")
2822 if(params.count() == 2)
2823 result.scale(params[0].toDouble(), params[1].toDouble());
2825 result.scale(params[0].toDouble(), params[0].toDouble());
2827 else if(subtransform[0] ==
"skewx")
2828 result.shear(tan(params[0].toDouble() * deg2rad), 0.0F);
2829 else if(subtransform[0] ==
"skewy")
2830 result.shear(tan(params[0].toDouble() * deg2rad), 0.0F);
2831 else if(subtransform[0] ==
"skewy")
2832 result.shear(0.0F, tan(params[0].toDouble() * deg2rad));
2833 else if(subtransform[0] ==
"matrix")
2835 if(params.count() >= 6)
2837 result.setMatrix(params[0].toDouble(), params[1].toDouble(), params[2].toDouble(), params[3].toDouble(), params[4].toDouble(), params[5].toDouble());