TouchGFX之LCD

 LCD类用于在LCD上绘制位图、文本和矩形等。这是一个LCD基类接口,包含纯虚函数。需要根据具体LCD进行实现

#ifndef TOUCHGFX_LCD_HPP
#define TOUCHGFX_LCD_HPP

#ifdef LCD
#undef LCD
#endif

#include <touchgfx/Bitmap.hpp>
#include <touchgfx/Font.hpp>
#include <touchgfx/TextProvider.hpp>
#include <touchgfx/TextureMapTypes.hpp>
#include <touchgfx/Unicode.hpp>
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/hal/VectorFontRenderer.hpp>
#include <touchgfx/lcd/DebugPrinter.hpp>

namespace touchgfx
{
/**  
 * 这个类包含各种低级绘制例程,用于绘制位图、文本和矩形/框。
 * 通常,这些绘制操作是从widget(部件)中调用的,这些部件还会跟踪逻辑状态,如可见性等。
 * LCD类不能被实例化,而是应该使用为其实现了特定显示配置的LCD绘制操作的子类。
 * @note 所有发送到LCD类中的函数的坐标都应该是绝对坐标,即(0, 0)是显示器的左上角。
 */
class LCD
{
public:
	/* 构造函数 */
	LCD() : textureMapperClass(0), vectorFontRenderer(0)
	{
	}

	/* 析构函数 */
	virtual ~LCD()
	{
	}

	/* 绘制一个位图的全部或部分
	 * @param  bitmap       要绘制的位图。  
	 * @param  x            在屏幕上的绝对x坐标处放置位图的(0, 0)。  
	 * @param  y            在屏幕上的绝对y坐标处放置位图的(0, 0)。  
	 * @param  rect         一个矩形,描述要绘制的位图的哪个区域。  
	 * @param  alpha        (可选) 可选的alpha值,范围从0=透明到255=不透明。默认为255(不透明)。  
	 * @param  useOptimized (可选) 如果为false,则不要尝试用更快的fillrects替换此位图的(部分)内容。  
	 */  
	virtual void drawPartialBitmap(const Bitmap& bitmap, int16_t x, int16_t y, const Rect& rect, uint8_t alpha = 255, bool useOptimized = true) = 0;

	/* 将一块数据直接复制到framebuffer,执行指定的alpha混合(和透明度键控)。  
	 * 如果HAL不支持BLIT_COPY_WITH_ALPHA且alpha不等于255(不透明),则执行软件混合。   
	 * @param  sourceData           源数组指针(指向数据的开始)。sourceData必须以适合所选显示的格式存储。  
	 * @param  source               源的位置和尺寸。此矩形的x和y都应为0。  
	 * @param  blitRect             一个矩形,描述要从sourceData中复制到帧缓冲区的区域。  
	 * @param  alpha                用于混合的alpha值,范围从0=透明到255=不透明=无混合。  
	 * @param  hasTransparentPixels 如果为true,则此数据复制包含透明像素,并需要启用硬件支持。  
	 */
	virtual void blitCopy(const uint16_t *sourceData, const Rect& source, const Rect& blitRect, uint8_t alpha, bool hasTransparentPixels) = 0;

	/* 将一块数据直接复制到framebuffer,执行指定的alpha混合(和透明度键控)。  
	 * 如果HAL不支持BLIT_COPY_WITH_ALPHA且alpha小于255(不透明),则执行软件混合。    
	 * 如果显示器不支持指定的sourceFormat,将引发assert。  
	 * @param  sourceData           源数组指针(指向数据的开始)。sourceData必须以适合所选显示的格式存储。  
	 * @param  sourceFormat         源数据中使用的位图格式。  
	 * @param  source               源的位置和尺寸。此矩形的x和y都应为0。  
	 * @param  blitRect             一个矩形,描述要从\a sourceData中复制到帧缓冲区的区域。  
	 * @param  alpha                用于混合的alpha值,范围从0=透明到255=不透明=无混合。  
	 * @param  hasTransparentPixels 如果为true,则此数据复制包含透明像素,并需要启用硬件支持。  
	 */ 
	virtual void blitCopy(const uint8_t* sourceData, Bitmap::BitmapFormat sourceFormat, const Rect& source, const Rect& blitRect, uint8_t alpha, bool hasTransparentPixels) = 0;

	/* 将framebuffer的部分内容复制到位图的数据区。位图必须是动态位图或动画存储(BITMAP_ANIMATION_STORAGE)。  
	 * 只复制由参数region指定的部分。  
	 *  
	 * 如果region 具有负x/y坐标或宽度/高度超过给定位图的尺寸,则只复制framebuffer中可见且合法的部分。  
	 * 位图图像的其余部分保持不变。  
	 *  
	 * @param  region   要复制的framebuffer的部分。  
	 * @param  bitmapId (可选)用于存储数据的位图。默认使用动画存储。  
	 *  
	 * @return 指向复制的指针。  
	 *  
	 * @see blitCopy  
	 *  
	 * @note 动画存储只有一个实例。位图数据(或动画存储)在给定区域外的内容保持不变。  
	 */ 
	uint16_t *copyFrameBufferRegionToMemory(const Rect& region, const BitmapId bitmapId = BITMAP_ANIMATION_STORAGE)
	{
		return copyFrameBufferRegionToMemory(region, region, bitmapId);
	}

	/* 将framebuffer的部分内容复制到位图的数据区。位图必须是动态位图或动画存储(BITMAP_ANIMATION_STORAGE)。  
	 * 给定的两个区域是可见区域和屏幕上的绝对区域。这用于只复制framebuffer的一部分。这可能是因为SnapshotWidget  
	 * 被放置在一个Container中,而SnapshotWidget的部分位于Container定义的区域之外。可见区域必须完全位于绝对区域内。  
	 *  
	 * @param  visRegion 可见区域。  
	 * @param  absRegion 绝对区域。  
	 * @param  bitmapId  位图的标识符。  
	 *  
	 * @return 如果失败则返回 Null,否则返回指向给定位图中数据的指针。  
	 *  
	 * @see blitCopy, copyFrameBufferRegionToMemory(const Rect&, const Rect&, uint8_t*, int16_t, int16_t)  
	 *  
	 * @note 动画存储只有一个实例。位图数据/动画存储在给定区域外的内容保持不变。  
	 */
	virtual uint16_t* copyFrameBufferRegionToMemory(const Rect& visRegion, const Rect& absRegion, const BitmapId bitmapId) = 0;

	/* 将framebuffer的部分内容复制到内存。假设内存具有与framebuffer相同的格式。给定的两个区域是可见区域和屏幕上的绝对区域。  
	 * 这用于只复制framebuffer的一部分。这可能是因为SnapshotWidget被放置在一个Container中,而SnapshotWidget的部分  
	 * 位于Container定义的区域之外。可见区域必须完全位于绝对区域内。  
	 *  
	 * @param           visRegion   可见区域。  
	 * @param           absRegion   绝对区域。  
	 * @param [in,out]  dst         与framebuffer格式相同的目标内存。  
	 * @param           dstWidth    目标的宽度。  
	 * @param           dstHeight   目标的高度。  
	 *  
	 * @return  实际复制到目标缓冲区的矩形区域。  
	 *  
	 * @see blitCopy, copyFrameBufferRegionToMemory(const Rect&, const Rect&, const BitmapId)  
	 *  
	 * @note    动画存储只有一个实例。位图数据/动画存储在给定区域外的内容保持不变。但是,请注意这个函数并不涉及动画存储或位图ID,它直接操作原始内存。  
	 */ 
	virtual Rect copyFrameBufferRegionToMemory(const Rect& visRegion, const Rect& absRegion, uint8_t* dst, int16_t dstWidth, int16_t dstHeight) = 0;

	/* 将显示的framebuffer的部分内容复制到当前framebuffer。给定的区域是屏幕上的绝对区域。  
	 *  
	 * @param  region		一个矩形,描述要从显示的framebuffer复制到当前framebuffer的区域。  
	 *  
	 * @note    复制仅在启用双缓冲时进行。否则,当前帧缓冲区中的给定区域保持不变。  
	 */
	virtual void copyAreaFromTFTToClientBuffer(const Rect& region) = 0;

	/* 在framebuffer中绘制一个填充的矩形,具有指定的颜色和透明度。默认情况下,矩形将绘制为一个实心框。  
	 * 可以通过指定alpha从0-255来绘制带有透明度的矩形。  
	 *  
	 * @param  rect  要绘制的矩形,使用绝对显示坐标。  
	 * @param  color 矩形的颜色。  
	 * @param  alpha (可选)矩形的透明度,从 0=不可见到 255=实心。  
	 *  
	 * @see fillBuffer  
	 */ 
	virtual void fillRect(const Rect& rect, colortype color, uint8_t alpha = 255) = 0;

	/* 在目标内存中使用指定的颜色和透明度绘制一个填充的矩形。  
	 * 目标内存必须具有与显示帧缓冲区相同的格式。  
	 * 默认情况下,矩形将被绘制为一个实心的盒子。  
	 * 通过指定从 0=不可见到 255=实心的 alpha 值,可以绘制带有透明度的矩形。  
	 *  
	 * @param [in]  destination 目标内存区域的起始地址。  
	 * @param       pixelStride 像素跨度,即一行中的像素数。  
	 * @param       rect        要填充的绝对坐标矩形。  
	 * @param       color       矩形的颜色。  
	 * @param       alpha       矩形的透明度,从 0=不可见到 255=实心。  
	 *  
	 * @note    对于每个字节包含多个像素的显示器(LCD1bpp,LCD2bpp 和 LCD4bpp),pixelStride 将向上舍入到最接近的整个字节。  
	 */  
	virtual void fillBuffer(uint8_t* const destination, uint16_t pixelStride, const Rect& rect, const colortype color, const uint8_t alpha) = 0;

	/* 当写入字符串时的可视元素。  
	 * 这个结构体用于描述如何渲染文本字符串的各种属性。  
	 */  
	struct StringVisuals  
	{  
		const Font* font;              ///< 要使用的字体。  
		Alignment alignment;           ///< 要使用的对齐方式。默认是 LEFT。  
		TextDirection textDirection;   ///< 要使用的文本方向。默认是 LTR(从左到右)。  
		TextRotation rotation;         ///< 文本的方向(旋转)。默认是 TEXT_ROTATE_0(不旋转)。  
		colortype color;               ///< RGB 颜色值。默认是 0(黑色)。  
		int16_t linespace;             ///< 多行字符串的行间距(以像素为单位)。默认是 0。  
		uint8_t alpha;                 ///< 8位 alpha 值。默认是 255(实心)。  
		uint8_t indentation;           ///< 文本在矩形内的缩进。文本将从这个距离开始,从左边/右边缘算起。  
		WideTextAction wideTextAction; ///< 对于宽文本行的处理方式。  

		/* 构造函数 */  
		StringVisuals()  
				: font(0), alignment(LEFT), textDirection(TEXT_DIRECTION_LTR), rotation(TEXT_ROTATE_0), color(0), linespace(0), alpha(255), indentation(0), wideTextAction(WIDE_TEXT_NONE)  
		{  
		}  

