Example #1
0
LICE_IFont* IGraphics::CacheFont(IText* pTxt)
{
  LICE_CachedFont* font = (LICE_CachedFont*)s_fontCache.Find(pTxt);
  if (!font)
  {
    font = new LICE_CachedFont;
    int h = pTxt->mSize;
    int esc = 10 * pTxt->mOrientation;
    int wt = (pTxt->mStyle == IText::kStyleBold ? FW_BOLD : FW_NORMAL);
    int it = (pTxt->mStyle == IText::kStyleItalic ? TRUE : FALSE);

    int q;
    if (pTxt->mQuality == IText::kQualityDefault)
      q = DEFAULT_QUALITY;
    #ifdef CLEARTYPE_QUALITY
    else if (pTxt->mQuality == IText::kQualityClearType)
      q = CLEARTYPE_QUALITY;
    else if (pTxt->mQuality == IText::kQualityAntiAliased)
    #else
    else if (pTxt->mQuality != IText::kQualityNonAntiAliased)
    #endif
      q = ANTIALIASED_QUALITY;
    else // if (pTxt->mQuality == IText::kQualityNonAntiAliased)
      q = NONANTIALIASED_QUALITY;

    #ifdef __APPLE__
    bool resized = false;
    Resize:
    if (h < 2) h = 2;
    #endif
    HFONT hFont = CreateFont(h, 0, esc, esc, wt, it, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, q, DEFAULT_PITCH, pTxt->mFont);
    if (!hFont)
    {
      delete(font);
      return 0;
    }
    font->SetFromHFont(hFont, LICE_FONT_FLAG_OWNS_HFONT | LICE_FONT_FLAG_FORCE_NATIVE);
    #ifdef __APPLE__
    if (!resized && font->GetLineHeight() != h)
    {
      h = int((double)(h * h) / (double)font->GetLineHeight() + 0.5);
      resized = true;
      goto Resize;
    }
    #endif
    s_fontCache.Add(font, pTxt);
  }
Example #2
0
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
}