资讯动态

ReactOS 图形系统分析(27):拉伸与透明传输 — stretchblt.c / transblt.c

发布时间:2026/8/15 14:52:28 来源:尧图企业网站定制
ReactOS 图形系统分析27拉伸与透明传输 — stretchblt.c / transblt.c1. 概述stretchblt.c与transblt.c位于win32ss/gdi/eng/实现两种位块传输变体文件功能核心函数[stretchblt.c](file:///d:/reactos/win32ss/gdi/eng/stretchblt.c)拉伸位块传输StretchBlt缩放 翻转复制可带掩码/图案/ROPEngStretchBltROP/EngStretchBlt/IntEngStretchBlt/NtGdiEngStretchBlt[transblt.c](file:///d:/reactos/win32ss/gdi/eng/transblt.c)透明传输TransparentBlt指定透明色像素不写入目标EngTransparentBlt/IntEngTransparentBlt二者延续引擎渲染范式参数校验 →IntEngEnter/Leave设备表面桥梁 → 裁剪三档分发 → DIB 函数表但各有独特难点应用 StretchBlt / TransparentBlt ↓ gdi32 → NtGdiStretchBlt / NtGdiTransparentBlt ntgdi/bitblt.cDC 处理、内存位图暂存 ↓ IntEngStretchBlt / IntEngTransparentBlt驱动挂钩优先 HOOK_STRETCHBLTROP / HOOK_TRANSPARENTBLT ? → DrvStretchBltROP / DrvTransparentBlt 否则 ↓ EngStretchBltROP / EngTransparentBlt ├─ 翻转语义解码DestRect 坐标符号 → bLeftToRight/bTopToBottom ├─ 裁剪rclBounds 裁剪 三档分发源矩形按比例换算 └─ DIB_StretchBlt / DIB_TransparentBltDIB 引擎按位深实现2. 拉伸位块传输 — stretchblt.c2.1 翻转语义文件头注释的核心设计StretchBlt 的prclDest/prclSrc矩形坐标可能顺序颠倒来表示翻转。为避免改动内部函数参数表用矩形坐标相对位置编码翻转状态!bTopToBottom !bLeftToRight → 无翻转正常矩形leftright, topbottom bTopToBottom → 上下翻转leftright, topbottom bLeftToRight → 左右翻转leftright, topbottom 两者都置 → 双重翻转leftright, topbottom判定cxSrc与cxDest符号相反 →bLeftToRightTRUEcySrc与cyDest符号相反 →bTopToBottomTRUE源/目标同向缩放不算翻转。2.2 IntEngStretchBlt — 挂钩分发 快路径引擎内部入口IntEngStretchBlt(psoDest,psoSource,MaskSurf,ClipRegion,...,Rop4){/* ① 16 种翻转组合预判Case0000 ~ Case1110cxSrc/cySrc/cxDest/cyDest 符号 */Case1110(cxDest0cyDest0cxSrc0cySrc0);.../* ② 等尺寸快路径源目标同大小时根本不需要拉伸 */if(|Dest 宽高||Source 宽高|){/* 按翻转组合修正 SourceRect/DestRect 方向后 直接转 IntEngBitBlt复用《分析_4》3.1 的 BitBlt 管线 */returnIntEngBitBlt(...);}/* ③ 负向源矩形归一化同时反转源/目标坐标并取绝对值等价变换 */if(cxSrc0){交换 SourceRect 左右;交换 DestRect 左右;cxSrc-cxSrc;cxDest-cxDest;}if(cySrc0){交换上下;...}/* ④ 各种翻转组合的 ±1 修正对齐 DIB 像素网格避免采样错位 */if(Case0010||Case0111)DestRect-left--;if(Case0000||Case0101)SourceRect/DestRect left/right.../* ⑤ 裁剪源矩形按裁剪偏移比例换算InputRect (InputW * Δ) / InputClW *//* ⑥ 驱动挂钩 → 软件兜底 */if(psurfDest-flagsHOOK_STRETCHBLTROP)retGDIDEVFUNCS(psoDest).StretchBltROP(...,COLORONCOLOR,pbo,Rop4);if(!ret)retEngStretchBltROP(...);// 软件实现}要点① 16 个Case*变量预计算所有源/目标符号组合②等尺寸时退化为普通 BitBlt最常用场景零额外开销③ 翻转归一化后再做 ±1 修正保证 DIB 采样与 Windows 一致这部分代码最复杂源于像素网格对齐的边界语义。2.3 EngStretchBltROP — 软件实现win32k 导出EngStretchBltROP(psoDest,psoSource,Mask,ClipRegion,ColorTranslation,pca,BrushOrigin,prclDest,prclSrc,MaskOrigin,Mode,pbo,Rop4){if(Rop4ROP4_NOOP)returnTRUE;// 空操作快退/* 翻转判定同 2.1 */bLeftToRight(cxSrc0)!(cxDest0);bTopToBottom(cySrc0)!(cyDest0);/* 源表面经 IntEngEnter 读入临时位图无源时构造全目标矩形 */if(UsesSource)IntEngEnter(es,psoSource,InputRect,TRUE,...);/* 先用裁剪 rclBounds 裁剪源/目标矩形保持比例 */if(ClipRegion){四边夹紧 OutputRect 并同步偏移 InputRect;}/* 裁剪三档分发同《分析_26》模式 */switch(clippingType){caseDC_TRIVIAL:/* 无裁剪按翻转交换 OutputRect 边 → CallDibStretchBlt 一次 */caseDC_RECT:/* 求交 InputToCombinedRect 按 Src/Dst 比例换算 → 一次 */caseDC_COMPLEX:/* 枚举矩形逐块同表面时按方向CD_RIGHTDOWN 等防自覆盖 */}IntEngLeave(...);}CallDibStretchBlt是 PSTRETCHRECTFUNC 分发函数处理图案画刷ROP4_USES_PATTERN 非纯色时BRUSHOBJ_psoPattern后调DibFunctionsForBitmapFormat[...].DIB_StretchBlt。EngStretchBlt是EngStretchBltROP的简化包装固定ROP4_SRCCOPY、pboNULLNtGdiEngStretchBlt是 UMPD 桩SEH 探测用户COLORADJUSTMENT/RECTL/POINTL后转发。3. 透明传输 — transblt.c3.1 EngTransparentBlt — 软件实现win32k 导出EngTransparentBlt(psoDest,psoSource,Clip,ColorTranslation,DestRect,SourceRect,iTransColor,Reserved){IntEngEnter(es,psoSource,InputRect,TRUE,...);// 读源/* 目标矩形规范化 裁剪 rclBounds 四边夹紧源按比例偏移 */if(OutputRect 退化)returnTRUE;// 无可绘制区域IntEngEnter(ed,psoDest,OutputRect,FALSE,...);// 写目标switch(ClippingType)// 裁剪三档{caseDC_TRIVIAL:DIB_TransparentBlt(OutputObj,InputObj,OutputRect,InputRect,...);caseDC_RECT:求交InputToCombinedRect 比例换算 → DIB_TransparentBlt;caseDC_COMPLEX:枚举矩形逐块同表面选方向失败即中断;}IntEngLeave(ed);IntEngLeave(es);}语义核心把源中颜色等于iTransColor经ColorTranslation转换后比较的像素跳过不写入目标——实现透明背景位图贴图。注意它是1 位透明要么画要么跳过不同于《分析_26》的 alpha 半透明。3.2 IntEngTransparentBlt — 驱动挂钩分发HOOK_TRANSPARENTBLT→DrvTransparentBlt否则EngTransparentBlt。调用方[ntgdi/bitblt.c](file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c#L297)NtGdiTransparentBlt先经内存位图暂存保证源/目标不重叠。4. 与《分析_4》标注对照标注核对《_4》第 49 行stretchblt.c/transblt.c 「拉伸/透明传输」准确。补充stretchblt 独特点是翻转语义编码DestRect 坐标符号与等尺寸退化为 BitBlt 的快路径transblt 是 1 位透明色抠图非 alpha5. 源码索引文件关键内容[stretchblt.c](file:///d:/reactos/win32ss/gdi/eng/stretchblt.c)EngStretchBltROP翻转裁剪三档CallDibStretchBlt、EngStretchBltSRCCOPY 包装、IntEngStretchBlt16 Case 翻转等尺寸快路径挂钩、NtGdiEngStretchBltUMPD 桩[transblt.c](file:///d:/reactos/win32ss/gdi/eng/transblt.c)EngTransparentBlt裁剪三档→DIB_TransparentBlt、IntEngTransparentBlt挂钩源矩形换算[ntgdi/bitblt.c](file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c#L166-L839)NtGdiStretchBlt/NtGdiTransparentBlt 入口StretchBlt/TransparentBlt API[dib/dib.h](file:///d:/reactos/win32ss/gdi/dib/dib.h)DIB_StretchBlt / DIB_TransparentBlt 函数指针[eng.h](file:///d:/reactos/win32ss/gdi/eng/eng.h)ROP4 宏ROP4_USES_SOURCE/PATTERN、ROP4_NOOP关联模块基础传输IntEngBitBlt等尺寸快路径复用《分析_4》3.1设备表面桥梁IntEngEnter/Leave《分析_25》7.1颜色转换XLATEOBJ_iXlate《分析_19》裁剪枚举CLIPOBJ_bEnum《分析_4》3.2图案画刷BRUSHOBJ_psoPatternengbrush.c6. 各函数作用和使用说明6.1 stretchblt.c6.1.1 IntEngStretchBlt — 拉伸传输入口引擎内部驱动挂钩快路径BOOLIntEngStretchBlt(SURFOBJ*psoDest,SURFOBJ*psoSource,SURFOBJ*MaskSurf,CLIPOBJ*ClipRegion,XLATEOBJ*ColorTranslation,COLORADJUSTMENT*pca,RECTL*DestRect,RECTL*SourceRect,POINTL*pMaskOrigin,BRUSHOBJ*pbo,POINTL*BrushOrigin,DWORD Rop4);使用要点引擎内部首选入口[ntgdi/bitblt.c](file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c#L805) 的 StretchBlt 路径调用。ClipRegion NULL时自动用全局平凡裁剪gxcoTrivial。等尺寸快路径源/目标大小相同含翻转时直接转IntEngBitBlt不走拉伸。内部完成16 种符号组合预判、负向矩形归一化、±1 像素对齐修正、裁剪源矩形换算。驱动挂钩HOOK_STRETCHBLTROP→DrvStretchBltROPCOLORONCOLOR未挂钩或失败 →EngStretchBltROP。返回 FALSE 表示失败ROP4须为合法值IS_VALID_ROP4断言。6.1.2 EngStretchBltROP — 拉伸软件实现win32k 导出BOOLEngStretchBltROP(SURFOBJ*psoDest,SURFOBJ*psoSource,SURFOBJ*Mask,CLIPOBJ*ClipRegion,XLATEOBJ*ColorTranslation,COLORADJUSTMENT*pca,POINTL*BrushOrigin,RECTL*prclDest,RECTL*prclSrc,POINTL*MaskOrigin,ULONG Mode,BRUSHOBJ*pbo,ROP4 Rop4);使用要点最完整的拉伸入口支持掩码、颜色转换、画刷图案、ROP4与翻转。Rop4 ROP4_NOOP直接返回 TRUE空操作。翻转语义由prclDest/prclSrc坐标符号隐式表达见 2.1——调用方可通过颠倒矩形坐标请求翻转。内部先按ClipRegion-rclBounds四边夹紧目标矩形并同步偏移源矩形再裁剪三档分发。DC_COMPLEX 且源目标时自动选枚举方向CD_RIGHTDOWN/CD_LEFTDOWN/...防止自覆盖。Mode参数如COLORONCOLOR当前未用于缩放算法DIB 引擎内部决定但按 DDI 约定须传入。6.1.3 EngStretchBlt — 简化包装win32k 导出BOOLEngStretchBlt(SURFOBJ*psoDest,SURFOBJ*psoSource,SURFOBJ*Mask,CLIPOBJ*ClipRegion,XLATEOBJ*ColorTranslation,COLORADJUSTMENT*pca,POINTL*BrushOrigin,RECTL*prclDest,RECTL*prclSrc,POINTL*MaskOrigin,ULONG Mode);使用要点固定ROP4_SRCCOPY、无画刷等价纯复制拉伸。适合驱动实现DrvStretchBlt时的软件回退效果等同EngStretchBltROP(..., NULL, ROP4_SRCCOPY)。6.1.4 NtGdiEngStretchBlt — UMPD 系统调用桩BOOLNtGdiEngStretchBlt(...,PRECTL prclDest,PRECTL prclSrc,POINTL*MaskOrigin,ULONG Mode);使用要点UMPD 用户模式驱动经 gdi32 → win32u 进入内核的入口。用ProbeForRead SEH 把用户COLORADJUSTMENT/POINTL/RECTL拷入内核栈再转发EngStretchBlt。仅供 UMPD 路径内核驱动直接用EngStretchBlt/EngStretchBltROP。6.1.5 CallDibStretchBlt — DIB 分发辅助内部静态staticBOOLEANCallDibStretchBlt(SURFOBJ*psoDest,SURFOBJ*psoSource,SURFOBJ*Mask,XLATEOBJ*ColorTranslation,RECTL*OutputRect,RECTL*InputRect,POINTL*MaskOrigin,BRUSHOBJ*pbo,POINTL*BrushOrigin,ROP4 Rop4);使用要点仅被EngStretchBltROP的裁剪三档调用PSTRETCHRECTFUNC 类型。处理图案画刷ROP4_USES_PATTERN且非纯色iSolidColor0xFFFFFFFF时取BRUSHOBJ_psoPattern取不到返回 FALSE。最终调DIB_StretchBlt进入 DIB 引擎按位深实现。6.2 transblt.c6.2.1 EngTransparentBlt — 透明传输软件实现win32k 导出BOOLEngTransparentBlt(SURFOBJ*psoDest,SURFOBJ*psoSource,CLIPOBJ*Clip,XLATEOBJ*ColorTranslation,PRECTL DestRect,PRECTL SourceRect,ULONG iTransColor,ULONG Reserved);参数说明iTransColor透明色源像素颜色经 ColorTranslation 转换后比较Reserved保留传 0使用要点源中颜色等于iTransColor的像素跳过不写1 位透明非 alpha。内部IntEngEnter读源/写目标自动支持设备表面。裁剪三档分发DC_COMPLEX 同表面时选枚举方向退化目标矩形直接返回 TRUE。返回 FALSE 表示失败含未识别的裁剪类型。6.2.2 IntEngTransparentBlt — 驱动挂钩分发内部BOOLIntEngTransparentBlt(SURFOBJ*psoDest,SURFOBJ*psoSource,CLIPOBJ*Clip,XLATEOBJ*ColorTranslation,PRECTL DestRect,PRECTL SourceRect,ULONG iTransColor,ULONG Reserved);使用要点引擎内部首选入口[ntgdi/bitblt.c](file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c#L297) 的NtGdiTransparentBlt调用。Clip NULL时用gxcoTrivial非 TRIVIAL 时先按rclBounds求交并按比例换算源矩形。HOOK_TRANSPARENTBLT→DrvTransparentBlt未挂钩或失败 →EngTransparentBlt。Reserved必须传 0。本文档基于 ReactOS 源代码win32ss/gdi/eng/stretchblt.c、transblt.c及关联模块分析2026 年 8 月

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价