		/* 构造函数允许用户指定各种文本渲染属性,如字体、颜色、对齐方式等。  
		 *  
		 * @param  参数列表... 这里列出了构造函数的所有参数,以及它们的含义和默认值(如果有的话)。  
		 */  
		StringVisuals(const Font* svFont, colortype svColor, uint8_t svAlpha, Alignment svAlignment, int16_t svLinespace, TextRotation svRotation, TextDirection svTextDirection, uint8_t svIndentation, WideTextAction svWideTextAction = WIDE_TEXT_NONE)  
				: font(svFont), alignment(svAlignment), textDirection(svTextDirection), rotation(svRotation), color(svColor), linespace(svLinespace), alpha(svAlpha), indentation(svIndentation), wideTextAction(svWideTextAction)  
		{  
		}  
	};

	/* 设置向量字体渲染器。  
	 *   
	 * 这个方法允许外部设置一个向量字体渲染器,该渲染器将被 LCD 类在处理向量字体时使用。  
	 *  
	 * @param renderer 要由 LCD 在处理向量字体时使用的渲染器。  
	 */ 
	void setVectorFontRenderer(VectorFontRenderer* renderer)
	{
		vectorFontRenderer = renderer;
	}

	/* 绘制指定的Unicode字符串。在新行处换行。  
	 * 
	 * widgetArea: 绘制控件在绝对坐标中覆盖的区域。  
	 * invalidatedArea: 需要绘制的(子)区域,相对于widgetArea表示。  
	 * stringVisuals: 用于绘制此字符串的字符串视觉效果(字体、对齐方式、行间距、颜色等)。  
	 * format: 指向带有可选额外通配符参数的空终止文本字符串的指针。  
	 * ...: 提供额外信息的可变参数 */
	void drawString(Rect widgetArea, const Rect& invalidatedArea, const StringVisuals& stringVisuals,
									const Unicode::UnicodeChar* format, ...);

	/* 显示屏每个像素使用的位数 */
	virtual uint8_t bitDepth() const = 0;

	/* 显示屏使用的framebuffer格式。  
	 * 返回值:一个Bitmap::BitmapFormat枚举值 */
	virtual Bitmap::BitmapFormat framebufferFormat() const = 0;

	/* framebuffer的跨度(以字节为单位)。从帧缓冲的一行开始到下一行的距离。  
	   返回值:帧缓冲一行的字节数 */
	virtual uint16_t framebufferStride() const = 0;

	/* 检查LCD是否支持动态位图绘制。  
	 * 参数:format - 动态位图的格式。  
	 * 返回值:如果支持动态位图绘制,则返回true,否则返回false */
	virtual bool supportDynamicBitmapDrawing(const Bitmap::BitmapFormat format)
	{
		return (format == framebufferFormat());
	}

	/* 设置默认颜色,用于仅由alpha级别表示的位图格式,例如A4。如果没有设置颜色,则默认是黑色。  
	   参数:color - 颜色值 */
	virtual void setDefaultColor(colortype color)
	{
		defaultColor = color;
	}

	/* 获取默认颜色 */
	colortype getDefaultColor() const
	{
		return defaultColor;
	}

	/**  
	 * 绘制纹理映射三角形。  
	 *   
	 * 该函数用于在屏幕上绘制一个具有透视效果的纹理映射三角形。  
	 * 顶点数组描述了三角形的表面,包括x,y,z坐标和纹理的u,v坐标。  
	 * 纹理包含了要绘制的图像数据。  
	 * 三角形将被放置在绝对矩形和脏矩形内进行裁剪。  
	 * alpha值决定了三角形的alpha混合程度。  
	 * subDivisionSize决定了扫描线上分段仿射纹理映射部分的大小。  
	 *   
	 * @param dest              描述纹理绘制位置的对象,可用于离屏绘制。  
	 * @param vertices          三角形的顶点数组。  
	 * @param texture           要绘制的纹理。  
	 * @param absoluteRect      包含绘制区域的绝对坐标矩形。  
	 * @param dirtyAreaAbsolute 脏区域的绝对坐标矩形,即需要更新的区域。  
	 * @param renderVariant     渲染变体,包括算法和像素格式。  
	 * @param alpha             (可选) alpha值,默认为255(不透明)。  
	 * @param subDivisionSize   (可选) 扫描线分段的大小,默认为12。  
	 */ 
	virtual void drawTextureMapTriangle(const DrawingSurface& dest,
																			const Point3D* vertices,
																			const TextureSurface& texture,
																			const Rect& absoluteRect,
																			const Rect& dirtyAreaAbsolute,
																			RenderingVariant renderVariant,
																			uint8_t alpha = 255,
																			uint16_t subDivisionSize = 12);

	/**  
	 * 绘制纹理映射四边形。  
	 *   
	 * 该函数用于在屏幕上绘制一个具有透视效果的纹理映射四边形。  
	 * 顶点数组描述了四边形的表面,包括x,y,z坐标和纹理的u,v坐标。  
	 * 纹理包含了要绘制的图像数据。  
	 * 四边形将被放置在绝对矩形和脏矩形内进行裁剪。  
	 * alpha值决定了四边形的alpha混合程度。  
	 * subDivisionSize决定了扫描线上分段仿射纹理映射部分的大小。  
	 *   
	 * @param dest              描述纹理绘制位置的对象,可用于离屏绘制。  
	 * @param vertices          四边形的顶点数组。  
	 * @param texture           要绘制的纹理。  
	 * @param absoluteRect      包含绘制区域的绝对坐标矩形。  
	 * @param dirtyAreaAbsolute 脏区域的绝对坐标矩形,即需要更新的区域。  
	 * @param renderVariant     渲染变体,包括算法和像素格式。  
	 * @param alpha             (可选) alpha值,默认为255(不透明)。  
	 * @param subDivisionSize   (可选) 扫描线分段的大小,默认为12。  
	 */
	virtual void drawTextureMapQuad(const DrawingSurface& dest,
																	const Point3D* vertices,
																	const TextureSurface& texture,
																	const Rect& absoluteRect,
																	const Rect& dirtyAreaAbsolute,
																	RenderingVariant renderVariant,
																	uint8_t alpha = 255,
																	uint16_t subDivisionSize = 12);

	/* 对一个16位数值进行除以255的近似整数除法。此方法常用于alpha混合操作后的结果除以255。  
	 *  
	 * @param [in] num 要除以255的分子。  
	 *  
	 * @return 除以255后的结果。  
	 */
	FORCE_INLINE_FUNCTION static uint8_t div255(uint16_t num)
	{
		return (num + 1 + (num >> 8)) >> 8;
	}

	/* 对32位ARGB像素的红色和蓝色分量乘以alpha因子后的结果进行除以255的操作。  
	 *  
	 * @param [in] pixelxAlpha 已乘以alpha因子的32位ARGB像素的红色和蓝色分量。  
	 *  
	 * @return 红色和蓝色分量除以255后的32位ARGB像素。  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div255rb(uint32_t pixelxAlpha)
	{
		return ((pixelxAlpha + 0x10001 + ((pixelxAlpha >> 8) & 0xFF00FF)) >> 8) & 0xFF00FF;
	}

	/* 对32位ARGB像素的绿色分量乘以alpha因子后的结果进行除以255的操作。  
	 *  
	 * @param [in] pixelxAlpha 已乘以alpha因子的32位ARGB像素的绿色分量。  
	 *  
	 * @return 绿色分量除以255后的32位ARGB像素。  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div255g(uint32_t pixelxAlpha)
	{
		return ((pixelxAlpha + 0x100 + (pixelxAlpha >> 8)) >> 8) & 0x00FF00;
	}

protected:
	static const uint16_t newLine = 10; ///< 换行符的数值表示,通常是10(/n)
	static colortype defaultColor; 			///< 当显示仅含透明度的元素(例如A4位图)时使用的默认颜色

	/* 用于通过纹理映射器绘制扫描线的基类 */
	class DrawTextureMapScanLineBase
	{
		public:
			/* 析构函数 */
			virtual ~DrawTextureMapScanLineBase()
			{
			}

			/**  
			 * 绘制纹理映射扫描线的细分。  
			 *  
			 * @param  subdivisions       细分的数量。  
			 * @param  widthModLength     长度(细分后)的余数。  
			 * @param  pixelsToDraw       要绘制的像素数量。  
			 * @param  affineLength       一个细分的长度。  
			 * @param  oneOverZRight      1/Z 右值。  
			 * @param  UOverZRight        U/Z 右值。  
			 * @param  VOverZRight        V/Z 右值。  
			 * @param  U                  U坐标,使用fixed16_16表示法。  
			 * @param  V                  V坐标,使用fixed16_16表示法。  
			 * @param  deltaU             到达下一个像素坐标的U增量。  
			 * @param  deltaV             到达下一个像素坐标的V增量。  
			 * @param  ULeft              左侧的U值。  
			 * @param  VLeft              左侧的V值。  
			 * @param  URight             右侧的U值。  
			 * @param  VRight             右侧的V值。  
			 * @param  ZRight             右侧的Z值。  
			 * @param  dest               目标绘制表面。  
			 * @param  destX              目标x坐标。  
			 * @param  destY              目标y坐标。  
			 * @param  texture            纹理。  
			 * @param  alpha              全局alpha值。  
			 * @param  dOneOverZdXAff     1/ZdX的仿射值。  
			 * @param  dUOverZdXAff       U/ZdX的仿射值。  
			 * @param  dVOverZdXAff       V/ZdX的仿射值。  
			 */
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff) = 0;

		protected:
			static const fixed16_16 half = 0x8000; ///< 定义了一个常量,表示1/2的fixed16_16格式值

			/**  
			 * 绘制纹理映射的下一个细分。  
			 * 这个方法用于计算并更新绘制纹理映射所需的各种参数,如U、V坐标,Z值等,并将它们转换为fixed16_16格式。  
			 *   
			 * @param [out]    ULeft          更新后的U左坐标。  
			 * @param [out]    VLeft          更新后的V左坐标。  
			 * @param [out]    ZRight         更新后的Z右坐标(通常用于深度或透视校正)。  
			 * @param [out]    URight         更新后的U右坐标。  
			 * @param [out]    VRight         更新后的V右坐标。  
			 * @param [in,out] oneOverZRight  更新后的1/Z右坐标的倒数。  
			 * @param          dOneOverZdXAff 1/Z在X方向上的仿射变化率。  
			 * @param [in,out] UOverZRight    更新后的U/Z右坐标。  
			 * @param          dUOverZdXAff   U/Z在X方向上的仿射变化率。  
			 * @param [in,out] VOverZRight    更新后的V/Z右坐标。  
			 * @param          dVOverZdXAff   V/Z在X方向上的仿射变化率。  
			 * @param          affineLength   仿射细分的长度。  
			 * @param [out]    U              转换为fixed16_16格式的U坐标。  
			 * @param [out]    V              转换为fixed16_16格式的V坐标。  
			 * @param [out]    deltaU         U坐标的变化量(delta)。  
			 * @param [out]    deltaV         V坐标的变化量(delta)。  
			 */ 
			FORCE_INLINE_FUNCTION void drawTextureMapNextSubdivision(float& ULeft, float& VLeft, float& ZRight, float& URight, float& VRight, float& oneOverZRight, const float dOneOverZdXAff, float& UOverZRight, const float dUOverZdXAff, float& VOverZRight, const float dVOverZdXAff, const int affineLength, fixed16_16& U, fixed16_16& V, fixed16_16& deltaU, fixed16_16& deltaV)
			{
				ULeft = URight;
				VLeft = VRight;

				oneOverZRight += dOneOverZdXAff;
				UOverZRight += dUOverZdXAff;
				VOverZRight += dVOverZdXAff;

				ZRight = 1 / oneOverZRight;
				URight = ZRight * UOverZRight;
				VRight = ZRight * VOverZRight;

				U = floatToFixed16_16(ULeft);
				V = floatToFixed16_16(VLeft);
				deltaU = floatToFixed16_16(URight - ULeft) / affineLength;
				deltaV = floatToFixed16_16(VRight - VLeft) / affineLength;
			}

