void Matrix4::mapRect(Rect& r) const { if (isIdentity()) return; if (isSimple()) { MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.right, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.top, data[kScaleY], data[kTranslateY]); MUL_ADD_STORE(r.bottom, data[kScaleY], data[kTranslateY]); if (r.left > r.right) { float x = r.left; r.left = r.right; r.right = x; } if (r.top > r.bottom) { float y = r.top; r.top = r.bottom; r.bottom = y; } return; } float vertices[] = { r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom }; float x, y, z; for (int i = 0; i < 8; i+= 2) { float px = vertices[i]; float py = vertices[i + 1]; x = px * data[kScaleX] + py * data[kSkewX] + data[kTranslateX]; y = px * data[kSkewY] + py * data[kScaleY] + data[kTranslateY]; z = px * data[kPerspective0] + py * data[kPerspective1] + data[kPerspective2]; if (z) z = 1.0f / z; vertices[i] = x * z; vertices[i + 1] = y * z; } r.left = r.right = vertices[0]; r.top = r.bottom = vertices[1]; for (int i = 2; i < 8; i += 2) { x = vertices[i]; y = vertices[i + 1]; if (x < r.left) r.left = x; else if (x > r.right) r.right = x; if (y < r.top) r.top = y; else if (y > r.bottom) r.bottom = y; } }
void Matrix4::mapPoint(float& x, float& y) const { if (isSimple()) { MUL_ADD_STORE(x, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(y, data[kScaleY], data[kTranslateY]); return; } float dx = x * data[kScaleX] + y * data[kSkewX] + data[kTranslateX]; float dy = x * data[kSkewY] + y * data[kScaleY] + data[kTranslateY]; float dz = x * data[kPerspective0] + y * data[kPerspective1] + data[kPerspective2]; if (dz) dz = 1.0f / dz; x = dx * dz; y = dy * dz; }