Mercurial > mplayer.hg
comparison libass/ass_render.c @ 28839:fda4cf558544
Replace rotation functions with a simplified version adapted from
vsfilter.
This (mostly) fixes http://bugzilla.mplayerhq.hu/show_bug.cgi?id=1394#c7
author | greg |
---|---|
date | Sun, 08 Mar 2009 02:53:14 +0000 |
parents | 98231639866f |
children | 7d0ea9013974 |
comparison
equal
deleted
inserted
replaced
28838:98231639866f | 28839:fda4cf558544 |
---|---|
1794 break; | 1794 break; |
1795 } | 1795 } |
1796 } | 1796 } |
1797 | 1797 |
1798 /** | 1798 /** |
1799 * \brief Multiply 4-vector by 4-matrix | 1799 * \brief Apply transformation to outline points of a glyph |
1800 * \param a 4-vector | 1800 * Applies rotations given by frx, fry and frz and projects the points back |
1801 * \param m 4-matrix] | 1801 * onto the screen plane. |
1802 * \param b out: 4-vector | 1802 */ |
1803 * Calculates a * m and stores result in b | 1803 static void transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, double fry, double frz) { |
1804 */ | 1804 double sx = sin(frx); |
1805 static inline void transform_point_3d(double *a, double *m, double *b) | 1805 double sy = sin(fry); |
1806 { | 1806 double sz = sin(frz); |
1807 b[0] = a[0] * m[0] + a[1] * m[4] + a[2] * m[8] + a[3] * m[12]; | 1807 double cx = cos(frx); |
1808 b[1] = a[0] * m[1] + a[1] * m[5] + a[2] * m[9] + a[3] * m[13]; | 1808 double cy = cos(fry); |
1809 b[2] = a[0] * m[2] + a[1] * m[6] + a[2] * m[10] + a[3] * m[14]; | 1809 double cz = cos(frz); |
1810 b[3] = a[0] * m[3] + a[1] * m[7] + a[2] * m[11] + a[3] * m[15]; | 1810 FT_Outline *outline = &((FT_OutlineGlyph) glyph)->outline; |
1811 } | 1811 FT_Vector* p = outline->points; |
1812 | 1812 double x, y, z, xx, yy, zz; |
1813 /** | |
1814 * \brief Apply 3d transformation to a vector | |
1815 * \param v FreeType vector (2d) | |
1816 * \param m 4-matrix | |
1817 * Transforms v by m, projects the result back to the screen plane | |
1818 * Result is returned in v. | |
1819 */ | |
1820 static inline void transform_vector_3d(FT_Vector* v, double *m) { | |
1821 const double camera = 2500 * frame_context.border_scale; // camera distance | |
1822 const double cutoff_z = 10.; | |
1823 double a[4], b[4]; | |
1824 a[0] = d6_to_double(v->x); | |
1825 a[1] = d6_to_double(v->y); | |
1826 a[2] = 0.; | |
1827 a[3] = 1.; | |
1828 transform_point_3d(a, m, b); | |
1829 /* Apply perspective projection with the following matrix: | |
1830 2500 0 0 0 | |
1831 0 2500 0 0 | |
1832 0 0 0 0 | |
1833 0 0 8 2500 | |
1834 where 2500 is camera distance, 8 - z-axis scale. | |
1835 Camera is always located in (org_x, org_y, -2500). This means | |
1836 that different subtitle events can be displayed at the same time | |
1837 using different cameras. */ | |
1838 b[0] *= camera; | |
1839 b[1] *= camera; | |
1840 b[3] = 8 * b[2] + camera; | |
1841 if (b[3] < cutoff_z) | |
1842 b[3] = cutoff_z; | |
1843 v->x = double_to_d6(b[0] / b[3]); | |
1844 v->y = double_to_d6(b[1] / b[3]); | |
1845 } | |
1846 | |
1847 /** | |
1848 * \brief Apply 3d transformation to a glyph | |
1849 * \param glyph FreeType glyph | |
1850 * \param m 4-matrix | |
1851 * Transforms glyph by m, projects the result back to the screen plane | |
1852 * Result is returned in glyph. | |
1853 */ | |
1854 static inline void transform_glyph_3d(FT_Glyph glyph, double *m, FT_Vector shift) { | |
1855 int i; | 1813 int i; |
1856 FT_Outline* outline = &((FT_OutlineGlyph)glyph)->outline; | |
1857 FT_Vector* p = outline->points; | |
1858 | 1814 |
1859 for (i=0; i<outline->n_points; i++) { | 1815 for (i=0; i<outline->n_points; i++) { |
1860 p[i].x += shift.x; | 1816 x = p[i].x + shift.x; |
1861 p[i].y += shift.y; | 1817 y = p[i].y + shift.y; |
1862 transform_vector_3d(p + i, m); | 1818 z = 0.; |
1863 p[i].x -= shift.x; | 1819 |
1864 p[i].y -= shift.y; | 1820 xx = x*cz + y*sz; |
1865 } | 1821 yy = -(x*sz - y*cz); |
1866 | 1822 zz = z; |
1867 //transform_vector_3d(&glyph->advance, m); | 1823 |
1824 x = xx; | |
1825 y = yy*cx + zz*sx; | |
1826 z = yy*sx - zz*cx; | |
1827 | |
1828 xx = x*cy + z*sy; | |
1829 yy = y; | |
1830 zz = x*sy - z*cy; | |
1831 | |
1832 zz = FFMAX(zz, -19000); | |
1833 | |
1834 x = (xx * 20000) / (zz + 20000); | |
1835 y = (yy * 20000) / (zz + 20000); | |
1836 p[i].x = x - shift.x + 0.5; | |
1837 p[i].y = y - shift.y + 0.5; | |
1838 } | |
1868 } | 1839 } |
1869 | 1840 |
1870 /** | 1841 /** |
1871 * \brief Apply 3d transformation to several objects | 1842 * \brief Apply 3d transformation to several objects |
1872 * \param shift FreeType vector | 1843 * \param shift FreeType vector |
1877 * \param frz z-axis rotation angle | 1848 * \param frz z-axis rotation angle |
1878 * Rotates both glyphs by frx, fry and frz. Shift vector is added before rotation and subtracted after it. | 1849 * Rotates both glyphs by frx, fry and frz. Shift vector is added before rotation and subtracted after it. |
1879 */ | 1850 */ |
1880 static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, double frx, double fry, double frz) | 1851 static void transform_3d(FT_Vector shift, FT_Glyph* glyph, FT_Glyph* glyph2, double frx, double fry, double frz) |
1881 { | 1852 { |
1882 fry = - fry; // FreeType's y axis goes in the opposite direction | 1853 frx = - frx; |
1854 frz = - frz; | |
1883 if (frx != 0. || fry != 0. || frz != 0.) { | 1855 if (frx != 0. || fry != 0. || frz != 0.) { |
1884 double m[16]; | |
1885 double sx = sin(frx); | |
1886 double sy = sin(fry); | |
1887 double sz = sin(frz); | |
1888 double cx = cos(frx); | |
1889 double cy = cos(fry); | |
1890 double cz = cos(frz); | |
1891 m[0] = cy * cz; m[1] = cy*sz; m[2] = -sy; m[3] = 0.0; | |
1892 m[4] = -cx*sz + sx*sy*cz; m[5] = cx*cz + sx*sy*sz; m[6] = sx*cy; m[7] = 0.0; | |
1893 m[8] = sx*sz + cx*sy*cz; m[9] = -sx*cz + cx*sy*sz; m[10] = cx*cy; m[11] = 0.0; | |
1894 m[12] = 0.0; m[13] = 0.0; m[14] = 0.0; m[15] = 1.0; | |
1895 | |
1896 if (glyph && *glyph) | 1856 if (glyph && *glyph) |
1897 transform_glyph_3d(*glyph, m, shift); | 1857 transform_3d_points(shift, *glyph, frx, fry, frz); |
1898 | 1858 |
1899 if (glyph2 && *glyph2) | 1859 if (glyph2 && *glyph2) |
1900 transform_glyph_3d(*glyph2, m, shift); | 1860 transform_3d_points(shift, *glyph2, frx, fry, frz); |
1901 } | 1861 } |
1902 } | 1862 } |
1863 | |
1903 | 1864 |
1904 /** | 1865 /** |
1905 * \brief Main ass rendering function, glues everything together | 1866 * \brief Main ass rendering function, glues everything together |
1906 * \param event event to render | 1867 * \param event event to render |
1907 * Process event, appending resulting ass_image_t's to images_root. | 1868 * Process event, appending resulting ass_image_t's to images_root. |