			/* 检查一个值是否在[0, limit)范围内(不包括limit) */
			FORCE_INLINE_FUNCTION bool is1Inside(int value, int limit) const
			{
				return (value >= 0 && value < limit);
			}

			/* 检查(x, y)坐标是否在([0, width), [0, height))范围内 */
			FORCE_INLINE_FUNCTION bool is1x1Inside(int x, int y, int width, int height) const
			{
				return is1Inside(x, width) && is1Inside(y, height);
			}

			/* 检查一个值和该值+1是否都在[0, limit)范围内 */
			FORCE_INLINE_FUNCTION bool is2Inside(int value, int limit) const
			{
				return is1Inside(value, limit - 1);
			}

			/* 检查(x, y)和(x+1, y+1)是否都在([0, width), [0, height))范围内 */
			FORCE_INLINE_FUNCTION bool is2x2Inside(int x, int y, int width, int height) const
			{
				return is2Inside(x, width) && is2Inside(y, height);
			}

			/* 检查一个值或该值+1是否至少有一个在[0, limit)范围内 */
			FORCE_INLINE_FUNCTION bool is2PartiallyInside(int value, int limit) const
			{
				return is1Inside(value + 1, limit + 1);
			}

			/* 检查(x, y)或(x+1, y+1)是否至少有一个在([0, width), [0, height))范围内 */
			FORCE_INLINE_FUNCTION bool is2x2PartiallyInside(int x, int y, int width, int height) const
			{
					return is2PartiallyInside(x, width) && is2PartiallyInside(y, height);
			}
	};

	/**  
	 * 获取可以绘制扫描线的对象的指针,该对象允许进行高度专门化和优化的实现。  
	 *   
	 * @param  texture       要使用的纹理表面。  
	 * @param  renderVariant 渲染变体。  
	 * @param  alpha         全局透明度。  
	 *   
	 * @return 如果失败,返回Null;否则,返回指向纹理映射器绘制扫描线对象的指针。  
	 */ 
	virtual DrawTextureMapScanLineBase* getTextureMapperDrawScanLine(const TextureSurface& texture, RenderingVariant renderVariant, uint8_t alpha);

	/**  
	 * 绘制扫描线。在屏幕上绘制纹理图的一个水平线。该扫描线将使用透视正确的纹理映射来绘制。  
	 * 线的外观由左右边缘和渐变结构决定。边缘包含有关左右两侧的 x, y, z 坐标以及所使用的纹理映射的 u, v 坐标的信息。  
	 * 渐变结构包含有关如何在扫描线上插值所有这些值的信息。应该在纹理参数中提供要绘制的数据。  
	 *   
	 * 该扫描线将使用附加的参数来绘制。将使用绝对和脏矩形来放置和剪裁扫描线。  
	 * alpha 将确定应该如何对扫描线进行 alpha 混合。subDivisionSize 将确定分段仿射纹理映射线的大小。  
	 *   
	 * @param  dest              描述纹理绘制位置的信息 - 可用于发出屏幕外绘制。  
	 * @param  gradients         在扫描线上插值使用的渐变。  
	 * @param  leftEdge          扫描线的左边缘。  
	 * @param  rightEdge         扫描线的右边缘。  
	 * @param  texture           纹理。  
	 * @param  absoluteRect      绝对坐标中的包含矩形。  
	 * @param  dirtyAreaAbsolute 绝对坐标中的脏区域。  
	 * @param  renderVariant     渲染变体 - 包括算法和像素格式。  
	 * @param  alpha             透明度。  
	 * @param  subDivisionSize   扫描线细分的大小。值为1将给出完全透视正确的纹理映射扫描线。  
	 *                           较大的值将给出仿射纹理映射扫描线。  
	 */
	virtual void drawTextureMapScanLine(const DrawingSurface& dest, const Gradients& gradients, const Edge* leftEdge, const Edge* rightEdge, const TextureSurface& texture, const Rect& absoluteRect, const Rect& dirtyAreaAbsolute, RenderingVariant renderVariant, uint8_t alpha, uint16_t subDivisionSize);

	/**  
	 * 带有显式目标缓冲区指针参数的drawString()函数的私有版本的draw-glyph。  
	 * 对于除缓冲区指针外的所有参数,请参阅公共函数drawString()。  
	 *   
	 * @param [out] wbuf16          要绘制到的目标(帧)缓冲区。  
	 * @param       widgetArea      要在其内部绘制字形的画布。  
	 * @param       x               水平偏移量,开始绘制字形的位置。  
	 * @param       y               垂直偏移量,开始绘制字形的位置。  
	 * @param       offsetX         在字形中的水平偏移量,开始绘制的位置。  
	 * @param       offsetY         在字形中的垂直偏移量,开始绘制的位置。  
	 * @param       invalidatedArea 要在其中绘制的区域。  
	 * @param       glyph           要绘制的字形的规格。  
	 * @param       glyphData       包含实际字形的数据(密集格式)  
	 * @param       byteAlignRow    每个字形数据行从新的字节开始。  
	 * @param       color           字形的颜色。  
	 * @param       bitsPerPixel    字形的位深度。  
	 * @param       alpha           字形的透明度。  
	 * @param       rotation        绘制字形之前的旋转操作。  
	 */
	virtual void drawGlyph(uint16_t* wbuf16, Rect widgetArea, int16_t x, int16_t y, uint16_t offsetX, uint16_t offsetY, const Rect& invalidatedArea, const GlyphNode* glyph, const uint8_t* glyphData, uint8_t byteAlignRow, colortype color, uint8_t bitsPerPixel, uint8_t alpha, TextRotation rotation) = 0;

	/**  
	 * 在另一个矩形内旋转一个矩形。  
	 *   
	 * @param [in,out] rect     要旋转的矩形。  
	 * @param          canvas   包含要旋转的矩形的矩形。  
	 * @param          rotation 要对rect执行的旋转操作。  
	 */
	static void rotateRect(Rect& rect, const Rect& canvas, const TextRotation rotation);

	/**  
	 * 根据给定的旋转角度,计算一个点在一个控件内的真实、绝对的x坐标。  
	 *  
	 * @param [in] widgetArea 控件的区域。  
	 * @param      x          点的x坐标。  
	 * @param      y          点的y坐标。  
	 * @param      rotation   旋转的角度。  
	 *  
	 * @return 旋转后的绝对x坐标。  
	 */
	static int realX(const Rect& widgetArea, int16_t x, int16_t y, TextRotation rotation);

	/**  
	 * 根据给定的旋转角度,计算一个点在一个控件内的真实、绝对的y坐标。  
	 *  
	 * @param [in] widgetArea 控件的区域。  
	 * @param      x          点的x坐标。  
	 * @param      y          点的y坐标。  
	 * @param      rotation   旋转的角度。  
	 *  
	 * @return 旋转后的绝对y坐标。  
	 */  
	static int realY(const Rect& widgetArea, int16_t x, int16_t y, TextRotation rotation);

	/**  
	 * 绘制指定的Unicode字符串。遇到换行符时换行。字符串被假定为只包含从左到右书写的拉丁字符。  
	 *  
	 * @param      widgetArea      控件在绝对坐标中覆盖的区域。  
	 * @param      invalidatedArea 需要绘制的控件区域的(子)区域,相对于控件区域表达。  
	 * @param [in] visuals         用于绘制此字符串的字符串视觉效果(字体、对齐方式、行间距、颜色)。  
	 * @param      format          指向一个以null结尾的文本字符串的指针,该字符串带有可选的额外通配符参数。  
	 * @param      pArg            提供额外信息的可变参数。  
	 *  
	 * @see drawString  
	 */ 
	void drawStringLTR(const Rect& widgetArea, const Rect& invalidatedArea, const StringVisuals& visuals, const Unicode::UnicodeChar* format, va_list pArg);

	/**  
	 * 绘制指定的Unicode字符串。遇到换行符时换行。字符串可以是从右到左或从左到右的,并可能包含阿拉伯/希伯来和拉丁字符的序列。  
	 *  
	 * @param      widgetArea      控件在绝对坐标中覆盖的区域。  
	 * @param      invalidatedArea 需要绘制的控件区域的(子)区域,相对于控件区域表达。  
	 * @param [in] visuals         用于绘制此字符串的字符串视觉效果(字体、对齐方式、行间距、颜色)。  
	 * @param      format          指向一个以null结尾的文本字符串的指针,该字符串带有可选的额外通配符参数。  
	 * @param      pArg            提供额外信息的可变参数。  
	 *  
	 * @see drawString  
	 */
	void drawStringRTL(const Rect& widgetArea, const Rect& invalidatedArea, const StringVisuals& visuals, const Unicode::UnicodeChar* format, va_list pArg);

	/**  
	 * 从给定的TextProvider中查找给定数量的连字(ligatures)的字符串宽度。在引入阿拉伯语、泰语、印地语和其他语言后,计算的是连字而不是字符。  
	 * 对于拉丁语言,字符数等于连字数。  
	 *  
	 * @param [in] textProvider  文本提供者。  
	 * @param      font          字体。  
	 * @param      numChars      字符(连字)的数量。  
	 * @param      textDirection 文本的方向。  
	 *  
	 * @return 一个uint16_t类型的值,表示字符串的宽度。  
	 */ 
	static uint16_t stringWidth(TextProvider& textProvider, const Font& font, const int numChars, TextDirection textDirection);

	/**  
	 * 获取给定文本的行数,同时考虑换行。为了确定在需要换行的情况下的行数,必须提供字体和宽度。  
	 *   
	 * @param [in] textProvider   文本提供者。它可能是包含要渲染的文本的对象。  
	 * @param      wideTextAction 当文本行超过文本区域宽度时的处理方式。  
	 * @param      textDirection  文本方向(从左到右或从右到左)。  
	 * @param      font           用于渲染文本的字体。  
	 * @param      width          文本区域的宽度。  
	 *   
	 * @return 文本的行数。  
	 */
	static uint16_t getNumLines(TextProvider& textProvider, WideTextAction wideTextAction, TextDirection textDirection, const Font* font, int16_t width);

	friend class Font;
	friend class TextArea;
	friend class TextAreaWithWildcardBase;

	/**  
	 * 从给定偏移量的A4图像中获取alpha值。该值从0-15的范围缩放到0-255的范围。  
	 * A4可能是一种具有4位alpha通道的图像格式,因此需要将其缩放到常见的8位范围。  
	 *   
	 * @param  data   指向A4数据起始位置的指针。  
	 * @param  offset 在A4图像中的偏移量。  
	 *   
	 * @return 缩放后的alpha值(0-255)。  
	 */
	FORCE_INLINE_FUNCTION static uint8_t getAlphaFromA4(const uint16_t* data, uint32_t offset)
	{
		uint8_t byte = reinterpret_cast<const uint8_t*>(data)[offset / 2];
		return ((offset & 1) == 0 ? byte & 0xF : byte >> 4) * 0x11;
	}

private:
	DrawTextureMapScanLineBase* textureMapperClass; //在更快的TextureMapper渲染期间使用的指针
	VectorFontRenderer *vectorFontRenderer;		//向量字体渲染器

