KHTML
SVGPreserveAspectRatio.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "wtf/Platform.h"
00025
00026 #if ENABLE(SVG)
00027 #include "SVGPreserveAspectRatio.h"
00028
00029 #include "SVGParserUtilities.h"
00030 #include "SVGSVGElement.h"
00031
00032 namespace WebCore {
00033
00034 SVGPreserveAspectRatio::SVGPreserveAspectRatio()
00035 : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
00036 , m_meetOrSlice(SVG_MEETORSLICE_MEET)
00037 {
00038
00039 }
00040
00041 SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
00042 {
00043 }
00044
00045 void SVGPreserveAspectRatio::setAlign(unsigned short align)
00046 {
00047 m_align = align;
00048 }
00049
00050 unsigned short SVGPreserveAspectRatio::align() const
00051 {
00052 return m_align;
00053 }
00054
00055 void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
00056 {
00057 m_meetOrSlice = meetOrSlice;
00058 }
00059
00060 unsigned short SVGPreserveAspectRatio::meetOrSlice() const
00061 {
00062 return m_meetOrSlice;
00063 }
00064
00065 bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate)
00066 {
00067 SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE;
00068 SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
00069 bool ret = false;
00070
00071 if (!skipOptionalSpaces(currParam, end))
00072 goto bail_out;
00073
00074 if (*currParam == 'd') {
00075
00076
00077
00078
00079
00080 }
00081
00082 if (*currParam == 'n') {
00083
00084
00085 skipOptionalSpaces(currParam, end);
00086 } else if (*currParam == 'x') {
00087 if ((end - currParam) < 8)
00088 goto bail_out;
00089 if (currParam[1] != 'M' || currParam[4] != 'Y' || currParam[5] != 'M')
00090 goto bail_out;
00091 if (currParam[2] == 'i') {
00092 if (currParam[3] == 'n') {
00093 if (currParam[6] == 'i') {
00094 if (currParam[7] == 'n')
00095 align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
00096 else if (currParam[7] == 'd')
00097 align = SVG_PRESERVEASPECTRATIO_XMINYMID;
00098 else
00099 goto bail_out;
00100 } else if (currParam[6] == 'a' && currParam[7] == 'x')
00101 align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
00102 else
00103 goto bail_out;
00104 } else if (currParam[3] == 'd') {
00105 if (currParam[6] == 'i') {
00106 if (currParam[7] == 'n')
00107 align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
00108 else if (currParam[7] == 'd')
00109 align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
00110 else
00111 goto bail_out;
00112 } else if (currParam[6] == 'a' && currParam[7] == 'x')
00113 align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
00114 else
00115 goto bail_out;
00116 } else
00117 goto bail_out;
00118 } else if (currParam[2] == 'a' && currParam[3] == 'x') {
00119 if (currParam[6] == 'i') {
00120 if (currParam[7] == 'n')
00121 align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
00122 else if (currParam[7] == 'd')
00123 align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
00124 else
00125 goto bail_out;
00126 } else if (currParam[6] == 'a' && currParam[7] == 'x')
00127 align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
00128 else
00129 goto bail_out;
00130 } else
00131 goto bail_out;
00132 currParam += 8;
00133 skipOptionalSpaces(currParam, end);
00134 } else
00135 goto bail_out;
00136
00137 if (currParam < end) {
00138 if (*currParam == 'm') {
00139
00140
00141
00142 } else if (*currParam == 's') {
00143
00144
00145
00146
00147
00148 }
00149 }
00150
00151 if (end != currParam && validate) {
00152 bail_out:
00153
00154 align = SVG_PRESERVEASPECTRATIO_NONE;
00155 meetOrSlice = SVG_MEETORSLICE_MEET;
00156 } else
00157 ret = true;
00158
00159 if (m_align == align && m_meetOrSlice == meetOrSlice)
00160 return ret;
00161
00162 m_align = align;
00163 m_meetOrSlice = meetOrSlice;
00164 return ret;
00165 }
00166
00167 AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY,
00168 double logicWidth, double logicHeight,
00169 double , double ,
00170 double physWidth, double physHeight)
00171 {
00172 AffineTransform temp;
00173
00174 if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN)
00175 return temp;
00176
00177 double vpar = logicWidth / logicHeight;
00178 double svgar = physWidth / physHeight;
00179
00180 if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
00181 temp.scale(physWidth / logicWidth, physHeight / logicHeight);
00182 temp.translate(-logicX, -logicY);
00183 } else if (vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET) || vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE)) {
00184 temp.scale(physHeight / logicHeight, physHeight / logicHeight);
00185
00186 if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX)
00187 temp.translate(-logicX, -logicY);
00188 else if (align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMAX)
00189 temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
00190 else
00191 temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
00192 } else {
00193 temp.scale(physWidth / logicWidth, physWidth / logicWidth);
00194
00195 if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
00196 temp.translate(-logicX, -logicY);
00197 else if (align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMAXYMID)
00198 temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
00199 else
00200 temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
00201 }
00202
00203 return temp;
00204 }
00205
00206 }
00207
00208 #endif // ENABLE(SVG)