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

📄 tview.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      if (x) {
	rma.right=rma.left+x;
	TDrawText(dc.DC(),rma.left,rma.top,cli,rma,NULL,0,NULL);
      }
      rma.left=line.left+x+img.width;
      rma.right=line.right;
      if (rma.right!=rma.left)
	TDrawText(dc.DC(),rma.left,rma.top,cli,rma,NULL,0,NULL);
      TDrawBitmap(dc.DC(),img.hBmp,line.left+x,line.top,
		  l.height,cli,img.width,img.height,l.yoffset);
    } else
      TDrawText(dc.DC(),line.left,line.top,cli,line,NULL,0,NULL);
  } else if (l.flags&Line::defstyle) {
    int	  fh,fa; // fontheight,fontascent

    dc.SelectFont(0,0);
    dc.GetFontSize(fh,fa);
    TDrawText(dc.DC(),x+line.left,line.top+l.base-fa,cli,line,
      l.str,l.str.size(),l.dx);
  } else {
    ComplexLine(dc,cli,line,x,l);
  }
}

void  CTView::HighlightBookmarks(CFDC& dc,const RECT& cli,int left,
				 int margin,int y,const Line& l,
				 FilePos bmkstart,FilePos bmkend)
{
  RECT	    r;
  int	    j,nc;

  while (m_textfile->bmk().BookmarkFind(bmkstart,bmkend)) {
    r.top=y;
    r.left=left+margin+l.ispace;
    nc=bmkstart.off-l.pos.off;
    for (j=0;j<nc;++j)
      r.left+=l.dx[j];
    r.right=r.left;
    r.bottom=y+l.height;
    TDrawLine(dc.DC(),cli,r);
    r.right=r.left+3;
    r.bottom=r.top;
    TDrawLine(dc.DC(),cli,r);
    bmkstart.off++;
  }
}

void CTView::PaintColumn(CFDC &dc,const RECT& update,
			 const RECT& col,const RECT& cli,IGetLine *gl,
			 int margin,bool chkbmk)
{
  RECT	  line;
  dc.SetTextColor(C_NORM);
  dc.SetBkColor(v_C_BG());

  line.top=col.top;

  int	i;
  int	pl=gl->Length();

  for (i=0;i<pl;++i,line.top=line.bottom) {
    line.left=col.left;
    line.right=col.right;
    const Line&	l=gl->At(i);
    line.bottom=line.top+l.height;
    if (!Overlap(line,update))
      continue;
    PaintLine(dc,cli,line,margin,l);
  }
  line.left=col.left;
  line.right=col.right;
  line.bottom=col.bottom;
  TDrawText(dc.DC(),line.left,line.top,cli,line,NULL,0,NULL);
  if (chkbmk && pl) { // now paint bookmarks if any
    FilePos bmkstart,bmkend;
    bmkend=gl->At(0).pos;
    dc.SetColor(C_TOCBM);
    int	    y=col.top;
    for (i=0;i<pl;++i) {
      const Line&	l=gl->At(i);
      bmkstart=bmkend;
      bmkend=gl->At(i+1).pos;
      HighlightBookmarks(dc,cli,col.left,margin,y,l,bmkstart,bmkend);
      y+=l.height;
    }
  }
}

/*
  Generic line structure:

  +-----------------+------+----------------------------+----+------------+
  |                 +  LM  +       text                 + RM +            +
  +-----------------+------+----------------------------+----+------------+
		    |                                        +---
		    |					      this is the
		    |                                         currently
		    |                                         painted coulmn
		    +--------------------------------------------

	  LM is the left margin an can be 0, same for RM

	  normally we iterate over text extracting segments with the same
	  formatting and painting them, but initial LM is handled separately.
	  if LM is not zero, and the first text segment has a different
	  backgound, then we reset the segment and paint only LM, otherwise
	  LM is attached to the first text segment. As a shortcut, when the
	  entire line has the same default formatting (as is the case for
	  99% of all text), the painting is done with the single
	  TDrawText call in the PaintColumn main loop.
*/