	// 内部结构体,用于绘制字符串时的各种参数和数据  
	class DrawStringInternalStruct  
	{  
		public:  
			uint16_t* frameBuffer;        // 指向帧缓冲区的指针,用于直接操作屏幕上的像素点  
			const Rect* widgetArea;       // 指向一个矩形区域的指针,表示要绘制的文本所在的控件区域  
			int16_t widgetRectY;          // 控件区域的Y坐标  
			const Rect* toDraw;           // 指向实际要绘制的矩形区域的指针  
			const StringVisuals* stringVisuals; // 指向字符串可视化信息的指针,包括颜色、背景等  

			// 构造函数
			DrawStringInternalStruct() : frameBuffer(0), widgetArea(0), widgetRectY(0), toDraw(0), stringVisuals(0)  
			{  
			}  
	};

	// 在LCD上从右到左绘制一行文本(RTL代表从右到左)
	void drawStringRTLLine(int16_t& offset, const Font* font, TextDirection textDirection, TextProvider& textProvider, const int numChars, const bool useEllipsis, const DrawStringInternalStruct* data);
	// 内部使用的从右到左绘制文本的函数
	void drawStringRTLInternal(int16_t& offset, const Font* font, const TextDirection textDirection, TextProvider& drawTextProvider, const int numChars, const uint16_t widthOfNumChars, const DrawStringInternalStruct* data);
	// 内部使用的绘制文本的函数,返回一个布尔值表示绘制是否成功
	bool drawStringInternal(uint16_t* frameBuffer, const Rect* widgetArea, int16_t widgetRectY, int16_t offset, const Rect& invalidatedArea, const StringVisuals* stringVisuals, const TextDirection textDirection, TextProvider& textProvider, const int numChars, bool useEllipsis);

	// 另一个内部结构体,用于处理宽文本(可能包含多行或特殊格式的文本)
	class WideTextInternalStruct
	{
		public:
			// 构造函数,初始化宽文本绘制所需的各种参数和数据
			WideTextInternalStruct(TextProvider& textProvider, uint16_t width, uint16_t height, TextDirection direction, const Font* _font, int16_t _linespace, WideTextAction action)
					: currChar(0), tp(textProvider), textDirection(direction), wideTextAction(action), font(_font), areaWidth(width), areaHeight(height), linespace(_linespace), charsRead(0), widthUsed(0), charsReadAhead(0), widthAhead(0), widthWithoutWhiteSpaceAtEnd(0), ellipsisGlyphWidth(0), useEllipsis(false)
			{
				if (wideTextAction != WIDE_TEXT_NONE)
				{
					Unicode::UnicodeChar ellipsisChar = font->getEllipsisChar();
					if (ellipsisChar != 0)
					{
						const GlyphNode* ellipsisGlyph = font->getGlyph(ellipsisChar);
						if (ellipsisGlyph != 0)
						{
							ellipsisGlyphWidth = ellipsisGlyph->advance();
							if (wideTextAction == WIDE_TEXT_CHARWRAP_DOUBLE_ELLIPSIS)
							{
								ellipsisGlyphWidth += font->getKerning(ellipsisChar, ellipsisGlyph) + ellipsisGlyph->advance();
							}
						}
					}
				}
			}

			// 扫描并计算当前行的字符串长度(考虑到宽文本的特殊处理)
			void scanStringLengthForLine();

			// 判断一个字符是否为空格(包括普通空格和零宽空格)
			bool isSpace(Unicode::UnicodeChar ch)
			{
				return ch == ' ' || ch == 0x200B;
			}

			// 获取当前处理的字符(Unicode字符)
			Unicode::UnicodeChar getCurrChar() const
			{
				return currChar;
			}

			// 获取当前行的宽度(不包括末尾的空格)
			uint16_t getLineWidth() const
			{
				return widthWithoutWhiteSpaceAtEnd;
			}

			// 获取已读取的字符数(在处理宽文本时用于追踪进度)
			uint16_t getCharsRead() const
			{
				return charsRead;
			}

			// 判断当前行是否因为超出区域宽度而添加了省略号
			bool ellipsisAtEndOfLine() const
			{
				return useEllipsis;
			}

		private:
			Unicode::UnicodeChar currChar;        // 当前处理的字符  
			TextProvider& tp;                     // 提供文本内容的对象引用(可能是字符串、文本文件等)  
			TextDirection textDirection;          // 文本的方向(从左到右或从右到左)  
			WideTextAction wideTextAction;        // 宽文本的行为(如何处理超出宽度的文本等)  
			const Font* font;                     // 用于绘制的字体对象指针  
			uint16_t areaWidth;                   // 绘制区域的宽度限制  
			uint16_t areaHeight;                  // 绘制区域的高度限制(虽然在这个结构体中未直接使用,但可能在外部有用)  
			int16_t linespace;                    // 行间距(在处理多行文本时使用)  
			uint16_t charsRead;                   // 已读取的字符数(用于追踪进度和状态)  
			uint16_t widthUsed;                   // 已使用的宽度(在处理当前行时用于计算剩余空间)  
			uint16_t charsReadAhead;              // 预先读取的字符数(用于处理宽文本的特殊情况)  
			uint16_t widthAhead;                  // 预先读取的字符所占的宽度(与上面的变量配合使用)  
			uint16_t widthWithoutWhiteSpaceAtEnd; // 当前行不包括末尾空格的宽度(用于精确控制文本的显示位置)  
			uint16_t ellipsisGlyphWidth;          // 省略号字符的宽度(如果需要添加省略号时使用)  
			bool useEllipsis;                     // 标记是否在当前行的末尾添加了省略号(因为文本超出了可用宽度)

			// 一个辅助函数,用于在宽文本处理中添加一个单词到当前行(同时考虑各种边界条件和特殊情况)
			void addWord(uint16_t widthBeforeCurrChar, uint16_t widthBeforeWhiteSpaceAtEnd, uint16_t charsReadTooMany);
	};
};

}

#endif

 下面是每像素16位的LCD子类,具体实现了各种绘图方法

#ifndef TOUCHGFX_LCD16BPP_HPP
#define TOUCHGFX_LCD16BPP_HPP
#include <touchgfx/Bitmap.hpp>
#include <touchgfx/hal/HAL.hpp>
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/lcd/LCD.hpp>
#include <touchgfx/lcd/LCD16DebugPrinter.hpp>

namespace touchgfx
{
struct GlyphNode;

/**
 * This class contains the various low-level drawing routines for drawing bitmaps, texts and
 * rectangles on 16 bits per pixel displays.
 *
 * @see LCD
 *
 * @note All coordinates are expected to be in absolute coordinates!
 */
class LCD16bpp : public LCD
{
public:
	/* 构造函数 */
	LCD16bpp();

	/* 绘制一个位图的全部或部分
	 * @param  bitmap       要绘制的位图。  
	 * @param  x            在屏幕上的绝对x坐标处放置位图的(0, 0)。  
	 * @param  y            在屏幕上的绝对y坐标处放置位图的(0, 0)。  
	 * @param  rect         一个矩形,描述要绘制的位图的哪个区域。  
	 * @param  alpha        (可选) 可选的alpha值,范围从0=透明到255=不透明。默认为255(不透明)。  
	 * @param  useOptimized (可选) 如果为false,则不要尝试用更快的fillrects替换此位图的(部分)内容。  
	 */ 
	virtual void drawPartialBitmap(const Bitmap& bitmap, int16_t x, int16_t y, const Rect& rect, uint8_t alpha = 255, bool useOptimized = true);

	/* 将一块数据直接复制到framebuffer,执行指定的alpha混合(和透明度键控)。  
	 * 如果HAL不支持BLIT_COPY_WITH_ALPHA且alpha不等于255(不透明),则执行软件混合。   
	 * @param  sourceData           源数组指针(指向数据的开始)。sourceData必须以适合所选显示的格式存储。  
	 * @param  source               源的位置和尺寸。此矩形的x和y都应为0。  
	 * @param  blitRect             一个矩形,描述要从sourceData中复制到帧缓冲区的区域。  
	 * @param  alpha                用于混合的alpha值,范围从0=透明到255=不透明=无混合。  
	 * @param  hasTransparentPixels 如果为true,则此数据复制包含透明像素,并需要启用硬件支持。  
	 */
	virtual void blitCopy(const uint16_t* sourceData, const Rect& source, const Rect& blitRect, uint8_t alpha, bool hasTransparentPixels);

	/* 将一块数据直接复制到framebuffer,执行指定的alpha混合(和透明度键控)。  
	 * 如果HAL不支持BLIT_COPY_WITH_ALPHA且alpha小于255(不透明),则执行软件混合。    
	 * 如果显示器不支持指定的sourceFormat,将引发assert。  
	 * @param  sourceData           源数组指针(指向数据的开始)。sourceData必须以适合所选显示的格式存储。  
	 * @param  sourceFormat         源数据中使用的位图格式。  
	 * @param  source               源的位置和尺寸。此矩形的x和y都应为0。  
	 * @param  blitRect             一个矩形,描述要从\a sourceData中复制到帧缓冲区的区域。  
	 * @param  alpha                用于混合的alpha值,范围从0=透明到255=不透明=无混合。  
	 * @param  hasTransparentPixels 如果为true,则此数据复制包含透明像素,并需要启用硬件支持。  
	 */ 
	virtual void blitCopy(const uint8_t* sourceData, Bitmap::BitmapFormat sourceFormat, const Rect& source, const Rect& blitRect, uint8_t alpha, bool hasTransparentPixels);

	/* 将framebuffer的部分内容复制到位图的数据区。位图必须是动态位图或动画存储(BITMAP_ANIMATION_STORAGE)。  
	 * 给定的两个区域是可见区域和屏幕上的绝对区域。这用于只复制framebuffer的一部分。这可能是因为SnapshotWidget  
	 * 被放置在一个Container中,而SnapshotWidget的部分位于Container定义的区域之外。可见区域必须完全位于绝对区域内。  
	 *  
	 * @param  visRegion 可见区域。  
	 * @param  absRegion 绝对区域。  
	 * @param  bitmapId  位图的标识符。  
	 *  
	 * @return 如果失败则返回 Null,否则返回指向给定位图中数据的指针。  
	 *  
	 * @see blitCopy, copyFrameBufferRegionToMemory(const Rect&, const Rect&, uint8_t*, int16_t, int16_t)  
	 *  
	 * @note 动画存储只有一个实例。位图数据/动画存储在给定区域外的内容保持不变。  
	 */
	virtual uint16_t* copyFrameBufferRegionToMemory(const Rect& visRegion, const Rect& absRegion, const BitmapId bitmapId);

	/* 将framebuffer的部分内容复制到内存。假设内存具有与framebuffer相同的格式。给定的两个区域是可见区域和屏幕上的绝对区域。  
	 * 这用于只复制framebuffer的一部分。这可能是因为SnapshotWidget被放置在一个Container中,而SnapshotWidget的部分  
	 * 位于Container定义的区域之外。可见区域必须完全位于绝对区域内。  
	 *  
	 * @param           visRegion   可见区域。  
	 * @param           absRegion   绝对区域。  
	 * @param [in,out]  dst         与framebuffer格式相同的目标内存。  
	 * @param           dstWidth    目标的宽度。  
	 * @param           dstHeight   目标的高度。  
	 *  
	 * @return  实际复制到目标缓冲区的矩形区域。  
	 *  
	 * @see blitCopy, copyFrameBufferRegionToMemory(const Rect&, const Rect&, const BitmapId)  
	 *  
	 * @note    动画存储只有一个实例。位图数据/动画存储在给定区域外的内容保持不变。但是,请注意这个函数并不涉及动画存储或位图ID,它直接操作原始内存。  
	 */ 
	virtual Rect copyFrameBufferRegionToMemory(const Rect& visRegion, const Rect& absRegion, uint8_t* dst, int16_t dstWidth, int16_t dstHeight);

