--- old/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h 2016-03-17 14:02:00.504158595 +0530 +++ new/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h 2016-03-17 14:02:00.264158595 +0530 @@ -1668,27 +1668,46 @@ } \ } while (0); +/* + * Antialiased glyph drawing results in artifacts around the character edges + * when text is drawn ontop of translucent background color. The standard + * blending equation for two colors: + * destColor = srcColor * glyphAlpha + destColor * (1 - glyphAlpha) + * works only when srcColor and destColor are opaque. For translucent srcColor + * and destColor, the respective alpha components in each color will influence + * the visibility of the color and the visibility of the color below it. Hence + * the equation for blending is given as: + * resA = 1 - ((1 - srcApha) * (1 - destAlpha)) + * resCol = (srcColor * srcAlpha + destColor * destAlpha * (1- srcAlpha))/resA + * In addition, srcAlpha is multiplied with the glyphAlpha- that indicates the + * grayscale mask value of the glyph being drawn. The combined result provides + * smooth antialiased text on the buffer without any artifacts. + */ #define GlyphListAABlend4ByteArgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ FG_PIXEL, PREFIX, SRC_PREFIX) \ - do { \ + do { \ DeclareAlphaVarFor4ByteArgb(dstA) \ DeclareCompVarsFor4ByteArgb(dst) \ + DeclareAlphaVarFor4ByteArgb(resA) \ + DeclareCompVarsFor4ByteArgb(res) \ + DeclareAlphaVarFor4ByteArgb(modSrcA) \ jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ - if (mixValSrc) { \ - if (mixValSrc < 255) { \ - jint mixValDst = 255 - mixValSrc; \ + modSrcA = MUL8(SRC_PREFIX ## A, mixValSrc); \ + if (modSrcA) { \ + if (modSrcA < 255) { \ + jint mixValDst = 255 - modSrcA; \ Load ## DST ## To4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ dstA, dstR, dstG, dstB); \ - dstA = MUL8(dstA, mixValDst) + \ - MUL8(SRC_PREFIX ## A, mixValSrc); \ - MultMultAddAndStore4ByteArgbComps(dst, mixValDst, dst, \ - mixValSrc, SRC_PREFIX); \ + resA = 255 - MUL8((255 - modSrcA), (255 - dstA)); \ + MultiplyAndStore4ByteArgbComps(dst, dstA, dst); \ + MultMultAddAndStore4ByteArgbComps(res, mixValDst, dst, \ + modSrcA, SRC_PREFIX); \ if (!(DST ## IsOpaque) && \ - !(DST ## IsPremultiplied) && dstA && dstA < 255) { \ - DivideAndStore4ByteArgbComps(dst, dst, dstA); \ + !(DST ## IsPremultiplied) && resA && resA < 255) { \ + DivideAndStore4ByteArgbComps(res, res, resA); \ } \ Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ - PIXEL_INDEX, dst); \ + PIXEL_INDEX, res); \ } else { \ Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ FG_PIXEL, PREFIX); \