|
1832 | 1832 | * |
1833 | 1833 | * @parameter glyphRun DWRITE_GLYPH_RUN object to render |
1834 | 1834 | */ |
1835 | | -void CGContextCairo::CGContextDrawGlyphRun(const DWRITE_GLYPH_RUN* glyphRun, float lineAscent) { |
| 1835 | +void CGContextCairo::CGContextDrawGlyphRun(const DWRITE_GLYPH_RUN* glyphRun) { |
1836 | 1836 | ObtainLock(); |
1837 | 1837 |
|
1838 | 1838 | CGContextStrokePath(); |
|
1853 | 1853 |
|
1854 | 1854 | // Apply the text transformation (text position, text matrix) in text space rather than user space |
1855 | 1855 | // This means flipping the coordinate system, |
1856 | | - // and applying the transformation about the center of the glyph run rather than about the baseline |
1857 | | - // Flip and translate by the difference between the center and the baseline, apply text transforms, then flip and translate back |
| 1856 | + // Apply text position, where it will be translated to correct position given text matrix value |
| 1857 | + CGAffineTransform textTransform = |
| 1858 | + CGAffineTransformTranslate(curState->curTextMatrix, curState->curTextPosition.x, curState->curTextPosition.y); |
1858 | 1859 |
|
1859 | | - // Transform to text space |
1860 | | - // Technically there should be a horizontal translation to the center as well, |
1861 | | - // but it's to the center of _each individual glyph_, as the reference platform applies the text matrix to each glyph individually |
1862 | | - // Uncertain whether it's ever going to be worth it to support this using DWrite, so just ignore it for now |
1863 | | - CGAffineTransform transform = CGAffineTransformMake(1, 0, 0, -1, 0, -lineAscent / 2.0f); |
1864 | | - |
1865 | | - // Apply text transforms |
1866 | | - transform = CGAffineTransformConcat(curState->curTextMatrix, transform); |
1867 | | - |
1868 | | - // Undo transform to text space |
1869 | | - transform = CGAffineTransformConcat(CGAffineTransformMake(1, 0, 0, -1, 0, lineAscent / 2.0f), transform); |
1870 | | - |
1871 | | - transform = CGAffineTransformTranslate(transform, curState->curTextPosition.x, curState->curTextPosition.y); |
| 1860 | + // Undo assumed inversion about Y axis |
| 1861 | + textTransform = CGAffineTransformConcat(CGAffineTransformMake(1, 0, 0, -1, 0, 0), textTransform); |
1872 | 1862 |
|
1873 | 1863 | // Find transform that user created by multiplying given transform by necessary transforms to draw with CoreText |
| 1864 | + // First multiply by inverse scale to get properly scaled values |
| 1865 | + // Then undo assumed inversion about Y axis |
| 1866 | + // Finally inverse translate by height |
| 1867 | + // All of which are rolled into one concatenation |
1874 | 1868 | float height = _imgDest->Backing()->Height(); |
1875 | 1869 | CGAffineTransform userTransform = |
1876 | | - CGAffineTransformConcat(curState->curTransform, CGAffineTransformMake(1.0f / _scale, 0, 0, 1.0f / _scale, 0, -height / _scale)); |
1877 | | - |
1878 | | - // Apply the context CTM |
1879 | | - transform = CGAffineTransformConcat(transform, userTransform); |
| 1870 | + CGAffineTransformConcat(curState->curTransform, CGAffineTransformMake(1.0f / _scale, 0, 0, -1.0f / _scale, 0, height / _scale)); |
1880 | 1871 |
|
1881 | | - // Perform anti-clockwise rotation required to match the reference platform. |
1882 | | - imgRenderTarget->SetTransform(D2D1::Matrix3x2F(transform.a, -transform.b, transform.c, transform.d, transform.tx, -transform.ty)); |
| 1872 | + // Apply the two transforms giving us the final result |
| 1873 | + CGAffineTransform transform = CGAffineTransformConcat(textTransform, userTransform); |
| 1874 | + imgRenderTarget->SetTransform(D2D1::Matrix3x2F(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty)); |
1883 | 1875 |
|
1884 | 1876 | // Draw the glyph using ID2D1RenderTarget |
1885 | 1877 | ComPtr<ID2D1SolidColorBrush> brush; |
|
0 commit comments