	/* 将显示的framebuffer的部分内容复制到当前framebuffer。给定的区域是屏幕上的绝对区域。  
	 *  
	 * @param  region		一个矩形,描述要从显示的framebuffer复制到当前framebuffer的区域。  
	 *  
	 * @note    复制仅在启用双缓冲时进行。否则,当前帧缓冲区中的给定区域保持不变。  
	 */
	virtual void copyAreaFromTFTToClientBuffer(const Rect& region);

	/* 在framebuffer中绘制一个填充的矩形,具有指定的颜色和透明度。默认情况下,矩形将绘制为一个实心框。  
	 * 可以通过指定alpha从0-255来绘制带有透明度的矩形。  
	 *  
	 * @param  rect  要绘制的矩形,使用绝对显示坐标。  
	 * @param  color 矩形的颜色。  
	 * @param  alpha (可选)矩形的透明度,从 0=不可见到 255=实心。  
	 *  
	 * @see fillBuffer  
	 */ 
	virtual void fillRect(const Rect& rect, colortype color, uint8_t alpha = 255);

	/* 在目标内存中使用指定的颜色和透明度绘制一个填充的矩形。  
	 * 目标内存必须具有与显示帧缓冲区相同的格式。  
	 * 默认情况下,矩形将被绘制为一个实心的盒子。  
	 * 通过指定从 0=不可见到 255=实心的 alpha 值,可以绘制带有透明度的矩形。  
	 *  
	 * @param [in]  destination 目标内存区域的起始地址。  
	 * @param       pixelStride 像素跨度,即一行中的像素数。  
	 * @param       rect        要填充的绝对坐标矩形。  
	 * @param       color       矩形的颜色。  
	 * @param       alpha       矩形的透明度,从 0=不可见到 255=实心。  
	 *  
	 * @note    对于每个字节包含多个像素的显示器(LCD1bpp,LCD2bpp 和 LCD4bpp),pixelStride 将向上舍入到最接近的整个字节。  
	 */  
	virtual void fillBuffer(uint8_t* const destination, uint16_t pixelStride, const Rect& rect, const colortype color, const uint8_t alpha);

	/* 显示屏每个像素使用的位数 */
	virtual uint8_t bitDepth() const
	{
		return 16;
	}

	/* 显示屏使用的framebuffer格式。  
	 * 返回值:一个Bitmap::BitmapFormat枚举值 */
	virtual Bitmap::BitmapFormat framebufferFormat() const
	{
		return Bitmap::RGB565;
	}

	/* framebuffer的跨度(以字节为单位)。从帧缓冲的一行开始到下一行的距离。  
	   返回值:帧缓冲一行的字节数 */
	virtual uint16_t framebufferStride() const
	{
		return getFramebufferStride();
	}

	/* framebuffer的跨度(以字节为单位)。从帧缓冲的一行开始到下一行的距离。  
	   返回值:帧缓冲一行的字节数 */
	FORCE_INLINE_FUNCTION static uint16_t getFramebufferStride()
	{
		assert(HAL::FRAME_BUFFER_WIDTH > 0 && "HAL has not been initialized yet");
		return HAL::FRAME_BUFFER_WIDTH * 2;
	}

	/* 根据24位RGB值生成用于LCD的颜色表示。  
	 *   
	 * @param  red   红色部分的值(0-255)。  
	 * @param  green 绿色部分的值(0-255)。  
	 * @param  blue  蓝色部分的值(0-255)。    
	 */
	FORCE_INLINE_FUNCTION static uint16_t getNativeColorFromRGB(uint8_t red, uint8_t green, uint8_t blue)
	{
		return ((red << 8) & 0xF800) | ((green << 3) & 0x07E0) | ((blue >> 3) & 0x001F);
	}

	/* 根据24位颜色值生成用于LCD的颜色表示 */
	FORCE_INLINE_FUNCTION static uint16_t getNativeColor(colortype color)
	{
		return ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | ((color >> 3) & 0x001F);
	}

	/* 为所有图像格式启用纹理映射器。这允许使用双线性插值和最近邻算法绘制任何图像,但可能会使用大量内存来执行绘制算法 */
	void enableTextureMapperAll();

	/**
	 * Enables the texture mappers for L8_RGB565 image format. This allows drawing L8_RGB565
	 * images using Bilinear Interpolation and Nearest Neighbor algorithms.
	 *
	 * @see enableTextureMapperL8_RGB565_BilinearInterpolation,
	 *      enableTextureMapperL8_RGB565_NearestNeighbor
	 */
	void enableTextureMapperL8_RGB565();

	/**
	 * Enables the texture mappers for L8_RGB565 image format. This allows drawing L8_RGB565
	 * images using Bilinear Interpolation algorithm.
	 *
	 * @see enableTextureMapperL8_RGB565, enableTextureMapperL8_RGB565_NearestNeighbor
	 */
	void enableTextureMapperL8_RGB565_BilinearInterpolation();

	/**
	 * Enables the texture mappers for L8_RGB565 image format. This allows drawing L8_RGB565
	 * images using Nearest Neighbor algorithm.
	 *
	 * @see enableTextureMapperL8_RGB565, enableTextureMapperL8_RGB565_BilinearInterpolation
	 */
	void enableTextureMapperL8_RGB565_NearestNeighbor();

	/**
	 * Enables the texture mappers for L8_RGB888 image format. This allows drawing L8_RGB888
	 * images using Bilinear Interpolation and Nearest Neighbor algorithms.
	 *
	 * @see enableTextureMapperL8_RGB888_BilinearInterpolation,
	 *      enableTextureMapperL8_RGB888_NearestNeighbor
	 */
	void enableTextureMapperL8_RGB888();

	/**
	 * Enables the texture mappers for L8_RGB888 image format. This allows drawing L8_RGB888
	 * images using Bilinear Interpolation algorithm.
	 *
	 * @see enableTextureMapperL8_RGB888, enableTextureMapperL8_RGB888_NearestNeighbor
	 */
	void enableTextureMapperL8_RGB888_BilinearInterpolation();

	/**
	 * Enables the texture mappers for L8_RGB888 image format. This allows drawing L8_RGB888
	 * images using Nearest Neighbor algorithm.
	 *
	 * @see enableTextureMapperL8_RGB888, enableTextureMapperL8_RGB888_BilinearInterpolation
	 */
	void enableTextureMapperL8_RGB888_NearestNeighbor();

	/**
	 * Enables the texture mappers for L8_ARGB8888 image format. This allows drawing
	 * L8_ARGB8888 images using Bilinear Interpolation and Nearest Neighbor algorithms.
	 *
	 * @see enableTextureMapperL8_ARGB8888_BilinearInterpolation,
	 *      enableTextureMapperL8_ARGB8888_NearestNeighbor
	 */
	void enableTextureMapperL8_ARGB8888();

	/**
	 * Enables the texture mappers for L8_ARGB8888 image format. This allows drawing
	 * L8_ARGB8888 images using Bilinear Interpolation algorithm.
	 *
	 * @see enableTextureMapperL8_ARGB8888, enableTextureMapperL8_ARGB8888_NearestNeighbor
	 */
	void enableTextureMapperL8_ARGB8888_BilinearInterpolation();

	/**
	 * Enables the texture mappers for L8_ARGB8888 image format. This allows drawing
	 * L8_ARGB8888 images using Nearest Neighbor algorithm.
	 *
	 * @see enableTextureMapperL8_ARGB8888, enableTextureMapperL8_ARGB8888_BilinearInterpolation
	 */
	void enableTextureMapperL8_ARGB8888_NearestNeighbor();

	/**  
	 * 启用RGB565图像格式的纹理映射器。这允许使用双线性插值和最近邻算法绘制RGB565图像。  
	 *   
	 * @see enableTextureMapperRGB565_Opaque_BilinearInterpolation,  
	 *      enableTextureMapperRGB565_Opaque_NearestNeighbor,  
	 *      enableTextureMapperRGB565_NonOpaque_BilinearInterpolation,  
	 *      enableTextureMapperRGB565_NonOpaque_NearestNeighbor  
	 */
	void enableTextureMapperRGB565();

	/* 启用不透明RGB565图像格式的双线性插值纹理映射器。这允许使用双线性插值算法绘制RGB565图像 */  
	void enableTextureMapperRGB565_Opaque_BilinearInterpolation();

	/* 启用非不透明RGB565图像格式的双线性插值纹理映射器。这允许使用双线性插值算法绘制RGB565图像 */
	void enableTextureMapperRGB565_NonOpaque_BilinearInterpolation();

	/* 启用不透明RGB565图像格式的最近邻纹理映射器。这允许使用最近邻算法绘制RGB565图像 */
	void enableTextureMapperRGB565_Opaque_NearestNeighbor();

	/* 启用非不透明RGB565图像格式的最近邻纹理映射器。这允许使用最近邻算法绘制RGB565图像 */
	void enableTextureMapperRGB565_NonOpaque_NearestNeighbor();

	/**
	 * Enables the texture mappers for ARGB8888 image format. This allows drawing ARGB8888
	 * images using Bilinear Interpolation and Nearest Neighbor algorithms.
	 *
	 * @see enableTextureMapperARGB8888_BilinearInterpolation,
	 *      enableTextureMapperARGB8888_NearestNeighbor
	 */
	void enableTextureMapperARGB8888();

	/**
	 * Enables the texture mappers for ARGB8888 image format. This allows drawing ARGB8888
	 * images using Bilinear Interpolation algorithm.
	 *
	 * @see enableTextureMapperARGB8888, enableTextureMapperARGB8888_NearestNeighbor
	 */
	void enableTextureMapperARGB8888_BilinearInterpolation();

	/**
	 * Enables the texture mappers for ARGB8888 image format. This allows drawing ARGB8888
	 * images using Nearest Neighbor algorithm.
	 *
	 * @see enableTextureMapperARGB8888, enableTextureMapperARGB8888_BilinearInterpolation
	 */
	void enableTextureMapperARGB8888_NearestNeighbor();

	/**
	 * Enables the texture mappers for A4 image format. This allows drawing A4 images using
	 * Bilinear Interpolation and Nearest Neighbor algorithms.
	 *
	 * @see enableTextureMapperA4_BilinearInterpolation, enableTextureMapperA4_NearestNeighbor
	 */
	void enableTextureMapperA4();

	/**
	 * Enables the texture mappers for A4 image format. This allows drawing A4 images using
	 * Bilinear Interpolation algorithm.
	 *
	 * @see enableTextureMapperA4, enableTextureMapperA4_NearestNeighbor
	 */
	void enableTextureMapperA4_BilinearInterpolation();

	/**
	 * Enables the texture mappers for A4 image format. This allows drawing A4 images using
	 * Nearest Neighbor algorithm.
	 *
	 * @see enableTextureMapperA4, enableTextureMapperA4_BilinearInterpolation
	 */
	void enableTextureMapperA4_NearestNeighbor();

