📄 tview.cpp
字号:
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 + -