⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdc.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
字号:
/*
 * Copyright (c) 2001,2002,2003 Mike Matsnev.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice immediately at the beginning of the file, without modification,
 *    this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Absolutely no warranty of function or purpose is made by the author
 *    Mike Matsnev.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * $Id: FDC.cpp,v 1.18.2.5 2003/09/27 11:30:55 mike Exp $
 * 
 */

#include <afx.h>

#include "config.h"
#include "FDC.h"
#include "ptr.h"
#include "Attr.h"
#include "Unicode.h"
#include "Colors.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

///////////////////////////////////////////////////////////////////////////////
// Font cache
struct Font {
  HFONT	  m_font;
  int	  m_size;
  int	  m_refcount;
  int	  m_height;
  int	  m_ascent;
  int	  m_angle;
  int	  m_hwidth;
  unsigned m_flags;
  bool	  m_ok;

  Font() : m_font(NULL), m_height(-1), m_ascent(-1), m_ok(false),
    m_angle(0), m_hwidth(-1) { }
  ~Font() { DeleteObject(m_font); }
  void	  Grab() { ++m_refcount; }
  void	  Release() { if (--m_refcount==0) delete this; }
};

struct FontCache {
  CPtrArray m_lru;
  int	    m_cachemax; // max number of entries in cache
  CString   m_face;
  int	    m_basesize;
  bool	    m_defbold;
  int	    m_cleartype;
  int	    m_angle;

  FontCache();
  ~FontCache() { RemoveAll(); }

  Font	    *AllocFont();
  void	    RemoveAll();
  void	    Release(Font *f);
  void	    SetDefault(const TCHAR *f,int bs,bool b,int ct,int an);
  Font	    *FindOrAlloc(int size,unsigned flags,int an);
};

#define	FNT(i)	  ((Font*)(m_lru[(i)]))

static FontCache g_fcache;

FontCache::FontCache() :
  m_cachemax(6), m_face(_T("Tahoma")),
  m_basesize(12), m_defbold(false), m_cleartype(0), m_angle(0)
{
}

void	FontCache::RemoveAll() {
  for (int i=0;i<m_lru.GetSize();++i) {
    FNT(i)->m_ok=false;
    FNT(i)->Release();
  }
  m_lru.RemoveAll();
}

Font	*FontCache::AllocFont() {
  if (m_lru.GetSize()<m_cachemax || FNT(0)->m_refcount>1) { // allocate new
    Font    *f=new Font;
    f->m_refcount=1;
    m_lru.Add(f);
    return f;
  }
  // reuse
  Font	  *f=FNT(0);
  m_lru.RemoveAt(0);
  m_lru.Add(f);
  DeleteObject(f->m_font);
  f->m_ok=false;
  f->m_ascent=f->m_height=-1;
  return f;
}

void  FontCache::SetDefault(const TCHAR *f,int bs,bool b,int ct,int an) {
  if (m_face!=f || ct!=m_cleartype)
    RemoveAll();
  m_face=f;
  m_basesize=bs;
  m_defbold=b;
  m_cleartype=ct;
  m_angle=an;
}

Font  *FontCache::FindOrAlloc(int size,unsigned flags,int an) {
  int	i;
  Font	*f;
  for (i=0;i<m_lru.GetSize();++i) {
    f=FNT(i);
    if (f->m_size==size && f->m_flags==flags && f->m_angle==an) {
      if (i!=m_lru.GetUpperBound()) {
	m_lru.RemoveAt(i);
	m_lru.Add(f);
      }
      return f;
    }
  }
  f=AllocFont();
  LOGFONT   lf;
  memset(&lf,0,sizeof(lf));
  lf.lfHeight=-size;
  lf.lfEscapement=lf.lfOrientation=an;
  lf.lfWeight=flags&Attr::BOLD ? FW_BOLD : FW_NORMAL;
  lf.lfItalic=flags&Attr::ITALIC ? 1 : 0;
  lf.lfUnderline=flags&Attr::UNDERLINE ? 1 : 0;
  lf.lfCharSet=DEFAULT_CHARSET;
  lf.lfOutPrecision=OUT_DEFAULT_PRECIS;
  lf.lfClipPrecision=CLIP_DEFAULT_PRECIS;
#ifdef _WIN32_WCE
  lf.lfQuality=m_cleartype ? CLEARTYPE_QUALITY : DEFAULT_QUALITY;
#else
  if (m_cleartype==1)
    lf.lfQuality=CLEARTYPE_QUALITY;
  else if (m_cleartype==2)
    lf.lfQuality=ANTIALIASED_QUALITY;
  else
    lf.lfQuality=NONANTIALIASED_QUALITY;
#endif
  lf.lfPitchAndFamily=DEFAULT_PITCH|FF_DONTCARE;
  if (flags&CFDC::FORCETAHOMA)
    _tcsncpy(lf.lfFaceName,_T("Tahoma"),LF_FACESIZE-1);
  else if (flags&Attr::XFONT) {
    _tcsncpy(lf.lfFaceName,_T("NewtonUni"),LF_FACESIZE-1);
    lf.lfHeight-=2; // adjust relative size to tahoma
  } else
    _tcsncpy(lf.lfFaceName,m_face,LF_FACESIZE-1);
  f->m_font=CreateFontIndirect(&lf);
  f->m_size=size;
  f->m_flags=flags;
  f->m_angle=an;
  f->m_ok=true;
  return f;
}