	/**
	 * Enables all the decompressors available for L8 images (L4, RLE and LZW9).
	 * This allows drawing L4, RLE and LZW9 compressed L8 images.
	 *
	 * @see enableDecompressorL8_L4, enableDecompressorL8_RLE, enableDecompressorL8_LZW9
	 */
	void enableDecompressorL8_All();

	/**
	 * Enables the decompressor for L8 images compressed with the L4 algorithm.
	 * This allows drawing L4 compressed L8 images.
	 */
	void enableDecompressorL8_L4();

	/**
	 * Enables the decompressor for L8 images compressed with the RLE algorithm.
	 * This allows drawing RLE compressed L8 images.
	 */
	void enableDecompressorL8_RLE();

	/**
	 * Enables the decompressor for L8 images compressed with the LZW9 algorithm.
	 * This allows drawing LZW9 compressed L8 images.
	 */
	void enableDecompressorL8_LZW9();

protected:
	/**  
	 * 获取可以绘制扫描线的对象的指针,该对象允许进行高度专门化和优化的实现。  
	 *   
	 * @param  texture       要使用的纹理表面。  
	 * @param  renderVariant 渲染变体。  
	 * @param  alpha         全局透明度。  
	 *   
	 * @return 如果失败,返回Null;否则,返回指向纹理映射器绘制扫描线对象的指针。  
	 */ 
	virtual DrawTextureMapScanLineBase* getTextureMapperDrawScanLine(const TextureSurface& texture, RenderingVariant renderVariant, uint8_t alpha);

	/* 计算在显示缓冲区中前进多少以到达下一个像素。  
	 *   
	 * @param rotatedDisplay 显示器是否以纵向模式运行。  
	 * @param textRotation   要执行的旋转。  
	 *   
	 * @return 前进多少以到达下一个像素。  
	 */
	static int nextPixel(bool rotatedDisplay, TextRotation textRotation);

	/**  
	 * 计算在显示缓冲区中前进多少以到达下一行。  
	 *   
	 * @param rotatedDisplay 显示器是否以纵向模式运行。  
	 * @param textRotation   要执行的旋转。  
	 *   
	 * @return 前进多少以到达下一行。  
	 */
	static int nextLine(bool rotatedDisplay, TextRotation textRotation);

	/**  
	 * 带有显式目标缓冲区指针参数的drawString()函数的私有版本的draw-glyph。  
	 * 对于除缓冲区指针外的所有参数,请参阅公共函数drawString()。  
	 *   
	 * @param [out] wbuf16          要绘制到的目标(帧)缓冲区。  
	 * @param       widgetArea      要在其内部绘制字形的画布。  
	 * @param       x               水平偏移量,开始绘制字形的位置。  
	 * @param       y               垂直偏移量,开始绘制字形的位置。  
	 * @param       offsetX         在字形中的水平偏移量,开始绘制的位置。  
	 * @param       offsetY         在字形中的垂直偏移量,开始绘制的位置。  
	 * @param       invalidatedArea 要在其中绘制的区域。  
	 * @param       glyph           要绘制的字形的规格。  
	 * @param       glyphData       包含实际字形的数据(密集格式)  
	 * @param       byteAlignRow    每个字形数据行从新的字节开始。  
	 * @param       color           字形的颜色。  
	 * @param       bitsPerPixel    字形的位深度。  
	 * @param       alpha           字形的透明度。  
	 * @param       rotation        绘制字形之前的旋转操作。  
	 */
	virtual void drawGlyph(uint16_t* wbuf16, Rect widgetArea, int16_t x, int16_t y, uint16_t offsetX, uint16_t offsetY, const Rect& invalidatedArea, const GlyphNode* glyph, const uint8_t* glyphData, uint8_t byteAlignRow, colortype color, uint8_t bitsPerPixel, uint8_t alpha, TextRotation rotation);