void  CTView::ComplexLine(CFDC& dc,const RECT& cli,RECT& line,
			  int x,const Line& l)
{
  int		  flags=ETO_OPAQUE;
  int		  len=l.str.size();
  int		  off=0;
  int		  fh,fa;
  int		  x0=line.left;
  int		  width=line.right-line.left;
  // check if the backgound is the same
  for (int i=0;i<len;++i)
    if (l.attr[i].hibg)
      goto normal_draw;
  // all bg is normal, so we clear the entire line and use transparent mode
  dc.SetBkColor(v_C_BG());
  TDrawText(dc.DC(),line.left,line.top,cli,line,NULL,0,NULL);
  flags=0;
normal_draw:
  while (len>0) {
    line.right=x0+x;
    COLORREF  bg=v_C_BG();
    Attr      attr=l.attr[off];
    int	      run=0;
    if (attr.img) {
      line.right+=l.dx[off];
      run=1;
    } else
      while (run<len && attr.wa==l.attr[off+run].wa) {
	line.right+=l.dx[off+run];
	++run;
      }
    if (run==len && !attr.hibg) // fill till the end
      line.right=x0+width;
    dc.SelectFont(attr.fsize,attr.fontattr());
    dc.GetFontSize(fh,fa);
    // non-default backgound, left margin present, and starting at the
    // very left edge of the column, then discard fisrt segment
    if (attr.hibg && x && line.left==x0) {
      line.right=x0+x;
      run=0;
      attr.wa=0;
    } else
      dc.SetTextColor(C_TCOLOR(attr.color));
    dc.SetBkColor(attr.hibg ? C_HBG : v_C_BG());
    const wchar_t   *txt=attr.img ? L" " : l.str+off;
    TDrawText(dc.DC(),x0+x,line.top+l.base-fa,cli,line,txt,run,l.dx+off,flags);
    if (attr.img) {
      // slow, but we were adding the feature later, and
      // the code wasn't designed for this in the first
      // place
      Paragraph	p(m_textfile->GetParagraph(l.pos.docid,l.pos.para));
      int	idx=l.str[off];
      Image	img;
      if (idx>=0 && idx<p.links.size() &&
	  m_textfile->GetImage(p.links[idx].target,dc.DC(),
	  l.dx[off],
	  l.height,m_TextDisp.angle,img))
	TDrawBitmap(dc.DC(),img.hBmp,x0+x,line.top+l.base-img.height,
	  l.height,cli,img.width,img.height,0);
    }
    len-=run;
    off+=run;
    line.left=line.right;
    x=line.left-x0;
  }
  if (x<width && flags) { // fill right part
    line.right=x0+width;
    dc.SetBkColor(v_C_BG());
    TDrawText(dc.DC(),line.left,line.top,cli,line,NULL,0,NULL);
  }
  dc.SetTextColor(C_NORM);
  dc.SetBkColor(v_C_BG());
}

void  CTView::PaintUserInput(CFDC& dc,const RECT& rc,const RECT& cli,
			     const Buffer<wchar_t>& text)
{
  dc.SelectFont(USERINPUTSIZE,USERINPUTFLAGS);
  dc.SetBkColor(C_UINPBG);
  dc.SetTextColor(C_UINP);
  TDrawText(dc.DC(),rc.left+2,rc.top+2,cli,rc,text,text.size(),NULL);
}

void CTView::CalcSizes()
{
  if (m_TextDisp.angle==900 || m_TextDisp.angle==2700) {
    m_Window.rheight=m_Window.cli.right-m_Window.cli.left;
    m_Window.rwidth=m_Window.cli.bottom-m_Window.cli.top;
  } else {
    m_Window.rheight=m_Window.cli.bottom-m_Window.cli.top;
    m_Window.rwidth=m_Window.cli.right-m_Window.cli.left;
  }
  m_Window.width=m_Window.rwidth;
  m_Window.height=m_Window.rheight;
  if (m_Window.showprogress())
    m_Window.height-=m_Window.progress_height;
  m_Window.width/=m_Window.columns;
  if (m_Window.width==0)
    m_Window.width=1;
  if (m_Window.height==0)
    m_Window.height=1;
  CFDC	fdc(m_hWnd);
  // calculate userinput window position
  fdc.SelectFont(3,0);
  int	  height,ascent;
  fdc.GetFontSize(height,ascent);
  int	  uwidth=m_Window.rwidth;
  if (uwidth>MAXUSERINPUTWIDTH)
    uwidth=MAXUSERINPUTWIDTH;
  m_UI.rc.left=(m_Window.rwidth-uwidth)/2;
  m_UI.rc.right=m_UI.rc.left+uwidth;
  m_UI.rc.top=20; // XXX
  m_UI.rc.bottom=m_UI.rc.top+height+4;
  if (m_formatter.get()) {
    m_formatter->SetSize(m_Window.width,m_TextDisp.margin_width,
      m_Window.height,m_Window.columns,m_TextDisp.angle);
    m_formatter->Reformat(fdc);
  }
  m_BP.visible=false;
}

