/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef LoopMacros_h_Included
#define LoopMacros_h_Included
#include "j2d_md.h"
#include "LineUtils.h"
/*
* This file contains macros to aid in defining native graphics
* primitive functions.
*
* A number of useful building block macros are defined, but the
* vast majority of primitives are defined completely by a single
* macro expansion which uses macro names in the argument list to
* choose not only from a small number of strategies but also to
* choose macro packages specific to the source and destination
* pixel formats - greatly simplifying all aspects of creating
* a new loop.
*
* See the following macros which define entire functions with
* just one or two surface names and sometimes a strategy name:
* DEFINE_ISOCOPY_BLIT(ANYTYPE)
* DEFINE_ISOXOR_BLIT(ANYTYPE)
* DEFINE_CONVERT_BLIT(SRC, DST, CONV_METHOD)
* DEFINE_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY)
* DEFINE_XPAR_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY)
* DEFINE_XPAR_BLITBG_LUT(SRC, DST, LUT_STRATEGY)
* DEFINE_SOLID_FILLRECT(DST)
* DEFINE_SOLID_FILLSPANS(DST)
* DEFINE_SOLID_DRAWLINE(DST)
*
* Many of these loop macros take the name of a SurfaceType as
* an argument and use the ANSI CPP token concatenation operator
* "##" to reference macro and type definitions that are specific
* to that type of surface.
*
* A description of the various surface specific macro utilities
* that are used by these loop macros appears at the end of the
* file. The definitions of these surface-specific macros will
* usually appear in a header file named after the SurfaceType
* name (i.e. IntArgb.h, ByteGray.h, etc.).
*/
/*
* This loop is the standard "while (--height > 0)" loop used by
* some of the blits below.
*/
do { \
do { \
BODY; \
} while (--HEIGHT > 0); \
} while (0)
/*
* used by most of the basic blits below.
*/
do { \
do { \
do { \
BODY; \
} while (--w > 0); \
} while (--HEIGHT > 0); \
} while (0)
/*
* used by most of the scaled blits below. It calculates the proper
* X source variable
*/
BODY) \
do { \
do { \
do { \
BODY; \
} while (--w > 0); \
} while (--HEIGHT > 0); \
} while (0)
/*
* This loop is a standard horizontal loop iterating with a "relative"
* X coordinate (0 <= X < WIDTH) used primarily by the LUT conversion
* preprocessing loops below.
*/
do { \
do { \
BODY; \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via an intermediate "jint rgb" format.
*/
do { \
int rgb; \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via an intermediate "jint argb" format.
*/
do { \
int argb; \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via an intermediate set of 3 component variables "jint r, g, b".
*/
do { \
jint r, g, b; \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via an intermediate set of 4 component variables "jint a, r, g, b".
*/
do { \
jint a, r, g, b; \
a, r, g, b); \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via an intermediate "jint gray" format.
*/
do { \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_XPAR_CONVERT_BLIT
* macros. It converts from the source pixel format to the destination
* via the specified intermediate format while testing for transparent pixels.
*/
do { \
int rgb; \
} \
} while (0)
/*
* This is a "conversion strategy" for use with the DEFINE_XPAR_BLITBG
* macros. It converts from the source pixel format to the destination
* via the specified intermediate format while substituting the specified
* bgcolor for transparent pixels.
*/
do { \
} else { \
int rgb; \
} \
} while (0)
/*
* This macro determines whether or not the given pixel is considered
* "transparent" for XOR purposes. The ARGB pixel is considered
* "transparent" if the alpha value is < 0.5.
*/
/*
* This is a "conversion strategy" for use with the DEFINE_XOR_BLIT macro. It
* converts the source pixel to an intermediate ARGB value and then converts
* the ARGB value to the pixel representation for the destination surface. It
* then XORs the srcpixel, xorpixel, and destination pixel together and stores
* the result in the destination surface.
*/
do { \
\
if (IsArgbTransparent(srcpixel)) { \
break; \
} \
\
\
MASK, MASKPREFIX); \
} while (0)
/*
* "LUT_STRATEGY" macro sets.
*
* There are 2 major strategies for dealing with luts and 3
* implementations of those strategies.
*
* The 2 strategies are "PreProcessLut" and "ConvertOnTheFly".
*
* For the "PreProcessLut" strategy, the raw ARGB lut supplied
* by the SD_LOCK_LUT flag is converted at the beginning into a
* form that is more suited for storing into the destination
* pixel format. The inner loop consists of a series of table
* lookups with very little conversion from that intermediate
* pixel format.
*
* For the "ConvertOnTheFly" strategy, the raw ARGB values are
* converted on a pixel by pixel basis in the inner loop itself.
* This strategy is most useful for formats which tend to use
* the ARGB color format as their pixel format also.
*
* Each of these strategies has 3 implementations which are needed
* for the special cases:
* - straight conversion (invoked from DEFINE_CONVERT_BLIT_LUT)
* - straight conversion with transparency handling (invoked from
* DEFINE_XPAR_CONVERT_BLIT_LUT)
* - straight conversion with a bgcolor for the transparent pixels
* (invoked from DEFINE_XPAR_BLITBG_LUT)
*/
/***
* Start of PreProcessLut strategy macros, CONVERT_BLIT implementation.
*/
do { \
} else { \
do { \
} \
do { \
} while (0)); \
} while (0)
/*
* End of PreProcessLut/CONVERT_BLIT macros.
***/
/***
* Start of ConvertOnTheFly strategy macros, CONVERT_BLIT implementation.
*/
/*
* End of ConvertOnTheFly/CONVERT_BLIT macros.
***/
/***
* Start of PreProcessLut strategy macros, XPAR_CONVERT_BLIT implementation.
*/
do { \
} else { \
do { \
} \
do { \
if (argb < 0) { \
} else { \
} \
} while (0)); \
} while (0)
do { \
} \
} while (0)
/*
* End of PreProcessLut/XPAR_CONVERT_BLIT macros.
***/
/***
* Start of ConvertOnTheFly strategy macros, CONVERT_BLIT implementation.
*/
do { \
if (argb < 0) { \
} \
} while (0)
/*
* End of ConvertOnTheFly/CONVERT_BLIT macros.
***/
/***
* Start of PreProcessLut strategy macros, BLITBG implementation.
*/
do { \
} else { \
do { \
} \
do { \
if (argb < 0) { \
x, argb); \
} else { \
} \
} while (0)); \
} while (0)
do { \
} while (0)
/*
* End of PreProcessLut/BLITBG implementation.
***/
/***
* Start of ConvertOnTheFly strategy macros, BLITBG implementation.
*/
do { \
} while (0)
do { \
if (argb < 0) { \
} else { \
} \
} while (0)
/*
* End of ConvertOnTheFly/BLITBG macros.
***/
/*
* These macros provide consistent naming conventions for the
* various types of native primitive inner loop functions.
* The names are mechanically constructed from the SurfaceType names.
*/
/*
* These macros conveniently name and declare the indicated native
* primitive loop function for forward referencing.
*/
/*
* These macros construct the necessary NativePrimitive structure
* for the indicated native primitive loop function which will be
* declared somewhere prior and defined elsewhere (usually after).
*/
NAME_SOLID_FILLPGRAM(TYPE)), \
NAME_XOR_FILLPGRAM(TYPE)), \
/*
* This macro defines an entire function to implement a Blit inner loop
* for copying pixels of a common type from one buffer to another.
*/
NativePrimitive *pPrim, \
{ \
height, \
}
/*
* This macro defines an entire function to implement a ScaleBlit inner loop
* for scaling pixels of a common type from one buffer to another.
*/
NativePrimitive *pPrim, \
{ \
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for XORing pixels of a common type from one buffer into another.
*/
NativePrimitive *pPrim, \
{ \
\
\
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for converting pixels from a buffer of one type into a buffer of
* another type. No blending is done of the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
0, 0)); \
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for converting pixels from a buffer of byte pixels with a lookup
* table into a buffer of another type. No blending is done of the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
pixLut, \
DstWrite, 0, 0));\
}
/*
* This macro defines an entire function to implement a ScaleBlit inner
* loop for scaling and converting pixels from a buffer of one type into
* a buffer of another type. No blending is done of the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
x, 0)); \
}
/*
* This macro defines an entire function to implement a ScaleBlit inner
* loop for scaling and converting pixels from a buffer of byte pixels
* with a lookup table into a buffer of another type. No blending is
* done of the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
DstWrite, x, 0));\
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for drawing opaque pixels from a buffer of one type onto a buffer of
* another type, ignoring the transparent pixels in the source buffer.
* No blending is done of the pixels - the converted pixel value is
* either copied or the destination is left untouched.
*/
NativePrimitive *pPrim, \
{ \
\
0, 0)); \
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for converting pixels from a buffer of byte pixels with a lookup
* table containing transparent pixels into a buffer of another type.
* No blending is done of the pixels - the converted pixel value is
* either copied or the destination is left untouched.
*/
NativePrimitive *pPrim, \
{ \
\
DstWrite, 0, 0)); \
}
/*
* This macro defines an entire function to implement a ScaleBlit inner
* loop for scaling and converting pixels from a buffer of byte pixels
* with a lookup table containing transparent pixels into a buffer of
* another type.
* No blending is done of the pixels - the converted pixel value is
* either copied or the destination is left untouched.
*/
NativePrimitive *pPrim, \
{ \
\
DstWrite, \
x, 0)); \
}
/*
* This macro defines an entire function to implement a ScaleBlit inner
* loop for scaling and converting pixels from a buffer of one type
* containing transparent pixels into a buffer of another type.
*
* No blending is done of the pixels - the converted pixel value is
* either copied or the destination is left untouched.
*/
NativePrimitive *pPrim, \
{ \
\
x, 0)); \
}
/*
* This macro defines an entire function to implement a BlitBg inner loop
* for converting pixels from a buffer of one type containing transparent
* pixels into a buffer of another type with a specified bgcolor for the
* transparent pixels.
* No blending is done of the pixels other than to substitute the
* bgcolor for any transparent pixels.
*/
NativePrimitive *pPrim, \
{ \
\
}
/*
* This macro defines an entire function to implement a BlitBg inner loop
* for converting pixels from a buffer of byte pixels with a lookup
* table containing transparent pixels into a buffer of another type
* with a specified bgcolor for the transparent pixels.
* No blending is done of the pixels other than to substitute the
* bgcolor for any transparent pixels.
*/
NativePrimitive *pPrim, \
{ \
\
bgpixel); \
DstWrite, 0, 0, \
bgpixel)); \
}
/*
* This macro defines an entire function to implement a Blit inner loop
* for converting pixels from a buffer of one type into a buffer of
* another type. Each source pixel is XORed with the current XOR color value.
* That result is then XORed with the destination pixel and the final
* result is stored in the destination surface.
*/
NativePrimitive *pPrim, \
{ \
\
\
}
/*
* This macro defines an entire function to implement a FillRect inner loop
* for setting a rectangular region of pixels to a specific pixel value.
* No blending of the fill color is done with the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
do { \
juint x = 0; \
do { \
} while (++x < width); \
} while (--height > 0); \
}
/*
* This macro defines an entire function to implement a FillSpans inner loop
* for iterating through a list of spans and setting those regions of pixels
* to a specific pixel value. No blending of the fill color is done with
* the pixels.
*/
{ \
\
x, DST ## PixelStride, \
y, scan); \
do { \
} \
} while (--h > 0); \
} \
}
/*
* This macro defines an entire function to implement a FillParallelogram
* inner loop for tracing 2 diagonal edges (left and right) and setting
* those regions of pixels between them to a specific pixel value.
* No blending of the fill color is done with the pixels.
*/
{ \
\
lx++; \
} \
loy++; \
} \
}
};
/*
* This macro declares the bumpmajor and bumpminor variables used for the
* DrawLine functions.
*/
/*
* This macro extracts "instructions" from the bumpmajor and bumpminor masks
* that determine the initial bumpmajor and bumpminor values. The bumpmajor
* and bumpminor masks are laid out in the following format:
*
* bumpmajormask: bumpminormask:
* bit0: bumpmajor = pixelStride bit0: bumpminor = pixelStride
* bit1: bumpmajor = -pixelStride bit1: bumpminor = -pixelStride
* bit2: bumpmajor = scanStride bit2: bumpminor = scanStride
* bit3: bumpmajor = -scanStride bit3: bumpminor = -scanStride
*/
-SCANSTRIDE; \
0; \
/*
* This macro defines an entire function to implement a DrawLine inner loop
* for iterating along a horizontal or vertical line and setting the pixels
* on that line to a specific pixel value. No blending of the fill color
* is done with the pixels.
*/
NativePrimitive *pPrim, \
{ \
\
if (errmajor == 0) { \
do { \
} while (--steps > 0); \
} else { \
do { \
if (error < 0) { \
} else { \
} \
} while (--steps > 0); \
} \
}
/*
* This macro defines an entire function to implement a FillRect inner loop
* for setting a rectangular region of pixels to a specific pixel value.
* Each destination pixel is XORed with the current XOR mode color as well as
* the current fill color.
*/
NativePrimitive *pPrim, \
{ \
\
\
do { \
juint x = 0; \
do { \
} while (++x < width); \
} while (--height > 0); \
}
/*
* This macro defines an entire function to implement a FillSpans inner loop
* for iterating through a list of spans and setting those regions of pixels
* to a specific pixel value. Each destination pixel is XORed with the
* current XOR mode color as well as the current fill color.
*/
NativePrimitive *pPrim, \
{ \
\
\
x, DST ## PixelStride, \
y, scan); \
do { \
} \
} while (--h > 0); \
} \
}
/*
* This macro defines an entire function to implement a DrawLine inner loop
* for iterating along a horizontal or vertical line and setting the pixels
* on that line to a specific pixel value. Each destination pixel is XORed
* with the current XOR mode color as well as the current draw color.
*/
NativePrimitive *pPrim, \
{ \
\
\
if (errmajor == 0) { \
do { \
} while (--steps > 0); \
} else { \
do { \
if (error < 0) { \
} else { \
} \
} while (--steps > 0); \
} \
}
/*
* This macro is used to declare the variables needed by the glyph clipping
* macro.
*/
int ROWBYTES; \
/*
* This macro represents the glyph clipping code used in the various
* DRAWGLYPHLIST macros. This macro is typically used within a loop. Note
* that the body of this macro is NOT wrapped in a do..while block due to
* the use of continue statements within the block (those continue statements
* are intended skip the outer loop, not the do..while loop). To combat this
* problem, pass in the code (typically a continue statement) that should be
* executed when a null glyph is encountered.
*/
if (!PIXELS) { \
} \
\
/* if any clipping required, modify parameters now */ \
/* Multiply needed for LCD text as PIXELS is really BYTES */ \
} \
} \
} \
if (BOTTOM > CLIPBOTTOM) { \
BOTTOM = CLIPBOTTOM; \
} \
} \
NativePrimitive *pPrim, \
{ \
jint glyphCounter; \
\
glyphs, glyphCounter, continue) \
\
do { \
int x = 0; \
do { \
if (pixels[x]) { \
} \
} while (++x < width); \
} while (--height > 0); \
} \
}
do { \
if (mixValSrc) { \
if (mixValSrc < 255) { \
mixValSrc, SRC_PREFIX); \
} else { \
} \
} \
} while (0);
do { \
if (mixValSrc) { \
if (mixValSrc < 255) { \
mixValSrc, SRC_PREFIX); \
} \
PIXEL_INDEX, dst); \
} else { \
} \
} \
} while (0);
do { \
if (mixValSrc) { \
if (mixValSrc < 255) { \
dstG); \
mixValSrc, SRC_PREFIX); \
dstG); \
} else { \
} \
} \
} while (0);
do { \
if (mixValSrc) { \
if (mixValSrc < 255) { \
dstG); \
mixValSrc, SRC_PREFIX); \
dstG); \
} else { \
} \
} \
} while (0);
NativePrimitive *pPrim, \
{ \
jint glyphCounter; \
\
\
\
glyphs, glyphCounter, continue) \
\
do { \
int x = 0; \
do { \
} while (++x < width); \
} while (--height > 0); \
} \
}
do { \
if (rgbOrder) { \
} else { \
} \
mixValSrc, SRC_PREFIX); \
} else { \
} \
} \
} while (0)
/* There is no alpha channel in the glyph data with which to interpolate
* between the src and dst alphas, but a reasonable approximation is to
* sum the coverage alphas of the colour channels and divide by 3.
* We can approximate division by 3 using mult and shift. See
* sun/font/scalerMethods.c for a detailed explanation of why "21931"
*/
do { \
if (rgbOrder) { \
} else { \
} \
* 21931) >> 16;\
mixValSrc, SRC_PREFIX); \
} \
PIXEL_INDEX, dst); \
} else { \
} \
} \
} while (0);
unsigned char *gammaLut, \
unsigned char * invGammaLut, \
NativePrimitive *pPrim, \
{ \
\
\
\
bpp = \
glyphs, glyphCounter, continue) \
\
if (bpp!=1) { \
/* subpixel positioning adjustment */ \
} \
do { \
int x = 0; \
if (bpp==1) { \
do { \
if (pixels[x]) { \
} \
} while (++x < width); \
} else { \
do { \
} while (++x < width); \
} \
} while (--height > 0); \
} \
}
NativePrimitive *pPrim, \
{ \
jint glyphCounter; \
\
glyphs, glyphCounter, continue) \
\
do { \
int x = 0; \
do { \
if (pixels[x]) { \
} \
} while (++x < width); \
} while (--height > 0); \
} \
}
{ \
\
\
pRGB++; \
} \
}
{ \
\
\
\
xlong -= LongOneHalf; \
ylong -= LongOneHalf; \
\
\
\
\
\
pRGB += 4; \
} \
}
{ \
\
\
\
xlong -= LongOneHalf; \
ylong -= LongOneHalf; \
\
\
\
\
\
pRGB += 16; \
} \
}
};
/*
* The macros defined above use the following macro definitions supplied
* for the various surface types to manipulate pixels and pixel data.
* The surface-specific macros are typically supplied by header files
* named after the SurfaceType name (i.e. IntArgb.h, ByteGray.h, etc.).
*
* In the macro names in the following definitions, the string <stype>
* is used as a place holder for the SurfaceType name (i.e. IntArgb).
* The macros above access these type specific macros using the ANSI
* CPP token concatenation operator "##".
*
* <stype>DataType A typedef for the type of the pointer
* that is used to access the raster data
* for the given surface type.
* <stype>PixelStride Pixel stride for the surface type.
*
* Declare<stype>LoadVars Declare the variables needed to control
* loading color information from an stype
* raster (i.e. lookup tables).
* Init<stype>LoadVars Init the lookup table variables.
* Declare<stype>StoreVars Declare the storage variables needed to
* control storing pixel data based on the
* pixel coordinate (i.e. dithering variables).
* Init<stype>StoreVarsY Init the dither variables for starting Y.
* Next<stype>StoreVarsY Increment the dither variables for next Y.
* Init<stype>StoreVarsX Init the dither variables for starting X.
* Next<stype>StoreVarsX Increment the dither variables for next X.
*
* Load<stype>To1IntRgb Load a pixel and form an INT_RGB integer.
* Store<stype>From1IntRgb Store a pixel from an INT_RGB integer.
* Load<stype>To1IntArgb Load a pixel and form an INT_ARGB integer.
* Store<stype>From1IntArgb Store a pixel from an INT_ARGB integer.
* Load<stype>To3ByteRgb Load a pixel into R, G, and B components.
* Store<stype>From3ByteRgb Store a pixel from R, G, and B components.
* Load<stype>To4ByteArgb Load a pixel into A, R, G, and B components.
* Store<stype>From4ByteArgb Store a pixel from A, R, G, and B components.
* Load<stype>To1ByteGray Load a pixel and form a BYTE_GRAY byte.
* Store<stype>From1ByteGray Store a pixel from a BYTE_GRAY byte.
*
* <stype>PixelType Typedef for a "single quantity pixel" (SQP)
* that can hold the data for one stype pixel.
* <stype>XparLutEntry An SQP that can be used to represent a
* transparent pixel for stype.
* Store<stype>NonXparFromArgb Store an SQP from an INT_ARGB integer in
* such a way that it would not be confused
* with the XparLutEntry value for stype.
* <stype>IsXparLutEntry Test an SQP for the XparLutEntry value.
* Store<stype>Pixel Store the pixel data from an SQP.
* <stype>PixelFromArgb Converts an INT_ARGB value into the specific
* pixel representation for the surface type.
*
* Declare<stype>PixelData Declare the pixel data variables (PDV) needed
* to hold the elements of pixel data ready to
* store into an stype raster (may be empty for
* stypes whose SQP format is their data format).
* Extract<stype>PixelData Extract an SQP value into the PDVs.
* Store<stype>PixelData Store the PDVs into an stype raster.
* XorCopy<stype>PixelData Xor the PDVs into an stype raster.
*/
#endif /* LoopMacros_h_Included */