File indexing completed on 2024-04-21 14:46:32
0001 /* 0002 SPDX-FileCopyrightText: 2011 Rafał Kułaga <rl.kulaga@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "simplefovexporter.h" 0008 0009 #include "kstars.h" 0010 #include "kstarsdata.h" 0011 #include "skymap.h" 0012 #include "skyqpainter.h" 0013 #include "fov.h" 0014 #include "skymapcomposite.h" 0015 #include "kstars/Options.h" 0016 0017 SimpleFovExporter::SimpleFovExporter() 0018 : m_KSData(KStarsData::Instance()), m_Map(KStars::Instance()->map()), m_StopClock(false), m_OverrideFovShape(false), 0019 m_DrawFovSymbol(false), m_PrevClockState(false), m_PrevSlewing(false), m_PrevPoint(nullptr), m_PrevZoom(0) 0020 { 0021 } 0022 0023 void SimpleFovExporter::exportFov(SkyPoint *point, FOV *fov, QPaintDevice *pd) 0024 { 0025 saveState(true); 0026 pExportFov(point, fov, pd); 0027 restoreState(true); 0028 } 0029 0030 void SimpleFovExporter::exportFov(FOV *fov, QPaintDevice *pd) 0031 { 0032 pExportFov(nullptr, fov, pd); 0033 } 0034 0035 void SimpleFovExporter::exportFov(QPaintDevice *pd) 0036 { 0037 SkyQPainter painter(m_Map, pd); 0038 painter.begin(); 0039 0040 painter.drawSkyBackground(); 0041 0042 // translate painter coordinates - it's necessary to extract only the area of interest (FOV) 0043 int dx = (m_Map->width() - pd->width()) / 2; 0044 int dy = (m_Map->height() - pd->height()) / 2; 0045 painter.translate(-dx, -dy); 0046 0047 m_KSData->skyComposite()->draw(&painter); 0048 m_Map->getSkyMapDrawAbstract()->drawOverlays(painter, false); 0049 } 0050 0051 void SimpleFovExporter::exportFov(const QList<SkyPoint *> &points, const QList<FOV *> &fovs, 0052 const QList<QPaintDevice *> &pds) 0053 { 0054 Q_ASSERT(points.size() == fovs.size() && fovs.size() == pds.size()); 0055 0056 saveState(true); 0057 0058 for (int i = 0; i < points.size(); i++) 0059 { 0060 exportFov(points.value(i), fovs.at(i), pds.value(i)); 0061 } 0062 0063 restoreState(true); 0064 } 0065 0066 void SimpleFovExporter::exportFov(const QList<SkyPoint *> &points, FOV *fov, const QList<QPaintDevice *> &pds) 0067 { 0068 Q_ASSERT(points.size() == pds.size()); 0069 0070 saveState(true); 0071 0072 for (int i = 0; i < points.size(); i++) 0073 { 0074 exportFov(points.at(i), fov, pds.at(i)); 0075 } 0076 0077 restoreState(true); 0078 } 0079 0080 void SimpleFovExporter::pExportFov(SkyPoint *point, FOV *fov, QPaintDevice *pd) 0081 { 0082 if (point) 0083 { 0084 // center sky map on selected point 0085 m_Map->setClickedPoint(point); 0086 m_Map->slotCenter(); 0087 } 0088 0089 // this is temporary 'solution' that will be changed during the implementation of printing 0090 // on large paper sizes (>A4), in which case it'll be desirable to export high-res FOV 0091 // representations 0092 if (pd->height() > m_Map->height() || pd->width() > m_Map->width()) 0093 { 0094 return; 0095 } 0096 0097 // calculate zoom factor 0098 double zoom = 0; 0099 QRegion region; 0100 int regionX(0), regionY(0); 0101 double fovSizeX(0), fovSizeY(0); 0102 if (fov->sizeX() > fov->sizeY()) 0103 { 0104 zoom = calculateZoomLevel(pd->width(), fov->sizeX()); 0105 0106 // calculate clipping region size 0107 fovSizeX = calculatePixelSize(fov->sizeX(), zoom); 0108 fovSizeY = calculatePixelSize(fov->sizeY(), zoom); 0109 regionX = 0; 0110 regionY = 0.5 * (pd->height() - fovSizeY); 0111 } 0112 0113 else 0114 { 0115 zoom = calculateZoomLevel(pd->height(), fov->sizeY()); 0116 0117 // calculate clipping region size 0118 fovSizeX = calculatePixelSize(fov->sizeX(), zoom); 0119 fovSizeY = calculatePixelSize(fov->sizeY(), zoom); 0120 regionX = 0.5 * (pd->width() - fovSizeX); 0121 regionY = 0; 0122 } 0123 0124 if (fov->shape() == FOV::SQUARE) 0125 { 0126 region = QRegion(regionX, regionY, fovSizeX, fovSizeY, QRegion::Rectangle); 0127 } 0128 0129 else 0130 { 0131 region = QRegion(regionX, regionY, fovSizeX, fovSizeY, QRegion::Ellipse); 0132 } 0133 0134 m_Map->setZoomFactor(zoom); 0135 0136 SkyQPainter painter(m_Map, pd); 0137 painter.begin(); 0138 0139 painter.drawSkyBackground(); 0140 0141 if (!m_OverrideFovShape) 0142 { 0143 painter.setClipRegion(region); 0144 } 0145 // translate painter coordinates - it's necessary to extract only the area of interest (FOV) 0146 int dx = (m_Map->width() - pd->width()) / 2; 0147 int dy = (m_Map->height() - pd->height()) / 2; 0148 painter.translate(-dx, -dy); 0149 0150 m_KSData->skyComposite()->draw(&painter); 0151 m_Map->getSkyMapDrawAbstract()->drawOverlays(painter, false); 0152 0153 // reset painter coordinate transform to paint FOV symbol in the center 0154 painter.resetTransform(); 0155 0156 if (m_DrawFovSymbol) 0157 { 0158 fov->draw(painter, zoom); 0159 } 0160 } 0161 0162 void SimpleFovExporter::saveState(bool savePos) 0163 { 0164 // stop simulation if it's not already stopped 0165 m_PrevClockState = m_KSData->clock()->isActive(); 0166 if (m_StopClock && m_PrevClockState) 0167 { 0168 m_KSData->clock()->stop(); 0169 } 0170 0171 // disable useAnimatedSlewing option 0172 m_PrevSlewing = Options::useAnimatedSlewing(); 0173 if (m_PrevSlewing) 0174 { 0175 Options::setUseAnimatedSlewing(false); 0176 } 0177 0178 // save current central point and zoom level 0179 m_PrevPoint = savePos ? m_Map->focusPoint() : nullptr; 0180 m_PrevZoom = Options::zoomFactor(); 0181 } 0182 0183 void SimpleFovExporter::restoreState(bool restorePos) 0184 { 0185 // restore previous useAnimatedSlewing option 0186 if (m_PrevSlewing) 0187 { 0188 Options::setUseAnimatedSlewing(true); 0189 } 0190 0191 if (restorePos) 0192 { 0193 // restore previous central point 0194 m_Map->setClickedPoint(m_PrevPoint); 0195 m_Map->slotCenter(); 0196 } 0197 // restore previous zoom level 0198 m_Map->setZoomFactor(m_PrevZoom); 0199 0200 // restore clock state (if it was stopped) 0201 if (m_StopClock && m_PrevClockState) 0202 { 0203 m_KSData->clock()->start(); 0204 } 0205 }