void CTView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
  UINT	cmd;

  // Check for key chatter and ignore event
  DWORD	now=::GetTickCount();
  if (m_Window.autorepeatlimit && now-m_Window.lastkeypress<REPEAT_THRESHOLD)
    return;
  m_Window.lastkeypress=now;

  // spaces are handled separately in OnChar
  if (nChar!=VK_SPACE && Keys::TranslateKey(nChar,cmd,
	  m_Window.rotbuttons ? m_TextDisp.angle : 0))
  {
    // repeated key
    if (nFlags&0x4000 && CTVApp::TopQueuedCmd()==cmd)
      return;
    CTVApp::QueueCmd(cmd);
    return;
  }

  CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CTView::OnLineUp() { Move(mBack,mLine); }
void CTView::OnLineDown() { Move(mFwd,mLine); }
void CTView::OnPageUp() { Move(mBack,mPage); }
void CTView::OnPageDown() { Move(mFwd,mPage); }
void CTView::OnStartFile() { Move(mBack,mFile); }
void CTView::OnEndFile() { Move(mFwd,mFile); }

void CTView::Move(int dir, int amount)
{
  if (dir==mBack) {
    if (m_formatter->AtTop())
      return;
  } else {
    if (m_formatter->AtEof())
      return;
  }
  Line	    l;
  CFDC	    fdc(m_hWnd);
  if (dir==mBack)
    switch (amount) {
    case mLine:
      m_formatter->FormatBack(fdc,m_formatter->GetLine(
	m_formatter->Length()-1).pos,m_formatter->Top());
      break;
    case mFile:
      PushPos();
      m_formatter->FormatFwd(fdc,m_formatter->Sof());
      break;
    default:
    case mPage:
      m_formatter->FormatBack(fdc,m_formatter->Top(),FilePos());
      break;
    }
  else
    switch (amount) {
    case mLine:
      m_formatter->FormatFwd(fdc,m_formatter->GetLine(1).pos);
      break;
    case mFile:
      PushPos();
      m_formatter->FormatBack(fdc,m_formatter->Eof(),FilePos());
      break;
    default:
    case mPage:
      m_formatter->FormatFwdAdj(fdc);
      break;
    }
  QueueRepaint();

  m_BP.bmkidx=-1;
}

BOOL CTView::OnEraseBkgnd(CDC* pDC)
{
  return FALSE; // we'll erase it in OnPaint
}

class CAboutDialog: public CDialog {
public:
  CAboutDialog(UINT id,CWnd *parent=NULL) : CDialog(id,parent) { }
  virtual BOOL	OnInitDialog();
  virtual BOOL	OnCommand(WPARAM,LPARAM);
  CString   m_info;
  bool	    m_finfo;
};

#include "buildnum.h"

#define	FILE_INFO_FORMAT	_T("File: %s\r\nSize: %d byte(s), %d paragraph(s)\r\n\r\nFormat: %s\r\nEncoding: %s\r\nCompression: %s\r\n\r\nPosition: %d:%d")
#define	ABOUT_FORMAT1	\
	  _T("expat 1.95.5 Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper.\r\n\r\n") \
	  _T("jpeg6b Copyright (C) 1991-1998, Thomas G. Lane.\r\n\r\n") \
	  _T("libpng version 1.2.8 Copyright (c) 1998-2002 Glenn Randers-Pehrson, Copyright (c) 1996-1997 Andreas Dilger, Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\r\n\r\n") \
	  _T("zlib 1.2.2 Copyright (C) 1995-2002 Mark Adler.")
#if PSPC
#define	ABOUT_FORMAT2	_T("Haali Reader v2.0b%d\nCopyright (C) 2001-2005\nMike Matsnev\nhttp://haali.cs.msu.ru/pocketpc/")
#else
#define ABOUT_FORMAT2	_T("Haali Reader v2.0b%d\nCopyright (C) 2001-2005 Mike Matsnev\nhttp://haali.cs.msu.ru/pocketpc/")
#endif

BOOL CAboutDialog::OnInitDialog() {
  CDialog::OnInitDialog();
  CString ver;
  ver.Format(ABOUT_FORMAT2,BUILD_NUM,BUILD_DATE);
  SetDlgItemText(IDC_ABOUTVER,ver);
  SetDlgItemText(IDC_ABOUTINFO,m_info);
  m_finfo=true;
  return TRUE;
}

BOOL CAboutDialog::OnCommand(WPARAM wParam,LPARAM lParam) {
  if (LOWORD(wParam)==IDC_ABOUT_TOGGLE) {
    if (m_finfo) {
      SetDlgItemText(IDC_ABOUTINFO,ABOUT_FORMAT1);
      SetDlgItemText(IDC_ABOUT_TOGGLE,_T("File Info"));
    } else {
      SetDlgItemText(IDC_ABOUTINFO,m_info);
      SetDlgItemText(IDC_ABOUT_TOGGLE,_T("Copyrights"));
    }
    m_finfo=!m_finfo;
  }
  return CDialog::OnCommand(wParam,lParam);
}

