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(resA) \ 1692 DeclareCompVarsFor4ByteArgb(res) \ 1693 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1694 if (mixValSrc) { \ 1695 if (mixValSrc != 0xff) { \ 1696 PromoteByteAlphaFor4ByteArgb(mixValSrc); \ 1697 resA = MultiplyAlphaFor4ByteArgb(mixValSrc, SRC_PREFIX ## A); \ 1698 MultiplyAndStore4ByteArgbComps(res, resA, SRC_PREFIX); \ 1699 } else { \ 1700 resA = SRC_PREFIX ## A; \ 1701 MultiplyAndStore4ByteArgbComps(res, \ 1702 SRC_PREFIX ## A, \ 1703 SRC_PREFIX); \ 1704 } \ 1705 if (resA != MaxValFor4ByteArgb) { \ 1706 DeclareAndInvertAlphaVarFor4ByteArgb(dstF, resA) \ 1707 DeclareAndClearAlphaVarFor4ByteArgb(dstA) \ 1708 Declare ## DST ## AlphaLoadData(DstPix) \ 1709 jint pixelOffset = PIXEL_INDEX * (DST ## PixelStride); \ 1710 DST ## DataType *pixelAddress = PtrAddBytes(DST_PTR, \ 1711 pixelOffset); \ 1712 LoadAlphaFrom ## DST ## For4ByteArgb(pixelAddress, \ 1713 DstPix, \ 1714 dst); \ 1715 dstA = MultiplyAlphaFor4ByteArgb(dstF, dstA); \ 1716 if (!(DST ## IsPremultiplied)) { \ 1717 dstF = dstA; \ 1718 } \ 1719 resA += dstA; \ 1720 if (dstF) { \ 1721 DeclareCompVarsFor4ByteArgb(tmp) \ 1722 Postload4ByteArgbFrom ## DST(pixelAddress, \ 1723 DstPix, \ 1724 tmp); \ 1725 if (dstF != MaxValFor4ByteArgb) { \ 1726 MultiplyAndStore4ByteArgbComps(tmp, \ 1727 dstF, \ 1728 tmp); \ 1729 } \ 1730 Store4ByteArgbCompsUsingOp(res, +=, tmp); \ 1731 } \ 1732 } \ 1733 if (!(DST ## IsOpaque) && \ 1734 !(DST ## IsPremultiplied) && resA && \ 1735 resA < MaxValFor4ByteArgb) \ 1736 { \ 1737 DivideAndStore4ByteArgbComps(res, res, resA); \ 1738 } \ 1739 Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ 1740 PIXEL_INDEX, res); \ 1741 } \ 1742 } while (0); 1743 1744 #define GlyphListAABlend1ByteGray(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ 1745 FG_PIXEL, PREFIX, SRC_PREFIX) \ 1746 do { \ 1747 DeclareCompVarsFor1ByteGray(dst) \ 1748 jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ 1749 if (mixValSrc) { \ 1750 if (mixValSrc < 255) { \ 1751 jint mixValDst = 255 - mixValSrc; \ 1752 Load ## DST ## To1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1753 dstG); \ 1754 MultMultAddAndStore1ByteGrayComps(dst, mixValDst, dst, \ 1755 mixValSrc, SRC_PREFIX); \ 1756 Store ## DST ## From1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ 1757 dstG); \ 1758 } else { \ 1759 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ 1760 FG_PIXEL, PREFIX); \ |