	/**
	 * Blits a 2D source-array to the framebuffer performing alpha-blending per pixel as
	 * specified. If ARGB8888 is not supported by the DMA a software blend is performed.
	 *
	 * @param  sourceData The source-array pointer (points to the beginning of the data). The
	 *                    sourceData must be stored as 32 bits ARGB8888 values.
	 * @param  source     The location and dimensions of the source.
	 * @param  blitRect   A rectangle describing what region is to be drawn.
	 * @param  alpha      The alpha value to use for blending applied to the whole image (255 =
	 *                    solid, no blending)
	 */
	static void blitCopyARGB8888(const uint32_t* sourceData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**
	 * Blits a 2D source-array to the framebuffer never performing alpha-blending per pixel as
	 * because it is assumed that all pixels in the bitmap are solid (i.e. alpha for each pixel is
	 * 255).
	 *
	 * @param   sourceData  The source-array pointer (points to the beginning of the data). The
	 *                      sourceData must be stored as 32 bits ARGB8888 values.
	 * @param   source      The location and dimensions of the source.
	 * @param   blitRect    A rectangle describing what region is to be drawn.
	 */
	void blitCopyARGB8888Solid(const uint32_t* sourceData, const Rect& source, const Rect& blitRect) const;

	/**
	 * Blits a 2D source-array to the framebuffer performing alpha-blending per pixel as specified.
	 * If RGB888 is not supported by the DMA a software blend is performed.
	 *
	 * @param   sourceData  The source-array pointer (points to the beginning of the data). The
	 *                      sourceData must be stored as 24 bits RGB888 values.
	 * @param   source      The location and dimensions of the source.
	 * @param   blitRect    A rectangle describing what region is to be drawn.
	 * @param   alpha       The alpha value to use for blending applied to the whole image (255 =
	 *                      solid, no blending)
	 */
	static void blitCopyRGB888(const uint8_t* sourceData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**
	 * Blits a 2D indexed 8-bit source to the framebuffer performing alpha-blending per
	 * pixel as specified if indexed format is not supported by the DMA a software blend is
	 * performed.
	 *
	 * @param  sourceData The source-indexes pointer (points to the beginning of the data). The
	 *                    sourceData must be stored as 8- bits indexes.
	 * @param  clutData   The source-clut pointer (points to the beginning of the CLUT color
	 *                    format and size data followed by colors entries.
	 * @param  source     The location and dimensions of the source.
	 * @param  blitRect   A rectangle describing what region is to be drawn.
	 * @param  alpha      The alpha value to use for blending applied to the whole image (255 =
	 *                    solid, no blending)
	 */
	void blitCopyL8(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**
	 * Blits a 2D indexed 8-bit source to the framebuffer performing alpha-blending per
	 * pixel as specified if L8_ARGB8888 is not supported by the DMA a software blend is
	 * performed.
	 *
	 * @param  sourceData The source-indexes pointer (points to the beginning of the data). The
	 *                    sourceData must be stored as 8- bits indexes.
	 * @param  clutData   The source-clut pointer (points to the beginning of the CLUT color
	 *                    format and size data followed by colors entries stored as 32-
	 *                    bits (ARGB8888) format.
	 * @param  source     The location and dimensions of the source.
	 * @param  blitRect   A rectangle describing what region is to be drawn.
	 * @param  alpha      The alpha value to use for blending applied to the whole image (255 =
	 *                    solid, no blending)
	 */
	static void blitCopyL8_ARGB8888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**
	 * Blits a 2D indexed 8-bit source to the framebuffer performing alpha-blending per
	 * pixel as specified if L8_RGB565 is not supported by the DMA a software blend is
	 * performed.
	 *
	 * @param  sourceData The source-indexes pointer (points to the beginning of the data). The
	 *                    sourceData must be stored as 8- bits indexes.
	 * @param  clutData   The source-clut pointer points to the beginning of the CLUT color
	 *                    format and size data followed by colors entries stored as 16-
	 *                    bits (RGB565) format. If the source have per pixel alpha
	 *                    channel, then alpha channel data will be following the clut
	 *                    entries data.
	 * @param  source     The location and dimensions of the source.
	 * @param  blitRect   A rectangle describing what region is to be drawn.
	 * @param  alpha      The alpha value to use for blending applied to the whole image (255 =
	 *                    solid, no blending)
	 */
	static void blitCopyL8_RGB565(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**
	 * Blits a 2D indexed 8-bit source to the framebuffer performing alpha-blending per
	 * pixel as specified if L8_RGB888 is not supported by the DMA a software blend is
	 * performed.
	 *
	 * @param  sourceData The source-indexes pointer (points to the beginning of the data). The
	 *                    sourceData must be stored as 8- bits indexes.
	 * @param  clutData   The source-clut pointer (points to the beginning of the CLUT color
	 *                    format and size data followed by colors entries stored as 32-
	 *                    bits (ARGB8888) format.
	 * @param  source     The location and dimensions of the source.
	 * @param  blitRect   A rectangle describing what region is to be drawn.
	 * @param  alpha      The alpha value to use for blending applied to the whole image (255 =
	 *                    solid, no blending)
	 */
	static void blitCopyL8_RGB888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

	/**  
	 * 将2D源数组复制到帧缓冲区,并执行每个像素的alpha混合。总是执行软件混合。  
	 *   
	 * @param sourceData    源数组指针(指向数据开始的位置)。sourceData必须存储为16位的RGB565值。  
	 * @param alphaData     alpha通道数组指针(指向数据开始的位置)。  
	 * @param source        源的位置和尺寸。  
	 * @param blitRect      描述要绘制的区域的矩形。  
	 * @param alpha         用于混合的alpha值(255 = 实体,无混合)。  
	 */
	static void blitCopyAlphaPerPixel(const uint16_t* sourceData, const uint8_t* alphaData, const Rect& source, const Rect& blitRect, uint8_t alpha);

private:
	// 以下是一系列指向不同纹理映射器对象的指针,这些对象用于执行实际的绘图操作
	DrawTextureMapScanLineBase* textureMapper_L8_RGB565_Opaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB565_Opaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB565_Opaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB565_Opaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB888_Opaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB888_Opaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB888_Opaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_RGB888_Opaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_L8_ARGB8888_NonOpaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_ARGB8888_NonOpaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_L8_ARGB8888_NonOpaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_L8_ARGB8888_NonOpaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_NonOpaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_NonOpaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_Opaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_Opaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_NonOpaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_NonOpaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_Opaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_RGB565_Opaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_ARGB8888_NonOpaque_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_ARGB8888_NonOpaque_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_ARGB8888_NonOpaque_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_ARGB8888_NonOpaque_BilinearInterpolation_NoGA;
	DrawTextureMapScanLineBase* textureMapper_A4_NearestNeighbor_GA;
	DrawTextureMapScanLineBase* textureMapper_A4_NearestNeighbor_NoGA;
	DrawTextureMapScanLineBase* textureMapper_A4_BilinearInterpolation_GA;
	DrawTextureMapScanLineBase* textureMapper_A4_BilinearInterpolation_NoGA;

	// 将16位RGB565颜色值扩展为32位颜色值
	FORCE_INLINE_FUNCTION static uint32_t expandRgb565(uint16_t c)
	{
		return ((c & 0x07E0) << 16) | (c & ~0x07E0);
	}

	// 将32位颜色值压缩为16位RGB565颜色值
	FORCE_INLINE_FUNCTION static uint16_t compactRgb565(uint32_t c)
	{
		return ((c >> 16) & 0x07E0) | (c & ~0x07E0);
	}

	// 以下函数执行双线性插值以计算RGB565颜色值
	FORCE_INLINE_FUNCTION static uint16_t bilinearInterpolate565(uint16_t c00, uint16_t c10, uint16_t c01, uint16_t c11, uint8_t x, uint8_t y)
	{
		assert(x < 16 && y < 16);
		uint32_t a00 = expandRgb565(c00);
		uint32_t a10 = expandRgb565(c10);
		uint32_t a01 = expandRgb565(c01);
		uint32_t a11 = expandRgb565(c11);

		uint8_t xy = (x * y) >> 3;
		return compactRgb565((a00 * (32 - 2 * y - 2 * x + xy) + a10 * (2 * x - xy) + a01 * (2 * y - xy) + a11 * xy) >> 5);
	}

	/**  
	 * 使用双线性插值计算两个16位RGB565颜色值之间的插值。  
	 *   
	 * @param c00 第一个颜色值  
	 * @param c10 第二个颜色值  
	 * @param x 插值因子,预期小于16  
	 *   
	 * @return 插值后的颜色值  
	 */ 
	FORCE_INLINE_FUNCTION static uint16_t bilinearInterpolate565(uint16_t c00, uint16_t c10, uint8_t x)
	{
		assert(x < 16);
		uint32_t a00 = expandRgb565(c00);
		uint32_t a10 = expandRgb565(c10);

		return compactRgb565((a00 * (32 - 2 * x) + a10 * (2 * x)) >> 5);
	}
	
	FORCE_INLINE_FUNCTION static uint8_t bilinearInterpolate8(uint8_t c00, uint8_t c10, uint8_t x)
	{
		assert(x < 16);
		uint16_t xy10 = 16 * x;
		uint16_t xy00 = 256 - xy10;

		return (c00 * xy00 + c10 * xy10) >> 8;
	}

	FORCE_INLINE_FUNCTION static uint8_t bilinearInterpolate8(uint8_t c00, uint8_t c10, uint8_t c01, uint8_t c11, uint8_t x, uint8_t y)
	{
		assert(x < 16 && y < 16);
		uint16_t xy11 = x * y;
		uint16_t xy10 = 16 * x - xy11;
		uint16_t xy01 = 16 * y - xy11;
		uint16_t xy00 = 256 - (xy11 + xy10 + xy01);

		return (c00 * xy00 + c10 * xy10 + c01 * xy01 + c11 * xy11) >> 8;
	}

	FORCE_INLINE_FUNCTION static uint32_t bilinearInterpolate888(uint32_t c00, uint32_t c10, uint8_t x)
	{
		assert(x < 16);
		uint16_t xy10 = 16 * x;
		uint16_t xy00 = 256 - xy10;

		return ((((c00 & 0xFF00FF) * xy00 + (c10 & 0xFF00FF) * xy10) >> 8) & 0xFF00FF) |
					 ((((c00 & 0x00FF00) * xy00 + (c10 & 0x00FF00) * xy10) >> 8) & 0x00FF00);
	}

	FORCE_INLINE_FUNCTION static uint32_t bilinearInterpolate888(uint32_t c00, uint32_t c10, uint32_t c01, uint32_t c11, uint8_t x, uint8_t y)
	{
		assert(x < 16 && y < 16);
		uint16_t xy11 = x * y;
		uint16_t xy10 = 16 * x - xy11;
		uint16_t xy01 = 16 * y - xy11;
		uint16_t xy00 = 256 - (xy11 + xy10 + xy01);

		return ((((c00 & 0xFF00FF) * xy00 + (c10 & 0xFF00FF) * xy10 + (c01 & 0xFF00FF) * xy01 + (c11 & 0xFF00FF) * xy11) >> 8) & 0xFF00FF) |
					 ((((c00 & 0x00FF00) * xy00 + (c10 & 0x00FF00) * xy10 + (c01 & 0x00FF00) * xy01 + (c11 & 0x00FF00) * xy11) >> 8) & 0x00FF00);
	}

	FORCE_INLINE_FUNCTION static uint32_t div255_888(uint32_t val, uint8_t factor)
	{
		return div255rb((val & 0xFF00FF) * factor) | div255g((val & 0x00FF00) * factor);
	}

	FORCE_INLINE_FUNCTION static uint32_t div255_888_FFcheck(uint32_t val, uint8_t factor)
	{
		return factor < 0xFF ? div255_888(val, factor) : val;
	}

	/**  
	 * 对RGB565颜色值的红色或蓝色分量执行特定的除法运算。  
	 *   
	 * @param val 输入值  
	 * @param factor 除数因子  
	 *   
	 * @return 运算结果  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div31rb(uint16_t val, uint8_t factor)
	{
		uint32_t val32 = (val & 0xF81F) * (factor >> 3);
		return ((val32 + 0x0801 + ((val32 >> 5) & 0xF81F)) >> 5) & 0xF81F;
	}

	/**  
	 * 对RGB565颜色值的绿色分量执行特定的除法运算。  
	 *   
	 * @param val 输入值  
	 * @param factor 除数因子  
	 *   
	 * @return 运算结果  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div31g(uint16_t val, uint8_t factor)
	{
		uint32_t val32 = (val & 0x07E0) * factor;
		return ((val32 + 0x0020 + (val32 >> 8)) >> 8) & 0x07E0;
	}

	/**  
	 * 对RGB565颜色值执行特定的除法运算,同时处理红色和蓝色分量以及绿色分量。  
	 *   
	 * @param val 输入值  
	 * @param factor 除数因子  
	 *   
	 * @return 运算结果  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div255_565(uint16_t val, uint8_t factor)
	{
		return div31rb(val, factor) | div31g(val, factor);
	}

	/**  
	 * 对RGB565颜色值执行特定的除法运算,同时处理红色和蓝色分量以及绿色分量。  
	 * 如果因子小于0xFF,则执行除法;否则直接返回原始值。  
	 *   
	 * @param val 输入值  
	 * @param factor 除数因子  
	 *   
	 * @return 运算结果或原始值  
	 */
	FORCE_INLINE_FUNCTION static uint32_t div255_565_FFcheck(uint16_t val, uint8_t factor)
	{
		return factor < 0xFF ? div31rb(val, factor) | div31g(val, factor) : val;
	}

	/**  
	 * DrawTextureMapScanLineBase16类,作为处理纹理映射扫描线的基础类。  
	 * 包含一些受保护的成员函数,用于处理纹理坐标的超出范围检查。  
	 */
	class DrawTextureMapScanLineBase16 : public DrawTextureMapScanLineBase
	{
		protected:
			/**  
			 * 检查最近邻插值时的纹理坐标是否超出范围。  
			 *   
			 * @param 参数列表包括目标位、要绘制的像素数、纹理坐标等。  
			 *   
			 * @return 如果超出范围,则进行适当的处理并返回true;否则返回false。  
			 * 注意:此函数的实际参数和返回值可能根据实现的具体需求而有所不同。  
			 */
			FORCE_INLINE_FUNCTION bool overrunCheckNearestNeighbor(uint16_t*& destBits, int& pixelsToDraw, fixed16_16& U, fixed16_16& V, fixed16_16 deltaU, fixed16_16 deltaV, const int16_t maxWidth, const int16_t maxHeight) const;
		
			/**  
			 * 检查双线性插值时的纹理坐标是否超出范围。  
			 *   
			 * @param 参数列表类似于overrunCheckNearestNeighbor函数。  
			 *   
			 * @return 如果超出范围,则进行适当的处理并返回true;否则返回false。  
			 * 注意:此函数的实际参数和返回值可能根据实现的具体需求而有所不同。  
			 */
			FORCE_INLINE_FUNCTION bool overrunCheckBilinearInterpolation(uint16_t*& destBits, int& pixelsToDraw, fixed16_16& U, fixed16_16& V, fixed16_16 deltaU, fixed16_16 deltaV, const int16_t maxWidth, const int16_t maxHeight) const;
	};

	class TextureMapper_L8_RGB565_Opaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	class TextureMapper_L8_RGB565_Opaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
		public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

		private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	class TextureMapper_L8_RGB565_Opaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	class TextureMapper_L8_RGB565_Opaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint16_t* const palette16, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	class TextureMapper_L8_RGB888_Opaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	class TextureMapper_L8_RGB888_Opaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	class TextureMapper_L8_RGB888_Opaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	class TextureMapper_L8_RGB888_Opaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint8_t* const palette8, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	class TextureMapper_L8_ARGB8888_NonOpaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	class TextureMapper_L8_ARGB8888_NonOpaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	class TextureMapper_L8_ARGB8888_NonOpaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	class TextureMapper_L8_ARGB8888_NonOpaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const textureBits8, const uint32_t* const palette32, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	/* TextureMapper_RGB565_NonOpaque_NearestNeighbor_GA类,用于处理非不透明纹理的最近邻插值,考虑全局Alpha */
	class TextureMapper_RGB565_NonOpaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			/**  
			 * 绘制纹理映射扫描线的子分区,使用最近邻插值和全局Alpha混合。  
			 *   
			 * @param 参数列表包括子分区数、宽度模长度、要绘制的像素数等。以及目标表面、纹理表面和混合因子等信息。  
			 * 注意:此函数的实际参数可能根据实现的具体需求而有所不同。  
			 */
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			/**  
			 * 写入像素值到目标位图,考虑纹理位图和全局Alpha值。  
			 *   
			 * @param 参数列表包括目标位、纹理位、Alpha位和纹理坐标等信息。此函数为const,因为它不修改类的任何成员变量。  
			 * 注意:此函数的实际参数和返回值可能根据实现的具体需求而有所不同。并且由于此处为内联函数声明,函数体在类外部定义。  
			 */  
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const uint8_t* const alphaBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	/**  
	 * TextureMapper_RGB565_NonOpaque_NearestNeighbor_NoGA 类是一个纹理映射器,  
	 * 它使用最近邻插值和非透明混合模式(但没有全局透明度)在RGB565格式的显示器上绘制纹理。  
	 */ 
	class TextureMapper_RGB565_NonOpaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			/**  
			 * 绘制带有细分的纹理映射扫描线。  
			 * @param subdivisions      细分数量。  
			 * @param widthModLength    宽度模长(可能与纹理的平铺有关)。  
			 * @param pixelsToDraw      要绘制的像素数量。  
			 * @param affineLength      仿射长度(可能与纹理的变形有关)。  
			 * @param oneOverZRight     1/Z的右侧值(用于3D变换)。  
			 * @param UOverZRight       U/Z的右侧值(用于3D纹理坐标变换)。  
			 * @param VOverZRight       V/Z的右侧值(用于3D纹理坐标变换)。  
			 * @param U, V, deltaU, deltaV 等是与纹理坐标和它们的增量有关的参数。  
			 * @param dest              目标绘制表面。  
			 * @param destX, destY      目标坐标。  
			 * @param texture           纹理表面。  
			 * @param alpha             透明度值(尽管这个函数名中有NoGA,但参数列表中仍然有alpha,可能是代码的不一致或错误)。  
			 * @param dOneOverZdXAff 等是与仿射变换有关的参数。  
			 */ 
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			/**  
			 * 在目标缓冲区上写入一个像素,使用最近邻插值从纹理中采样颜色。  
			 * @param destBits      目标缓冲区的指针。  
			 * @param textureBits   纹理缓冲区的指针。  
			 * @param alphaBits     透明度缓冲区的指针(尽管类名中有NoGA,但这里仍然有这个参数,可能是代码的不一致或错误)。  
			 * @param bitmapWidth   位图的宽度。  
			 * @param UInt, VInt    整数部分的纹理坐标。  
			 */ 
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const uint8_t* alphaBits, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	/* 使用最近邻插值和不考虑全局alpha的RGB565纹理映射类 */
	class TextureMapper_RGB565_Opaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			/**  
			 * 绘制带有细分的纹理映射扫描线。  
			 *   
			 * @param subdivisions         细分数量  
			 * @param widthModLength      与宽度相关的模长度  
			 * @param pixelsToDraw        要绘制的像素数  
			 * @param affineLength        仿射长度  
			 * @param oneOverZRight       1/ZRight的值,用于透视校正  
			 * @param UOverZRight         U/ZRight的值,用于透视校正  
			 * @param VOverZRight         V/ZRight的值,用于透视校正  
			 * @param U, V, deltaU, deltaV 纹理坐标和增量  
			 * @param ULeft, VLeft, URight, VRight 纹理坐标的左右边界  
			 * @param ZRight              ZRight的值,用于透视校正  
			 * @param dest                目标绘制表面  
			 * @param destX, destY        目标绘制坐标  
			 * @param texture             纹理表面  
			 * @param alpha               全局alpha值(虽然此方法不考虑它)  
			 * @param d...                透视校正的增量和导数  
			 */
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			/**  
			 * 写入一个像素到目标位图中,使用最近邻插值。  
			 *   
			 * @param destBits       目标位图位  
			 * @param textureBits    纹理位图位  
			 * @param bitmapWidth    位图宽度  
			 * @param UInt, VInt     计算得到的纹理坐标的整数部分  
			 * @param alpha          全局alpha值(此方法不使用)  
			 */ 
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	// 这个类负责以不透明、最近邻插值的方式绘制RGB565纹理
	class TextureMapper_RGB565_Opaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			// 这个函数绘制带有多个细分的纹理映射扫描线
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			// 这个函数用于在给定的目标像素位置写入一个来自纹理的像素值
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	// 这个类负责以非不透明、双线性插值、带全局Alpha的方式绘制RGB565纹理
	class TextureMapper_RGB565_NonOpaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			// 这个函数绘制带有多个细分的纹理映射扫描线
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			// 这个函数用于在给定的目标像素位置写入一个双线性插值的纹理像素值,考虑alpha值
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const uint8_t* const alphaBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			
			// 当纹理坐标在纹理边界上时调用此函数
			void writePixelOnEdge(uint16_t* const destBits, const uint16_t* const textureBits, const uint8_t* const alphaBits, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	// 这个类负责以非不透明、双线性插值、不带全局Alpha的方式绘制RGB565纹理
	class TextureMapper_RGB565_NonOpaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			// 这个函数绘制带有多个细分的纹理映射扫描线
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			// 这个函数用于在给定的目标像素位置写入一个双线性插值的纹理像素值,不考虑全局alpha值
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t* const alphaBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			// 当纹理坐标在纹理边界上时调用此函数
			void writePixelOnEdge(uint16_t* const destBits, const uint8_t* const alphaBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	// 这个类负责以不透明、双线性插值、带全局Alpha的方式绘制RGB565纹理
	class TextureMapper_RGB565_Opaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			// 这个函数绘制带有多个细分的纹理映射扫描线
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			// 这个函数用于在给定的目标像素位置写入一个双线性插值的纹理像素值,虽然函数签名中包括alpha参数,但请注意这是不透明的绘制方式,所以alpha参数可能会被忽略
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			// 当纹理坐标在纹理边界上时调用此函数
			void writePixelOnEdge(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	/**  
	 * TextureMapper_RGB565_Opaque_BilinearInterpolation_NoGA类,继承自DrawTextureMapScanLineBase16类,  
	 * 是一个用于处理特定纹理映射和绘制的内部类。  
	 * 该类使用双线性插值算法,在不考虑全局透明度(NoGA)的情况下,处理RGB565格式的纹理数据。  
	 */
	class TextureMapper_RGB565_Opaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			/**  
			 * 绘制纹理映射扫描线的子划分。  
			 * 该函数负责根据提供的参数和纹理数据,在目标绘制表面上绘制纹理映射扫描线的子划分。  
			 *   
			 * @param subdivisions 子划分数量  
			 * @param widthModLength 宽度模长(可能与纹理的重复或平铺有关)  
			 * @param pixelsToDraw 要绘制的像素数量  
			 * @param affineLength 仿射长度(与仿射变换有关)  
			 * @param oneOverZRight 1除以右边的Z值(用于透视校正)  
			 * @param UOverZRight U除以右边的Z值(用于透视校正)  
			 * @param VOverZRight V除以右边的Z值(用于透视校正)  
			 * @param U 固定点数的U坐标  
			 * @param V 固定点数的V坐标  
			 * @param deltaU U坐标的增量  
			 * @param deltaV V坐标的增量  
			 * @param ULeft 左边的U坐标(浮点)  
			 * @param VLeft 左边的V坐标(浮点)  
			 * @param URight 右边的U坐标(浮点)  
			 * @param VRight 右边的V坐标(浮点)  
			 * @param ZRight 右边的Z坐标(浮点)  
			 * @param dest 目标绘制表面  
			 * @param destX 目标X坐标  
			 * @param destY 目标Y坐标  
			 * @param texture 纹理表面  
			 * @param alpha 透明度值(尽管类名中有Opaque,但函数参数中包含了alpha,这可能是一个设计错误或遗留参数)  
			 * @param dOneOverZdXAff 透视校正相关的参数(1/Z对X的导数)  
			 * @param dUOverZdXAff 透视校正相关的参数(U/Z对X的导数)  
			 * @param dVOverZdXAff 透视校正相关的参数(V/Z对X的导数)  
			 */
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			/**  
			 * 在目标缓冲区上写入一个像素,使用双线性插值从纹理中采样颜色。  
			 * 该函数是一个内联函数,用于优化性能。它负责根据提供的U和V坐标(及其分数部分)从纹理中采样颜色,并将结果写入目标缓冲区。  
			 *   
			 * @param destBits 目标缓冲区的指针(16位每像素格式)  
			 * @param textureBits 纹理缓冲区的指针(假设为RGB565格式)  
			 * @param bitmapWidth 位图的宽度(以像素为单位)  
			 * @param UInt U坐标的整数部分  
			 * @param VInt V坐标的整数部分  
			 * @param UFrac U坐标的分数部分(以8位表示)  
			 * @param VFrac V坐标的分数部分(以8位表示)  
			 * @const 该函数不会修改类的任何成员变量,因此被标记为const。  
			 */
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			
			/**  
			 * 在目标缓冲区边缘上写入一个像素,使用双线性插值从纹理中采样颜色。  
			 * 该函数与writePixel函数类似,但专门用于处理位于目标缓冲区边缘的像素。它可能包含一些额外的逻辑来处理边缘情况。  
			 *   
			 * @param destBits 目标缓冲区的指针(16位每像素格式)  
			 * @param textureBits 纹理缓冲区的指针(假设为RGB565格式)  
			 * @param bitmapWidth 位图的宽度(以像素为单位)  
			 * @param bitmapHeight 位图的高度(以像素为单位)  
			 * @param UInt U坐标的整数部分  
			 * @param VInt V坐标的整数部分  
			 * @param UFrac U坐标的分数部分(以8位表示)  
			 * @param VFrac V坐标的分数部分(以8位表示)  
			 * @const 该函数不会修改类的任何成员变量,因此被标记为const。  
			 */
			void writePixelOnEdge(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	class TextureMapper_ARGB8888_NonOpaque_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t alpha) const;
	};

	class TextureMapper_ARGB8888_NonOpaque_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int UInt, const int VInt) const;
	};

	class TextureMapper_ARGB8888_NonOpaque_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	class TextureMapper_ARGB8888_NonOpaque_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint32_t* const textureBits32, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	class TextureMapper_A4_NearestNeighbor_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t a4, const uint8_t alpha) const;
	};

	class TextureMapper_A4_NearestNeighbor_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint8_t a) const;
	};

	class TextureMapper_A4_BilinearInterpolation_GA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const uint32_t offset, const int16_t bitmapStride, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapStride, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac, const uint8_t alpha) const;
	};

	class TextureMapper_A4_BilinearInterpolation_NoGA : public DrawTextureMapScanLineBase16
	{
    public:
			virtual void drawTextureMapScanLineSubdivisions(int subdivisions, const int widthModLength, int pixelsToDraw, const int affineLength, float oneOverZRight, float UOverZRight, float VOverZRight, fixed16_16 U, fixed16_16 V, fixed16_16 deltaU, fixed16_16 deltaV, float ULeft, float VLeft, float URight, float VRight, float ZRight, const DrawingSurface& dest, const int destX, const int destY, const TextureSurface& texture, uint8_t alpha, const float dOneOverZdXAff, const float dUOverZdXAff, const float dVOverZdXAff);

    private:
			FORCE_INLINE_FUNCTION void writePixel(uint16_t* const destBits, const uint16_t* const textureBits, const uint32_t offset, const int16_t bitmapStride, const uint8_t UFrac, const uint8_t VFrac) const;
			void writePixelOnEdge(uint16_t* const destBits, const uint16_t* const textureBits, const int16_t bitmapStride, const int16_t bitmapWidth, const int16_t bitmapHeight, const int UInt, const int VInt, const uint8_t UFrac, const uint8_t VFrac) const;
	};

	class DecompressorL8Base
	{
    public:
			virtual ~DecompressorL8Base()
			{
			}

			virtual void blitCopyRGB565(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha) = 0;
			virtual void blitCopyARGB8888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha) = 0;
			virtual void blitCopyRGB888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha) = 0;
	};

