接下来,我们将继续分析UIlib.h文件中其他的文件, UIContainer.h, UIRender.h, WinImplBase.h, UIManager.h,以及其他布局、控件等;

  1. UIRender.h:UI渲染器,其中cpp文件中,定义的ZIP压缩相关的数据结构,以及宏操作,与XUnzip.cpp中一样的(个人认为可以提取出来作为共用的一部分),此外还有stbi_load_from_memory、

        stbi_image_free,涉及到图片加载操作,具体详细细节可参考stb_image.c中开源库JPEG/PNG图片加载器stbi_image(支持的格式也比较多的)。

    CRenderClip:渲染剪切区域类,数据成员:rcItem:渲染剪切区域大小,hDC:设备环境句柄 ,hRgn:标识被剪切的区域句柄,hOldRgn:保存早前剪切区域的句柄,静态成员函数:GenerateClip:

    生成剪切区域,参数rc:新的剪切区域大小,内部调用GetClipBox获取到环境句柄的剪切区域大小,并调用CreateRectRgnIndirect创建剪切区域句柄,此外ExtSelectClipRgn将新的剪切区域与当前

    环境句柄的剪切区域进行扩展、合并,GenerateRoundClip:生成圆角剪切区域,参数rcItem为圆角区域位置大小,width、height:圆角矩形的逻辑高度和宽度,内部通过CreateRoundRectRgn

    创建一个圆角矩形区域句柄,并与当前区域合并,UseOldClipBegin:使用早期的矩形区域作为当前的剪切区域区域,UseOldClipEnd:使用当前区域作为设备环境剪切区域;

    CRenderEngine:渲染引擎类,整个类中基本上均是静态成员函数,AdjustColor:色彩调整,在分析如何处理色彩调整前,先分析静态全局函数RGBtoHSL、HSLtoRGB分别为RGB颜色空间互转为

    HSL色彩空间,RGB和HSL属于不同的色彩空间,此外在不同平台下,HSL表现不一样,即范围不一致,RGB的取值范围在0~255之间,HSL的取值H为0~240,SL在0~1之间,需要对RGB和HSL颜色

    空间有足够的认识可查阅相关资料,算法处理(摘自网络):

  HSL与RGB转换(伪代码表示)
  a) RGB→HSL的算法描述。 
  步骤1:把RGB值转成【0,1】中数值。 
  步骤2:找出R,G和B中的最大值。 
  步骤3:设L=(maxcolor + mincolor)/2 
  步骤4:如果最大和最小的颜色值相同,即表示灰色,那么S定义为0,而H未定义并在程序中通常写成0。 
  步骤5:否则,测试L: 
  If L<0.5, S=(maxcolor-mincolor)/(maxcolor + mincolor) 
  If L>=0.5, S=(maxcolor-mincolor)/(2.0-maxcolor-mincolor) 
  步骤6: If R==maxcolor, H=(G-B)/(maxcolor-mincolor) 
  If G==maxcolor, H=2.0+(B-R)/(maxcolor-mincolor) 
  If B==maxcolor, H=4.0+(R-G)/(maxcolor-mincolor) 
  步骤7:从第6步的计算看,H分成0~6区域。RGB颜色空间是一个立方体而HSL颜色空间是两个六角形锥体,其中的L是RGB立方体的主对角线。因此,RGB立方体的顶点:红、黄、绿、青、蓝

  和品红就成为HSL六角形的顶点,而数值0~6就告诉我们H在哪个部分;H=H*60.0,如果H为负值,则加360。

  b) HSL→RGB的算法描述。 
  步骤1:If S==0,表示灰色,定义R,G和B都为L. 
  步骤2:否则,测试L: 
  If L<0.5,temp2=L*(1.0+S) 
  If L>=0.5,temp2=L+S-L*S 
  步骤3:temp1=2.0*-temp2 
  步骤4:把H转换到0~1。 
  步骤5:对于R,G,B,计算另外的临时值temp3。方法如下: 
  for R, temp3=H+1.0/3.0 
  for G, temp3=H 
  for B, temp3=H-1.0/3.0 
  if temp3<0, temp3=temp3+1.0 
  if temp3>1, temp3=temp3-1.0 
  步骤6:对于R,G,B做如下测试: 
  If 6.0*temp3<1,color=temp1+(temp2-temp1)*6.0*temp3 
  else if 2.0*temp3<1,color=temp2 
  else if 3.0*temp3<2, color=temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0 
  else color=temp1。

  有兴趣时可以仔细推导一下算法;

  好啦,我们回到AdjustColor函数中,内部现通过获取到指定颜色RGB值dwColor的HSL值并重新根据传入的参数H、S、L修正HSL值,此后再转化为RGB值;可以看到内部修正HSL值时,将S、L分别/100,

  += (H - 180)?事实上我们可以跟踪发现CPaintManagerUI类中的m_H、m_S、m_L的值预设值为180、100、100;duilib中一般在绘制背景色PaintBkColor时会使用到;

  LoadImage:从文件或可执行应用程序、资源DLL中加载图片,参数bitmap为图片资源ID或资源字符串,type为图片类型或资源类型,mask为掩码,内部实现为:若type为空,若CPaintManagerUI已有

  资源ZIP文件,则从压缩文件中获取指定文件的内容,否则则直接从指定文件中获取内容,若type不为空,则从可执行应用程序或资源DLL中获取内容,得到内容后,再通过stbi_load_from_memory加载

  解析得到pImage的图片内容,此外因pImage与CreateDIBSection创建的BITMAP数据格式不一致,需要转化;此后返回TImageInfo数据结构的内容,释放pImage资源,TImageInfo结构后面会解析

  ,整个图片加载,图片格式因stbi-info支持格式,若需要支持其他格式或是其他处理可以更换图片加载模块,FreeImage:释放加载的图片资源(实时上主要是释放通过LoadImage创建的BITMAP数据资源)

  DrawImage:绘制图片,参数hDC,控件或窗口上下文句柄,hBitmap为位图句柄,rc为窗口区域大小,rcPaint为绘制区域大小,rcBmpPart为图片源窗口区域大小,rcCorners为拐角区域大小,此外

  alphaChannel释放开启了alpha通道,uFade为淡色值(透明度),hole、xtiled、ytiled分别为释放开启凹陷效果、X或Y方向平铺效果;DrawImageString:绘制图片(通过内容字符串解析绘制),内部调用

  DrawImage实现,DrawColor:绘制颜色,参数hDC为上下文句柄,rc为绘制区域,color为绘制颜色值,内部通过创建单一颜色的32bpp的HBITMAP来绘制区域,DrawGradient:渐变绘制,用在绘制

  背景色中,在dulib中提供了三个背景渐变色彩区域见CControlUI中m_dwBackColor、m_dwBackColor2,m_dwBackColor3,参数hDC为上下文句柄,rc为绘制区域,dwFirst、dwSecond为第一色

  、第二色(即首尾色),bVertical为是否为垂直方向,否则为水平,nSteps指定渐变的步进值,函数内部通过双缓存技术实现绘制通过计算step调整每Step各RGB色彩值创建CreateSolidBrush画刷分区域

  地FillRect填充实现绘图,DrawLine:绘制线段,参数hDC为上下文句柄,rc为绘制区域(事实上绘制线段为该区域的左上角至右下角的对角线线段),nSize为画笔宽度,dwPenColor为画笔颜色,nStyle

  为画笔风格,DrawRect:绘制矩形,参数同DrawLine,少了画笔风格的参数,内部调用Rectangle绘制,矩形内部不会被填充,DrawRoundRect:绘制圆角矩形,参数同DrawRect,此外内部调用了

  RoundRect绘制圆角矩形,同样内部不会被填充,DrawText:绘制文本,参数hDC上下文句柄,pManager为绘制管理对象,rc为绘制区域大小,pstrText为绘制文本字符串,dwTextColor为文本颜色,

  iFont为字体索引,通过pManager中获取其字体句柄,uStyle为绘制风格,函数内部调用DrawText实现绘制文本,DrawHtmlText:绘制HTML文本,GenerateBitmap:生成bitmap,参数pManager

  获取对应绘制管理器对象,pControl控件对象,rc为bitmap大小,使用绘制管理对象中绘制句柄对象绘制控件对象区域并返回该绘制后指定大小的bitmap大小;GetTextSize:获取字符串大小(高、宽度)

  参数hDC为上下文句柄,pManager为绘制管理对象提供当前应用于(hDC下的当前所选字体来计算字符串尺寸)该字符串上的字体,pstrText为字符串,iFont为字体索引,uStyle参数暂时未被用到,

  内部使用GetTextExtentPoint32获取到字符串高度和宽度信息。

  2. UIContainer.h:控件容器,一般用在具有子控件的控件中,如:UIList、UICombox、UITreeView、以及布局控件;

    IContainerUI:UI容器基类,提供了对元素项的索引查找和设置,控件添加和移除等操作的接口定义;GetItemAt:获取指定索引的下的控件对象,GetItemIndex:获取指定控件对应的索引值,此外对应

    SetItemIndex:设置控件对象与索引对,对应早期索引下的Item将被移除,GetCount:获取容器中控件数,Add:添加(追加)控件对象至容器,AddAt:在指定索引处添加控件,Remove:移除指定控件

    对象,RemoveAt:移除指定索引下的控件对象,RemoveAll:移除所有容器下对象;

    CContainerUI:继承于IContainerUI、CControlUI,UI容器CContainerUI也为控件UI对象,因该类比较大,从成员函数开始,GetClass:获取当前对象的类名,GetInterface:获取参数pstrName指定

    类名的控件对象指针,接下来的几个函数继承于IContainerUI,此处不再说明,需要说的是成员变量m_items:容纳控件对象,即为控件容器,DoEvent:事件源处理函数,处理各种事件消息,SetVisible:

    设置当前容器对象可见性并设置容器内各控件对象的可见性状态,SetInternVisible:设置控件内部可见性状态,SetMouseEnabled:设置鼠标是否可用,内部若存在垂直、水平滚动条则也被设置,GetInset

    、SetInset:获取/设置内边距(即客户区)m_rcInset,GetChildPadding/SetChildPadding:获取/设置子对象内边距m_iChildPadding(控件边距),SetAutoDestroy/GetAutoDestroy:设置或查询当前

    容器内对象是否自动销毁(事实上内部还有个延迟销毁),SetDelayedDestroy/GetDelayedDestroy:设置/查询是否延迟销毁,SetMouseChildEnabled/GetMouseChildEnabled:设置或查询本控件的子

    控件是否可以响应用户操作,FindSelectable:查找容器中下一个可用控件索引,SetPos:设置控件位置,若存在子控件则若子控件为浮动的,则调整该控件,否则则设置为当前控件区域的大小,DoPaint:

    绘制操作,SetAttribute:设置控件相关的属性,SetManager:设置控件管理器(绘制管理器UI、控件父窗口,是否初始化),FindControl:查找控件并执行相应提供的回调函数,参数pData一般为鼠标

    点击位置或其他的附加值,SetSubControlText/GetSubControlText:设置/获取子控件文本,SetSubControlFixedHeight/GetSubControlFixedHeight/SetSubControlFixedWdith等分别为获取或

    设置子控件高度或宽度,SetSubControlUserData:设置子控件用户数据,FindSubControl:查找子控件对象,GetScrollPos/SetScrollPos:获取/设置滚动条位置,LineUp/LineDown、PageUp、

    HomeUp、EndDown、LineLeft、LineRight、PageLeft、PageRight、HomeLeft、EndRight等均为对滚动条的控制,EnableScrollBar:是否启用垂直滚动条和水平滚动条;GetVerticalScrollBar、

    GetHorizontalScrollBar:获取垂直滚动条、水平滚动条控件对象;SetFloatPos:设置指定容器元素浮动位置显示,ProcessScrollBar:调整滚动条位置;

    

    

Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备三)的更多相关文章

  1. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备四)

    接下来,分析uilib.h中的WinImplBase.h和UIManager.h: WinImplBase.h:窗口实现基类,已实现大部分的工作,基本上窗口类均可直接继承该类,可发现该类继承于多个类, ...

  2. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备二)

    接下来,我们继续分析UIlib.h文件中余下的文件,当然部分文件可能顺序错开分析,这样便于从简单到复杂的整个过程的里面,而避免一开始就出现各种不理解的地方. 1. UIManager.h:UI管理器, ...

  3. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备一)

    上节中提到在遍历创建控件树后,执行了以下操作:      1. CDialogBuilder构建各控件对象并形成控件树,并返回第一个控件对象pRoot:     2. m_pm.AttachDialo ...

  4. Duilib源码分析(四)绘制管理器—CPaintManagerUI

    接下来,分析uilib.h中的UIManager.h,在正式分析CPaintManagerUI前先了解前面的一些宏.结构: 枚举类型EVENTTYPE_UI:定义了UIManager.h中事件通告类型 ...

  5. Duilib源码分析(六)整体流程

    在<Duilib源码分析(一)整体框架>.<Duilib源码分析(二)控件构造器—CDialogBuilder>以及<Duilib源码分析(三)XML解析器—CMarku ...

  6. Duilib源码分析(一)整体框架

    Duilib界面库是一款由杭州月牙儿网络技术有限公司开发的界面开源库,以viksoe项目下的UiLib库的基础上开发(此后也将对UiLib库进行源码分析):通过XML布局界面,将用户界面和处理逻辑彻底 ...

  7. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  8. Memcached源码分析之内存管理

    先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到). 一)模型分析在开始解剖memcached关于内存管 ...

  9. springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

    之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...

