| 923 | } |
| 924 | |
| 925 | QImage Viewer::grabMagnifiedRegion(const QPoint &viewerPos, const QSize &glassSize, float zoomLevel) const |
| 926 | { |
| 927 | const int glassW = glassSize.width(); |
| 928 | const int glassH = glassSize.height(); |
| 929 | const int zoomW = static_cast<int>(glassW * zoomLevel); |
| 930 | const int zoomH = static_cast<int>(glassH * zoomLevel); |
| 931 | const QColor bgColor = Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor); |
| 932 | |
| 933 | if (continuousScroll) { |
| 934 | // --- continuous mode --- |
| 935 | // map viewer coords to continuousWidget coords |
| 936 | const int scrollPos = verticalScrollBar()->sliderPosition(); |
| 937 | const int cwX = viewerPos.x(); |
| 938 | const int cwY = viewerPos.y() + scrollPos; |
| 939 | const int widgetW = continuousWidget->width(); |
| 940 | |
| 941 | // use the page under the cursor to derive source-to-widget scale factors, |
| 942 | // so the result image is sized at source resolution (like single-page mode) |
| 943 | int centerPageIdx = continuousViewModel->pageAtY(cwY); |
| 944 | centerPageIdx = qBound(0, centerPageIdx, continuousViewModel->numPages() - 1); |
| 945 | const QImage *centerImg = continuousPageProvider->image(centerPageIdx); |
| 946 | const QSize centerScaledSize = continuousViewModel->scaledPageSize(centerPageIdx); |
| 947 | |
| 948 | float wFactor = 1.0f, hFactor = 1.0f; |
| 949 | if (centerImg && !centerImg->isNull() && !centerScaledSize.isEmpty()) { |
| 950 | wFactor = static_cast<float>(centerImg->width()) / centerScaledSize.width(); |
| 951 | hFactor = static_cast<float>(centerImg->height()) / centerScaledSize.height(); |
| 952 | } |
| 953 | |
| 954 | // result image sized in source-resolution pixels (full quality) |
| 955 | const int resultW = static_cast<int>(zoomW * wFactor); |
| 956 | const int resultH = static_cast<int>(zoomH * hFactor); |
| 957 | |
| 958 | QImage result(resultW, resultH, QImage::Format_RGB32); |
| 959 | result.fill(bgColor); |
| 960 | |
| 961 | // zoom region in widget coordinates (centered on cursor) |
| 962 | const int regionLeft = cwX - zoomW / 2; |
| 963 | const int regionTop = cwY - zoomH / 2; |
| 964 | const int regionRight = regionLeft + zoomW; |
| 965 | const int regionBottom = regionTop + zoomH; |
| 966 | |
| 967 | // find which pages overlap the zoom region |
| 968 | int firstPage = continuousViewModel->pageAtY(regionTop); |
| 969 | int lastPage = continuousViewModel->pageAtY(regionBottom); |
| 970 | firstPage = qBound(0, firstPage, continuousViewModel->numPages() - 1); |
| 971 | lastPage = qBound(0, lastPage, continuousViewModel->numPages() - 1); |
| 972 | |
| 973 | QPainter painter(&result); |
| 974 | for (int i = firstPage; i <= lastPage; ++i) { |
| 975 | const QImage *srcImg = continuousPageProvider->image(i); |
| 976 | if (!srcImg || srcImg->isNull()) { |
| 977 | continue; |
| 978 | } |
| 979 | |
| 980 | const QSize scaledSize = continuousViewModel->scaledPageSize(i); |
| 981 | const int pageY = continuousViewModel->yPositionForPage(i); |
| 982 | int pageX = (widgetW - scaledSize.width()) / 2; |
no test coverage detected