	class DecompressorL8_L4 : public DecompressorL8Base
	{
    public:
			virtual void blitCopyRGB565(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyARGB8888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyRGB888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

    private:
			uint16_t blendPixelRGB565(uint16_t imagePixel, uint16_t fbPixel, int alpha, int ialpha) const;
			uint16_t blendPixelARGB8888(uint32_t imagePixel, uint16_t fbPixel, int alpha, uint8_t alphapix) const;
			uint16_t blendPixelRGB888(const uint8_t* imagePixel, uint16_t fbPixel, uint8_t alpha, uint8_t ialpha) const;
	};

	class DecompressorL8_RLE : public DecompressorL8Base
	{
    public:
			virtual void blitCopyRGB565(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyARGB8888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyRGB888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

    private:
			static const uint16_t BLOCK_SIZE = 1024U;
	};

	class DecompressorL8_LZW9 : public DecompressorL8Base
	{
    public:
			virtual void blitCopyRGB565(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyARGB8888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);
			virtual void blitCopyRGB888(const uint8_t* sourceData, const uint8_t* clutData, const Rect& source, const Rect& blitRect, uint8_t alpha);

    private:
			static const uint16_t MAX_DICT_SIZE = 512U;
			static const uint16_t BLOCK_SIZE = 1024U;

			LZW9DictionaryEntry lzw9Dictionary[MAX_DICT_SIZE];
			uint8_t entryBuffer[64]; // Having 64byte max entry sizes entails 1 + 2 + ... + 63 + 64 = 2080px size image blocks
	};

	DecompressorL8Base *decompressorL8_L4;
	DecompressorL8Base *decompressorL8_RLE;
	DecompressorL8Base *decompressorL8_LZW9;
};

}

#endif

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值