void CTView::OnAppAbout()
{
  CAboutDialog	  dlg(IDD_ABOUTBOX,this);
  CString	  fmt,enc;
  FilePos	  p=CurFilePos();

  if (m_textfile->GetFormat()<0) { // auto
    fmt.Format(_T("Auto, detected: %s"),
      m_textfile->GetFormatName(m_textfile->GetRealFormat()));
  } else { // set by user
    fmt=m_textfile->GetFormatName(m_textfile->GetFormat());
  }
  if (m_textfile->GetEncoding()<0) { // auto
    enc.Format(_T("Auto, detected: %s"),
      m_textfile->GetEncodingName(m_textfile->GetRealEncoding()));
  } else {
    enc=m_textfile->GetEncodingName(m_textfile->GetEncoding());
  }
  dlg.m_info.Format(FILE_INFO_FORMAT,
    (LPCTSTR)m_textfile->Name(),m_textfile->ByteLength(),
    m_textfile->Length(CurFilePos().docid),(LPCTSTR)fmt,(LPCTSTR)enc,
    (LPCTSTR)m_textfile->CompressionInfo(),
    p.para,p.off);
  dlg.DoModal();
}

void CTView::OnUpdateOptions(CCmdUI* pCmdUI) {
  pCmdUI->Enable();
}

void CTView::OnOptions()
{
  COptionsDialog    opt;

  opt.m_bold=m_TextDisp.bold;
  opt.m_cleartype=m_TextDisp.cleartype;
  opt.m_justify=m_TextDisp.justify;
  opt.m_margins=m_TextDisp.margin_width;
  opt.m_size=m_TextDisp.fontsize;
  opt.m_face=m_TextDisp.fontface;
  opt.m_hyphenate=m_TextDisp.hyphenate;
  opt.m_angle=m_TextDisp.angle/900;
  opt.m_columns=m_Window.columns-1;

  if (opt.DoModal()==IDOK) { // try to apply settings
    bool    update=false;
    if (m_TextDisp.fontface!=opt.m_face || m_TextDisp.fontsize!=opt.m_size ||
	m_TextDisp.bold!=(opt.m_bold!=0) || m_TextDisp.cleartype!=opt.m_cleartype ||
	m_TextDisp.angle!=opt.m_angle*900 || m_TextDisp.margin_width!=opt.m_margins ||
	m_TextDisp.justify!=(opt.m_justify!=0) ||
	m_TextDisp.hyphenate!=(opt.m_hyphenate!=0))
    {
      m_TextDisp.hyphenate=(opt.m_hyphenate!=0);
      m_formatter->SetHyphenate(m_TextDisp.hyphenate);
      m_TextDisp.justify=(opt.m_justify!=0);
      m_formatter->SetJustified(m_TextDisp.justify);
      m_TextDisp.angle=opt.m_angle*900;
      m_TextDisp.margin_width=opt.m_margins;
      m_TextDisp.SetFont(opt.m_face,opt.m_bold!=0,opt.m_size,opt.m_cleartype);
      m_TextDisp.SaveSettings();
      SetRotAngle(m_TextDisp.angle);
      update=true;
    }
    if (m_Window.columns!=opt.m_columns+1)
    {
      m_Window.columns=opt.m_columns+1;
      m_Window.SaveSettings();
      update=true;
    }
    if (update) {
      CalcSizes();
      QueueRepaint();
    }
  }
}

void CTView::OnUpdateFileformat(CCmdUI* pCmdUI) {
  pCmdUI->Enable(m_formatter->DocId()>=0);
}

void CTView::OnFileformat()
{
  if (m_formatter->DocId()<0)
    return;
  CFileFormatDialog fmt;

  fmt.m_format=m_textfile->GetFormat()+1;
  fmt.m_encoding=m_textfile->GetEncoding()+1;
  fmt.m_defencoding=CTVApp::GetInt(_T("DefEncoding"),-1)+1;

  if (fmt.DoModal()==IDOK) {
    if (fmt.m_defencoding!=CTVApp::GetInt(_T("DefEncoding"),-1)+1)
      CTVApp::SetInt(_T("DefEncoding"),fmt.m_defencoding-1);
    m_textfile->SetFormatEncoding(fmt.m_format-1,fmt.m_encoding-1);
    m_formatter->SetTop(FilePos());
    CFDC	  fdc(m_hWnd);
    m_formatter->Reformat(fdc);
    QueueRepaint();

⌨️ 快捷键说明

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