随机推荐

  1. Zookeeper学习之:paxos算法

    paxos算法的重要性众所周知,它给如今的分布式一致性提供了迄今为止最好的解决方案.无论是Lamport自己的论文描述,还是网上的诸多资料,对paxos的描述都是及其简洁的,给人的感觉是paxos看似 ...

  2. php程序 注册机制

    密码加密方式 1.直接md5加密 2.md5和随机数(也可以是固定参数,如(Rfd4WE784)) 3.md5(md5) 4. 参考 function sp_password($pw,$authcod ...

  3. git查看本地和创建分支、上传分支、提交代码到分支、删除分支等,git分支、git查看本地和创建分支以及上传分支到服务器

    以下是git命令行里边的命令操作 ##进入项目目录下 giscafer@Faronsince2016 /G/002_project $ cd Comments ##查看远程分支有哪些 giscafer ...

  4. SpringMVC学习记录2

    废话 最近在看SpringMVC...里面东西好多...反正东看一点西看一点吧... 分享一下最近的一些心得..是关于DispatcherServlet的 DispatcherServlet与Cont ...

  5. java的锁机制

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

  6. ump_player在线直播播放器

      ump_player在线直播播放器封装,可以支持加载在线直播流 https://github.com/Mrxdh/EveryExercise/blob/master/ump_player%E5%9 ...

  7. leetcode--Majority Element

    题目链接:https://leetcode.com/problems/majority-element/ 算法类型:分治法 题目分析:获取长度为n的数组中的众数(出现次数大于等于⌊ n/2 ⌋) 代码 ...

  8. vtkQuadratic创建半球面

    用的关键类:vtkQuadric.vtkSampleFunction.vtkContourFilter:用于创建方框的类vtkOutlineFilter #ifndef INITIAL_OPENGL ...

  9. Be careful about the upper limit of integer

    在面对整数时,要留心整数溢出的情况. 在探索一个数有多少个除数的程序中,原本我们只要累加自然数到大于根号N停止即可. 不过因为计算机的整数范围的限制,我们需要判断是否i*i<(i-1)*(i-1 ...

  10. Mac 操作技巧

    1.OS X下如何在同一个程序之中快速切换窗口 command+`(1左边的那个) 2.