void  FontCache::Release(Font *f) {
  int	i;
  for (i=0;i<m_lru.GetSize();++i)
    if (FNT(i)==f) {
      if (f->m_refcount>1) {
	f->Release();
	if (i>0 && FNT(i)->m_refcount>1) {
	  m_lru.RemoveAt(i);
	  m_lru.InsertAt(0,f);
	}
	while (m_lru.GetSize()>m_cachemax && FNT(0)->m_refcount==1) {
	  f=FNT(0);
	  m_lru.RemoveAt(0);
	  f->Release();
	}
      }
      return;
    }
  f->Release();
}

void  CFDC::SetDefaultFont(const TCHAR *face,int basesize,bool bold,
			   int cleartype,int angle) {
  g_fcache.SetDefault(face,basesize,bold,cleartype,angle);
}

void  CFDC::SelectFontAbs(int size,unsigned flags,bool zesc) {
  Font	*f=(Font*)m_hFont;
  if (g_fcache.m_defbold && !(flags&FORCENORMALWEIGHT))
    flags|=Attr::BOLD;
  int ang=zesc ? 0 : g_fcache.m_angle;
  if (f && f->m_ok && f->m_size==size && f->m_flags==flags && f->m_angle==ang)
    return;
  if (f)
    g_fcache.Release(f);
  f=g_fcache.FindOrAlloc(size,flags,ang);
  f->Grab();
  m_hFont=(void*)f;
  HGDIOBJ obj=SelectObject(m_hDC,f->m_font);
  if (!m_hOrigFont)
    m_hOrigFont=obj;
}

void  CFDC::SelectFont(int size,unsigned flags,bool zesc) {
  SelectFontAbs(size+g_fcache.m_basesize,flags,zesc);
}

CFDC::CFDC(HWND hWnd,PAINTSTRUCT *ps) :
  m_hFont(NULL), m_hOrigFont(NULL), m_hOrigPen(NULL), m_hWnd(hWnd), m_ps(ps),
  m_lpx(0)
{
  if (m_ps)
    m_hDC=BeginPaint(m_hWnd,m_ps);
  else
    m_hDC=GetDC(m_hWnd);
  SetBkMode(m_hDC,TRANSPARENT);
  ::SetTextColor(m_hDC,m_fg=C_NORM);
  ::SetBkColor(m_hDC,m_bg=C_BG);
  m_pfg=RGB(0,0,0); // default pen is black
}

CFDC::~CFDC() {
  if (m_hOrigFont)
    SelectObject(m_hDC,m_hOrigFont);
  if (m_hOrigPen)
    DeleteObject(SelectObject(m_hDC,m_hOrigPen));
  if (m_hFont)
    g_fcache.Release((Font*)m_hFont);
  if (m_ps)
    EndPaint(m_hWnd,m_ps);
  else
    ReleaseDC(m_hWnd,m_hDC);
}

void  CFDC::GetFontSize(int& height,int& ascent) {
  Font	*f=(Font*)m_hFont;
  if (!f || f->m_height<0) {
    TEXTMETRIC	tm;
    GetTextMetrics(m_hDC,&tm);
    height=tm.tmAscent+tm.tmDescent+tm.tmExternalLeading;
    ascent=tm.tmAscent;
    if (f) {
      f->m_height=height;
      f->m_ascent=ascent;
    }
  } else {
    height=f->m_height;
    ascent=f->m_ascent;
  }
}

int  CFDC::GetHypWidth() {
  Font	*f=(Font*)m_hFont;
  if (!f || f->m_hwidth<0) {
    SIZE    sz;
    ::GetTextExtentPoint32(m_hDC,_T("-"),1,&sz);
    if (f)
      f->m_hwidth=sz.cx;
    return sz.cx;
  }
  return f->m_hwidth;
}

void  CFDC::SetCacheSize(int cs) {
  if (cs>0 && cs<100)
    g_fcache.m_cachemax=cs;
}

int  CFDC::GetLPX() {
  if (!m_lpx)
    m_lpx=GetDeviceCaps(m_hDC,LOGPIXELSX);
  return m_lpx;
}

void  CFDC::GetTextExtent(const wchar_t *str,int len,
			  int width,int& nch,int *dx,SIZE& sz)
{
  GetTextExtentExPoint(m_hDC,str,len,width,&nch,dx,&sz);
}

void  CFDC::SetColor(COLORREF c) {
  if (c!=m_pfg) {
    HGDIOBJ obj=::SelectObject(m_hDC,::CreatePen(PS_SOLID,0,c));
    if (m_hOrigPen)
      DeleteObject(obj);
    else
      m_hOrigPen=obj;
    m_pfg=c;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -