mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Some new dimensions
This commit is contained in:
		| @@ -115,6 +115,10 @@ void PDFSnapper::drawSnapPoints(QPainter* painter) const | ||||
|                 newColor = Qt::green; | ||||
|                 break; | ||||
|  | ||||
|             case SnapType::Custom: | ||||
|                 newColor = Qt::black; | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 newColor = Qt::red; | ||||
|                 break; | ||||
| @@ -200,6 +204,20 @@ void PDFSnapper::buildSnapPoints(const PDFWidgetSnapshot& snapshot) | ||||
|             m_snapPoints.push_back(qMove(viewportSnapPoint)); | ||||
|         } | ||||
|  | ||||
|         // Add custom snap points | ||||
|         if (m_currentPage == item.pageIndex) | ||||
|         { | ||||
|             for (const QPointF& customSnapPoint : m_customSnapPoints) | ||||
|             { | ||||
|                 ViewportSnapPoint viewportSnapPoint; | ||||
|                 viewportSnapPoint.type = SnapType::Custom; | ||||
|                 viewportSnapPoint.point = customSnapPoint; | ||||
|                 viewportSnapPoint.pageIndex = item.pageIndex; | ||||
|                 viewportSnapPoint.viewportPoint = item.pageToDeviceMatrix.map(customSnapPoint); | ||||
|                 m_snapPoints.push_back(qMove(viewportSnapPoint)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Fill line projections snap points | ||||
|         if (m_currentPage == item.pageIndex && m_referencePoint.has_value()) | ||||
|         { | ||||
| @@ -298,12 +316,19 @@ const PDFSnapper::ViewportSnapImage* PDFSnapper::getSnappedImage() const | ||||
|  | ||||
| void PDFSnapper::setReferencePoint(PDFInteger pageIndex, QPointF pagePoint) | ||||
| { | ||||
|     // Clear custom snap points, if page changes | ||||
|     if (m_currentPage != pageIndex) | ||||
|     { | ||||
|         m_customSnapPoints.clear(); | ||||
|     } | ||||
|  | ||||
|     m_currentPage = pageIndex; | ||||
|     m_referencePoint = pagePoint; | ||||
| } | ||||
|  | ||||
| void PDFSnapper::clearReferencePoint() | ||||
| { | ||||
|     m_customSnapPoints.clear(); | ||||
|     m_currentPage = -1; | ||||
|     m_referencePoint = std::nullopt; | ||||
| } | ||||
| @@ -312,6 +337,7 @@ void PDFSnapper::clear() | ||||
| { | ||||
|     clearReferencePoint(); | ||||
|  | ||||
|     m_customSnapPoints.clear(); | ||||
|     m_snapPoints.clear(); | ||||
|     m_snapImages.clear(); | ||||
|     m_snappedPoint = std::nullopt; | ||||
| @@ -319,4 +345,14 @@ void PDFSnapper::clear() | ||||
|     m_mousePoint = QPointF(); | ||||
| } | ||||
|  | ||||
| const std::vector<QPointF>& PDFSnapper::getCustomSnapPoints() const | ||||
| { | ||||
|     return m_customSnapPoints; | ||||
| } | ||||
|  | ||||
| void PDFSnapper::setCustomSnapPoints(const std::vector<QPointF>& customSnapPoints) | ||||
| { | ||||
|     m_customSnapPoints = customSnapPoints; | ||||
| } | ||||
|  | ||||
| }   // namespace pdf | ||||
|   | ||||
| @@ -41,7 +41,8 @@ enum class SnapType | ||||
|     PageCenter,        ///< Center of page media box | ||||
|     ImageCenter,       ///< Center of image | ||||
|     LineCenter,        ///< Center of line | ||||
|     GeneratedLineProjection    ///< Generated point to line projections | ||||
|     GeneratedLineProjection,   ///< Generated point to line projections | ||||
|     Custom  ///< Custom snap point | ||||
| }; | ||||
|  | ||||
| /// Contain informations for snap points in the pdf page. Snap points | ||||
| @@ -184,6 +185,14 @@ public: | ||||
|     /// Clears all snapped data, including snap points, images and referenced data. | ||||
|     void clear(); | ||||
|  | ||||
|     /// Returns a vector of custom snap points | ||||
|     const std::vector<QPointF>& getCustomSnapPoints() const; | ||||
|  | ||||
|     /// Sets custom set of snap points. Snap points are always referred to current | ||||
|     /// page index. If page index changes, then custom snap points are cleared. | ||||
|     /// \param customSnapPoints Custom snap points | ||||
|     void setCustomSnapPoints(const std::vector<QPointF>& customSnapPoints); | ||||
|  | ||||
| private: | ||||
|     struct SnappedPoint | ||||
|     { | ||||
| @@ -193,6 +202,7 @@ private: | ||||
|  | ||||
|     std::vector<ViewportSnapPoint> m_snapPoints; | ||||
|     std::vector<ViewportSnapImage> m_snapImages; | ||||
|     std::vector<QPointF> m_customSnapPoints; | ||||
|     std::optional<ViewportSnapPoint> m_snappedPoint; | ||||
|     std::optional<ViewportSnapImage> m_snappedImage; | ||||
|     QPointF m_mousePoint; | ||||
|   | ||||
| @@ -1152,6 +1152,14 @@ QPointF PDFPickTool::getSnappedPoint() const | ||||
|     return m_snapper.getSnappedPoint(); | ||||
| } | ||||
|  | ||||
| void PDFPickTool::setCustomSnapPoints(PDFInteger pageIndex, const std::vector<QPointF>& snapPoints) | ||||
| { | ||||
|     if (m_pageIndex == pageIndex) | ||||
|     { | ||||
|         m_snapper.setCustomSnapPoints(snapPoints); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void PDFPickTool::setActiveImpl(bool active) | ||||
| { | ||||
|     BaseClass::setActiveImpl(active); | ||||
|   | ||||
| @@ -327,6 +327,12 @@ public: | ||||
|     PDFInteger getPageIndex() const { return m_pageIndex; } | ||||
|     const std::vector<QPointF>& getPickedPoints() const { return m_pickedPoints; } | ||||
|  | ||||
|     /// Sets custom snap points for given page. If points on page aren't currently picked, | ||||
|     /// function does nothing. Snap data are not updated. | ||||
|     /// \param pageIndex pageIndex | ||||
|     /// \param snapPoints Custom snap points | ||||
|     void setCustomSnapPoints(PDFInteger pageIndex, const std::vector<QPointF>& snapPoints); | ||||
|  | ||||
|     void resetTool(); | ||||
|  | ||||
| signals: | ||||
|   | ||||
							
								
								
									
										126
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/angle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/angle.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="30mm" | ||||
|    height="30mm" | ||||
|    viewBox="0 0 30 30" | ||||
|    version="1.1" | ||||
|    id="svg8" | ||||
|    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||
|    sodipodi:docname="angle.svg"> | ||||
|   <defs | ||||
|      id="defs2"> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect831" | ||||
|        is_visible="true" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="5.6" | ||||
|      inkscape:cx="113.0623" | ||||
|      inkscape:cy="47.635251" | ||||
|      inkscape:document-units="mm" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="3840" | ||||
|      inkscape:window-height="2035" | ||||
|      inkscape:window-x="-13" | ||||
|      inkscape:window-y="-13" | ||||
|      inkscape:window-maximized="1" /> | ||||
|   <metadata | ||||
|      id="metadata5"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|         <cc:license | ||||
|            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||
|         <dc:creator> | ||||
|           <cc:Agent> | ||||
|             <dc:title>Jakub Melka</dc:title> | ||||
|           </cc:Agent> | ||||
|         </dc:creator> | ||||
|       </cc:Work> | ||||
|       <cc:License | ||||
|          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||
|       </cc:License> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Vrstva 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-267)"> | ||||
|     <path | ||||
|        style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        d="m 11.646391,283.58184 v 0 0" | ||||
|        id="path837" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | ||||
|        d="M 14.315848,269.9747 4.2522322,293.17299" | ||||
|        id="path5831" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | ||||
|        d="M 4.2522322,293.17299 26.03311,293.03125" | ||||
|        id="path5833" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99838448;paint-order:stroke fill markers" | ||||
|        id="path5847" | ||||
|        sodipodi:type="arc" | ||||
|        sodipodi:cx="4.2522321" | ||||
|        sodipodi:cy="293.173" | ||||
|        sodipodi:rx="9.307663" | ||||
|        sodipodi:ry="9.4730282" | ||||
|        sodipodi:start="5.1487213" | ||||
|        sodipodi:end="0" | ||||
|        d="M 8.1858205,284.58752 A 9.307663,9.4730282 0 0 1 13.559895,293.173" | ||||
|        sodipodi:open="true" /> | ||||
|     <g | ||||
|        aria-label="β°" | ||||
|        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.11111069px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||
|        id="text5851"> | ||||
|       <path | ||||
|          d="m 21.426328,283.01723 q 0,1.39182 -0.930176,2.30133 -0.923285,0.9095 -2.335774,0.9095 -0.544325,0 -1.150662,-0.15158 -0.606337,-0.15159 -1.040419,-0.44098 v 3.27974 h -1.295356 v -10.26639 q 0,-1.5434 0.868164,-2.41846 0.875054,-0.87505 2.411567,-0.87505 0.620117,0 1.129991,0.15158 0.516764,0.1447 0.923286,0.46165 0.392741,0.29628 0.627007,0.7717 0.234267,0.47542 0.234267,1.10243 0,0.87505 -0.482314,1.52962 -0.475423,0.64768 -1.350477,0.90262 v 0.11713 q 1.09554,0.17914 1.743218,0.86816 0.647678,0.68213 0.647678,1.757 z m -1.336697,-0.0344 q 0,-0.61323 -0.241157,-0.99219 -0.234266,-0.38585 -0.633897,-0.59944 -0.406521,-0.22049 -0.909505,-0.29628 -0.502984,-0.0758 -1.005968,-0.0758 h -0.248047 v -1.10243 h 0.248047 q 0.454752,0 0.902615,-0.0965 0.447862,-0.10335 0.71658,-0.31005 0.316948,-0.23427 0.468533,-0.57189 0.158474,-0.33762 0.158474,-0.92329 0,-0.7717 -0.475423,-1.17133 -0.475423,-0.39963 -1.226454,-0.39963 -0.502984,0 -0.861274,0.18604 -0.35829,0.17914 -0.585666,0.48231 -0.220486,0.30317 -0.323839,0.70969 -0.103353,0.39963 -0.103353,0.82682 v 5.93935 q 0.454752,0.26182 0.971517,0.37207 0.516764,0.10335 1.012858,0.10335 1.026638,0 1.577854,-0.53744 0.558105,-0.54432 0.558105,-1.5434 z" | ||||
|          style="stroke-width:0.26458332" | ||||
|          id="path5853" | ||||
|          inkscape:connector-curvature="0" /> | ||||
|       <path | ||||
|          d="m 28.7506,278.38702 q 0,1.15756 -0.799262,1.95682 -0.799262,0.79926 -1.963704,0.79926 -1.164442,0 -1.963704,-0.79237 -0.799263,-0.79926 -0.799263,-1.96371 0,-1.15755 0.799263,-1.95681 0.799262,-0.79926 1.963704,-0.79926 1.171332,0 1.963704,0.79926 0.799262,0.79926 0.799262,1.95681 z m -1.136881,0 q 0,-0.7028 -0.461643,-1.17822 -0.461643,-0.48231 -1.164442,-0.48231 -0.7028,0 -1.164442,0.48231 -0.461643,0.47542 -0.461643,1.17822 0,0.71658 0.468533,1.19201 0.475423,0.46853 1.157552,0.46853 0.702799,0 1.164442,-0.48231 0.461643,-0.48232 0.461643,-1.17823 z" | ||||
|          style="stroke-width:0.26458332" | ||||
|          id="path5855" | ||||
|          inkscape:connector-curvature="0" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 6.2 KiB | 
| @@ -46,25 +46,37 @@ void DimensionsPlugin::setWidget(pdf::PDFWidget* widget) | ||||
|     QAction* verticalDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear-vertical.svg"), tr("Vertical Dimension"), this); | ||||
|     QAction* linearDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/linear.svg"), tr("Linear Dimension"), this); | ||||
|     QAction* perimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/perimeter.svg"), tr("Perimeter"), this); | ||||
|     QAction* rectanglePerimeterDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-perimeter.svg"), tr("Rectangle Perimeter"), this); | ||||
|     QAction* areaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/area.svg"), tr("Area"), this); | ||||
|     QAction* rectangleAreaDimensionAction = new QAction(QIcon(":/pdfplugins/dimensiontool/rectangle-area.svg"), tr("Rectangle Area"), this); | ||||
|     QAction* angleAction = new QAction(QIcon(":/pdfplugins/dimensiontool/angle.svg"), tr("Angle"), this); | ||||
|  | ||||
|     horizontalDimensionAction->setObjectName("dimensiontool_LinearHorizontalAction"); | ||||
|     verticalDimensionAction->setObjectName("dimensiontool_LinearVerticalAction"); | ||||
|     linearDimensionAction->setObjectName("dimensiontool_LinearAction"); | ||||
|     perimeterDimensionAction->setObjectName("dimensiontool_PerimeterAction"); | ||||
|     rectanglePerimeterDimensionAction->setObjectName("dimensiontool_RectanglePerimeterAction"); | ||||
|     areaDimensionAction->setObjectName("dimensiontool_AreaAction"); | ||||
|     rectangleAreaDimensionAction->setObjectName("dimensiontool_RectangleAreaAction"); | ||||
|     angleAction->setObjectName("dimensiontool_AngleAction"); | ||||
|  | ||||
|     horizontalDimensionAction->setCheckable(true); | ||||
|     verticalDimensionAction->setCheckable(true); | ||||
|     linearDimensionAction->setCheckable(true); | ||||
|     perimeterDimensionAction->setCheckable(true); | ||||
|     rectanglePerimeterDimensionAction->setCheckable(true); | ||||
|     areaDimensionAction->setCheckable(true); | ||||
|     rectangleAreaDimensionAction->setCheckable(true); | ||||
|     angleAction->setCheckable(true); | ||||
|  | ||||
|     m_dimensionTools[DimensionTool::LinearHorizontal] = new DimensionTool(DimensionTool::LinearHorizontal, widget->getDrawWidgetProxy(), horizontalDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::LinearVertical] = new DimensionTool(DimensionTool::LinearVertical, widget->getDrawWidgetProxy(), verticalDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::Linear] = new DimensionTool(DimensionTool::Linear, widget->getDrawWidgetProxy(), linearDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::Perimeter] = new DimensionTool(DimensionTool::Perimeter, widget->getDrawWidgetProxy(), perimeterDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::RectanglePerimeter] = new DimensionTool(DimensionTool::RectanglePerimeter, widget->getDrawWidgetProxy(), rectanglePerimeterDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::Area] = new DimensionTool(DimensionTool::Area, widget->getDrawWidgetProxy(), areaDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::RectangleArea] = new DimensionTool(DimensionTool::RectangleArea, widget->getDrawWidgetProxy(), rectangleAreaDimensionAction, this); | ||||
|     m_dimensionTools[DimensionTool::Angle] = new DimensionTool(DimensionTool::Angle, widget->getDrawWidgetProxy(), angleAction, this); | ||||
|  | ||||
|     pdf::PDFToolManager* toolManager = widget->getToolManager(); | ||||
|     for (DimensionTool* tool : m_dimensionTools) | ||||
| @@ -146,6 +158,8 @@ void DimensionsPlugin::drawPage(QPainter* painter, | ||||
|     } | ||||
|  | ||||
|     QLocale locale; | ||||
|     painter->setRenderHint(QPainter::Antialiasing, true); | ||||
|  | ||||
|     for (const Dimension& dimension : m_dimensions) | ||||
|     { | ||||
|         if (pageIndex != dimension.getPageIndex()) | ||||
| @@ -204,10 +218,89 @@ void DimensionsPlugin::drawPage(QPainter* painter, | ||||
|             } | ||||
|  | ||||
|             case Dimension::Perimeter: | ||||
|                 break; | ||||
|  | ||||
|             case Dimension::Area: | ||||
|             { | ||||
|                 const bool isArea = dimension.getType() == Dimension::Type::Area; | ||||
|                 const std::vector<QPointF>& polygon = dimension.getPolygon(); | ||||
|  | ||||
|                 qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1); | ||||
|                 qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5); | ||||
|  | ||||
|                 painter->save(); | ||||
|                 QPen pen(Qt::black); | ||||
|                 pen.setWidthF(lineSize); | ||||
|                 pen.setCosmetic(true); | ||||
|  | ||||
|                 QColor brushColor = Qt::black; | ||||
|                 brushColor.setAlphaF(0.1); | ||||
|                 painter->setPen(qMove(pen)); | ||||
|                 painter->setBrush(QBrush(brushColor, isArea ? Qt::SolidPattern : Qt::DiagCrossPattern)); | ||||
|  | ||||
|                 painter->setMatrix(pagePointToDevicePointMatrix, true); | ||||
|                 painter->drawPolygon(polygon.data(), int(polygon.size()), Qt::OddEvenFill); | ||||
|                 painter->restore(); | ||||
|  | ||||
|                 QPen penPoint(Qt::black); | ||||
|                 penPoint.setCapStyle(Qt::RoundCap); | ||||
|                 penPoint.setWidthF(pointSize); | ||||
|                 painter->setPen(penPoint); | ||||
|  | ||||
|                 QPointF centerPoint(0, 0); | ||||
|                 for (const QPointF& point : polygon) | ||||
|                 { | ||||
|                     QPointF mappedPoint = pagePointToDevicePointMatrix.map(point); | ||||
|                     centerPoint += mappedPoint; | ||||
|                     painter->drawPoint(mappedPoint); | ||||
|                 } | ||||
|  | ||||
|                 centerPoint *= 1.0 / qreal(polygon.size()); | ||||
|  | ||||
|                 QString text; | ||||
|  | ||||
|                 if (isArea) | ||||
|                 { | ||||
|                     text = tr("A = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_areaUnit.scale, 'f', 2), m_areaUnit.symbol); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     text = tr("p = %1 %2").arg(locale.toString(dimension.getMeasuredValue() * m_lengthUnit.scale, 'f', 2), m_lengthUnit.symbol); | ||||
|                 } | ||||
|                 painter->drawText(centerPoint, text); | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             case Dimension::Angular: | ||||
|             { | ||||
|                 const std::vector<QPointF>& polygon = dimension.getPolygon(); | ||||
|                 QLineF line1(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.front())); | ||||
|                 QLineF line2(pagePointToDevicePointMatrix.map(polygon[1]), pagePointToDevicePointMatrix.map(polygon.back())); | ||||
|  | ||||
|                 qreal lineSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 1); | ||||
|                 qreal pointSize = pdf::PDFWidgetUtils::scaleDPI_x(painter->device(), 5); | ||||
|  | ||||
|                 qreal maxLength = qMax(line1.length(), line2.length()); | ||||
|                 line1.setLength(maxLength); | ||||
|                 line2.setLength(maxLength); | ||||
|  | ||||
|                 QPen pen(Qt::black); | ||||
|                 pen.setWidthF(lineSize); | ||||
|                 painter->setPen(qMove(pen)); | ||||
|  | ||||
|                 painter->drawLine(line1); | ||||
|                 painter->drawLine(line2); | ||||
|  | ||||
|                 QPen penPoint(Qt::black); | ||||
|                 penPoint.setCapStyle(Qt::RoundCap); | ||||
|                 penPoint.setWidthF(pointSize); | ||||
|                 painter->setPen(penPoint); | ||||
|  | ||||
|                 painter->drawPoint(line1.p1()); | ||||
|                 painter->drawPoint(line1.p2()); | ||||
|                 painter->drawPoint(line2.p2()); | ||||
|  | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             default: | ||||
|                 Q_ASSERT(false); | ||||
|   | ||||
| @@ -21,15 +21,18 @@ | ||||
|  | ||||
| #include <QPainter> | ||||
|  | ||||
| DimensionTool::DimensionTool(DimensionTool::Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : | ||||
| DimensionTool::DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent) : | ||||
|     BaseClass(proxy, action, parent), | ||||
|     m_style(style), | ||||
|     m_previewPointPixelSize(0), | ||||
|     m_pickTool(nullptr) | ||||
| { | ||||
|     m_pickTool = new pdf::PDFPickTool(proxy, pdf::PDFPickTool::Mode::Points, this); | ||||
|     const bool isRectanglePicking = style == RectanglePerimeter || style == RectangleArea; | ||||
|     const pdf::PDFPickTool::Mode pickingMode = isRectanglePicking ? pdf::PDFPickTool::Mode::Rectangles : pdf::PDFPickTool::Mode::Points; | ||||
|     m_pickTool = new pdf::PDFPickTool(proxy, pickingMode, this); | ||||
|     addTool(m_pickTool); | ||||
|     connect(m_pickTool, &pdf::PDFPickTool::pointPicked, this, &DimensionTool::onPointPicked); | ||||
|     connect(m_pickTool, &pdf::PDFPickTool::rectanglePicked, this, &DimensionTool::onRectanglePicked); | ||||
|     m_previewPointPixelSize = pdf::PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 5); | ||||
| } | ||||
|  | ||||
| @@ -50,6 +53,12 @@ void DimensionTool::drawPage(QPainter* painter, | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (m_style == RectanglePerimeter || m_style == RectangleArea) | ||||
|     { | ||||
|         // Nothing to draw, picking tool is already drawing picked rectangle | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     painter->setPen(Qt::black); | ||||
|     const std::vector<QPointF>& points = m_pickTool->getPickedPoints(); | ||||
|     for (size_t i = 1; i < points.size(); ++i) | ||||
| @@ -92,6 +101,24 @@ void DimensionTool::onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint) | ||||
|         emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points))); | ||||
|         m_pickTool->resetTool(); | ||||
|     } | ||||
|  | ||||
|     if ((m_style == Perimeter || m_style == Area) && m_pickTool->getPickedPoints().size() == 1) | ||||
|     { | ||||
|         m_pickTool->setCustomSnapPoints(pageIndex, m_pickTool->getPickedPoints()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void DimensionTool::onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle) | ||||
| { | ||||
|     if (pageRectangle.isEmpty()) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::vector<QPointF> points = { pageRectangle.topLeft(), pageRectangle.topRight(), pageRectangle.bottomRight(), pageRectangle.bottomLeft(), pageRectangle.topLeft() }; | ||||
|     Q_ASSERT(Dimension::isComplete(getDimensionType(), points)); | ||||
|     pdf::PDFReal measuredValue = getMeasuredValue(pageIndex, points); | ||||
|     emit dimensionCreated(Dimension(getDimensionType(), pageIndex, measuredValue, qMove(points))); | ||||
| } | ||||
|  | ||||
| QPointF DimensionTool::adjustPagePoint(QPointF pagePoint) const | ||||
| @@ -155,10 +182,15 @@ Dimension::Type DimensionTool::getDimensionType() const | ||||
|             return Dimension::Type::Linear; | ||||
|  | ||||
|         case DimensionTool::Perimeter: | ||||
|         case DimensionTool::RectanglePerimeter: | ||||
|             return Dimension::Type::Perimeter; | ||||
|  | ||||
|         case DimensionTool::Area: | ||||
|         case DimensionTool::RectangleArea: | ||||
|             return Dimension::Type::Area; | ||||
|  | ||||
|         case DimensionTool::Angle: | ||||
|             return Dimension::Type::Angular; | ||||
|     } | ||||
|  | ||||
|     Q_ASSERT(false); | ||||
| @@ -204,6 +236,14 @@ pdf::PDFReal DimensionTool::getMeasuredValue(pdf::PDFInteger pageIndex, const st | ||||
|             return area * page->getUserUnit() * page->getUserUnit(); | ||||
|         } | ||||
|  | ||||
|         case Dimension::Angular: | ||||
|         { | ||||
|             Q_ASSERT(pickedPoints.size() == 3); | ||||
|             QLineF line1(pickedPoints[1], pickedPoints.front()); | ||||
|             QLineF line2(pickedPoints[1], pickedPoints.back()); | ||||
|             return line1.angleTo(line2); | ||||
|         } | ||||
|  | ||||
|         default: | ||||
|             Q_ASSERT(false); | ||||
|             break; | ||||
| @@ -223,6 +263,9 @@ bool Dimension::isComplete(Type type, const std::vector<QPointF>& polygon) | ||||
|         case Dimension::Area: | ||||
|             return polygon.size() > 2 && polygon.front() == polygon.back(); | ||||
|  | ||||
|         case Dimension::Angular: | ||||
|             return polygon.size() == 3; | ||||
|  | ||||
|         default: | ||||
|             Q_ASSERT(false); | ||||
|             break; | ||||
| @@ -259,8 +302,8 @@ DimensionUnits DimensionUnit::getAngleUnits() | ||||
| { | ||||
|     DimensionUnits units; | ||||
|  | ||||
|     units.emplace_back(qRadiansToDegrees(1.0), DimensionTool::tr("°")); | ||||
|     units.emplace_back(1.0, DimensionTool::tr("rad")); | ||||
|     units.emplace_back(1.0, DimensionTool::tr("°")); | ||||
|     units.emplace_back(qDegreesToRadians(1.0), DimensionTool::tr("rad")); | ||||
|  | ||||
|     return units; | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,8 @@ public: | ||||
|     { | ||||
|         Linear, | ||||
|         Perimeter, | ||||
|         Area | ||||
|         Area, | ||||
|         Angular | ||||
|     }; | ||||
|  | ||||
|     inline explicit Dimension() = default; | ||||
| @@ -95,7 +96,10 @@ public: | ||||
|         LinearVertical, | ||||
|         Linear, | ||||
|         Perimeter, | ||||
|         RectanglePerimeter, | ||||
|         Area, | ||||
|         RectangleArea, | ||||
|         Angle, | ||||
|         LastStyle | ||||
|     }; | ||||
|  | ||||
| @@ -114,6 +118,8 @@ signals: | ||||
|  | ||||
| private: | ||||
|     void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint); | ||||
|     void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle); | ||||
|  | ||||
|     QPointF adjustPagePoint(QPointF pagePoint) const; | ||||
|     Dimension::Type getDimensionType() const; | ||||
|     pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector<QPointF>& pickedPoints) const; | ||||
|   | ||||
| @@ -8,5 +8,8 @@ | ||||
|         <file>clear-dimensions.svg</file> | ||||
|         <file>settings.svg</file> | ||||
|         <file>show-dimensions.svg</file> | ||||
|         <file>angle.svg</file> | ||||
|         <file>rectangle-area.svg</file> | ||||
|         <file>rectangle-perimeter.svg</file> | ||||
|     </qresource> | ||||
| </RCC> | ||||
|   | ||||
							
								
								
									
										126
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/rectangle-area.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/rectangle-area.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 109 KiB | 
							
								
								
									
										107
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/rectangle-perimeter.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								PdfForQtViewerPlugins/DimensionsPlugin/rectangle-perimeter.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="30mm" | ||||
|    height="30mm" | ||||
|    viewBox="0 0 30 30" | ||||
|    version="1.1" | ||||
|    id="svg8" | ||||
|    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||
|    sodipodi:docname="rectangle-perimeter.svg"> | ||||
|   <defs | ||||
|      id="defs2"> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect831" | ||||
|        is_visible="true" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="5.6" | ||||
|      inkscape:cx="113.0623" | ||||
|      inkscape:cy="47.635251" | ||||
|      inkscape:document-units="mm" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="3840" | ||||
|      inkscape:window-height="2035" | ||||
|      inkscape:window-x="-13" | ||||
|      inkscape:window-y="-13" | ||||
|      inkscape:window-maximized="1" /> | ||||
|   <metadata | ||||
|      id="metadata5"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|         <cc:license | ||||
|            rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /> | ||||
|         <dc:creator> | ||||
|           <cc:Agent> | ||||
|             <dc:title>Jakub Melka</dc:title> | ||||
|           </cc:Agent> | ||||
|         </dc:creator> | ||||
|       </cc:Work> | ||||
|       <cc:License | ||||
|          rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Reproduction" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#Distribution" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Notice" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#Attribution" /> | ||||
|         <cc:permits | ||||
|            rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> | ||||
|         <cc:requires | ||||
|            rdf:resource="http://creativecommons.org/ns#ShareAlike" /> | ||||
|       </cc:License> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Vrstva 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-267)"> | ||||
|     <path | ||||
|        style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        d="m 11.646391,283.58184 v 0 0" | ||||
|        id="path837" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <rect | ||||
|        style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.5;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" | ||||
|        id="rect4611" | ||||
|        width="21.591888" | ||||
|        height="18.048363" | ||||
|        x="4.4790177" | ||||
|        y="273.08356" /> | ||||
|     <g | ||||
|        aria-label="o" | ||||
|        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.28888893px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" | ||||
|        id="text4615" | ||||
|        transform="translate(0.52916667)"> | ||||
|       <path | ||||
|          d="m 17.786142,281.98022 q 0,1.50482 -0.771701,2.37574 -0.771701,0.87092 -2.067057,0.87092 -1.306381,0 -2.078082,-0.87092 -0.766189,-0.87092 -0.766189,-2.37574 0,-1.50482 0.766189,-2.37574 0.771701,-0.87643 2.078082,-0.87643 1.295356,0 2.067057,0.87643 0.771701,0.87092 0.771701,2.37574 z m -1.069357,0 q 0,-1.19614 -0.468533,-1.77491 -0.468533,-0.58429 -1.300868,-0.58429 -0.84336,0 -1.311893,0.58429 -0.463021,0.57877 -0.463021,1.77491 0,1.15755 0.468533,1.75838 0.468533,0.59531 1.306381,0.59531 0.826823,0 1.295356,-0.5898 0.474045,-0.59532 0.474045,-1.76389 z" | ||||
|          style="stroke-width:0.26458332" | ||||
|          id="path4617" | ||||
|          inkscape:connector-curvature="0" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.2 KiB | 
		Reference in New Issue
	
	Block a user