1649 {
1650 switch ( face->glyph->format ) {
1651 case FT_GLYPH_FORMAT_OUTLINE: {
1652 FT_Outline* outline = &face->glyph->outline;
1653
1658
1659 dy = -dy;
1660 }
1661
1663
1667
1668 FT_Outline_Translate(outline,
dx, dy);
1669 FT_Error err = FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V :
1670 FT_RENDER_MODE_LCD);
1671 if (err) {
1672 SK_TRACEFTR(err,
"Could not render glyph %p.", face->glyph);
1673 return;
1674 }
1675
1678
1679 if constexpr (kSkShowTextBlitCoverage) {
1680 memset(mask.image(), 0x80, mask.fBounds.height() * mask.fRowBytes);
1681 }
1682 FT_GlyphSlotRec& ftGlyph = *face->glyph;
1683
1686 -ftGlyph.bitmap_top,
1687 ftGlyph.bitmap.width,
1688 ftGlyph.bitmap.rows)))
1689 {
1690 return;
1691 }
1692
1693
1694
1695 unsigned char* origBuffer = ftGlyph.bitmap.buffer;
1696
1697 if (-ftGlyph.bitmap_top < mask.fBounds.fTop) {
1698 int32_t topDiff = mask.fBounds.fTop - (-ftGlyph.bitmap_top);
1699 ftGlyph.bitmap.buffer += ftGlyph.bitmap.pitch * topDiff;
1700 ftGlyph.bitmap.rows -= topDiff;
1701 ftGlyph.bitmap_top = -mask.fBounds.fTop;
1702 }
1703 if (ftGlyph.bitmap_left < mask.fBounds.fLeft) {
1704 int32_t leftDiff = mask.fBounds.fLeft - ftGlyph.bitmap_left;
1705 ftGlyph.bitmap.buffer += leftDiff;
1706 ftGlyph.bitmap.width -= leftDiff;
1707 ftGlyph.bitmap_left = mask.fBounds.fLeft;
1708 }
1709 if (mask.fBounds.fTop < -ftGlyph.bitmap_top) {
1710 mask.image() += mask.fRowBytes * (-ftGlyph.bitmap_top - mask.fBounds.fTop);
1711 mask.bounds().fTop = -ftGlyph.bitmap_top;
1712 }
1713 if (mask.fBounds.fLeft < ftGlyph.bitmap_left) {
1714 mask.image() += sizeof(uint16_t) * (ftGlyph.bitmap_left - mask.fBounds.fLeft);
1715 mask.bounds().fLeft = ftGlyph.bitmap_left;
1716 }
1717
1718 int ftVertScale = (doVert ? 3 : 1);
1719 int ftHoriScale = (doVert ? 1 : 3);
1720 if (mask.fBounds.height() * ftVertScale <
SkToInt(ftGlyph.bitmap.rows)) {
1721 ftGlyph.bitmap.rows = mask.fBounds.height() * ftVertScale;
1722 }
1723 if (mask.fBounds.width() * ftHoriScale <
SkToInt(ftGlyph.bitmap.width)) {
1724 ftGlyph.bitmap.width = mask.fBounds.width() * ftHoriScale;
1725 }
1726 if (
SkToInt(ftGlyph.bitmap.rows) < mask.fBounds.height() * ftVertScale) {
1727 mask.bounds().fBottom = mask.fBounds.fTop + ftGlyph.bitmap.rows / ftVertScale;
1728 }
1729 if (
SkToInt(ftGlyph.bitmap.width) < mask.fBounds.width() * ftHoriScale) {
1730 mask.bounds().fRight = mask.fBounds.fLeft + ftGlyph.bitmap.width / ftHoriScale;
1731 }
1733 copyFT2LCD16<true>(ftGlyph.bitmap, &mask, doBGR,
1734 preBlend.
fR, preBlend.
fG, preBlend.
fB);
1735 } else {
1736 copyFT2LCD16<false>(ftGlyph.bitmap, &mask, doBGR,
1737 preBlend.
fR, preBlend.
fG, preBlend.
fB);
1738 }
1739
1740 ftGlyph.bitmap.buffer = origBuffer;
1741 } else {
1744 FT_Outline_Get_CBox(outline, &bbox);
1745
1746
1747
1748
1749
1750
1751
1752
1753 FT_Outline_Translate(outline,
dx - ((bbox.xMin +
dx) & ~63),
1754 dy - ((bbox.yMin + dy) & ~63));
1755
1759 target.buffer =
static_cast<uint8_t*
>(imageBuffer);
1762
1763 FT_Outline_Get_Bitmap(face->glyph->library, outline, &
target);
1764 if constexpr (kSkShowTextBlitCoverage) {
1766 for (
unsigned y = 0;
y <
target.rows;
y += 2) {
1767 for (
unsigned x = (
y & 0x2);
x <
target.width;
x+=4) {
1769 b =
b ^ (1 << (0x7 - (
x & 0x7)));
1770 }
1771 }
1772 } else {
1773 for (
unsigned y = 0;
y <
target.rows; ++
y) {
1774 for (
unsigned x = 0;
x <
target.width; ++
x) {
1776 a = std::max<uint8_t>(
a, 0x20);
1777 }
1778 }
1779 }
1780 }
1781 }
1782 } break;
1783
1784 case FT_GLYPH_FORMAT_BITMAP: {
1785 FT_Pixel_Mode pixel_mode = static_cast<FT_Pixel_Mode>(face->glyph->bitmap.pixel_mode);
1787
1788
1789 SkASSERT(FT_PIXEL_MODE_MONO == pixel_mode ||
1790 FT_PIXEL_MODE_GRAY == pixel_mode ||
1792
1793
1798
1799
1804 copyFTBitmap(face->glyph->bitmap, &dstMask);
1805 break;
1806 }
1807
1808
1809
1810
1812
1814 face->glyph->bitmap.rows,
1815 SkColorType_for_FTPixelMode(pixel_mode),
1818
1820 return;
1821 }
1822
1824 reinterpret_cast<uint8_t*
>(unscaledBitmap.
getPixels()),
1827 SkMaskFormat_for_SkColorType(unscaledBitmap.
colorType()));
1828 copyFTBitmap(face->glyph->bitmap, &unscaledBitmapAlias);
1829
1830
1831
1832
1833
1834 int bitmapRowBytes = 0;
1837 }
1839
1841 SkColorType_for_SkMaskFormat(maskFormat),
1843 bitmapRowBytes);
1846
1848 return;
1849 }
1850 } else {
1852 }
1853
1854
1856 if constexpr (kSkShowTextBlitCoverage) {
1857 canvas.clear(0x33FF0000);
1858 } else {
1860 }
1861 canvas.translate(-glyph.
left(), -glyph.
top());
1862 canvas.concat(bitmapTransform);
1863 canvas.translate(face->glyph->bitmap_left, -face->glyph->bitmap_top);
1864
1867
1868
1870
1875
1877 uint16_t*
dst =
reinterpret_cast<uint16_t*
>(imageBuffer);
1878 for (
int y = dstBitmap.
height();
y --> 0;) {
1879 for (
int x = 0;
x < dstBitmap.
width(); ++
x) {
1881 }
1884 }
1885 }
1886 } break;
1887
1888 default:
1891 return;
1892 }
1893
1894
1895
1896#if defined(SK_GAMMA_APPLY_TO_A8)
1899 unsigned rowBytes = glyph.
rowBytes();
1900
1901 for (
int y = glyph.
height() - 1;
y >= 0; --
y) {
1902 for (
int x = glyph.
width() - 1;
x >= 0; --
x) {
1904 }
1906 }
1907 }
1908#endif
1909}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkDEBUGFAIL(message)
constexpr SkColor SK_ColorTRANSPARENT
#define SkFixedToFDot6(x)
#define FT_PIXEL_MODE_BGRA
#define SK_TRACEFTR(ERR,...)
static void packA8ToA1(SkMaskBuilder &dstMask, const uint8_t *src, size_t srcRB)
constexpr int SkToInt(S x)
static constexpr bool SkToBool(const T &x)
sk_sp< SkImage > asImage() const
uint8_t * getAddr8(int x, int y) const
SkColorType colorType() const
void setPixels(void *pixels)
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
bool tryAllocPixels(const SkImageInfo &info, size_t rowBytes)
SkMask::Format maskFormat() const
SkFixed getSubYFixed() const
SkFixed getSubXFixed() const
bool isApplicable() const
SkSamplingOptions sampling
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
static bool Intersects(const SkIRect &a, const SkIRect &b)
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
@ kLCD16_Format
565 alpha for r/g/b
@ kARGB32_Format
SkPMColor.
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
SkScalerContext::Flags fFlags