void SNM_DynSizedText::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) { RECT r = m_position; r.left += origin_x; r.right += origin_x; r.top += origin_y; r.bottom += origin_y; int h = r.bottom-r.top; int w = r.right-r.left; ColorTheme* ct = SNM_GetColorTheme(); int col = m_col; if (!col) col = ct ? LICE_RGBA_FROMNATIVE(ct->main_text, m_alpha) : LICE_RGBA(255,255,255,255); if (m_wantBorder) LICE_DrawRect(drawbm,r.left,r.top,w,h,col,0.2f); // title lane int laneHeight = GetTitleLaneHeight(); if (WantTitleLane() && HasTitleLane()) { if (m_wantBorder) LICE_Line(drawbm, r.left,r.top+laneHeight-1,r.right,r.top+laneHeight-1,col,0.2f); // title's band coloring (works for all themes) LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,laneHeight,col,1.0f,LICE_BLIT_MODE_OVERLAY); LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,laneHeight,col,1.0f,LICE_BLIT_MODE_OVERLAY); static LICE_CachedFont sFont; if (!sFont.GetHFont()) // single lazy init.. { LOGFONT lf = { SNM_FONT_HEIGHT, 0,0,0,FW_BOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,SNM_FONT_NAME }; sFont.SetFromHFont(CreateFontIndirect(&lf),LICE_FONT_FLAG_OWNS_HFONT|LICE_FONT_FLAG_FORCE_NATIVE); // others props are set on demand (support theme switches) } sFont.SetBkMode(TRANSPARENT); sFont.SetTextColor(LICE_RGBA_FROMNATIVE(WDL_STYLE_GetSysColor(COLOR_WINDOW), 255)); // "negative" color { RECT tr = {r.left,r.top,r.right,r.top+laneHeight}; char buf[64] = ""; _snprintfSafe(buf, sizeof(buf), " %s ", m_title.Get()); // trick for better display when left/right align sFont.DrawText(drawbm, buf, -1, &tr, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER|m_titleAlign); } // resize draw rect: take band into account r.top += laneHeight; h = r.bottom-r.top; } // ok, now the meat: render lines with a dynamic sized text if (!m_lines.GetSize() || !m_lines.Get(m_maxLineIdx)) return; /////////////////////////////////////////////////////////////////////////////// #ifndef _SNM_MISC // 1st sol.: full width but several fonts can be tried // initial font height estimation // touchy: the better estimation, the less cpu use! int estimFontH = int((w*2.65)/m_lines.Get(m_maxLineIdx)->GetLength()); // 2.65 = average from tests.. if (estimFontH > int(h/m_lines.GetSize())+0.5) estimFontH = int(h/m_lines.GetSize()+0.5); // check if the current font can do the job if (m_lastFontH>=SNM_FONT_HEIGHT && abs(estimFontH-m_lastFontH) < 2) // tolerance: 2 pixels { #ifdef _SNM_DYN_FONT_DEBUG OutputDebugString("SNM_DynSizedText::OnPaint() - Skip font creation\n"); #endif m_font.SetTextColor(col); DrawLines(drawbm, &r, m_lastFontH); } else { m_lastFontH = estimFontH; #ifdef _SNM_DYN_FONT_DEBUG int dbgTries=0; #endif while(m_lastFontH>SNM_FONT_HEIGHT) { HFONT lf = CreateFont(m_lastFontH,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,m_fontName.Get()); m_font.SetFromHFont(lf, LICE_FONT_FLAG_OWNS_HFONT|LICE_FONT_FLAG_FORCE_NATIVE); m_font.SetBkMode(TRANSPARENT); m_font.SetTextColor(col); RECT tr = {0,0,0,0}; // DT flags must be consistent with DrawLines() m_font.DrawText(NULL, m_lines.Get(m_maxLineIdx)->Get(), -1, &tr, DT_SINGLELINE|DT_BOTTOM|DT_NOPREFIX|DT_CALCRECT); if ((tr.right - tr.left) > (w-int(w*0.02+0.5))) // room: 2% of w { m_font.SetFromHFont(NULL,LICE_FONT_FLAG_OWNS_HFONT); DeleteObject(lf); m_lastFontH--; #ifdef _SNM_DYN_FONT_DEBUG dbgTries++; #endif } else { DrawLines(drawbm, &r, m_lastFontH); // no font deletion: will try to re-use it.. break; } } #ifdef _SNM_DYN_FONT_DEBUG char dbg[256]; _snprintfSafe(dbg, sizeof(dbg), "SNM_DynSizedText::OnPaint() - %d tries, estim: %d, real: %d\n", dbgTries, estimFontH, m_lastFontH); OutputDebugString(dbg); #endif } /////////////////////////////////////////////////////////////////////////////// #else // 2nd sol.: render text in best effort, single font creation /*JFB commented: truncated text.. int fontHeight = int((w*2.65)/m_lines.Get(m_maxLineIdx)->GetLength()); // 2.65 = average from tests.. if (fontHeight > int(h/m_lines.GetSize())+0.5) fontHeight = int(h/m_lines.GetSize()+0.5); */ // font height estimation (safe but it does not use all the available width/height) int fontHeight = int(h/m_lines.GetSize() + 0.5); while (fontHeight>SNM_FONT_HEIGHT && (fontHeight*m_lines.Get(m_maxLineIdx)->GetLength()*0.55) > w) // 0.55: h/w factor fontHeight--; if (fontHeight>=SNM_FONT_HEIGHT) { HFONT lf = CreateFont(fontHeight,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,m_fontName.Get()); m_font.SetFromHFont(lf, LICE_FONT_FLAG_OWNS_HFONT|LICE_FONT_FLAG_FORCE_NATIVE); m_font.SetBkMode(TRANSPARENT); m_font.SetTextColor(col); DrawLines(drawbm, &r, fontHeight); m_font.SetFromHFont(NULL,LICE_FONT_FLAG_OWNS_HFONT); DeleteObject(lf); } #endif }
void WDL_VirtualComboBox::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) { { if (m_font) m_font->SetBkMode(TRANSPARENT); RECT r=m_position; r.left+=origin_x; r.right+=origin_x; r.top+=origin_y; r.bottom+=origin_y; int col=WDL_STYLE_GetSysColor(COLOR_WINDOW); col = LICE_RGBA_FROMNATIVE(col,255); LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,col,1.0f,LICE_BLIT_MODE_COPY); { RECT tr=r; tr.left=tr.right-(tr.bottom-tr.top); int col2=WDL_STYLE_GetSysColor(COLOR_BTNFACE); col2 = LICE_RGBA_FROMNATIVE(col2,255); LICE_FillRect(drawbm,tr.left,tr.top,tr.right-tr.left,tr.bottom-tr.top,col,1.0f,LICE_BLIT_MODE_COPY); } int tcol=WDL_STYLE_GetSysColor(COLOR_BTNTEXT); tcol=LICE_RGBA_FROMNATIVE(tcol,255); if (m_font && m_items.Get(m_curitem)&&m_items.Get(m_curitem)[0]) { RECT tr=r; tr.left+=2; tr.right-=16; m_font->SetTextColor(tcol); m_font->DrawText(drawbm,m_items.Get(m_curitem),-1,&tr,DT_SINGLELINE|DT_VCENTER|(m_align<0?DT_LEFT:m_align>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); } // pen3=tcol int pencol = WDL_STYLE_GetSysColor(COLOR_3DSHADOW); pencol = LICE_RGBA_FROMNATIVE(pencol,255); int pencol2 = WDL_STYLE_GetSysColor(COLOR_3DHILIGHT); pencol2 = LICE_RGBA_FROMNATIVE(pencol2,255); // draw the down arrow button { int bs=(r.bottom-r.top); int l=r.right-bs; int a=(bs/4)&~1; LICE_Line(drawbm,l,r.top,l,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,l-1,r.top,l-1,r.bottom-1,pencol2,1.0f,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,l+bs/2-a,r.top+bs/2-a/2, l+bs/2,r.top+bs/2+a/2,tcol,1.0f,LICE_BLIT_MODE_COPY,true); LICE_Line(drawbm,l+bs/2,r.top+bs/2+a/2, l+bs/2+a,r.top+bs/2-a/2, tcol,1.0f,LICE_BLIT_MODE_COPY,true); } // draw the border LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,0,false); LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,0,false); LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol2,1.0f,0,false); LICE_Line(drawbm,r.left,r.bottom-1,r.right-1,r.bottom-1,pencol2,1.0f,0,false); } }
void WDL_VirtualStaticText::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) { RECT r=m_position; r.left+=origin_x; r.right+=origin_x; r.top += origin_y; r.bottom += origin_y; if (m_bkbm && m_bkbm->bgimage) { WDL_VirtualWnd_ScaledBlitBG(drawbm,m_bkbm, r.left,r.top,r.right-r.left,r.bottom-r.top, r.left,r.top,r.right-r.left,r.bottom-r.top, 1.0,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); if (m_dotint && LICE_GETA(m_bg)) { float amt = LICE_GETA(m_bg)/255.0f; // todo: apply amt float rv=LICE_GETR(m_bg)/255.0f; float gv=LICE_GETG(m_bg)/255.0f; float bv=LICE_GETB(m_bg)/255.0f; float avg=(rv+gv+bv)*0.33333f; if (avg<0.05f)avg=0.05f; float sc=0.5f*amt; float sc2 = (amt-sc)/avg; float sc3=32.0f * amt; float sc4=64.0f*(avg-0.5f) * amt; // tint LICE_MultiplyAddRect(drawbm, r.left,r.top, r.right-r.left, r.bottom-r.top, sc+rv*sc2 + (1.0-amt), sc+gv*sc2 + (1.0-amt), sc+bv*sc2 + (1.0-amt), 1, (rv-avg)*sc3+sc4, (gv-avg)*sc3+sc4, (bv-avg)*sc3+sc4, 0); } } else { if (LICE_GETA(m_bg)) { LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,m_bg,LICE_GETA(m_bg)/255.0f,LICE_BLIT_MODE_COPY); } if (m_wantborder) { int cidx=COLOR_3DSHADOW; int pencol = WDL_STYLE_GetSysColor(cidx); pencol = LICE_RGBA_FROMNATIVE(pencol,255); LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,1.0f,LICE_BLIT_MODE_COPY,false); cidx=COLOR_3DHILIGHT; pencol = WDL_STYLE_GetSysColor(cidx); pencol = LICE_RGBA_FROMNATIVE(pencol,255); LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,1.0f,LICE_BLIT_MODE_COPY,false); r.left++; r.bottom--; r.top++; r.right--; } } if (m_text.Get()[0]) { r.left += m_margin_l; r.right -= m_margin_r; r.top += m_margin_t; r.bottom -= m_margin_b; m_didvert=m_vfont && (r.right-r.left)<(r.bottom-r.top); LICE_IFont *font = m_didvert ? m_vfont : m_font; if (font) { font->SetBkMode(TRANSPARENT); m_didalign=m_align; if (m_didalign==0) { RECT r2={0,0,0,0}; font->DrawText(drawbm,m_text.Get(),-1,&r2,DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX|DT_CALCRECT); if (r2.right > r.right-r.left) m_didalign=-1; } int tcol=m_fg ? m_fg : LICE_RGBA_FROMNATIVE(WDL_STYLE_GetSysColor(COLOR_BTNTEXT)); font->SetTextColor(tcol); if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,LICE_GETA(m_fg)/255.0f); font->DrawText(drawbm,m_text.Get(),-1,&r,DT_SINGLELINE|DT_VCENTER|(m_didalign<0?DT_LEFT:m_didalign>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); if (m_fg && LICE_GETA(m_fg) != 0xff) font->SetCombineMode(LICE_BLIT_MODE_COPY,1.0f); } } WDL_VWnd::OnPaint(drawbm,origin_x,origin_y,cliprect); }
void WDL_VirtualIconButton::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect) { HDC hdc=drawbm->getDC(); int col; float alpha = (m_grayed ? 0.25f : 1.0f) * m_alpha; bool isdown = !!(m_pressed&1); bool ishover = !!(m_pressed&2); if (m_iconCfg && m_iconCfg->image && !m_iconCfg->image_issingle) { bool swapupdown = (m_checkstate > 0); bool isdownimg = (swapupdown != isdown); RECT r=m_position; int sx=0; int sy=0; int w=m_iconCfg->image->getWidth(); int h=m_iconCfg->image->getHeight(); if (w>0 && (m_iconCfg->image_ltrb_used.flags&2)) w-=2; w/=3; if (w>0 && h > 0) { if (m_is_button) { if (isdownimg) sx += w*2; else if (ishover) sx += w; } if (m_iconCfg->image_ltrb_used.flags&2) { WDL_VirtualWnd_BGCfg cfg={0,}; LICE_SubBitmap sb(m_iconCfg->image,sx+1,sy+1,w,h-2); cfg.bgimage = &sb; cfg.bgimage_lt[0] = m_iconCfg->image_ltrb_main[0]; cfg.bgimage_lt[1] = m_iconCfg->image_ltrb_main[1]; cfg.bgimage_rb[0] = m_iconCfg->image_ltrb_main[2]; cfg.bgimage_rb[1] = m_iconCfg->image_ltrb_main[3]; cfg.bgimage_noalphaflags=0; WDL_VirtualWnd_ScaledBlitBG(drawbm,&cfg, r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, r.left+origin_x,r.top+origin_y,r.right-r.left,r.bottom-r.top, alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); } else LICE_ScaledBlit(drawbm,m_iconCfg->image,r.left+origin_x,r.top+origin_y, r.right-r.left, r.bottom-r.top, (float)sx,(float)sy,(float)w,(float)h, alpha, LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); } } else { RECT r=m_position; r.left+=origin_x; r.right+=origin_x; r.top+=origin_y; r.bottom+=origin_y; if (m_is_button) { if (WDL_STYLE_WantGlobalButtonBackground(&col)) { LICE_FillRect(drawbm,r.left,r.top,r.right-r.left,r.bottom-r.top,LICE_RGBA_FROMNATIVE(col,255),alpha,LICE_BLIT_MODE_COPY); } if (ishover || m_forceborder || WDL_STYLE_WantGlobalButtonBorders()) { int cidx=isdown?COLOR_3DSHADOW:COLOR_3DHILIGHT; int pencol = WDL_STYLE_GetSysColor(cidx); pencol = LICE_RGBA_FROMNATIVE(pencol,255); LICE_Line(drawbm,r.left,r.bottom-1,r.left,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,r.left,r.top,r.right-1,r.top,pencol,alpha,LICE_BLIT_MODE_COPY,false); cidx = isdown?COLOR_3DHILIGHT:COLOR_3DSHADOW; pencol = WDL_STYLE_GetSysColor(cidx); pencol = LICE_RGBA_FROMNATIVE(pencol,255); LICE_Line(drawbm,r.right-1,r.top,r.right-1,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,r.right-1,r.bottom-1,r.left,r.bottom-1,pencol,alpha,LICE_BLIT_MODE_COPY,false); } } if (m_iconCfg && m_iconCfg->image) { int sz=16,sz2=16; WDL_STYLE_ScaleImageCoords(&sz,&sz2); //if (m_position.right-m_position.left > 24) sz=m_position.right-m_position.left-8; int x=r.left+((r.right-r.left)-sz)/2; int y=r.top+((r.bottom-r.top)-sz2)/2; if (m_is_button) { if (isdown && ishover) { x++; y++; } } LICE_ScaledBlit(drawbm,m_iconCfg->image,x,y,sz,sz2,0.0f,0.0f, (float)m_iconCfg->image->getWidth(), (float)m_iconCfg->image->getHeight(),alpha,LICE_BLIT_MODE_COPY|LICE_BLIT_FILTER_BILINEAR|LICE_BLIT_USE_ALPHA); } } if (!m_iconCfg || m_forcetext) { RECT r2=m_position; r2.left+=origin_x; r2.right+=origin_x; r2.top+=origin_y; r2.bottom+=origin_y; if (m_checkstate>=0 && !m_iconCfg) { RECT tr=r2; int sz=tr.bottom-tr.top; r2.left+=sz+2; tr.top+=2; tr.bottom-=2; sz-=4; sz&=~1; LICE_FillRect(drawbm ,tr.left,tr.top,sz,sz,LICE_RGBA(255,255,255,255),alpha,LICE_BLIT_MODE_COPY); LICE_Line(drawbm,tr.left,tr.top,tr.left+sz,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,tr.left+sz,tr.top,tr.left+sz,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,tr.left+sz,tr.bottom,tr.left,tr.bottom,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); LICE_Line(drawbm,tr.left,tr.bottom,tr.left,tr.top,LICE_RGBA(128,128,128,255),alpha,LICE_BLIT_MODE_COPY,false); int nl = (m_checkstate>0) ? 3:0; if (isdown) nl ^= 2; if (nl&1) LICE_Line(drawbm,tr.left+2,tr.bottom-2,tr.left+sz-2,tr.top+2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); if (nl&2) LICE_Line(drawbm,tr.left+2,tr.top+2,tr.left+sz-2,tr.bottom-2,LICE_RGBA(0,0,0,255),alpha,LICE_BLIT_MODE_COPY,false); } LICE_IFont *font = m_textfont; if (font && m_textfontv && m_position.right-m_position.left < m_position.bottom - m_position.top) { font = m_textfontv; } // draw text if (font&&m_textlbl.Get()[0]) { int fgc=m_forcetext_color ? m_forcetext_color : LICE_RGBA_FROMNATIVE(WDL_STYLE_GetSysColor(COLOR_BTNTEXT),255); //font->SetCombineMode(LICE_BLIT_MODE_COPY, alpha); // this affects the glyphs that get cached font->SetBkMode(TRANSPARENT); font->SetTextColor(fgc); r2.left += m_margin_l; r2.right -= m_margin_r; r2.top += m_margin_t; r2.bottom -= m_margin_b; if (isdown) { if (m_textalign<0) r2.left+=1; else if (m_textalign>0) r2.right+=1; else r2.left+=2; r2.top+=2; } font->DrawText(drawbm,m_textlbl.Get(),-1,&r2,DT_SINGLELINE|DT_VCENTER|(m_textalign<0?DT_LEFT:m_textalign>0?DT_RIGHT:DT_CENTER)|DT_NOPREFIX); } } if (m_bgcol1_msg) { int brcol=-100; SendCommand(m_bgcol1_msg,(INT_PTR)&brcol,GetID(),this); if (brcol != -100) { RECT r=m_position; int bh=(r.bottom-r.top)/5; if (bh<1) bh=1; int bw=(r.right-r.left)/5; if (bw<1) bw=1; LICE_FillRect(drawbm, r.left+origin_x,r.top+origin_y, r.right-r.left, bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); LICE_FillRect(drawbm, r.left+origin_x,r.top+origin_y+bh, bw, r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); LICE_FillRect(drawbm, r.right+origin_x-bw,r.top+origin_y+bh, bw, r.bottom-r.top-bh*2,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); LICE_FillRect(drawbm, r.left+origin_x,r.bottom+origin_y-bh, r.right-r.left, bh,LICE_RGBA_FROMNATIVE(brcol,255),0.75,LICE_BLIT_MODE_COPY); } } }