void ZoomToSelection(WindowInfo *win, float factor, bool scrollToFit, bool relative) { if (!win->IsDocLoaded()) return; PointI pt; bool zoomToPt = win->showSelection && win->selectionOnPage; // either scroll towards the center of the current selection if (zoomToPt) { RectI selRect; for (size_t i = 0; i < win->selectionOnPage->Count(); i++) { selRect = selRect.Union(win->selectionOnPage->At(i).GetRect(win->dm)); } ClientRect rc(win->hwndCanvas); pt.x = 2 * selRect.x + selRect.dx - rc.dx / 2; pt.y = 2 * selRect.y + selRect.dy - rc.dy / 2; pt.x = limitValue(pt.x, selRect.x, selRect.x + selRect.dx); pt.y = limitValue(pt.y, selRect.y, selRect.y + selRect.dy); int pageNo = win->dm->GetPageNoByPoint(pt); if (!win->dm->ValidPageNo(pageNo) || !win->dm->PageVisible(pageNo)) zoomToPt = false; } // or towards the top-left-most part of the first visible page else { int page = win->dm->FirstVisiblePageNo(); PageInfo *pageInfo = win->dm->GetPageInfo(page); if (pageInfo) { RectI visible = pageInfo->pageOnScreen.Intersect(win->canvasRc); pt = visible.TL(); int pageNo = win->dm->GetPageNoByPoint(pt); if (!visible.IsEmpty() && win->dm->ValidPageNo(pageNo) && win->dm->PageVisible(pageNo)) zoomToPt = true; } } if (!relative && (ZOOM_FIT_PAGE == factor || ZOOM_FIT_CONTENT == factor) && scrollToFit) zoomToPt = false; if (relative) win->dm->ZoomBy(factor, zoomToPt ? &pt : NULL); else win->dm->ZoomTo(factor, zoomToPt ? &pt : NULL); UpdateToolbarState(win); }
void EnsureAreaVisibility(RectI& r) { // adjust to the work-area of the current monitor (not necessarily the primary one) RectI work = GetWorkAreaRect(r); // make sure that the window is neither too small nor bigger than the monitor if (r.dx < MIN_WIN_DX || r.dx > work.dx) r.dx = (int)min(work.dy * DEF_PAGE_RATIO, work.dx); if (r.dy < MIN_WIN_DY || r.dy > work.dy) r.dy = work.dy; // check whether the lower half of the window's title bar is // inside a visible working area int captionDy = GetSystemMetrics(SM_CYCAPTION); RectI halfCaption(r.x, r.y + captionDy / 2, r.dx, captionDy / 2); if (halfCaption.Intersect(work).IsEmpty()) r = RectI(work.TL(), r.Size()); }
void ZoomToSelection(WindowInfo* win, float factor, bool scrollToFit, bool relative) { PointI pt; bool zoomToPt = false; if (win->AsFixed()) { DisplayModel* dm = win->AsFixed(); // when not zooming to fit (which contradicts zooming to a specific point), ... if (!relative && (ZOOM_FIT_PAGE == factor || ZOOM_FIT_CONTENT == factor) && scrollToFit) { zoomToPt = false; } // either scroll towards the center of the current selection (if there is any) ... else if (win->showSelection && win->currentTab->selectionOnPage) { RectI selRect; for (SelectionOnPage& sel : *win->currentTab->selectionOnPage) { selRect = selRect.Union(sel.GetRect(dm)); } ClientRect rc(win->hwndCanvas); pt.x = 2 * selRect.x + selRect.dx - rc.dx / 2; pt.y = 2 * selRect.y + selRect.dy - rc.dy / 2; pt.x = limitValue(pt.x, selRect.x, selRect.x + selRect.dx); pt.y = limitValue(pt.y, selRect.y, selRect.y + selRect.dy); int pageNo = dm->GetPageNoByPoint(pt); zoomToPt = dm->ValidPageNo(pageNo) && dm->PageVisible(pageNo); } // or towards the top-left-most part of the first visible page else { int page = dm->FirstVisiblePageNo(); PageInfo* pageInfo = dm->GetPageInfo(page); if (pageInfo) { RectI visible = pageInfo->pageOnScreen.Intersect(win->canvasRc); pt = visible.TL(); int pageNo = dm->GetPageNoByPoint(pt); zoomToPt = !visible.IsEmpty() && dm->ValidPageNo(pageNo) && dm->PageVisible(pageNo); } } } win->ctrl->SetZoomVirtual(factor * (relative ? win->ctrl->GetZoomVirtual(true) : 1), zoomToPt ? &pt : nullptr); UpdateToolbarState(win); }
/* Draws the about screen and remembers some state for hyperlinking. It transcribes the design I did in graphics software - hopeless to understand without seeing the design. */ static void DrawAbout(HWND hwnd, HDC hdc, RectI rect, Vec<StaticLinkInfo>& linkInfo) { HPEN penBorder = CreatePen(PS_SOLID, ABOUT_LINE_OUTER_SIZE, WIN_COL_BLACK); HPEN penDivideLine = CreatePen(PS_SOLID, ABOUT_LINE_SEP_SIZE, WIN_COL_BLACK); HPEN penLinkLine = CreatePen(PS_SOLID, ABOUT_LINE_SEP_SIZE, COL_BLUE_LINK); ScopedFont fontLeftTxt(GetSimpleFont(hdc, LEFT_TXT_FONT, LEFT_TXT_FONT_SIZE)); ScopedFont fontRightTxt(GetSimpleFont(hdc, RIGHT_TXT_FONT, RIGHT_TXT_FONT_SIZE)); HGDIOBJ origFont = SelectObject(hdc, fontLeftTxt); /* Just to remember the orig font */ ClientRect rc(hwnd); RECT rTmp = rc.ToRECT(); ScopedGdiObj<HBRUSH> brushAboutBg(CreateSolidBrush(GetAboutBgColor())); FillRect(hdc, &rTmp, brushAboutBg); /* render title */ RectI titleRect(rect.TL(), CalcSumatraVersionSize(hdc)); ScopedGdiObj<HBRUSH> bgBrush(CreateSolidBrush(GetLogoBgColor())); SelectObject(hdc, bgBrush); SelectObject(hdc, penBorder); #ifndef ABOUT_USE_LESS_COLORS Rectangle(hdc, rect.x, rect.y + ABOUT_LINE_OUTER_SIZE, rect.x + rect.dx, rect.y + titleRect.dy + ABOUT_LINE_OUTER_SIZE); #else RectI titleBgBand(0, rect.y, rc.dx, titleRect.dy); RECT rcLogoBg = titleBgBand.ToRECT(); FillRect(hdc, &rcLogoBg, bgBrush); PaintLine(hdc, RectI(0, rect.y, rc.dx, 0)); PaintLine(hdc, RectI(0, rect.y + titleRect.dy, rc.dx, 0)); #endif titleRect.Offset((rect.dx - titleRect.dx) / 2, 0); DrawSumatraVersion(hdc, titleRect); /* render attribution box */ SetTextColor(hdc, ABOUT_BORDER_COL); SetBkMode(hdc, TRANSPARENT); #ifndef ABOUT_USE_LESS_COLORS Rectangle(hdc, rect.x, rect.y + titleRect.dy, rect.x + rect.dx, rect.y + rect.dy); #endif /* render text on the left*/ SelectObject(hdc, fontLeftTxt); for (AboutLayoutInfoEl *el = gAboutLayoutInfo; el->leftTxt; el++) { TextOut(hdc, el->leftPos.x, el->leftPos.y, el->leftTxt, (int)str::Len(el->leftTxt)); } /* render text on the right */ SelectObject(hdc, fontRightTxt); SelectObject(hdc, penLinkLine); linkInfo.Reset(); for (AboutLayoutInfoEl *el = gAboutLayoutInfo; el->leftTxt; el++) { bool hasUrl = HasPermission(Perm_DiskAccess) && el->url; SetTextColor(hdc, hasUrl ? COL_BLUE_LINK : ABOUT_BORDER_COL); TextOut(hdc, el->rightPos.x, el->rightPos.y, el->rightTxt, (int)str::Len(el->rightTxt)); if (hasUrl) { int underlineY = el->rightPos.y + el->rightPos.dy - 3; PaintLine(hdc, RectI(el->rightPos.x, underlineY, el->rightPos.dx, 0)); linkInfo.Append(StaticLinkInfo(el->rightPos, el->url, el->url)); } } SelectObject(hdc, penDivideLine); RectI divideLine(gAboutLayoutInfo[0].rightPos.x - ABOUT_LEFT_RIGHT_SPACE_DX, rect.y + titleRect.dy + 4, 0, rect.y + rect.dy - 4 - gAboutLayoutInfo[0].rightPos.y); PaintLine(hdc, divideLine); SelectObject(hdc, origFont); DeleteObject(penBorder); DeleteObject(penDivideLine); DeleteObject(penLinkLine); }