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);
}
示例#2
0
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());
}
示例#3
0
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);
}