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