MCPcopy Create free account
hub / github.com/Tencent/tgfx / ComputeViewboxMatrix

Method ComputeViewboxMatrix

src/svg/node/SVGNode.cpp:146–190  ·  view source on GitHub ↗

https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute

Source from the content-addressed store, hash-verified

144
145// https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute
146Matrix SVGNode::ComputeViewboxMatrix(const Rect& viewBox, const Rect& viewPort,
147 SVGPreserveAspectRatio PreAspectRatio) {
148 if (viewBox.isEmpty() || viewPort.isEmpty()) {
149 return Matrix::MakeScale(0, 0);
150 }
151
152 auto computeScale = [&]() -> Point {
153 const auto scaleX = viewPort.width() / viewBox.width();
154 const auto scaleY = viewPort.height() / viewBox.height();
155
156 if (PreAspectRatio.align == SVGPreserveAspectRatio::Align::None) {
157 // none -> anisotropic scaling, regardless of fScale
158 return {scaleX, scaleY};
159 }
160
161 // isotropic scaling
162 const auto s = PreAspectRatio.scale == SVGPreserveAspectRatio::Scale::Meet
163 ? std::min(scaleX, scaleY)
164 : std::max(scaleX, scaleY);
165 return {s, s};
166 };
167
168 auto computeTrans = [&](const Point& scale) -> Point {
169 static constexpr float alignCoeffs[] = {
170 0.0f, // Min
171 0.5f, // Mid
172 1.0f // Max
173 };
174
175 const size_t x_coeff = static_cast<int>(PreAspectRatio.align) >> 0 & 0x03;
176 const size_t y_coeff = static_cast<int>(PreAspectRatio.align) >> 2 & 0x03;
177
178 const auto tx = -viewBox.x() * scale.x;
179 const auto ty = -viewBox.y() * scale.y;
180 const auto dx = viewPort.width() - viewBox.width() * scale.x;
181 const auto dy = viewPort.height() - viewBox.height() * scale.y;
182
183 return {tx + dx * alignCoeffs[x_coeff], ty + dy * alignCoeffs[y_coeff]};
184 };
185
186 auto scale = computeScale();
187 auto transform = computeTrans(scale);
188
189 return Matrix::MakeTrans(transform.x, transform.y) * Matrix::MakeScale(scale.x, scale.y);
190}
191} // namespace tgfx

Callers

nothing calls this directly

Calls 5

xMethod · 0.80
yMethod · 0.80
isEmptyMethod · 0.45
widthMethod · 0.45
heightMethod · 0.45

Tested by

no test coverage detected