1651 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1652 do { \ 1653 DeclareCompVarsFor3ByteRgb(dst) \ 1654 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1655 if (mixValSrc) { \ 1656 if (mixValSrc < 255) { \ 1657 jint mixValDst = 255 - mixValSrc; \ 1658 Load ## DST ## To3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ 1659 dstR, dstG, dstB); \ 1660 MultMultAddAndStore3ByteRgbComps(dst, mixValDst, dst, \ 1661 mixValSrc, SRC_PREFIX); \ 1662 Store ## DST ## From3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ 1663 dstR, dstG, dstB); \ 1664 } else { \ 1665 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1666 FG_PIXEL, PREFIX); \ 1667 } \ 1668 } \ 1669 } while (0); 1670 1671 #define GlyphListAABlend4ByteArgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ 1672 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1673 do { \ 1674 DeclareAlphaVarFor4ByteArgb(dstA) \ 1675 DeclareCompVarsFor4ByteArgb(dst) \ 1676 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1677 if (mixValSrc) { \ 1678 if (mixValSrc < 255) { \ 1679 jint mixValDst = 255 - mixValSrc; \ 1680 Load ## DST ## To4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ 1681 dstA, dstR, dstG, dstB); \ 1682 dstA = MUL8(dstA, mixValDst) + \ 1683 MUL8(SRC_PREFIX ## A, mixValSrc); \ 1684 MultMultAddAndStore4ByteArgbComps(dst, mixValDst, dst, \ 1685 mixValSrc, SRC_PREFIX); \ 1686 if (!(DST ## IsOpaque) && \ 1687 !(DST ## IsPremultiplied) && dstA && dstA < 255) { \ 1688 DivideAndStore4ByteArgbComps(dst, dst, dstA); \ 1689 } \ 1690 Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ 1691 PIXEL_INDEX, dst); \ 1692 } else { \ 1693 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1694 FG_PIXEL, PREFIX); \ 1695 } \ 1696 } \ 1697 } while (0); 1698 1699 #define GlyphListAABlend1ByteGray(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ 1700 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1701 do { \ 1702 DeclareCompVarsFor1ByteGray(dst) \ 1703 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1704 if (mixValSrc) { \ 1705 if (mixValSrc < 255) { \ 1706 jint mixValDst = 255 - mixValSrc; \ 1707 Load ## DST ## To1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1708 dstG); \ 1709 MultMultAddAndStore1ByteGrayComps(dst, mixValDst, dst, \ 1710 mixValSrc, SRC_PREFIX); \ 1711 Store ## DST ## From1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1712 dstG); \ 1713 } else { \ 1714 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1715 FG_PIXEL, PREFIX); \ | 1651 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1652 do { \ 1653 DeclareCompVarsFor3ByteRgb(dst) \ 1654 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1655 if (mixValSrc) { \ 1656 if (mixValSrc < 255) { \ 1657 jint mixValDst = 255 - mixValSrc; \ 1658 Load ## DST ## To3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ 1659 dstR, dstG, dstB); \ 1660 MultMultAddAndStore3ByteRgbComps(dst, mixValDst, dst, \ 1661 mixValSrc, SRC_PREFIX); \ 1662 Store ## DST ## From3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ 1663 dstR, dstG, dstB); \ 1664 } else { \ 1665 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1666 FG_PIXEL, PREFIX); \ 1667 } \ 1668 } \ 1669 } while (0); 1670 1671 /* 1672 * Antialiased glyph drawing results in artifacts around the character edges 1673 * when text is drawn ontop of translucent background color. The standard 1674 * blending equation for two colors: 1675 * destColor = srcColor * glyphAlpha + destColor * (1 - glyphAlpha) 1676 * works only when srcColor and destColor are opaque. For translucent srcColor 1677 * and destColor, the respective alpha components in each color will influence 1678 * the visibility of the color and the visibility of the color below it. Hence 1679 * the equation for blending is given as: 1680 * resA = srcAlpha + dstAlpha * (1 - srcAlpha) 1681 * resCol = (srcColor * srcAlpha + destColor * destAlpha * (1- srcAlpha))/resA 1682 * In addition, srcAlpha is multiplied with the glyphAlpha- that indicates the 1683 * grayscale mask value of the glyph being drawn. The combined result provides 1684 * smooth antialiased text on the buffer without any artifacts. Since the 1685 * logic is executed for every pixel in a glyph, the implementation is further 1686 * optimized to reduce computation and improve execution time. 1687 */ 1688 #define GlyphListAABlend4ByteArgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ 1689 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1690 do { \ 1691 DeclareAlphaVarFor4ByteArgb(dstA) \ 1692 DeclareCompVarsFor4ByteArgb(dst) \ 1693 DeclareAlphaVarFor4ByteArgb(resA) \ 1694 DeclareCompVarsFor4ByteArgb(res) \ 1695 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1696 if (mixValSrc) { \ 1697 if (mixValSrc != 0xff) { \ 1698 PromoteByteAlphaFor4ByteArgb(mixValSrc); \ 1699 resA = MultiplyAlphaFor4ByteArgb(mixValSrc, SRC_PREFIX ## A); \ 1700 MultiplyAndStore4ByteArgbComps(res, resA, SRC_PREFIX); \ 1701 } else { \ 1702 resA = SRC_PREFIX ## A; \ 1703 MultiplyAndStore4ByteArgbComps(res, \ 1704 SRC_PREFIX ## A, \ 1705 SRC_PREFIX); \ 1706 } \ 1707 if (resA != MaxValFor4ByteArgb) { \ 1708 DeclareAndInvertAlphaVarFor4ByteArgb(dstF, resA) \ 1709 Load ## DST ## To4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ 1710 dstA, dstR, dstG, dstB); \ 1711 dstA = MultiplyAlphaFor4ByteArgb(dstF, dstA); \ 1712 if (!(IntArgbIsPremultiplied)) { \ 1713 dstF = dstA; \ 1714 } \ 1715 resA += dstA; \ 1716 if (dstF) { \ 1717 DeclareCompVarsFor4ByteArgb(tmp) \ 1718 Store4ByteArgbCompsUsingOp(tmp, =, dst); \ 1719 if (dstF != MaxValFor4ByteArgb) { \ 1720 MultiplyAndStore4ByteArgbComps(tmp, \ 1721 dstF, \ 1722 tmp); \ 1723 } \ 1724 Store4ByteArgbCompsUsingOp(res, +=, tmp); \ 1725 } \ 1726 } \ 1727 if (!(DST ## IsOpaque) && \ 1728 !(DST ## IsPremultiplied) && resA && \ 1729 resA < MaxValFor4ByteArgb) \ 1730 { \ 1731 DivideAndStore4ByteArgbComps(res, res, resA); \ 1732 } \ 1733 Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ 1734 PIXEL_INDEX, res); \ 1735 } \ 1736 } while (0); 1737 1738 #define GlyphListAABlend1ByteGray(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ 1739 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1740 do { \ 1741 DeclareCompVarsFor1ByteGray(dst) \ 1742 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1743 if (mixValSrc) { \ 1744 if (mixValSrc < 255) { \ 1745 jint mixValDst = 255 - mixValSrc; \ 1746 Load ## DST ## To1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1747 dstG); \ 1748 MultMultAddAndStore1ByteGrayComps(dst, mixValDst, dst, \ 1749 mixValSrc, SRC_PREFIX); \ 1750 Store ## DST ## From1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1751 dstG); \ 1752 } else { \ 1753 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1754 FG_PIXEL, PREFIX); \ |